From 9934a7534c3837384187ff075624b05e5203ac08 Mon Sep 17 00:00:00 2001 From: Gatsby Van Date: Fri, 19 Jan 2024 17:19:32 +0800 Subject: [PATCH] first commit, new repo branches from datalink_repo --- Makefile | 8 + README.md | 0 df_datalink_sp/bsp/Makefile | 35 + .../include/_profile_timer_hw.h | 308 + .../bsp/ps7_cortexa9_0/include/bspconfig.h | 44 + .../ps7_cortexa9_0/include/mblaze_nt_types.h | 50 + .../bsp/ps7_cortexa9_0/include/profile.h | 127 + .../bsp/ps7_cortexa9_0/include/sleep.h | 115 + .../bsp/ps7_cortexa9_0/include/smc.h | 110 + .../bsp/ps7_cortexa9_0/include/vectors.h | 84 + .../bsp/ps7_cortexa9_0/include/xadcps.h | 589 ++ .../bsp/ps7_cortexa9_0/include/xadcps_hw.h | 498 ++ .../bsp/ps7_cortexa9_0/include/xbasic_types.h | 127 + .../bsp/ps7_cortexa9_0/include/xbram.h | 223 + .../bsp/ps7_cortexa9_0/include/xbram_hw.h | 405 + .../ps7_cortexa9_0/include/xcoresightpsdcc.h | 74 + .../ps7_cortexa9_0/include/xcpu_cortexa9.h | 47 + .../bsp/ps7_cortexa9_0/include/xddrps.h | 62 + .../bsp/ps7_cortexa9_0/include/xdebug.h | 40 + .../bsp/ps7_cortexa9_0/include/xdevcfg.h | 399 + .../bsp/ps7_cortexa9_0/include/xdevcfg_hw.h | 391 + .../bsp/ps7_cortexa9_0/include/xdmaps.h | 349 + .../bsp/ps7_cortexa9_0/include/xdmaps_hw.h | 289 + .../bsp/ps7_cortexa9_0/include/xenv.h | 183 + .../ps7_cortexa9_0/include/xenv_standalone.h | 364 + .../bsp/ps7_cortexa9_0/include/xgpiops.h | 283 + .../bsp/ps7_cortexa9_0/include/xgpiops_hw.h | 168 + .../bsp/ps7_cortexa9_0/include/xil_assert.h | 191 + .../bsp/ps7_cortexa9_0/include/xil_cache.h | 118 + .../bsp/ps7_cortexa9_0/include/xil_cache_l.h | 97 + .../include/xil_cache_vxworks.h | 89 + .../bsp/ps7_cortexa9_0/include/xil_errata.h | 127 + .../ps7_cortexa9_0/include/xil_exception.h | 285 + .../bsp/ps7_cortexa9_0/include/xil_hal.h | 65 + .../bsp/ps7_cortexa9_0/include/xil_io.h | 341 + .../ps7_cortexa9_0/include/xil_macroback.h | 1056 +++ .../bsp/ps7_cortexa9_0/include/xil_mem.h | 68 + .../include/xil_misc_psreset_api.h | 273 + .../bsp/ps7_cortexa9_0/include/xil_mmu.h | 106 + .../bsp/ps7_cortexa9_0/include/xil_printf.h | 48 + .../ps7_cortexa9_0/include/xil_sleeptimer.h | 128 + .../ps7_cortexa9_0/include/xil_testcache.h | 67 + .../bsp/ps7_cortexa9_0/include/xil_testio.h | 90 + .../bsp/ps7_cortexa9_0/include/xil_testmem.h | 154 + .../bsp/ps7_cortexa9_0/include/xil_types.h | 214 + .../bsp/ps7_cortexa9_0/include/xil_util.h | 57 + .../bsp/ps7_cortexa9_0/include/xl2cc.h | 168 + .../ps7_cortexa9_0/include/xl2cc_counter.h | 110 + .../bsp/ps7_cortexa9_0/include/xparameters.h | 470 ++ .../ps7_cortexa9_0/include/xparameters_ps.h | 334 + .../ps7_cortexa9_0/include/xplatform_info.h | 120 + .../bsp/ps7_cortexa9_0/include/xpm_counter.h | 572 ++ .../bsp/ps7_cortexa9_0/include/xpseudo_asm.h | 82 + .../ps7_cortexa9_0/include/xpseudo_asm_gcc.h | 252 + .../bsp/ps7_cortexa9_0/include/xqspips.h | 804 ++ .../bsp/ps7_cortexa9_0/include/xqspips_hw.h | 421 + .../ps7_cortexa9_0/include/xreg_cortexa9.h | 587 ++ .../bsp/ps7_cortexa9_0/include/xscugic.h | 598 ++ .../bsp/ps7_cortexa9_0/include/xscugic_hw.h | 753 ++ .../bsp/ps7_cortexa9_0/include/xscutimer.h | 364 + .../bsp/ps7_cortexa9_0/include/xscutimer_hw.h | 283 + .../bsp/ps7_cortexa9_0/include/xscuwdt.h | 379 + .../bsp/ps7_cortexa9_0/include/xscuwdt_hw.h | 178 + .../bsp/ps7_cortexa9_0/include/xstatus.h | 533 ++ .../bsp/ps7_cortexa9_0/include/xtime_l.h | 104 + .../bsp/ps7_cortexa9_0/include/xuartps.h | 517 ++ .../bsp/ps7_cortexa9_0/include/xuartps_hw.h | 447 + .../libsrc/bram_v4_3/src/Makefile | 28 + .../libsrc/bram_v4_3/src/xbram.c | 145 + .../libsrc/bram_v4_3/src/xbram.h | 223 + .../libsrc/bram_v4_3/src/xbram_g.c | 104 + .../libsrc/bram_v4_3/src/xbram_hw.h | 405 + .../libsrc/bram_v4_3/src/xbram_intr.c | 234 + .../libsrc/bram_v4_3/src/xbram_selftest.c | 557 ++ .../libsrc/bram_v4_3/src/xbram_sinit.c | 101 + .../libsrc/coresightps_dcc_v1_5/src/Makefile | 40 + .../src/xcoresightpsdcc.c | 186 + .../src/xcoresightpsdcc.h | 74 + .../libsrc/cpu_cortexa9_v2_7/src/Makefile | 25 + .../cpu_cortexa9_v2_7/src/xcpu_cortexa9.h | 47 + .../libsrc/ddrps_v1_0/src/Makefile | 40 + .../libsrc/ddrps_v1_0/src/xddrps.h | 62 + .../libsrc/devcfg_v3_5/src/Makefile | 40 + .../libsrc/devcfg_v3_5/src/xdevcfg.c | 941 +++ .../libsrc/devcfg_v3_5/src/xdevcfg.h | 399 + .../libsrc/devcfg_v3_5/src/xdevcfg_g.c | 51 + .../libsrc/devcfg_v3_5/src/xdevcfg_hw.c | 109 + .../libsrc/devcfg_v3_5/src/xdevcfg_hw.h | 391 + .../libsrc/devcfg_v3_5/src/xdevcfg_intr.c | 306 + .../libsrc/devcfg_v3_5/src/xdevcfg_selftest.c | 110 + .../libsrc/devcfg_v3_5/src/xdevcfg_sinit.c | 90 + .../libsrc/dmaps_v2_4/src/Makefile | 41 + .../libsrc/dmaps_v2_4/src/xdmaps.c | 1978 +++++ .../libsrc/dmaps_v2_4/src/xdmaps.h | 349 + .../libsrc/dmaps_v2_4/src/xdmaps_g.c | 55 + .../libsrc/dmaps_v2_4/src/xdmaps_hw.c | 112 + .../libsrc/dmaps_v2_4/src/xdmaps_hw.h | 289 + .../libsrc/dmaps_v2_4/src/xdmaps_selftest.c | 106 + .../libsrc/dmaps_v2_4/src/xdmaps_sinit.c | 100 + .../libsrc/gpiops_v3_5/src/Makefile | 40 + .../libsrc/gpiops_v3_5/src/xgpiops.c | 830 ++ .../libsrc/gpiops_v3_5/src/xgpiops.h | 283 + .../libsrc/gpiops_v3_5/src/xgpiops_g.c | 51 + .../libsrc/gpiops_v3_5/src/xgpiops_hw.c | 262 + .../libsrc/gpiops_v3_5/src/xgpiops_hw.h | 168 + .../libsrc/gpiops_v3_5/src/xgpiops_intr.c | 813 ++ .../libsrc/gpiops_v3_5/src/xgpiops_selftest.c | 134 + .../libsrc/gpiops_v3_5/src/xgpiops_sinit.c | 97 + .../libsrc/qspips_v3_6/src/Makefile | 40 + .../libsrc/qspips_v3_6/src/xqspips.c | 1611 ++++ .../libsrc/qspips_v3_6/src/xqspips.h | 804 ++ .../libsrc/qspips_v3_6/src/xqspips_g.c | 53 + .../libsrc/qspips_v3_6/src/xqspips_hw.c | 220 + .../libsrc/qspips_v3_6/src/xqspips_hw.h | 421 + .../libsrc/qspips_v3_6/src/xqspips_options.c | 426 + .../libsrc/qspips_v3_6/src/xqspips_selftest.c | 135 + .../libsrc/qspips_v3_6/src/xqspips_sinit.c | 96 + .../libsrc/scugic_v4_0/src/Makefile | 40 + .../libsrc/scugic_v4_0/src/xscugic.c | 1133 +++ .../libsrc/scugic_v4_0/src/xscugic.h | 598 ++ .../libsrc/scugic_v4_0/src/xscugic_g.c | 53 + .../libsrc/scugic_v4_0/src/xscugic_hw.c | 652 ++ .../libsrc/scugic_v4_0/src/xscugic_hw.h | 753 ++ .../libsrc/scugic_v4_0/src/xscugic_intr.c | 185 + .../libsrc/scugic_v4_0/src/xscugic_selftest.c | 114 + .../libsrc/scugic_v4_0/src/xscugic_sinit.c | 101 + .../libsrc/scutimer_v2_1/src/Makefile | 40 + .../libsrc/scutimer_v2_1/src/xscutimer.c | 282 + .../libsrc/scutimer_v2_1/src/xscutimer.h | 364 + .../libsrc/scutimer_v2_1/src/xscutimer_g.c | 51 + .../libsrc/scutimer_v2_1/src/xscutimer_hw.h | 283 + .../scutimer_v2_1/src/xscutimer_selftest.c | 135 + .../scutimer_v2_1/src/xscutimer_sinit.c | 92 + .../libsrc/scuwdt_v2_1/src/Makefile | 40 + .../libsrc/scuwdt_v2_1/src/xscuwdt.c | 213 + .../libsrc/scuwdt_v2_1/src/xscuwdt.h | 379 + .../libsrc/scuwdt_v2_1/src/xscuwdt_g.c | 51 + .../libsrc/scuwdt_v2_1/src/xscuwdt_hw.h | 178 + .../libsrc/scuwdt_v2_1/src/xscuwdt_selftest.c | 127 + .../libsrc/scuwdt_v2_1/src/xscuwdt_sinit.c | 92 + .../libsrc/standalone_v7_0/src/Makefile | 83 + .../libsrc/standalone_v7_0/src/_exit.c | 40 + .../libsrc/standalone_v7_0/src/_open.c | 50 + .../libsrc/standalone_v7_0/src/_sbrk.c | 61 + .../libsrc/standalone_v7_0/src/abort.c | 38 + .../libsrc/standalone_v7_0/src/asm_vectors.S | 199 + .../libsrc/standalone_v7_0/src/boot.S | 492 ++ .../libsrc/standalone_v7_0/src/bspconfig.h | 44 + .../libsrc/standalone_v7_0/src/changelog.txt | 593 ++ .../libsrc/standalone_v7_0/src/close.c | 45 + .../libsrc/standalone_v7_0/src/config.make | 3 + .../libsrc/standalone_v7_0/src/cpu_init.S | 76 + .../libsrc/standalone_v7_0/src/errno.c | 47 + .../libsrc/standalone_v7_0/src/fcntl.c | 42 + .../libsrc/standalone_v7_0/src/fstat.c | 46 + .../libsrc/standalone_v7_0/src/getpid.c | 47 + .../libsrc/standalone_v7_0/src/inbyte.c | 14 + .../libsrc/standalone_v7_0/src/isatty.c | 52 + .../libsrc/standalone_v7_0/src/kill.c | 56 + .../libsrc/standalone_v7_0/src/lseek.c | 57 + .../libsrc/standalone_v7_0/src/open.c | 49 + .../libsrc/standalone_v7_0/src/outbyte.c | 15 + .../libsrc/standalone_v7_0/src/print.c | 36 + .../standalone_v7_0/src/profile/Makefile | 74 + .../src/profile/_profile_clean.c | 43 + .../src/profile/_profile_init.c | 86 + .../src/profile/_profile_timer_hw.c | 383 + .../src/profile/_profile_timer_hw.h | 308 + .../standalone_v7_0/src/profile/dummy.S | 60 + .../src/profile/mblaze_nt_types.h | 50 + .../standalone_v7_0/src/profile/profile.h | 127 + .../standalone_v7_0/src/profile/profile_cg.c | 167 + .../src/profile/profile_config.h | 52 + .../src/profile/profile_hist.c | 67 + .../src/profile/profile_mcount_arm.S | 41 + .../src/profile/profile_mcount_mb.S | 65 + .../src/profile/profile_mcount_ppc.S | 67 + .../libsrc/standalone_v7_0/src/putnum.c | 59 + .../libsrc/standalone_v7_0/src/read.c | 100 + .../libsrc/standalone_v7_0/src/sbrk.c | 57 + .../libsrc/standalone_v7_0/src/sleep.c | 88 + .../libsrc/standalone_v7_0/src/sleep.h | 115 + .../libsrc/standalone_v7_0/src/smc.h | 110 + .../standalone_v7_0/src/translation_table.S | 226 + .../libsrc/standalone_v7_0/src/unlink.c | 46 + .../libsrc/standalone_v7_0/src/usleep.c | 103 + .../libsrc/standalone_v7_0/src/vectors.c | 227 + .../libsrc/standalone_v7_0/src/vectors.h | 84 + .../libsrc/standalone_v7_0/src/write.c | 117 + .../libsrc/standalone_v7_0/src/xbasic_types.h | 127 + .../libsrc/standalone_v7_0/src/xdebug.h | 40 + .../libsrc/standalone_v7_0/src/xenv.h | 183 + .../standalone_v7_0/src/xenv_standalone.h | 364 + .../libsrc/standalone_v7_0/src/xil-crt0.S | 155 + .../libsrc/standalone_v7_0/src/xil_assert.c | 143 + .../libsrc/standalone_v7_0/src/xil_assert.h | 191 + .../libsrc/standalone_v7_0/src/xil_cache.c | 1637 ++++ .../libsrc/standalone_v7_0/src/xil_cache.h | 118 + .../libsrc/standalone_v7_0/src/xil_cache_l.h | 97 + .../standalone_v7_0/src/xil_cache_vxworks.h | 89 + .../libsrc/standalone_v7_0/src/xil_errata.h | 127 + .../standalone_v7_0/src/xil_exception.c | 379 + .../standalone_v7_0/src/xil_exception.h | 285 + .../libsrc/standalone_v7_0/src/xil_hal.h | 65 + .../libsrc/standalone_v7_0/src/xil_io.c | 98 + .../libsrc/standalone_v7_0/src/xil_io.h | 341 + .../standalone_v7_0/src/xil_macroback.h | 1056 +++ .../libsrc/standalone_v7_0/src/xil_mem.c | 85 + .../libsrc/standalone_v7_0/src/xil_mem.h | 68 + .../src/xil_misc_psreset_api.c | 520 ++ .../src/xil_misc_psreset_api.h | 273 + .../libsrc/standalone_v7_0/src/xil_mmu.c | 227 + .../libsrc/standalone_v7_0/src/xil_mmu.h | 106 + .../libsrc/standalone_v7_0/src/xil_printf.c | 443 + .../libsrc/standalone_v7_0/src/xil_printf.h | 48 + .../standalone_v7_0/src/xil_sleepcommon.c | 102 + .../standalone_v7_0/src/xil_sleeptimer.c | 162 + .../standalone_v7_0/src/xil_sleeptimer.h | 128 + .../standalone_v7_0/src/xil_testcache.c | 367 + .../standalone_v7_0/src/xil_testcache.h | 67 + .../libsrc/standalone_v7_0/src/xil_testio.c | 295 + .../libsrc/standalone_v7_0/src/xil_testio.h | 90 + .../libsrc/standalone_v7_0/src/xil_testmem.c | 864 ++ .../libsrc/standalone_v7_0/src/xil_testmem.h | 154 + .../libsrc/standalone_v7_0/src/xil_types.h | 214 + .../libsrc/standalone_v7_0/src/xil_util.c | 175 + .../libsrc/standalone_v7_0/src/xil_util.h | 57 + .../libsrc/standalone_v7_0/src/xl2cc.h | 168 + .../standalone_v7_0/src/xl2cc_counter.c | 165 + .../standalone_v7_0/src/xl2cc_counter.h | 110 + .../standalone_v7_0/src/xparameters_ps.h | 334 + .../standalone_v7_0/src/xplatform_info.c | 162 + .../standalone_v7_0/src/xplatform_info.h | 120 + .../libsrc/standalone_v7_0/src/xpm_counter.c | 293 + .../libsrc/standalone_v7_0/src/xpm_counter.h | 572 ++ .../libsrc/standalone_v7_0/src/xpseudo_asm.h | 82 + .../standalone_v7_0/src/xpseudo_asm_gcc.h | 252 + .../standalone_v7_0/src/xreg_cortexa9.h | 587 ++ .../libsrc/standalone_v7_0/src/xstatus.h | 533 ++ .../libsrc/standalone_v7_0/src/xtime_l.c | 118 + .../libsrc/standalone_v7_0/src/xtime_l.h | 104 + .../libsrc/uartps_v3_7/src/Makefile | 40 + .../libsrc/uartps_v3_7/src/xuartps.c | 642 ++ .../libsrc/uartps_v3_7/src/xuartps.h | 517 ++ .../libsrc/uartps_v3_7/src/xuartps_g.c | 53 + .../libsrc/uartps_v3_7/src/xuartps_hw.c | 176 + .../libsrc/uartps_v3_7/src/xuartps_hw.h | 447 + .../libsrc/uartps_v3_7/src/xuartps_intr.c | 447 + .../libsrc/uartps_v3_7/src/xuartps_options.c | 760 ++ .../libsrc/uartps_v3_7/src/xuartps_selftest.c | 162 + .../libsrc/uartps_v3_7/src/xuartps_sinit.c | 95 + .../libsrc/xadcps_v2_3/src/Makefile | 40 + .../libsrc/xadcps_v2_3/src/xadcps.c | 1830 ++++ .../libsrc/xadcps_v2_3/src/xadcps.h | 589 ++ .../libsrc/xadcps_v2_3/src/xadcps_g.c | 51 + .../libsrc/xadcps_v2_3/src/xadcps_hw.h | 498 ++ .../libsrc/xadcps_v2_3/src/xadcps_intr.c | 246 + .../libsrc/xadcps_v2_3/src/xadcps_selftest.c | 137 + .../libsrc/xadcps_v2_3/src/xadcps_sinit.c | 99 + df_datalink_sp/bsp/system.mss | 232 + df_datalink_sp/build/Xilinx.spec | 2 + df_datalink_sp/build/makefile | 82 + df_datalink_sp/build/objects.mk | 8 + df_datalink_sp/build/sources.mk | 34 + .../build/src/dev_profile/subdir.mk | 39 + .../build/src/drivers/adc/ad9694/subdir.mk | 24 + .../build/src/drivers/api/subdir.mk | 39 + .../src/drivers/axi_core/axi_dmac/subdir.mk | 24 + .../src/drivers/axi_core/spi_engine/subdir.mk | 24 + .../src/drivers/frequency/hmc7044/subdir.mk | 24 + .../build/src/drivers/platform/subdir.mk | 48 + .../drivers/rf-transceiver/ad9361/subdir.mk | 33 + .../rf-transceiver/ad9361_reg/subdir.mk | 24 + .../networking/link_layer/geometry/subdir.mk | 30 + .../build/src/networking/link_layer/subdir.mk | 42 + .../build/src/networking/phy_layer/subdir.mk | 27 + df_datalink_sp/build/src/subdir.mk | 30 + df_datalink_sp/build/src/systembus/subdir.mk | 27 + df_datalink_sp/build/src/util/subdir.mk | 36 + df_datalink_sp/src/Xilinx.spec | 2 + df_datalink_sp/src/config/app_config.h | 194 + .../src/dev_profile/ad9361_profile.c | 340 + .../src/dev_profile/ad9361_reg_profile.c | 1746 ++++ df_datalink_sp/src/dev_profile/dev_profile.h | 30 + .../src/dev_profile/global_timer_profile.c | 11 + .../src/dev_profile/hmc7044_profile.c | 132 + df_datalink_sp/src/dev_profile/intc_profile.c | 13 + .../src/dev_profile/timer_profile.c | 17 + .../src/drivers/adc/ad9694/ad9694.c | 128 + .../src/drivers/adc/ad9694/ad9694.h | 231 + df_datalink_sp/src/drivers/api/gpio.c | 241 + df_datalink_sp/src/drivers/api/i2c.c | 135 + df_datalink_sp/src/drivers/api/irq.c | 229 + df_datalink_sp/src/drivers/api/spi.c | 161 + df_datalink_sp/src/drivers/api/timer.c | 211 + df_datalink_sp/src/drivers/api/trng.c | 111 + .../src/drivers/axi_core/axi_dmac/axi_dmac.c | 547 ++ .../src/drivers/axi_core/axi_dmac/axi_dmac.h | 156 + .../drivers/axi_core/spi_engine/spi_engine.c | 997 +++ .../drivers/axi_core/spi_engine/spi_engine.h | 229 + .../axi_core/spi_engine/spi_engine_private.h | 154 + .../src/drivers/frequency/hmc7044/hmc7044.c | 927 ++ .../src/drivers/frequency/hmc7044/hmc7044.h | 276 + .../src/drivers/platform/xilinx_axi_io.c | 79 + .../src/drivers/platform/xilinx_delay.c | 100 + .../src/drivers/platform/xilinx_gpio.c | 464 + .../src/drivers/platform/xilinx_gpio.h | 95 + .../src/drivers/platform/xilinx_gpio_irq.c | 360 + .../src/drivers/platform/xilinx_gpio_irq.h | 92 + .../src/drivers/platform/xilinx_i2c.c | 514 ++ .../src/drivers/platform/xilinx_i2c.h | 115 + .../src/drivers/platform/xilinx_irq.c | 433 + .../src/drivers/platform/xilinx_irq.h | 91 + .../src/drivers/platform/xilinx_spi.c | 462 + .../src/drivers/platform/xilinx_spi.h | 115 + .../src/drivers/platform/xilinx_spi_pl.c | 533 ++ .../src/drivers/platform/xilinx_timer.c | 456 + .../src/drivers/platform/xilinx_timer.h | 101 + .../drivers/rf-transceiver/ad9361/ad9361.c | 7475 +++++++++++++++++ .../drivers/rf-transceiver/ad9361/ad9361.h | 3568 ++++++++ .../rf-transceiver/ad9361/ad9361_api.c | 2157 +++++ .../rf-transceiver/ad9361/ad9361_api.h | 552 ++ .../rf-transceiver/ad9361/ad9361_conv.c | 86 + .../rf-transceiver/ad9361/ad9361_util.c | 335 + .../rf-transceiver/ad9361/ad9361_util.h | 120 + .../drivers/rf-transceiver/ad9361/common.h | 66 + .../rf-transceiver/ad9361_reg/ad9361_reg.c | 151 + .../rf-transceiver/ad9361_reg/ad9361_reg.h | 104 + df_datalink_sp/src/include/axi_io.h | 59 + df_datalink_sp/src/include/circ_queue.h | 111 + df_datalink_sp/src/include/common.h | 92 + df_datalink_sp/src/include/delay.h | 70 + df_datalink_sp/src/include/error.h | 47 + df_datalink_sp/src/include/global_timer.h | 95 + df_datalink_sp/src/include/gpio.h | 188 + df_datalink_sp/src/include/i2c.h | 134 + df_datalink_sp/src/include/irq.h | 235 + df_datalink_sp/src/include/list.h | 327 + df_datalink_sp/src/include/spi.h | 209 + df_datalink_sp/src/include/timer.h | 159 + df_datalink_sp/src/include/trng.h | 115 + df_datalink_sp/src/include/util.h | 195 + df_datalink_sp/src/lscript.ld | 291 + df_datalink_sp/src/main.c | 777 ++ .../src/networking/link_layer/framing.c | 141 + .../networking/link_layer/geometry/coord.c | 211 + .../networking/link_layer/geometry/coord.h | 80 + .../link_layer/geometry/eulerangles.c | 61 + .../link_layer/geometry/eulerangles.h | 55 + .../link_layer/geometry/quaternion.c | 452 + .../link_layer/geometry/quaternion.h | 109 + .../src/networking/link_layer/link_layer.c | 1234 +++ .../src/networking/link_layer/link_layer.h | 145 + .../networking/link_layer/link_layer_types.h | 212 + .../src/networking/link_layer/msg_def.h | 68 + .../src/networking/link_layer/node_list.c | 527 ++ .../src/networking/link_layer/node_list.h | 66 + .../src/networking/link_layer/routine_table.c | 928 ++ .../src/networking/link_layer/scan.c | 354 + .../src/networking/link_layer/service.c | 524 ++ .../src/networking/link_layer/time_sync.c | 126 + .../src/networking/phy_layer/phy_antenna.c | 348 + .../src/networking/phy_layer/phy_layer.c | 921 ++ .../src/networking/phy_layer/phy_layer.h | 249 + .../src/networking/phy_layer/phy_reg.h | 334 + df_datalink_sp/src/system_monitor.c | 625 ++ df_datalink_sp/src/system_monitor.h | 160 + df_datalink_sp/src/systembus/systembus.c | 579 ++ df_datalink_sp/src/systembus/systembus.h | 65 + df_datalink_sp/src/systembus/systembus_uart.c | 248 + df_datalink_sp/src/systembus/systembus_uart.h | 99 + df_datalink_sp/src/util/circ_queue.c | 141 + df_datalink_sp/src/util/common.c | 46 + df_datalink_sp/src/util/crc.c | 439 + df_datalink_sp/src/util/list.c | 887 ++ df_datalink_sp/src/util/tables.txt | 231 + df_datalink_sp/src/util/util.c | 368 + unit_test_framework.h | 332 + 378 files changed, 103816 insertions(+) create mode 100644 Makefile create mode 100644 README.md create mode 100644 df_datalink_sp/bsp/Makefile create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/_profile_timer_hw.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/bspconfig.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/mblaze_nt_types.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/profile.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/sleep.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/smc.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/vectors.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xadcps.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xadcps_hw.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xbasic_types.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xbram.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xbram_hw.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xcoresightpsdcc.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xcpu_cortexa9.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xddrps.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xdebug.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xdevcfg.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xdevcfg_hw.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xdmaps.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xdmaps_hw.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xenv.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xenv_standalone.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xgpiops.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xgpiops_hw.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_assert.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_cache.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_cache_l.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_cache_vxworks.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_errata.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_exception.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_hal.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_io.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_macroback.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_mem.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_misc_psreset_api.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_mmu.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_printf.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_sleeptimer.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_testcache.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_testio.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_testmem.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_types.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_util.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xl2cc.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xl2cc_counter.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xparameters.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xparameters_ps.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xplatform_info.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xpm_counter.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xpseudo_asm.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xpseudo_asm_gcc.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xqspips.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xqspips_hw.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xreg_cortexa9.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xscugic.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xscugic_hw.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xscutimer.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xscutimer_hw.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xscuwdt.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xscuwdt_hw.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xstatus.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xtime_l.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xuartps.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/include/xuartps_hw.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/Makefile create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram_g.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram_hw.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram_intr.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram_selftest.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram_sinit.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/coresightps_dcc_v1_5/src/Makefile create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/coresightps_dcc_v1_5/src/xcoresightpsdcc.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/coresightps_dcc_v1_5/src/xcoresightpsdcc.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/cpu_cortexa9_v2_7/src/Makefile create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/cpu_cortexa9_v2_7/src/xcpu_cortexa9.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/ddrps_v1_0/src/Makefile create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/ddrps_v1_0/src/xddrps.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/Makefile create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg_g.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg_hw.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg_hw.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg_intr.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg_selftest.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg_sinit.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/Makefile create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps_g.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps_hw.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps_hw.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps_selftest.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps_sinit.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/Makefile create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops_g.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops_hw.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops_hw.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops_intr.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops_selftest.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops_sinit.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/Makefile create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips_g.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips_hw.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips_hw.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips_options.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips_selftest.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips_sinit.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/Makefile create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic_g.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic_hw.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic_hw.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic_intr.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic_selftest.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic_sinit.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/Makefile create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/xscutimer.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/xscutimer.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/xscutimer_g.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/xscutimer_hw.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/xscutimer_selftest.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/xscutimer_sinit.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/Makefile create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/xscuwdt.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/xscuwdt.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/xscuwdt_g.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/xscuwdt_hw.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/xscuwdt_selftest.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/xscuwdt_sinit.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/Makefile create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/_exit.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/_open.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/_sbrk.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/abort.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/asm_vectors.S create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/boot.S create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/bspconfig.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/changelog.txt create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/close.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/config.make create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/cpu_init.S create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/errno.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/fcntl.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/fstat.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/getpid.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/inbyte.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/isatty.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/kill.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/lseek.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/open.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/outbyte.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/print.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/Makefile create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/_profile_clean.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/_profile_init.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/_profile_timer_hw.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/_profile_timer_hw.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/dummy.S create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/mblaze_nt_types.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/profile.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/profile_cg.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/profile_config.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/profile_hist.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/profile_mcount_arm.S create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/profile_mcount_mb.S create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/profile_mcount_ppc.S create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/putnum.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/read.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/sbrk.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/sleep.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/sleep.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/smc.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/translation_table.S create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/unlink.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/usleep.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/vectors.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/vectors.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/write.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xbasic_types.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xdebug.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xenv.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xenv_standalone.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil-crt0.S create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_assert.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_assert.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_cache.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_cache.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_cache_l.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_cache_vxworks.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_errata.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_exception.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_exception.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_hal.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_io.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_io.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_macroback.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_mem.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_mem.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_misc_psreset_api.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_misc_psreset_api.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_mmu.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_mmu.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_printf.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_printf.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_sleepcommon.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_sleeptimer.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_sleeptimer.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_testcache.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_testcache.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_testio.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_testio.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_testmem.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_testmem.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_types.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_util.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_util.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xl2cc.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xl2cc_counter.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xl2cc_counter.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xparameters_ps.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xplatform_info.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xplatform_info.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xpm_counter.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xpm_counter.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xpseudo_asm.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xpseudo_asm_gcc.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xreg_cortexa9.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xstatus.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xtime_l.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xtime_l.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/Makefile create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_g.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_hw.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_hw.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_intr.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_options.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_selftest.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_sinit.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/Makefile create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/xadcps.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/xadcps.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/xadcps_g.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/xadcps_hw.h create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/xadcps_intr.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/xadcps_selftest.c create mode 100644 df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/xadcps_sinit.c create mode 100644 df_datalink_sp/bsp/system.mss create mode 100644 df_datalink_sp/build/Xilinx.spec create mode 100644 df_datalink_sp/build/makefile create mode 100644 df_datalink_sp/build/objects.mk create mode 100644 df_datalink_sp/build/sources.mk create mode 100644 df_datalink_sp/build/src/dev_profile/subdir.mk create mode 100644 df_datalink_sp/build/src/drivers/adc/ad9694/subdir.mk create mode 100644 df_datalink_sp/build/src/drivers/api/subdir.mk create mode 100644 df_datalink_sp/build/src/drivers/axi_core/axi_dmac/subdir.mk create mode 100644 df_datalink_sp/build/src/drivers/axi_core/spi_engine/subdir.mk create mode 100644 df_datalink_sp/build/src/drivers/frequency/hmc7044/subdir.mk create mode 100644 df_datalink_sp/build/src/drivers/platform/subdir.mk create mode 100644 df_datalink_sp/build/src/drivers/rf-transceiver/ad9361/subdir.mk create mode 100644 df_datalink_sp/build/src/drivers/rf-transceiver/ad9361_reg/subdir.mk create mode 100644 df_datalink_sp/build/src/networking/link_layer/geometry/subdir.mk create mode 100644 df_datalink_sp/build/src/networking/link_layer/subdir.mk create mode 100644 df_datalink_sp/build/src/networking/phy_layer/subdir.mk create mode 100644 df_datalink_sp/build/src/subdir.mk create mode 100644 df_datalink_sp/build/src/systembus/subdir.mk create mode 100644 df_datalink_sp/build/src/util/subdir.mk create mode 100644 df_datalink_sp/src/Xilinx.spec create mode 100644 df_datalink_sp/src/config/app_config.h create mode 100644 df_datalink_sp/src/dev_profile/ad9361_profile.c create mode 100644 df_datalink_sp/src/dev_profile/ad9361_reg_profile.c create mode 100644 df_datalink_sp/src/dev_profile/dev_profile.h create mode 100644 df_datalink_sp/src/dev_profile/global_timer_profile.c create mode 100644 df_datalink_sp/src/dev_profile/hmc7044_profile.c create mode 100644 df_datalink_sp/src/dev_profile/intc_profile.c create mode 100644 df_datalink_sp/src/dev_profile/timer_profile.c create mode 100644 df_datalink_sp/src/drivers/adc/ad9694/ad9694.c create mode 100644 df_datalink_sp/src/drivers/adc/ad9694/ad9694.h create mode 100644 df_datalink_sp/src/drivers/api/gpio.c create mode 100644 df_datalink_sp/src/drivers/api/i2c.c create mode 100644 df_datalink_sp/src/drivers/api/irq.c create mode 100644 df_datalink_sp/src/drivers/api/spi.c create mode 100644 df_datalink_sp/src/drivers/api/timer.c create mode 100644 df_datalink_sp/src/drivers/api/trng.c create mode 100644 df_datalink_sp/src/drivers/axi_core/axi_dmac/axi_dmac.c create mode 100644 df_datalink_sp/src/drivers/axi_core/axi_dmac/axi_dmac.h create mode 100644 df_datalink_sp/src/drivers/axi_core/spi_engine/spi_engine.c create mode 100644 df_datalink_sp/src/drivers/axi_core/spi_engine/spi_engine.h create mode 100644 df_datalink_sp/src/drivers/axi_core/spi_engine/spi_engine_private.h create mode 100644 df_datalink_sp/src/drivers/frequency/hmc7044/hmc7044.c create mode 100644 df_datalink_sp/src/drivers/frequency/hmc7044/hmc7044.h create mode 100644 df_datalink_sp/src/drivers/platform/xilinx_axi_io.c create mode 100644 df_datalink_sp/src/drivers/platform/xilinx_delay.c create mode 100644 df_datalink_sp/src/drivers/platform/xilinx_gpio.c create mode 100644 df_datalink_sp/src/drivers/platform/xilinx_gpio.h create mode 100644 df_datalink_sp/src/drivers/platform/xilinx_gpio_irq.c create mode 100644 df_datalink_sp/src/drivers/platform/xilinx_gpio_irq.h create mode 100644 df_datalink_sp/src/drivers/platform/xilinx_i2c.c create mode 100644 df_datalink_sp/src/drivers/platform/xilinx_i2c.h create mode 100644 df_datalink_sp/src/drivers/platform/xilinx_irq.c create mode 100644 df_datalink_sp/src/drivers/platform/xilinx_irq.h create mode 100644 df_datalink_sp/src/drivers/platform/xilinx_spi.c create mode 100644 df_datalink_sp/src/drivers/platform/xilinx_spi.h create mode 100644 df_datalink_sp/src/drivers/platform/xilinx_spi_pl.c create mode 100644 df_datalink_sp/src/drivers/platform/xilinx_timer.c create mode 100644 df_datalink_sp/src/drivers/platform/xilinx_timer.h create mode 100644 df_datalink_sp/src/drivers/rf-transceiver/ad9361/ad9361.c create mode 100644 df_datalink_sp/src/drivers/rf-transceiver/ad9361/ad9361.h create mode 100644 df_datalink_sp/src/drivers/rf-transceiver/ad9361/ad9361_api.c create mode 100644 df_datalink_sp/src/drivers/rf-transceiver/ad9361/ad9361_api.h create mode 100644 df_datalink_sp/src/drivers/rf-transceiver/ad9361/ad9361_conv.c create mode 100644 df_datalink_sp/src/drivers/rf-transceiver/ad9361/ad9361_util.c create mode 100644 df_datalink_sp/src/drivers/rf-transceiver/ad9361/ad9361_util.h create mode 100644 df_datalink_sp/src/drivers/rf-transceiver/ad9361/common.h create mode 100644 df_datalink_sp/src/drivers/rf-transceiver/ad9361_reg/ad9361_reg.c create mode 100644 df_datalink_sp/src/drivers/rf-transceiver/ad9361_reg/ad9361_reg.h create mode 100644 df_datalink_sp/src/include/axi_io.h create mode 100644 df_datalink_sp/src/include/circ_queue.h create mode 100644 df_datalink_sp/src/include/common.h create mode 100644 df_datalink_sp/src/include/delay.h create mode 100644 df_datalink_sp/src/include/error.h create mode 100644 df_datalink_sp/src/include/global_timer.h create mode 100644 df_datalink_sp/src/include/gpio.h create mode 100644 df_datalink_sp/src/include/i2c.h create mode 100644 df_datalink_sp/src/include/irq.h create mode 100644 df_datalink_sp/src/include/list.h create mode 100644 df_datalink_sp/src/include/spi.h create mode 100644 df_datalink_sp/src/include/timer.h create mode 100644 df_datalink_sp/src/include/trng.h create mode 100644 df_datalink_sp/src/include/util.h create mode 100644 df_datalink_sp/src/lscript.ld create mode 100644 df_datalink_sp/src/main.c create mode 100644 df_datalink_sp/src/networking/link_layer/framing.c create mode 100644 df_datalink_sp/src/networking/link_layer/geometry/coord.c create mode 100644 df_datalink_sp/src/networking/link_layer/geometry/coord.h create mode 100644 df_datalink_sp/src/networking/link_layer/geometry/eulerangles.c create mode 100644 df_datalink_sp/src/networking/link_layer/geometry/eulerangles.h create mode 100644 df_datalink_sp/src/networking/link_layer/geometry/quaternion.c create mode 100644 df_datalink_sp/src/networking/link_layer/geometry/quaternion.h create mode 100644 df_datalink_sp/src/networking/link_layer/link_layer.c create mode 100644 df_datalink_sp/src/networking/link_layer/link_layer.h create mode 100644 df_datalink_sp/src/networking/link_layer/link_layer_types.h create mode 100644 df_datalink_sp/src/networking/link_layer/msg_def.h create mode 100644 df_datalink_sp/src/networking/link_layer/node_list.c create mode 100644 df_datalink_sp/src/networking/link_layer/node_list.h create mode 100644 df_datalink_sp/src/networking/link_layer/routine_table.c create mode 100644 df_datalink_sp/src/networking/link_layer/scan.c create mode 100644 df_datalink_sp/src/networking/link_layer/service.c create mode 100644 df_datalink_sp/src/networking/link_layer/time_sync.c create mode 100644 df_datalink_sp/src/networking/phy_layer/phy_antenna.c create mode 100644 df_datalink_sp/src/networking/phy_layer/phy_layer.c create mode 100644 df_datalink_sp/src/networking/phy_layer/phy_layer.h create mode 100644 df_datalink_sp/src/networking/phy_layer/phy_reg.h create mode 100644 df_datalink_sp/src/system_monitor.c create mode 100644 df_datalink_sp/src/system_monitor.h create mode 100644 df_datalink_sp/src/systembus/systembus.c create mode 100644 df_datalink_sp/src/systembus/systembus.h create mode 100644 df_datalink_sp/src/systembus/systembus_uart.c create mode 100644 df_datalink_sp/src/systembus/systembus_uart.h create mode 100644 df_datalink_sp/src/util/circ_queue.c create mode 100644 df_datalink_sp/src/util/common.c create mode 100644 df_datalink_sp/src/util/crc.c create mode 100644 df_datalink_sp/src/util/list.c create mode 100644 df_datalink_sp/src/util/tables.txt create mode 100644 df_datalink_sp/src/util/util.c create mode 100644 unit_test_framework.h diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e3124b8 --- /dev/null +++ b/Makefile @@ -0,0 +1,8 @@ +DIR := $(shell pwd) + +compile_test: + cd $(DIR)/df_datalink_sp/build && make all + +clean: + cd $(DIR)/df_datalink_sp/build && make clean +.PHONY: clean compile_test \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/df_datalink_sp/bsp/Makefile b/df_datalink_sp/bsp/Makefile new file mode 100644 index 0000000..a21f237 --- /dev/null +++ b/df_datalink_sp/bsp/Makefile @@ -0,0 +1,35 @@ +# Makefile generated by Xilinx. + +PROCESSOR = ps7_cortexa9_0 +LIBRARIES = ${PROCESSOR}/lib/libxil.a +BSP_MAKEFILES := $(wildcard $(PROCESSOR)/libsrc/*/src/Makefile) +SUBDIRS := $(patsubst %/Makefile, %, $(BSP_MAKEFILES)) + +ifneq (,$(findstring win,$(RDI_PLATFORM))) + SHELL = CMD +endif + +all: libs + @echo 'Finished building libraries' + +include: $(addsuffix /make.include,$(SUBDIRS)) + +libs: $(addsuffix /make.libs,$(SUBDIRS)) + +clean: $(addsuffix /make.clean,$(SUBDIRS)) + +$(PROCESSOR)/lib/libxil.a: $(PROCESSOR)/lib/libxil_init.a + cp -f $< $@ + +%/make.include: $(if $(wildcard $(PROCESSOR)/lib/libxil_init.a),$(PROCESSOR)/lib/libxil.a,) + @echo "Running Make include in $(subst /make.include,,$@)" + $(MAKE) -C $(subst /make.include,,$@) -s include "SHELL=$(SHELL)" "COMPILER=$(CC)" "ARCHIVER=arm-none-eabi-ar" "COMPILER_FLAGS= -O2 -c" "EXTRA_COMPILER_FLAGS=-DDEBUG -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -nostartfiles -g -Wall -Wformat=2 -Wextra" + +%/make.libs: include + @echo "Running Make libs in $(subst /make.libs,,$@)" + $(MAKE) -C $(subst /make.libs,,$@) -s libs "SHELL=$(SHELL)" "COMPILER=$(CC)" "ARCHIVER=arm-none-eabi-ar" "COMPILER_FLAGS= -O2 -c" "EXTRA_COMPILER_FLAGS=-DDEBUG -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -nostartfiles -g -Wall -Wformat=2 -Wextra" + +%/make.clean: + $(MAKE) -C $(subst /make.clean,,$@) -s clean +clean: + rm -f ${PROCESSOR}/lib/libxil.a diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/_profile_timer_hw.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/_profile_timer_hw.h new file mode 100644 index 0000000..1647600 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/_profile_timer_hw.h @@ -0,0 +1,308 @@ +/****************************************************************************** +* +* Copyright (C) 2004 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +****************************************************************************** +* +* _program_timer_hw.h: +* Timer related functions +* +******************************************************************************/ + +#ifndef PROFILE_TIMER_HW_H +#define PROFILE_TIMER_HW_H + +#include "profile.h" + +#ifdef PROC_PPC +#if defined __GNUC__ +# define SYNCHRONIZE_IO __asm__ volatile ("eieio") +#elif defined __DCC__ +# define SYNCHRONIZE_IO __asm volatile(" eieio") +#else +# define SYNCHRONIZE_IO +#endif +#endif + +#ifdef PROC_PPC +#define ProfIo_In32(InputPtr) { (*(volatile u32 *)(InputPtr)); SYNCHRONIZE_IO; } +#define ProfIo_Out32(OutputPtr, Value) { (*(volatile u32 *)(OutputPtr) = Value); SYNCHRONIZE_IO; } +#else +#define ProfIo_In32(InputPtr) (*(volatile u32 *)(InputPtr)); +#define ProfIo_Out32(OutputPtr, Value) { (*(volatile u32 *)(OutputPtr) = (Value)); } +#endif + +#define ProfTmrCtr_mWriteReg(BaseAddress, TmrCtrNumber, RegOffset, ValueToWrite)\ + ProfIo_Out32(((u32)(BaseAddress) + (u32)XTmrCtr_Offsets[(TmrCtrNumber)] + \ + (u32)(RegOffset)), (u32)(ValueToWrite)) + +#define ProfTimerCtr_mReadReg(BaseAddress, TmrCtrNumber, RegOffset) \ + ProfIo_In32((u32)(BaseAddress) + (u32)XTmrCtr_Offsets[(TmrCtrNumber)] + (u32)(RegOffset)) + +#define ProfTmrCtr_mSetControlStatusReg(BaseAddress, TmrCtrNumber, RegisterValue)\ + ProfTmrCtr_mWriteReg((BaseAddress), (TmrCtrNumber), XTC_TCSR_OFFSET, \ + (RegisterValue)) + +#define ProfTmrCtr_mGetControlStatusReg(BaseAddress, TmrCtrNumber) \ + ProfTimerCtr_mReadReg((u32)(BaseAddress), (TmrCtrNumber), XTC_TCSR_OFFSET) + + + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef PROC_PPC +#include "xexception_l.h" +#include "xtime_l.h" +#include "xpseudo_asm.h" +#endif + +#ifdef TIMER_CONNECT_INTC +#include "xintc_l.h" +#include "xintc.h" +#endif /* TIMER_CONNECT_INTC */ + +#if (!defined PPC_PIT_INTERRUPT && !defined PROC_CORTEXA9) +#include "xtmrctr_l.h" +#endif + +#ifdef PROC_CORTEXA9 +#include "xscutimer_hw.h" +#include "xscugic.h" +#endif + +extern u32 timer_clk_ticks ; + +/*-------------------------------------------------------------------- + * PowerPC Target - Timer related functions + *-------------------------------------------------------------------- */ +#ifdef PROC_PPC + +#ifdef PPC_PIT_INTERRUPT +u32 timer_lo_clk_ticks ; /* Clk ticks when Timer is disabled in CG */ +#endif + +#ifdef PROC_PPC440 +#define XREG_TCR_PIT_INTERRUPT_ENABLE XREG_TCR_DEC_INTERRUPT_ENABLE +#define XREG_TSR_PIT_INTERRUPT_STATUS XREG_TSR_DEC_INTERRUPT_STATUS +#define XREG_SPR_PIT XREG_SPR_DEC +#define XEXC_ID_PIT_INT XEXC_ID_DEC_INT +#endif + +/* -------------------------------------------------------------------- + * Disable the Timer - During Profiling + * + * For PIT Timer - + * 1. XTime_PITDisableInterrupt() ; + * 2. Store the remaining timer clk tick + * 3. Stop the PIT Timer + *-------------------------------------------------------------------- */ + +#ifdef PPC_PIT_INTERRUPT +#define disable_timer() \ + { \ + u32 val; \ + val=mfspr(XREG_SPR_TCR); \ + mtspr(XREG_SPR_TCR, val & (~XREG_TCR_PIT_INTERRUPT_ENABLE)); \ + timer_lo_clk_ticks = mfspr(XREG_SPR_PIT); \ + mtspr(XREG_SPR_PIT, 0); \ + } +#else +#define disable_timer() \ + { \ + u32 addr = (PROFILE_TIMER_BASEADDR) + XTmrCtr_Offsets[(0)] + XTC_TCSR_OFFSET; \ + u32 tmp_v = ProfIo_In32(addr); \ + tmp_v = tmp_v & (~XTC_CSR_ENABLE_TMR_MASK); \ + ProfIo_Out32((PROFILE_TIMER_BASEADDR) + XTmrCtr_Offsets[(0)] + XTC_TCSR_OFFSET, tmp_v); \ + } +#endif + + + +/* -------------------------------------------------------------------- + * Enable the Timer + * + * For PIT Timer - + * 1. Load the remaining timer clk ticks + * 2. XTime_PITEnableInterrupt() ; + *-------------------------------------------------------------------- */ +#ifdef PPC_PIT_INTERRUPT +#define enable_timer() \ + { \ + u32 val; \ + val=mfspr(XREG_SPR_TCR); \ + mtspr(XREG_SPR_PIT, timer_lo_clk_ticks); \ + mtspr(XREG_SPR_TCR, val | XREG_TCR_PIT_INTERRUPT_ENABLE); \ + } +#else +#define enable_timer() \ + { \ + u32 addr = (PROFILE_TIMER_BASEADDR) + XTmrCtr_Offsets[(0)] + XTC_TCSR_OFFSET; \ + u32 tmp_v = ProfIo_In32(addr); \ + tmp_v = tmp_v | XTC_CSR_ENABLE_TMR_MASK; \ + ProfIo_Out32((PROFILE_TIMER_BASEADDR) + XTmrCtr_Offsets[(0)] + XTC_TCSR_OFFSET, tmp_v); \ + } +#endif + + + +/* -------------------------------------------------------------------- + * Send Ack to Timer Interrupt + * + * For PIT Timer - + * 1. Load the timer clk ticks + * 2. Enable AutoReload and Interrupt + * 3. Clear PIT Timer Status bits + *-------------------------------------------------------------------- */ +#ifdef PPC_PIT_INTERRUPT +#define timer_ack() \ + { \ + u32 val; \ + mtspr(XREG_SPR_PIT, timer_clk_ticks); \ + mtspr(XREG_SPR_TSR, XREG_TSR_PIT_INTERRUPT_STATUS); \ + val=mfspr(XREG_SPR_TCR); \ + mtspr(XREG_SPR_TCR, val| XREG_TCR_PIT_INTERRUPT_ENABLE| XREG_TCR_AUTORELOAD_ENABLE); \ + } +#else +#define timer_ack() \ + { \ + u32 csr; \ + csr = ProfTmrCtr_mGetControlStatusReg(PROFILE_TIMER_BASEADDR, 0); \ + ProfTmrCtr_mSetControlStatusReg(PROFILE_TIMER_BASEADDR, 0, csr); \ + } +#endif + +/*-------------------------------------------------------------------- */ +#endif /* PROC_PPC */ +/* -------------------------------------------------------------------- */ + + + + +/* -------------------------------------------------------------------- + * MicroBlaze Target - Timer related functions + *-------------------------------------------------------------------- */ +#ifdef PROC_MICROBLAZE + +/* -------------------------------------------------------------------- + * Disable the Timer during Call-Graph Data collection + * + *-------------------------------------------------------------------- */ +#define disable_timer() \ + { \ + u32 Addr = ((u32)PROFILE_TIMER_BASEADDR); \ + Addr += (u32)XTmrCtr_Offsets[(u16)(0)]; \ + Addr += (u32)XTC_TCSR_OFFSET; \ + u32 tmp_v = ProfIo_In32(Addr); \ + tmp_v = tmp_v & (u32)(~XTC_CSR_ENABLE_TMR_MASK); \ + u32 OutAddr = (u32)PROFILE_TIMER_BASEADDR; \ + OutAddr += (u32)XTmrCtr_Offsets[(u16)(0)]; \ + OutAddr += (u32)XTC_TCSR_OFFSET; \ + ProfIo_Out32(OutAddr, (u32)tmp_v); \ + } + + +/* -------------------------------------------------------------------- + * Enable the Timer after Call-Graph Data collection + * + *-------------------------------------------------------------------- */ +#define enable_timer() \ + { \ + u32 Addr = ((u32)PROFILE_TIMER_BASEADDR); \ + Addr += (u32)XTmrCtr_Offsets[(u16)(0)]; \ + Addr += (u32)XTC_TCSR_OFFSET; \ + u32 tmp_v = (u32)ProfIo_In32(Addr); \ + tmp_v = tmp_v | (u32)XTC_CSR_ENABLE_TMR_MASK; \ + ProfIo_Out32((u32)(PROFILE_TIMER_BASEADDR) + (u32)XTmrCtr_Offsets[(u16)(0)] + (u32)XTC_TCSR_OFFSET, (u32)tmp_v); \ + } + + +/* -------------------------------------------------------------------- + * Send Ack to Timer Interrupt + * + *-------------------------------------------------------------------- */ +#define timer_ack() \ + { \ + u32 csr; \ + csr = ProfTmrCtr_mGetControlStatusReg((u32)PROFILE_TIMER_BASEADDR, (u16)0); \ + ProfTmrCtr_mSetControlStatusReg((u32)PROFILE_TIMER_BASEADDR, (u16)0, (u32)csr); \ + } + +/*-------------------------------------------------------------------- */ +#endif /* PROC_MICROBLAZE */ +/*-------------------------------------------------------------------- */ + +/* -------------------------------------------------------------------- + * Cortex A9 Target - Timer related functions + *-------------------------------------------------------------------- */ +#ifdef PROC_CORTEXA9 + +/* -------------------------------------------------------------------- + * Disable the Timer during Call-Graph Data collection + * + *-------------------------------------------------------------------- */ +#define disable_timer() \ +{ \ + u32 Reg; \ + Reg = Xil_In32(PROFILE_TIMER_BASEADDR + XSCUTIMER_CONTROL_OFFSET); \ + Reg &= (~XSCUTIMER_CONTROL_ENABLE_MASK);\ + Xil_Out32(PROFILE_TIMER_BASEADDR + XSCUTIMER_CONTROL_OFFSET, Reg);\ +} + + +/* -------------------------------------------------------------------- + * Enable the Timer after Call-Graph Data collection + * + *-------------------------------------------------------------------- */ +#define enable_timer() \ +{ \ + u32 Reg; \ + Reg = Xil_In32(PROFILE_TIMER_BASEADDR + XSCUTIMER_CONTROL_OFFSET); \ + Reg |= XSCUTIMER_CONTROL_ENABLE_MASK; \ + Xil_Out32(PROFILE_TIMER_BASEADDR + XSCUTIMER_CONTROL_OFFSET, Reg);\ +} + + +/* -------------------------------------------------------------------- + * Send Ack to Timer Interrupt + * + *-------------------------------------------------------------------- */ +#define timer_ack() \ +{ \ + Xil_Out32((u32)PROFILE_TIMER_BASEADDR + (u32)XSCUTIMER_ISR_OFFSET, \ + (u32)XSCUTIMER_ISR_EVENT_FLAG_MASK);\ +} + +/*-------------------------------------------------------------------- */ +#endif /* PROC_CORTEXA9 */ +/*-------------------------------------------------------------------- */ + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/bspconfig.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/bspconfig.h new file mode 100644 index 0000000..488641c --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/bspconfig.h @@ -0,0 +1,44 @@ + +/******************************************************************* +* +* CAUTION: This file is automatically generated by HSI. +* Version: 2019.1.3 +* DO NOT EDIT. +* +* Copyright (C) 2010-2023 Xilinx, Inc. All Rights Reserved.* +*Permission is hereby granted, free of charge, to any person obtaining a copy +*of this software and associated documentation files (the Software), to deal +*in the Software without restriction, including without limitation the rights +*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +*copies of the Software, and to permit persons to whom the Software is +*furnished to do so, subject to the following conditions: +* +*The above copyright notice and this permission notice shall be included in +*all copies or substantial portions of the Software. +* +*THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +*XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +*OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*Except as contained in this notice, the name of the Xilinx shall not be used +*in advertising or otherwise to promote the sale, use or other dealings in +*this Software without prior written authorization from Xilinx. +* + +* +* Description: Configurations for Standalone BSP +* +*******************************************************************/ + +#ifndef BSPCONFIG_H /* prevent circular inclusions */ +#define BSPCONFIG_H /* by using protection macros */ + +#define MICROBLAZE_PVR_NONE + +/* Definition for hard-float ABI */ +#define FPU_HARD_FLOAT_ABI_ENABLED 1 + +#endif /*end of __BSPCONFIG_H_*/ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/mblaze_nt_types.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/mblaze_nt_types.h new file mode 100644 index 0000000..807dda3 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/mblaze_nt_types.h @@ -0,0 +1,50 @@ +/****************************************************************************** +* +* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ + + +#ifndef _MBLAZE_NT_TYPES_H +#define _MBLAZE_NT_TYPES_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef char byte; +typedef short half; +typedef int word; +typedef unsigned char ubyte; +typedef unsigned short uhalf; +typedef unsigned int uword; +typedef ubyte boolean; + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/profile.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/profile.h new file mode 100644 index 0000000..63f503a --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/profile.h @@ -0,0 +1,127 @@ +/****************************************************************************** +* +* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ + +#ifndef PROFILE_H +#define PROFILE_H 1 + +#include +#include "xil_types.h" +#include "profile_config.h" + +#ifdef PROC_MICROBLAZE +#include "mblaze_nt_types.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +void _system_init( void ) ; +void _system_clean( void ) ; +void mcount(u32 frompc, u32 selfpc); +void profile_intr_handler( void ) ; +void _profile_init( void ); + + + +/**************************************************************************** + * Profiling on hardware - Hash table maintained on hardware and data sent + * to xmd for gmon.out generation. + ****************************************************************************/ +/* + * histogram counters are unsigned shorts (according to the kernel). + */ +#define HISTCOUNTER u16 + +struct tostruct { + u32 selfpc; + s32 count; + s16 link; + u16 pad; +}; + +struct fromstruct { + u32 frompc ; + s16 link ; + u16 pad ; +} ; + +/* + * general rounding functions. + */ +#define ROUNDDOWN(x,y) (((x)/(y))*(y)) +#define ROUNDUP(x,y) ((((x)+(y)-1)/(y))*(y)) + +/* + * The profiling data structures are housed in this structure. + */ +struct gmonparam { + s32 state; + + /* Histogram Information */ + u16 *kcount; /* No. of bins in histogram */ + u32 kcountsize; /* Histogram samples */ + + /* Call-graph Information */ + struct fromstruct *froms; + u32 fromssize; + struct tostruct *tos; + u32 tossize; + + /* Initialization I/Ps */ + u32 lowpc; + u32 highpc; + u32 textsize; + /* u32 cg_froms, */ + /* u32 cg_tos, */ +}; +extern struct gmonparam *_gmonparam; +extern s32 n_gmon_sections; + +/* + * Possible states of profiling. + */ +#define GMON_PROF_ON 0 +#define GMON_PROF_BUSY 1 +#define GMON_PROF_ERROR 2 +#define GMON_PROF_OFF 3 + +/* + * Sysctl definitions for extracting profiling information from the kernel. + */ +#define GPROF_STATE 0 /* int: profiling enabling variable */ +#define GPROF_COUNT 1 /* struct: profile tick count buffer */ +#define GPROF_FROMS 2 /* struct: from location hash bucket */ +#define GPROF_TOS 3 /* struct: destination/count structure */ +#define GPROF_GMONPARAM 4 /* struct: profiling parameters (see above) */ + +#ifdef __cplusplus +} +#endif + +#endif /* PROFILE_H */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/sleep.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/sleep.h new file mode 100644 index 0000000..f3a632b --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/sleep.h @@ -0,0 +1,115 @@ +/****************************************************************************** +* +* Copyright (C) 2014 - 2017 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ + +/*****************************************************************************/ +/** +* @file sleep.h +* +* This header file contains ARM Cortex A53,A9,R5,Microblaze specific sleep +* related APIs. +* +*
+* MODIFICATION HISTORY :
+*
+* Ver   Who  Date	 Changes
+* ----- ---- -------- -------------------------------------------------------
+* 6.6   srm  11/02/17 Added processor specific sleep rountines
+*								 function prototypes.
+*
+* 
+* +******************************************************************************/ + +#ifndef SLEEP_H +#define SLEEP_H + +#include "xil_types.h" +#include "xil_io.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*****************************************************************************/ +/** +* +* This macro polls an address periodically until a condition is met or till the +* timeout occurs. +* The minimum timeout for calling this macro is 100us. If the timeout is less +* than 100us, it still waits for 100us. Also the unit for the timeout is 100us. +* If the timeout is not a multiple of 100us, it waits for a timeout of +* the next usec value which is a multiple of 100us. +* +* @param IO_func - accessor function to read the register contents. +* Depends on the register width. +* @param ADDR - Address to be polled +* @param VALUE - variable to read the value +* @param COND - Condition to checked (usually involves VALUE) +* @param TIMEOUT_US - timeout in micro seconds +* +* @return 0 - when the condition is met +* -1 - when the condition is not met till the timeout period +* +* @note none +* +*****************************************************************************/ +#define Xil_poll_timeout(IO_func, ADDR, VALUE, COND, TIMEOUT_US) \ + ( { \ + u64 timeout = TIMEOUT_US/100; \ + if(TIMEOUT_US%100!=0) \ + timeout++; \ + for(;;) { \ + VALUE = IO_func(ADDR); \ + if(COND) \ + break; \ + else { \ + usleep(100); \ + timeout--; \ + if(timeout==0) \ + break; \ + } \ + } \ + (timeout>0) ? 0 : -1; \ + } ) + +void usleep(unsigned long useconds); +void sleep(unsigned int seconds); +int usleep_R5(unsigned long useconds); +unsigned sleep_R5(unsigned int seconds); +int usleep_MB(unsigned long useconds); +unsigned sleep_MB(unsigned int seconds); +int usleep_A53(unsigned long useconds); +unsigned sleep_A53(unsigned int seconds); +int usleep_A9(unsigned long useconds); +unsigned sleep_A9(unsigned int seconds); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/smc.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/smc.h new file mode 100644 index 0000000..f7cc91c --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/smc.h @@ -0,0 +1,110 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* @file smc.h +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- ---------------------------------------------------
+* 1.00a sdm  11/03/09 Initial release.
+* 4.2	pkp	 08/04/14 Removed function definition of XSmc_NorInit and XSmc_NorInit
+*					  as smc.c is removed
+* 
+* +* @note None. +* +******************************************************************************/ + +#ifndef SMC_H /* prevent circular inclusions */ +#define SMC_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +#include "xparameters.h" +#include "xil_io.h" + +/***************** Macros (Inline Functions) Definitions *********************/ + +/**************************** Type Definitions *******************************/ + +/************************** Constant Definitions *****************************/ + +/* Memory controller configuration register offset */ +#define XSMCPSS_MC_STATUS 0x000U /* Controller status reg, RO */ +#define XSMCPSS_MC_INTERFACE_CONFIG 0x004U /* Interface config reg, RO */ +#define XSMCPSS_MC_SET_CONFIG 0x008U /* Set configuration reg, WO */ +#define XSMCPSS_MC_CLR_CONFIG 0x00CU /* Clear config reg, WO */ +#define XSMCPSS_MC_DIRECT_CMD 0x010U /* Direct command reg, WO */ +#define XSMCPSS_MC_SET_CYCLES 0x014U /* Set cycles register, WO */ +#define XSMCPSS_MC_SET_OPMODE 0x018U /* Set opmode register, WO */ +#define XSMCPSS_MC_REFRESH_PERIOD_0 0x020U /* Refresh period_0 reg, RW */ +#define XSMCPSS_MC_REFRESH_PERIOD_1 0x024U /* Refresh period_1 reg, RW */ + +/* Chip select configuration register offset */ +#define XSMCPSS_CS_IF0_CHIP_0_OFFSET 0x100U /* Interface 0 chip 0 config */ +#define XSMCPSS_CS_IF0_CHIP_1_OFFSET 0x120U /* Interface 0 chip 1 config */ +#define XSMCPSS_CS_IF0_CHIP_2_OFFSET 0x140U /* Interface 0 chip 2 config */ +#define XSMCPSS_CS_IF0_CHIP_3_OFFSET 0x160U /* Interface 0 chip 3 config */ +#define XSMCPSS_CS_IF1_CHIP_0_OFFSET 0x180U /* Interface 1 chip 0 config */ +#define XSMCPSS_CS_IF1_CHIP_1_OFFSET 0x1A0U /* Interface 1 chip 1 config */ +#define XSMCPSS_CS_IF1_CHIP_2_OFFSET 0x1C0U /* Interface 1 chip 2 config */ +#define XSMCPSS_CS_IF1_CHIP_3_OFFSET 0x1E0U /* Interface 1 chip 3 config */ + +/* User configuration register offset */ +#define XSMCPSS_UC_STATUS_OFFSET 0x200U /* User status reg, RO */ +#define XSMCPSS_UC_CONFIG_OFFSET 0x204U /* User config reg, WO */ + +/* Integration test register offset */ +#define XSMCPSS_IT_OFFSET 0xE00U + +/* ID configuration register offset */ +#define XSMCPSS_ID_PERIP_0_OFFSET 0xFE0U +#define XSMCPSS_ID_PERIP_1_OFFSET 0xFE4U +#define XSMCPSS_ID_PERIP_2_OFFSET 0xFE8U +#define XSMCPSS_ID_PERIP_3_OFFSET 0xFECU +#define XSMCPSS_ID_PCELL_0_OFFSET 0xFF0U +#define XSMCPSS_ID_PCELL_1_OFFSET 0xFF4U +#define XSMCPSS_ID_PCELL_2_OFFSET 0xFF8U +#define XSMCPSS_ID_PCELL_3_OFFSET 0xFFCU + +/************************** Variable Definitions *****************************/ + +/************************** Function Prototypes ******************************/ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SMC_H */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/vectors.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/vectors.h new file mode 100644 index 0000000..56bacbc --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/vectors.h @@ -0,0 +1,84 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2016 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* @file vectors.h +* +* This file contains the C level vector prototypes for the ARM Cortex A9 core. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- ---------------------------------------------------
+* 1.00a ecm  10/20/10 Initial version, moved over from bsp area
+* 6.0   mus  07/27/16 Consolidated vectors for a9,a53 and r5 processors
+* 
+* +* @note +* +* None. +* +******************************************************************************/ + +#ifndef _VECTORS_H_ +#define _VECTORS_H_ + +/***************************** Include Files *********************************/ + +#include "xil_types.h" +#include "xil_assert.h" + +#ifdef __cplusplus +extern "C" { +#endif +/***************** Macros (Inline Functions) Definitions *********************/ + +/**************************** Type Definitions *******************************/ + +/************************** Constant Definitions *****************************/ + +/************************** Function Prototypes ******************************/ + +void FIQInterrupt(void); +void IRQInterrupt(void); +#if !defined (__aarch64__) +void SWInterrupt(void); +void DataAbortInterrupt(void); +void PrefetchAbortInterrupt(void); +void UndefinedException(void); +#else +void SynchronousInterrupt(void); +void SErrorInterrupt(void); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* protection macro */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xadcps.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xadcps.h new file mode 100644 index 0000000..900edf0 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xadcps.h @@ -0,0 +1,589 @@ +/****************************************************************************** +* +* Copyright (C) 2011 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xadcps.h +* @addtogroup xadcps_v2_3 +* @{ +* @details +* +* The XAdcPs driver supports the Xilinx XADC/ADC device. +* +* The XADC/ADC device has the following features: +* - 10-bit, 200-KSPS (kilo samples per second) +* Analog-to-Digital Converter (ADC) +* - Monitoring of on-chip supply voltages and temperature +* - 1 dedicated differential analog-input pair and +* 16 auxiliary differential analog-input pairs +* - Automatic alarms based on user defined limits for the on-chip +* supply voltages and temperature +* - Automatic Channel Sequencer, programmable averaging, programmable +* acquisition time for the external inputs, unipolar or differential +* input selection for the external inputs +* - Inbuilt Calibration +* - Optional interrupt request generation +* +* +* The user should refer to the hardware device specification for detailed +* information about the device. +* +* This header file contains the prototypes of driver functions that can +* be used to access the XADC/ADC device. +* +* +* XADC Channel Sequencer Modes +* +* The XADC Channel Sequencer supports the following operating modes: +* +* - Default : This is the default mode after power up. +* In this mode of operation the XADC operates in +* a sequence mode, monitoring the on chip sensors: +* Temperature, VCCINT, and VCCAUX. +* - One pass through sequence : In this mode the XADC +* converts the channels enabled in the Sequencer Channel Enable +* registers for a single pass and then stops. +* - Continuous cycling of sequence : In this mode the XADC +* converts the channels enabled in the Sequencer Channel Enable +* registers continuously. +* - Single channel mode: In this mode the XADC Channel +* Sequencer is disabled and the XADC operates in a +* Single Channel Mode. +* The XADC can operate either in a Continuous or Event +* driven sampling mode in the single channel mode. +* - Simultaneous Sampling Mode: In this mode the XADC Channel +* Sequencer will automatically sequence through eight fixed pairs +* of auxiliary analog input channels for simulataneous conversion. +* - Independent ADC mode: In this mode the first ADC (A) is used to +* is used to implement a fixed monitoring mode similar to the +* default mode but the alarm fucntions ar eenabled. +* The second ADC (B) is available to be used with external analog +* input channels only. +* +* Read the XADC spec for more information about the sequencer modes. +* +* Initialization and Configuration +* +* The device driver enables higher layer software (e.g., an application) to +* communicate to the XADC/ADC device. +* +* XAdcPs_CfgInitialize() API is used to initialize the XADC/ADC +* device. The user needs to first call the XAdcPs_LookupConfig() API which +* returns the Configuration structure pointer which is passed as a parameter to +* the XAdcPs_CfgInitialize() API. +* +* +* Interrupts +* +* The XADC/ADC device supports interrupt driven mode and the default +* operation mode is polling mode. +* +* The interrupt mode is available only if hardware is configured to support +* interrupts. +* +* This driver does not provide a Interrupt Service Routine (ISR) for the device. +* It is the responsibility of the application to provide one if needed. Refer to +* the interrupt example provided with this driver for details on using the +* device in interrupt mode. +* +* +* Virtual Memory +* +* This driver supports Virtual Memory. The RTOS is responsible for calculating +* the correct device base address in Virtual Memory space. +* +* +* Threads +* +* This driver is not thread safe. Any needs for threads or thread mutual +* exclusion must be satisfied by the layer above this driver. +* +* +* Asserts +* +* Asserts are used within all Xilinx drivers to enforce constraints on argument +* values. Asserts can be turned off on a system-wide basis by defining, at +* compile time, the NDEBUG identifier. By default, asserts are turned on and it +* is recommended that users leave asserts on during development. +* +* +* Building the driver +* +* The XAdcPs driver is composed of several source files. This allows the user +* to build and link only those parts of the driver that are necessary. +* +* Limitations of the driver +* +* XADC/ADC device can be accessed through the JTAG port and the PLB +* interface. The driver implementation does not support the simultaneous access +* of the device by both these interfaces. The user has to care of this situation +* in the user application code. +* +*

+* +*
+*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date     Changes
+* ----- -----  -------- -----------------------------------------------------
+* 1.00a ssb    12/22/11 First release based on the XPS/AXI xadc driver
+* 1.01a bss    02/18/13	Modified XAdcPs_SetSeqChEnables,XAdcPs_SetSeqAvgEnables
+*			XAdcPs_SetSeqInputMode and XAdcPs_SetSeqAcqTime APIs
+*			in xadcps.c to fix CR #693371
+* 1.03a bss    11/01/13 Modified xadcps_hw.h to use correct Register offsets
+*			CR#749687
+* 2.1   bss    08/05/14 Added declarations for XAdcPs_SetSequencerEvent,
+*			XAdcPs_GetSamplingMode, XAdcPs_SetMuxMode,
+*			XAdcPs_SetPowerdownMode and XAdcPs_GetPowerdownMode
+*			functions.
+*			Modified Assert for XAdcPs_SetSingleChParams in
+*			xadcps.c to fix CR #807563.
+* 2.2   bss    04/27/14 Modified to use correct Device Config base address in
+*						xadcps.c (CR#854437).
+*       ms     01/23/17 Added xil_printf statement in main function for all
+*                       examples to ensure that "Successfully ran" and "Failed"
+*                       strings are available in all examples. This is a fix
+*                       for CR-965028.
+*       ms     03/17/17 Added readme.txt file in examples folder for doxygen
+*                       generation.
+*       ms     04/05/17 Modified Comment lines in functions of xadcps
+*                       examples to recognize it as documentation block
+*                       for doxygen generation.
+* 2.3   mn     07/09/18 Fix Doxygen warning
+*
+* 
+* +*****************************************************************************/ +#ifndef XADCPS_H /* Prevent circular inclusions */ +#define XADCPS_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files ********************************/ + +#include "xil_types.h" +#include "xil_assert.h" +#include "xstatus.h" +#include "xadcps_hw.h" + +/************************** Constant Definitions ****************************/ + + +/** + * @name Indexes for the different channels. + * @{ + */ +#define XADCPS_CH_TEMP 0x0 /**< On Chip Temperature */ +#define XADCPS_CH_VCCINT 0x1 /**< VCCINT */ +#define XADCPS_CH_VCCAUX 0x2 /**< VCCAUX */ +#define XADCPS_CH_VPVN 0x3 /**< VP/VN Dedicated analog inputs */ +#define XADCPS_CH_VREFP 0x4 /**< VREFP */ +#define XADCPS_CH_VREFN 0x5 /**< VREFN */ +#define XADCPS_CH_VBRAM 0x6 /**< On-chip VBRAM Data Reg, 7 series */ +#define XADCPS_CH_SUPPLY_CALIB 0x07 /**< Supply Calib Data Reg */ +#define XADCPS_CH_ADC_CALIB 0x08 /**< ADC Offset Channel Reg */ +#define XADCPS_CH_GAINERR_CALIB 0x09 /**< Gain Error Channel Reg */ +#define XADCPS_CH_VCCPINT 0x0D /**< On-chip PS VCCPINT Channel , Zynq */ +#define XADCPS_CH_VCCPAUX 0x0E /**< On-chip PS VCCPAUX Channel , Zynq */ +#define XADCPS_CH_VCCPDRO 0x0F /**< On-chip PS VCCPDRO Channel , Zynq */ +#define XADCPS_CH_AUX_MIN 16 /**< Channel number for 1st Aux Channel */ +#define XADCPS_CH_AUX_MAX 31 /**< Channel number for Last Aux channel */ + +/*@}*/ + + +/** + * @name Indexes for reading the Calibration Coefficient Data. + * @{ + */ +#define XADCPS_CALIB_SUPPLY_COEFF 0 /**< Supply Offset Calib Coefficient */ +#define XADCPS_CALIB_ADC_COEFF 1 /**< ADC Offset Calib Coefficient */ +#define XADCPS_CALIB_GAIN_ERROR_COEFF 2 /**< Gain Error Calib Coefficient*/ +/*@}*/ + + +/** + * @name Indexes for reading the Minimum/Maximum Measurement Data. + * @{ + */ +#define XADCPS_MAX_TEMP 0 /**< Maximum Temperature Data */ +#define XADCPS_MAX_VCCINT 1 /**< Maximum VCCINT Data */ +#define XADCPS_MAX_VCCAUX 2 /**< Maximum VCCAUX Data */ +#define XADCPS_MAX_VBRAM 3 /**< Maximum VBRAM Data */ +#define XADCPS_MIN_TEMP 4 /**< Minimum Temperature Data */ +#define XADCPS_MIN_VCCINT 5 /**< Minimum VCCINT Data */ +#define XADCPS_MIN_VCCAUX 6 /**< Minimum VCCAUX Data */ +#define XADCPS_MIN_VBRAM 7 /**< Minimum VBRAM Data */ +#define XADCPS_MAX_VCCPINT 8 /**< Maximum VCCPINT Register , Zynq */ +#define XADCPS_MAX_VCCPAUX 9 /**< Maximum VCCPAUX Register , Zynq */ +#define XADCPS_MAX_VCCPDRO 0xA /**< Maximum VCCPDRO Register , Zynq */ +#define XADCPS_MIN_VCCPINT 0xC /**< Minimum VCCPINT Register , Zynq */ +#define XADCPS_MIN_VCCPAUX 0xD /**< Minimum VCCPAUX Register , Zynq */ +#define XADCPS_MIN_VCCPDRO 0xE /**< Minimum VCCPDRO Register , Zynq */ + +/*@}*/ + + +/** + * @name Alarm Threshold(Limit) Register (ATR) indexes. + * @{ + */ +#define XADCPS_ATR_TEMP_UPPER 0 /**< High user Temperature */ +#define XADCPS_ATR_VCCINT_UPPER 1 /**< VCCINT high voltage limit register */ +#define XADCPS_ATR_VCCAUX_UPPER 2 /**< VCCAUX high voltage limit register */ +#define XADCPS_ATR_OT_UPPER 3 /**< VCCAUX high voltage limit register */ +#define XADCPS_ATR_TEMP_LOWER 4 /**< Upper Over Temperature limit Reg */ +#define XADCPS_ATR_VCCINT_LOWER 5 /**< VCCINT high voltage limit register */ +#define XADCPS_ATR_VCCAUX_LOWER 6 /**< VCCAUX low voltage limit register */ +#define XADCPS_ATR_OT_LOWER 7 /**< Lower Over Temperature limit */ +#define XADCPS_ATR_VBRAM_UPPER_ 8 /**< VRBAM Upper Alarm Reg, 7 Series */ +#define XADCPS_ATR_VCCPINT_UPPER 9 /**< VCCPINT Upper Alarm Reg, Zynq */ +#define XADCPS_ATR_VCCPAUX_UPPER 0xA /**< VCCPAUX Upper Alarm Reg, Zynq */ +#define XADCPS_ATR_VCCPDRO_UPPER 0xB /**< VCCPDRO Upper Alarm Reg, Zynq */ +#define XADCPS_ATR_VBRAM_LOWER 0xC /**< VRBAM Lower Alarm Reg, 7 Series */ +#define XADCPS_ATR_VCCPINT_LOWER 0xD /**< VCCPINT Lower Alarm Reg , Zynq */ +#define XADCPS_ATR_VCCPAUX_LOWER 0xE /**< VCCPAUX Lower Alarm Reg , Zynq */ +#define XADCPS_ATR_VCCPDRO_LOWER 0xF /**< VCCPDRO Lower Alarm Reg , Zynq */ + +/*@}*/ + + +/** + * @name Averaging to be done for the channels. + * @{ + */ +#define XADCPS_AVG_0_SAMPLES 0 /**< No Averaging */ +#define XADCPS_AVG_16_SAMPLES 1 /**< Average 16 samples */ +#define XADCPS_AVG_64_SAMPLES 2 /**< Average 64 samples */ +#define XADCPS_AVG_256_SAMPLES 3 /**< Average 256 samples */ + +/*@}*/ + + +/** + * @name Channel Sequencer Modes of operation + * @{ + */ +#define XADCPS_SEQ_MODE_SAFE 0 /**< Default Safe Mode */ +#define XADCPS_SEQ_MODE_ONEPASS 1 /**< Onepass through Sequencer */ +#define XADCPS_SEQ_MODE_CONTINPASS 2 /**< Continuous Cycling Sequencer */ +#define XADCPS_SEQ_MODE_SINGCHAN 3 /**< Single channel -No Sequencing */ +#define XADCPS_SEQ_MODE_SIMUL_SAMPLING 4 /**< Simultaneous sampling */ +#define XADCPS_SEQ_MODE_INDEPENDENT 8 /**< Independent mode */ + +/*@}*/ + + + +/** + * @name Power Down Modes + * @{ + */ +#define XADCPS_PD_MODE_NONE 0 /**< No Power Down */ +#define XADCPS_PD_MODE_ADCB 1 /**< Power Down ADC B */ +#define XADCPS_PD_MODE_XADC 2 /**< Power Down ADC A and ADC B */ +/*@}*/ + +/**************************** Type Definitions ******************************/ + +/** + * This typedef contains configuration information for the XADC/ADC + * device. + */ +typedef struct { + u16 DeviceId; /**< Unique ID of device */ + u32 BaseAddress; /**< Device base address */ +} XAdcPs_Config; + + +/** + * The driver's instance data. The user is required to allocate a variable + * of this type for every XADC/ADC device in the system. A pointer to + * a variable of this type is then passed to the driver API functions. + */ +typedef struct { + XAdcPs_Config Config; /**< XAdcPs_Config of current device */ + u32 IsReady; /**< Device is initialized and ready */ + +} XAdcPs; + +/***************** Macros (Inline Functions) Definitions ********************/ + +/****************************************************************************/ +/** +* +* This macro checks if the XADC device is in Event Sampling mode. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @return +* - TRUE if the device is in Event Sampling Mode. +* - FALSE if the device is in Continuous Sampling Mode. +* +* @note C-Style signature: +* int XAdcPs_IsEventSamplingMode(XAdcPs *InstancePtr); +* +*****************************************************************************/ +#define XAdcPs_IsEventSamplingModeSet(InstancePtr) \ + (((XAdcPs_ReadInternalReg(InstancePtr, \ + XADCPS_CFR0_OFFSET) & XADCPS_CFR0_EC_MASK) ? \ + TRUE : FALSE)) + + +/****************************************************************************/ +/** +* +* This macro checks if the XADC device is in External Mux mode. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @return +* - TRUE if the device is in External Mux Mode. +* - FALSE if the device is NOT in External Mux Mode. +* +* @note C-Style signature: +* int XAdcPs_IsExternalMuxMode(XAdcPs *InstancePtr); +* +*****************************************************************************/ +#define XAdcPs_IsExternalMuxModeSet(InstancePtr) \ + (((XAdcPs_ReadInternalReg(InstancePtr, \ + XADCPS_CFR0_OFFSET) & XADCPS_CFR0_MUX_MASK) ? \ + TRUE : FALSE)) + +/****************************************************************************/ +/** +* +* This macro converts XADC Raw Data to Temperature(centigrades). +* +* @param AdcData is the Raw ADC Data from XADC. +* +* @return The Temperature in centigrades. +* +* @note C-Style signature: +* float XAdcPs_RawToTemperature(u32 AdcData); +* +*****************************************************************************/ +#define XAdcPs_RawToTemperature(AdcData) \ + ((((float)(AdcData)/65536.0f)/0.00198421639f ) - 273.15f) + +/****************************************************************************/ +/** +* +* This macro converts XADC/ADC Raw Data to Voltage(volts). +* +* @param AdcData is the XADC/ADC Raw Data. +* +* @return The Voltage in volts. +* +* @note C-Style signature: +* float XAdcPs_RawToVoltage(u32 AdcData); +* +*****************************************************************************/ +#define XAdcPs_RawToVoltage(AdcData) \ + ((((float)(AdcData))* (3.0f))/65536.0f) + +/****************************************************************************/ +/** +* +* This macro converts Temperature in centigrades to XADC/ADC Raw Data. +* +* @param Temperature is the Temperature in centigrades to be +* converted to XADC/ADC Raw Data. +* +* @return The XADC/ADC Raw Data. +* +* @note C-Style signature: +* int XAdcPs_TemperatureToRaw(float Temperature); +* +*****************************************************************************/ +#define XAdcPs_TemperatureToRaw(Temperature) \ + ((int)(((Temperature) + 273.15f)*65536.0f*0.00198421639f)) + +/****************************************************************************/ +/** +* +* This macro converts Voltage in Volts to XADC/ADC Raw Data. +* +* @param Voltage is the Voltage in volts to be converted to +* XADC/ADC Raw Data. +* +* @return The XADC/ADC Raw Data. +* +* @note C-Style signature: +* int XAdcPs_VoltageToRaw(float Voltage); +* +*****************************************************************************/ +#define XAdcPs_VoltageToRaw(Voltage) \ + ((int)((Voltage)*65536.0f/3.0f)) + + +/****************************************************************************/ +/** +* +* This macro is used for writing to the XADC Registers using the +* command FIFO. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param Data is the value to be written to XADC register. +* +* @return None. +* +* @note C-Style signature: +* void XAdcPs_WriteFifo(XAdcPs *InstancePtr, u32 Data); +* +*****************************************************************************/ +#define XAdcPs_WriteFifo(InstancePtr, Data) \ + XAdcPs_WriteReg((InstancePtr)->Config.BaseAddress, \ + XADCPS_CMDFIFO_OFFSET, Data); + + +/****************************************************************************/ +/** +* +* This macro is used for reading from the XADC Registers using the +* data FIFO. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @return Data read from the FIFO +* +* @note C-Style signature: +* u32 XAdcPs_ReadFifo(XAdcPs *InstancePtr); +* +*****************************************************************************/ +#define XAdcPs_ReadFifo(InstancePtr) \ + XAdcPs_ReadReg((InstancePtr)->Config.BaseAddress, \ + XADCPS_RDFIFO_OFFSET); + + +/************************** Function Prototypes *****************************/ + + + +/** + * Functions in xadcps_sinit.c + */ +XAdcPs_Config *XAdcPs_LookupConfig(u16 DeviceId); + +/** + * Functions in xadcps.c + */ +int XAdcPs_CfgInitialize(XAdcPs *InstancePtr, + XAdcPs_Config *ConfigPtr, + u32 EffectiveAddr); + + +u32 XAdcPs_GetStatus(XAdcPs *InstancePtr); + +u32 XAdcPs_GetAlarmOutputStatus(XAdcPs *InstancePtr); + +void XAdcPs_StartAdcConversion(XAdcPs *InstancePtr); + +void XAdcPs_Reset(XAdcPs *InstancePtr); + +u16 XAdcPs_GetAdcData(XAdcPs *InstancePtr, u8 Channel); + +u16 XAdcPs_GetCalibCoefficient(XAdcPs *InstancePtr, u8 CoeffType); + +u16 XAdcPs_GetMinMaxMeasurement(XAdcPs *InstancePtr, u8 MeasurementType); + +void XAdcPs_SetAvg(XAdcPs *InstancePtr, u8 Average); +u8 XAdcPs_GetAvg(XAdcPs *InstancePtr); + +int XAdcPs_SetSingleChParams(XAdcPs *InstancePtr, + u8 Channel, + int IncreaseAcqCycles, + int IsEventMode, + int IsDifferentialMode); + + +void XAdcPs_SetAlarmEnables(XAdcPs *InstancePtr, u16 AlmEnableMask); +u16 XAdcPs_GetAlarmEnables(XAdcPs *InstancePtr); + +void XAdcPs_SetCalibEnables(XAdcPs *InstancePtr, u16 Calibration); +u16 XAdcPs_GetCalibEnables(XAdcPs *InstancePtr); + +void XAdcPs_SetSequencerMode(XAdcPs *InstancePtr, u8 SequencerMode); +u8 XAdcPs_GetSequencerMode(XAdcPs *InstancePtr); + +void XAdcPs_SetAdcClkDivisor(XAdcPs *InstancePtr, u8 Divisor); +u8 XAdcPs_GetAdcClkDivisor(XAdcPs *InstancePtr); + +int XAdcPs_SetSeqChEnables(XAdcPs *InstancePtr, u32 ChEnableMask); +u32 XAdcPs_GetSeqChEnables(XAdcPs *InstancePtr); + +int XAdcPs_SetSeqAvgEnables(XAdcPs *InstancePtr, u32 AvgEnableChMask); +u32 XAdcPs_GetSeqAvgEnables(XAdcPs *InstancePtr); + +int XAdcPs_SetSeqInputMode(XAdcPs *InstancePtr, u32 InputModeChMask); +u32 XAdcPs_GetSeqInputMode(XAdcPs *InstancePtr); + +int XAdcPs_SetSeqAcqTime(XAdcPs *InstancePtr, u32 AcqCyclesChMask); +u32 XAdcPs_GetSeqAcqTime(XAdcPs *InstancePtr); + +void XAdcPs_SetAlarmThreshold(XAdcPs *InstancePtr, u8 AlarmThrReg, u16 Value); +u16 XAdcPs_GetAlarmThreshold(XAdcPs *InstancePtr, u8 AlarmThrReg); + +void XAdcPs_EnableUserOverTemp(XAdcPs *InstancePtr); +void XAdcPs_DisableUserOverTemp(XAdcPs *InstancePtr); + +void XAdcPs_SetSequencerEvent(XAdcPs *InstancePtr, int IsEventMode); + +int XAdcPs_GetSamplingMode(XAdcPs *InstancePtr); + +void XAdcPs_SetMuxMode(XAdcPs *InstancePtr, int MuxMode, u8 Channel); + +void XAdcPs_SetPowerdownMode(XAdcPs *InstancePtr, u32 Mode); + +u32 XAdcPs_GetPowerdownMode(XAdcPs *InstancePtr); + +/** + * Functions in xadcps_selftest.c + */ +int XAdcPs_SelfTest(XAdcPs *InstancePtr); + +/** + * Functions in xadcps_intr.c + */ +void XAdcPs_IntrEnable(XAdcPs *InstancePtr, u32 Mask); +void XAdcPs_IntrDisable(XAdcPs *InstancePtr, u32 Mask); +u32 XAdcPs_IntrGetEnabled(XAdcPs *InstancePtr); + +u32 XAdcPs_IntrGetStatus(XAdcPs *InstancePtr); +void XAdcPs_IntrClear(XAdcPs *InstancePtr, u32 Mask); + + +#ifdef __cplusplus +} +#endif + +#endif /* End of protection macro. */ +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xadcps_hw.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xadcps_hw.h new file mode 100644 index 0000000..dd51473 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xadcps_hw.h @@ -0,0 +1,498 @@ +/****************************************************************************** +* +* Copyright (C) 2011 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xadcps_hw.h +* @addtogroup xadcps_v2_3 +* @{ +* +* This header file contains identifiers and basic driver functions (or +* macros) that can be used to access the XADC device through the Device +* Config Interface of the Zynq. +* +* +* Refer to the device specification for more information about this driver. +* +* @note None. +* +* +*
+*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date     Changes
+* ----- -----  -------- -----------------------------------------------------
+* 1.00a bss    12/22/11 First release based on the XPS/AXI xadc driver
+* 1.03a bss    11/01/13 Modified macros to use correct Register offsets
+*			CR#749687
+*
+* 
+* +*****************************************************************************/ +#ifndef XADCPS_HW_H /* Prevent circular inclusions */ +#define XADCPS_HW_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files ********************************/ + +#include "xil_types.h" +#include "xil_assert.h" +#include "xil_io.h" + +/************************** Constant Definitions ****************************/ + + +/**@name Register offsets of XADC in the Device Config + * + * The following constants provide access to each of the registers of the + * XADC device. + * @{ + */ + +#define XADCPS_CFG_OFFSET 0x00 /**< Configuration Register */ +#define XADCPS_INT_STS_OFFSET 0x04 /**< Interrupt Status Register */ +#define XADCPS_INT_MASK_OFFSET 0x08 /**< Interrupt Mask Register */ +#define XADCPS_MSTS_OFFSET 0x0C /**< Misc status register */ +#define XADCPS_CMDFIFO_OFFSET 0x10 /**< Command FIFO Register */ +#define XADCPS_RDFIFO_OFFSET 0x14 /**< Read FIFO Register */ +#define XADCPS_MCTL_OFFSET 0x18 /**< Misc control register */ + +/* @} */ + + + + + +/** @name XADC Config Register Bit definitions + * @{ + */ +#define XADCPS_CFG_ENABLE_MASK 0x80000000 /**< Enable access from PS mask */ +#define XADCPS_CFG_CFIFOTH_MASK 0x00F00000 /**< Command FIFO Threshold mask */ +#define XADCPS_CFG_DFIFOTH_MASK 0x000F0000 /**< Data FIFO Threshold mask */ +#define XADCPS_CFG_WEDGE_MASK 0x00002000 /**< Write Edge Mask */ +#define XADCPS_CFG_REDGE_MASK 0x00001000 /**< Read Edge Mask */ +#define XADCPS_CFG_TCKRATE_MASK 0x00000300 /**< Clock freq control */ +#define XADCPS_CFG_IGAP_MASK 0x0000001F /**< Idle Gap between + * successive commands */ +/* @} */ + + +/** @name XADC Interrupt Status/Mask Register Bit definitions + * + * The definitions are same for the Interrupt Status Register and + * Interrupt Mask Register. They are defined only once. + * @{ + */ +#define XADCPS_INTX_ALL_MASK 0x000003FF /**< Alarm Signals Mask */ +#define XADCPS_INTX_CFIFO_LTH_MASK 0x00000200 /**< CMD FIFO less than threshold */ +#define XADCPS_INTX_DFIFO_GTH_MASK 0x00000100 /**< Data FIFO greater than threshold */ +#define XADCPS_INTX_OT_MASK 0x00000080 /**< Over temperature Alarm Status */ +#define XADCPS_INTX_ALM_ALL_MASK 0x0000007F /**< Alarm Signals Mask */ +#define XADCPS_INTX_ALM6_MASK 0x00000040 /**< Alarm 6 Mask */ +#define XADCPS_INTX_ALM5_MASK 0x00000020 /**< Alarm 5 Mask */ +#define XADCPS_INTX_ALM4_MASK 0x00000010 /**< Alarm 4 Mask */ +#define XADCPS_INTX_ALM3_MASK 0x00000008 /**< Alarm 3 Mask */ +#define XADCPS_INTX_ALM2_MASK 0x00000004 /**< Alarm 2 Mask */ +#define XADCPS_INTX_ALM1_MASK 0x00000002 /**< Alarm 1 Mask */ +#define XADCPS_INTX_ALM0_MASK 0x00000001 /**< Alarm 0 Mask */ + +/* @} */ + + +/** @name XADC Miscellaneous Register Bit definitions + * @{ + */ +#define XADCPS_MSTS_CFIFO_LVL_MASK 0x000F0000 /**< Command FIFO Level mask */ +#define XADCPS_MSTS_DFIFO_LVL_MASK 0x0000F000 /**< Data FIFO Level Mask */ +#define XADCPS_MSTS_CFIFOF_MASK 0x00000800 /**< Command FIFO Full Mask */ +#define XADCPS_MSTS_CFIFOE_MASK 0x00000400 /**< Command FIFO Empty Mask */ +#define XADCPS_MSTS_DFIFOF_MASK 0x00000200 /**< Data FIFO Full Mask */ +#define XADCPS_MSTS_DFIFOE_MASK 0x00000100 /**< Data FIFO Empty Mask */ +#define XADCPS_MSTS_OT_MASK 0x00000080 /**< Over Temperature Mask */ +#define XADCPS_MSTS_ALM_MASK 0x0000007F /**< Alarms Mask */ +/* @} */ + + +/** @name XADC Miscellaneous Control Register Bit definitions + * @{ + */ +#define XADCPS_MCTL_RESET_MASK 0x00000010 /**< Reset XADC */ +#define XADCPS_MCTL_FLUSH_MASK 0x00000001 /**< Flush the FIFOs */ +/* @} */ + + +/**@name Internal Register offsets of the XADC + * + * The following constants provide access to each of the internal registers of + * the XADC device. + * @{ + */ + +/* + * XADC Internal Channel Registers + */ +#define XADCPS_TEMP_OFFSET 0x00 /**< On-chip Temperature Reg */ +#define XADCPS_VCCINT_OFFSET 0x01 /**< On-chip VCCINT Data Reg */ +#define XADCPS_VCCAUX_OFFSET 0x02 /**< On-chip VCCAUX Data Reg */ +#define XADCPS_VPVN_OFFSET 0x03 /**< ADC out of VP/VN */ +#define XADCPS_VREFP_OFFSET 0x04 /**< On-chip VREFP Data Reg */ +#define XADCPS_VREFN_OFFSET 0x05 /**< On-chip VREFN Data Reg */ +#define XADCPS_VBRAM_OFFSET 0x06 /**< On-chip VBRAM , 7 Series */ +#define XADCPS_ADC_A_SUPPLY_CALIB_OFFSET 0x08 /**< ADC A Supply Offset Reg */ +#define XADCPS_ADC_A_OFFSET_CALIB_OFFSET 0x09 /**< ADC A Offset Data Reg */ +#define XADCPS_ADC_A_GAINERR_CALIB_OFFSET 0x0A /**< ADC A Gain Error Reg */ +#define XADCPS_VCCPINT_OFFSET 0x0D /**< On-chip VCCPINT Reg, Zynq */ +#define XADCPS_VCCPAUX_OFFSET 0x0E /**< On-chip VCCPAUX Reg, Zynq */ +#define XADCPS_VCCPDRO_OFFSET 0x0F /**< On-chip VCCPDRO Reg, Zynq */ + +/* + * XADC External Channel Registers + */ +#define XADCPS_AUX00_OFFSET 0x10 /**< ADC out of VAUXP0/VAUXN0 */ +#define XADCPS_AUX01_OFFSET 0x11 /**< ADC out of VAUXP1/VAUXN1 */ +#define XADCPS_AUX02_OFFSET 0x12 /**< ADC out of VAUXP2/VAUXN2 */ +#define XADCPS_AUX03_OFFSET 0x13 /**< ADC out of VAUXP3/VAUXN3 */ +#define XADCPS_AUX04_OFFSET 0x14 /**< ADC out of VAUXP4/VAUXN4 */ +#define XADCPS_AUX05_OFFSET 0x15 /**< ADC out of VAUXP5/VAUXN5 */ +#define XADCPS_AUX06_OFFSET 0x16 /**< ADC out of VAUXP6/VAUXN6 */ +#define XADCPS_AUX07_OFFSET 0x17 /**< ADC out of VAUXP7/VAUXN7 */ +#define XADCPS_AUX08_OFFSET 0x18 /**< ADC out of VAUXP8/VAUXN8 */ +#define XADCPS_AUX09_OFFSET 0x19 /**< ADC out of VAUXP9/VAUXN9 */ +#define XADCPS_AUX10_OFFSET 0x1A /**< ADC out of VAUXP10/VAUXN10 */ +#define XADCPS_AUX11_OFFSET 0x1B /**< ADC out of VAUXP11/VAUXN11 */ +#define XADCPS_AUX12_OFFSET 0x1C /**< ADC out of VAUXP12/VAUXN12 */ +#define XADCPS_AUX13_OFFSET 0x1D /**< ADC out of VAUXP13/VAUXN13 */ +#define XADCPS_AUX14_OFFSET 0x1E /**< ADC out of VAUXP14/VAUXN14 */ +#define XADCPS_AUX15_OFFSET 0x1F /**< ADC out of VAUXP15/VAUXN15 */ + +/* + * XADC Registers for Maximum/Minimum data captured for the + * on chip Temperature/VCCINT/VCCAUX data. + */ +#define XADCPS_MAX_TEMP_OFFSET 0x20 /**< Max Temperature Reg */ +#define XADCPS_MAX_VCCINT_OFFSET 0x21 /**< Max VCCINT Register */ +#define XADCPS_MAX_VCCAUX_OFFSET 0x22 /**< Max VCCAUX Register */ +#define XADCPS_MAX_VCCBRAM_OFFSET 0x23 /**< Max BRAM Register, 7 series */ +#define XADCPS_MIN_TEMP_OFFSET 0x24 /**< Min Temperature Reg */ +#define XADCPS_MIN_VCCINT_OFFSET 0x25 /**< Min VCCINT Register */ +#define XADCPS_MIN_VCCAUX_OFFSET 0x26 /**< Min VCCAUX Register */ +#define XADCPS_MIN_VCCBRAM_OFFSET 0x27 /**< Min BRAM Register, 7 series */ +#define XADCPS_MAX_VCCPINT_OFFSET 0x28 /**< Max VCCPINT Register, Zynq */ +#define XADCPS_MAX_VCCPAUX_OFFSET 0x29 /**< Max VCCPAUX Register, Zynq */ +#define XADCPS_MAX_VCCPDRO_OFFSET 0x2A /**< Max VCCPDRO Register, Zynq */ +#define XADCPS_MIN_VCCPINT_OFFSET 0x2C /**< Min VCCPINT Register, Zynq */ +#define XADCPS_MIN_VCCPAUX_OFFSET 0x2D /**< Min VCCPAUX Register, Zynq */ +#define XADCPS_MIN_VCCPDRO_OFFSET 0x2E /**< Min VCCPDRO Register,Zynq */ + /* Undefined 0x2F to 0x3E */ +#define XADCPS_FLAG_OFFSET 0x3F /**< Flag Register */ + +/* + * XADC Configuration Registers + */ +#define XADCPS_CFR0_OFFSET 0x40 /**< Configuration Register 0 */ +#define XADCPS_CFR1_OFFSET 0x41 /**< Configuration Register 1 */ +#define XADCPS_CFR2_OFFSET 0x42 /**< Configuration Register 2 */ + +/* Test Registers 0x43 to 0x47 */ + +/* + * XADC Sequence Registers + */ +#define XADCPS_SEQ00_OFFSET 0x48 /**< Seq Reg 00 Adc Channel Selection */ +#define XADCPS_SEQ01_OFFSET 0x49 /**< Seq Reg 01 Adc Channel Selection */ +#define XADCPS_SEQ02_OFFSET 0x4A /**< Seq Reg 02 Adc Average Enable */ +#define XADCPS_SEQ03_OFFSET 0x4B /**< Seq Reg 03 Adc Average Enable */ +#define XADCPS_SEQ04_OFFSET 0x4C /**< Seq Reg 04 Adc Input Mode Select */ +#define XADCPS_SEQ05_OFFSET 0x4D /**< Seq Reg 05 Adc Input Mode Select */ +#define XADCPS_SEQ06_OFFSET 0x4E /**< Seq Reg 06 Adc Acquisition Select */ +#define XADCPS_SEQ07_OFFSET 0x4F /**< Seq Reg 07 Adc Acquisition Select */ + +/* + * XADC Alarm Threshold/Limit Registers (ATR) + */ +#define XADCPS_ATR_TEMP_UPPER_OFFSET 0x50 /**< Temp Upper Alarm Register */ +#define XADCPS_ATR_VCCINT_UPPER_OFFSET 0x51 /**< VCCINT Upper Alarm Reg */ +#define XADCPS_ATR_VCCAUX_UPPER_OFFSET 0x52 /**< VCCAUX Upper Alarm Reg */ +#define XADCPS_ATR_OT_UPPER_OFFSET 0x53 /**< Over Temp Upper Alarm Reg */ +#define XADCPS_ATR_TEMP_LOWER_OFFSET 0x54 /**< Temp Lower Alarm Register */ +#define XADCPS_ATR_VCCINT_LOWER_OFFSET 0x55 /**< VCCINT Lower Alarm Reg */ +#define XADCPS_ATR_VCCAUX_LOWER_OFFSET 0x56 /**< VCCAUX Lower Alarm Reg */ +#define XADCPS_ATR_OT_LOWER_OFFSET 0x57 /**< Over Temp Lower Alarm Reg */ +#define XADCPS_ATR_VBRAM_UPPER_OFFSET 0x58 /**< VBRAM Upper Alarm, 7 series */ +#define XADCPS_ATR_VCCPINT_UPPER_OFFSET 0x59 /**< VCCPINT Upper Alarm, Zynq */ +#define XADCPS_ATR_VCCPAUX_UPPER_OFFSET 0x5A /**< VCCPAUX Upper Alarm, Zynq */ +#define XADCPS_ATR_VCCPDRO_UPPER_OFFSET 0x5B /**< VCCPDRO Upper Alarm, Zynq */ +#define XADCPS_ATR_VBRAM_LOWER_OFFSET 0x5C /**< VRBAM Lower Alarm, 7 Series */ +#define XADCPS_ATR_VCCPINT_LOWER_OFFSET 0x5D /**< VCCPINT Lower Alarm, Zynq */ +#define XADCPS_ATR_VCCPAUX_LOWER_OFFSET 0x5E /**< VCCPAUX Lower Alarm, Zynq */ +#define XADCPS_ATR_VCCPDRO_LOWER_OFFSET 0x5F /**< VCCPDRO Lower Alarm, Zynq */ + +/* Undefined 0x60 to 0x7F */ + +/*@}*/ + + + +/** + * @name Configuration Register 0 (CFR0) mask(s) + * @{ + */ +#define XADCPS_CFR0_CAL_AVG_MASK 0x8000 /**< Averaging enable Mask */ +#define XADCPS_CFR0_AVG_VALID_MASK 0x3000 /**< Averaging bit Mask */ +#define XADCPS_CFR0_AVG1_MASK 0x0000 /**< No Averaging */ +#define XADCPS_CFR0_AVG16_MASK 0x1000 /**< Average 16 samples */ +#define XADCPS_CFR0_AVG64_MASK 0x2000 /**< Average 64 samples */ +#define XADCPS_CFR0_AVG256_MASK 0x3000 /**< Average 256 samples */ +#define XADCPS_CFR0_AVG_SHIFT 12 /**< Averaging bits shift */ +#define XADCPS_CFR0_MUX_MASK 0x0800 /**< External Mask Enable */ +#define XADCPS_CFR0_DU_MASK 0x0400 /**< Bipolar/Unipolar mode */ +#define XADCPS_CFR0_EC_MASK 0x0200 /**< Event driven/ + * Continuous mode selection + */ +#define XADCPS_CFR0_ACQ_MASK 0x0100 /**< Add acquisition by 6 ADCCLK */ +#define XADCPS_CFR0_CHANNEL_MASK 0x001F /**< Channel number bit Mask */ + +/*@}*/ + +/** + * @name Configuration Register 1 (CFR1) mask(s) + * @{ + */ +#define XADCPS_CFR1_SEQ_VALID_MASK 0xF000 /**< Sequence bit Mask */ +#define XADCPS_CFR1_SEQ_SAFEMODE_MASK 0x0000 /**< Default Safe Mode */ +#define XADCPS_CFR1_SEQ_ONEPASS_MASK 0x1000 /**< Onepass through Seq */ +#define XADCPS_CFR1_SEQ_CONTINPASS_MASK 0x2000 /**< Continuous Cycling Seq */ +#define XADCPS_CFR1_SEQ_SINGCHAN_MASK 0x3000 /**< Single channel - No Seq */ +#define XADCPS_CFR1_SEQ_SIMUL_SAMPLING_MASK 0x4000 /**< Simulataneous Sampling Mask */ +#define XADCPS_CFR1_SEQ_INDEPENDENT_MASK 0x8000 /**< Independent Mode */ +#define XADCPS_CFR1_SEQ_SHIFT 12 /**< Sequence bit shift */ +#define XADCPS_CFR1_ALM_VCCPDRO_MASK 0x0800 /**< Alm 6 - VCCPDRO, Zynq */ +#define XADCPS_CFR1_ALM_VCCPAUX_MASK 0x0400 /**< Alm 5 - VCCPAUX, Zynq */ +#define XADCPS_CFR1_ALM_VCCPINT_MASK 0x0200 /**< Alm 4 - VCCPINT, Zynq */ +#define XADCPS_CFR1_ALM_VBRAM_MASK 0x0100 /**< Alm 3 - VBRAM, 7 series */ +#define XADCPS_CFR1_CAL_VALID_MASK 0x00F0 /**< Valid Calibration Mask */ +#define XADCPS_CFR1_CAL_PS_GAIN_OFFSET_MASK 0x0080 /**< Calibration 3 -Power + Supply Gain/Offset + Enable */ +#define XADCPS_CFR1_CAL_PS_OFFSET_MASK 0x0040 /**< Calibration 2 -Power + Supply Offset Enable */ +#define XADCPS_CFR1_CAL_ADC_GAIN_OFFSET_MASK 0x0020 /**< Calibration 1 -ADC Gain + Offset Enable */ +#define XADCPS_CFR1_CAL_ADC_OFFSET_MASK 0x0010 /**< Calibration 0 -ADC Offset + Enable */ +#define XADCPS_CFR1_CAL_DISABLE_MASK 0x0000 /**< No Calibration */ +#define XADCPS_CFR1_ALM_ALL_MASK 0x0F0F /**< Mask for all alarms */ +#define XADCPS_CFR1_ALM_VCCAUX_MASK 0x0008 /**< Alarm 2 - VCCAUX Enable */ +#define XADCPS_CFR1_ALM_VCCINT_MASK 0x0004 /**< Alarm 1 - VCCINT Enable */ +#define XADCPS_CFR1_ALM_TEMP_MASK 0x0002 /**< Alarm 0 - Temperature */ +#define XADCPS_CFR1_OT_MASK 0x0001 /**< Over Temperature Enable */ + +/*@}*/ + +/** + * @name Configuration Register 2 (CFR2) mask(s) + * @{ + */ +#define XADCPS_CFR2_CD_VALID_MASK 0xFF00 /** +* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ---- -------- ------------------------------------------------------- +* 1.00a adk 1/31/14 Added in bsp common folder for backward compatibility +* 7.0 aru 01/21/19 Modified the typedef of u32,u16,u8 +* 7.0 aru 02/06/19 Included stdint.h and stddef.h +* +* +******************************************************************************/ + +#ifndef XBASIC_TYPES_H /* prevent circular inclusions */ +#define XBASIC_TYPES_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/** @name Legacy types + * Deprecated legacy types. + * @{ + */ +typedef uint8_t Xuint8; /**< unsigned 8-bit */ +typedef char Xint8; /**< signed 8-bit */ +typedef uint16_t Xuint16; /**< unsigned 16-bit */ +typedef short Xint16; /**< signed 16-bit */ +typedef uint32_t Xuint32; /**< unsigned 32-bit */ +typedef long Xint32; /**< signed 32-bit */ +typedef float Xfloat32; /**< 32-bit floating point */ +typedef double Xfloat64; /**< 64-bit double precision FP */ +typedef unsigned long Xboolean; /**< boolean (XTRUE or XFALSE) */ + +#if !defined __XUINT64__ +typedef struct +{ + Xuint32 Upper; + Xuint32 Lower; +} Xuint64; +#endif + +/** @name New types + * New simple types. + * @{ + */ +#ifndef __KERNEL__ +#ifndef XIL_TYPES_H +typedef Xuint32 u32; +typedef Xuint16 u16; +typedef Xuint8 u8; +#endif +#else +#include +#endif + +#ifndef TRUE +# define TRUE 1U +#endif + +#ifndef FALSE +# define FALSE 0U +#endif + +#ifndef NULL +#define NULL 0U +#endif + +/* + * Xilinx NULL, TRUE and FALSE legacy support. Deprecated. + * Please use NULL, TRUE and FALSE + */ +#define XNULL NULL +#define XTRUE TRUE +#define XFALSE FALSE + +/* + * This file is deprecated and users + * should use xil_types.h and xil_assert.h\n\r + */ +#warning The xbasics_type.h file is deprecated and users should use xil_types.h and xil_assert. +#warning Please refer the Standalone BSP UG647 for further details + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xbram.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xbram.h new file mode 100644 index 0000000..246df6d --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xbram.h @@ -0,0 +1,223 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2019 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* @file xbram.h +* @addtogroup bram_v4_2 +* @{ +* @details +* +* If ECC is not enabled, this driver exists only to allow the tools to +* create a memory test application and to populate xparameters.h with memory +* range constants. In this case there is no source code. +* +* If ECC is enabled, this file contains the software API definition of the +* Xilinx BRAM Interface Controller (XBram) device driver. +* +* The Xilinx BRAM controller is a soft IP core designed for Xilinx +* FPGAs and contains the following general features: +* - LMB v2.0 bus interfaces with byte enable support +* - Used in conjunction with bram_block peripheral to provide fast BRAM +* memory solution for MicroBlaze ILMB and DLMB ports +* - Supports byte, half-word, and word transfers +* - Supports optional BRAM error correction and detection. +* +* The driver provides interrupt management functions. Implementation of +* interrupt handlers is left to the user. Refer to the provided interrupt +* example in the examples directory for details. +* +* This driver is intended to be RTOS and processor independent. Any needs for +* dynamic memory management, threads or thread mutual exclusion, virtual +* memory, or cache control must be satisfied by the layer above this driver. +* +* Initialization & Configuration +* +* The XBram_Config structure is used by the driver to configure +* itself. This configuration structure is typically created by the tool-chain +* based on HW build properties. +* +* To support multiple runtime loading and initialization strategies employed +* by various operating systems, the driver instance can be initialized as +* follows: +* +* - XBram_CfgInitialize(InstancePtr, CfgPtr, EffectiveAddr) - +* Uses a configuration structure provided by the caller. If running in a +* system with address translation, the provided virtual memory base address +* replaces the physical address present in the configuration structure. +* +* @note +* +* This API utilizes 32 bit I/O to the BRAM registers. With less +* than 32 bits, the unused bits from registers are read as zero and written as +* don't cares. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 3.00a sa  05/11/10 Added ECC support
+* 3.01a sa  01/13/12  Changed Selftest API from
+*		      XBram_SelfTest(XBram *InstancePtr) to
+*		      XBram_SelfTest(XBram *InstancePtr, u8 IntMask) and
+*		      fixed a problem with interrupt generation for CR 639274
+*		      Modified Selftest example to return XST_SUCCESS when
+*		      ECC is not enabled and return XST_FAILURE when ECC is
+*		      enabled and Control Base Address is zero (CR 636581)
+*		      Modified Selftest to use correct CorrectableCounterBits
+*		      for CR 635655
+*		      Updated to check CorrectableFailingDataRegs in the case
+*		      of LMB BRAM.
+* 		      Added CorrectableFailingDataRegs and
+*		      UncorrectableFailingDataRegs to the config structure to
+*		      distinguish between AXI BRAM and LMB BRAM.
+*		      These registers are not present in the current version of
+*		      the AXI BRAM Controller.
+* 3.02a sa 04/16/12   Added test of byte and halfword read-modify-write
+* 3.02a sa 04/16/12   Modified driver tcl to sort the address parameters
+*  	       	      to support both xps and vivado designs.
+* 3.02a adk 24/4/13   Modified the tcl file to avoid warnings
+*	       	      when ecc is disabled cr:705002.
+* 3.03a bss 05/22/13  Added Xil_DCacheFlushRange in xbram_selftest.c to
+*		      flush the Cache after writing to BRAM in InjectErrors
+*		      API(CR #719011)
+* 4.0   adk  19/12/13 Updated as per the New Tcl API's
+* 4.1   sk   11/10/15 Used UINTPTR instead of u32 for Baseaddress CR# 867425.
+*                     Changed the prototype of XBram_CfgInitialize API.
+*       ms  01/23/17 Modified xil_printf statement in main function for all
+*                    examples to ensure that "Successfully ran" and "Failed"
+*                    strings are available in all examples. This is a fix
+*                    for CR-965028.
+*       ms  03/17/17 Added readme.txt file in examples folder for doxygen
+*                    generation.
+* 4.2   ms  04/18/17 Modified tcl file to add suffix U for all macro
+*                    definitions of bram in xparameters.h
+*       ms  08/07/17 Fixed compilation warnings in xbram_sinit.c
+* 4.3   aru 03/23/19 Used UINTPTR instead of u32 for MemBaseAddress and
+*                    MemHighAddress.
+* 
+*****************************************************************************/ +#ifndef XBRAM_H /* prevent circular inclusions */ +#define XBRAM_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files ********************************/ + +#include "xil_types.h" +#include "xil_assert.h" +#include "xstatus.h" +#include "xbram_hw.h" + +/************************** Constant Definitions ****************************/ + + +/**************************** Type Definitions ******************************/ + +/** + * This typedef contains configuration information for the device. + */ +typedef struct { + u16 DeviceId; /**< Unique ID of device */ + u32 DataWidth; /**< BRAM data width */ + int EccPresent; /**< Is ECC supported in H/W */ + int FaultInjectionPresent; /**< Is Fault Injection + * supported in H/W */ + int CorrectableFailingRegisters; /**< Is Correctable Failing Registers + * supported in H/W */ + int CorrectableFailingDataRegs; /**< Is Correctable Failing Data + * Registers supported in H/W */ + int UncorrectableFailingRegisters; /**< Is Un-correctable Failing + * Registers supported in H/W */ + int UncorrectableFailingDataRegs; /**< Is Un-correctable Failing Data + * Registers supported in H/W */ + int EccStatusInterruptPresent; /**< Are ECC status and interrupts + * supported in H/W */ + int CorrectableCounterBits; /**< Number of bits in the + * Correctable Error Counter */ + int EccOnOffRegister; /**< Is ECC on/off register supported + * in h/w */ + int EccOnOffResetValue; /**< Reset value of the ECC on/off + * register in h/w */ + int WriteAccess; /**< Is write access enabled in + * h/w */ + UINTPTR MemBaseAddress; /**< Device memory base address */ + UINTPTR MemHighAddress; /**< Device memory high address */ + UINTPTR CtrlBaseAddress; /**< Device register base address.*/ + UINTPTR CtrlHighAddress; /**< Device register base address.*/ +} XBram_Config; + +/** + * The XBram driver instance data. The user is required to + * allocate a variable of this type for every BRAM device in the + * system. A pointer to a variable of this type is then passed to the driver + * API functions. + */ +typedef struct { + XBram_Config Config; /* BRAM config structure */ + u32 IsReady; /* Device is initialized and ready */ +} XBram; + +/***************** Macros (Inline Functions) Definitions ********************/ + + +/************************** Function Prototypes *****************************/ + +/* + * Functions in xbram_sinit.c + */ +XBram_Config *XBram_LookupConfig(u16 DeviceId); + +/* + * Functions implemented in xbram.c + */ +int XBram_CfgInitialize(XBram *InstancePtr, XBram_Config *Config, + UINTPTR EffectiveAddr); + +/* + * Functions implemented in xbram_selftest.c + */ +int XBram_SelfTest(XBram *InstancePtr, u8 IntMask); + +/* + * Functions implemented in xbram_intr.c + */ +void XBram_InterruptEnable(XBram *InstancePtr, u32 Mask); +void XBram_InterruptDisable(XBram *InstancePtr, u32 Mask); +void XBram_InterruptClear(XBram *InstancePtr, u32 Mask); +u32 XBram_InterruptGetEnabled(XBram *InstancePtr); +u32 XBram_InterruptGetStatus(XBram *InstancePtr); + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xbram_hw.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xbram_hw.h new file mode 100644 index 0000000..55a2505 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xbram_hw.h @@ -0,0 +1,405 @@ +/****************************************************************************** +* +* Copyright (C) 2011 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xbram_hw.h +* @addtogroup bram_v4_2 +* @{ +* +* This header file contains identifiers and driver functions (or +* macros) that can be used to access the device. The user should refer to the +* hardware device specification for more details of the device operation. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a sa   24/11/10 First release
+* 
+* +******************************************************************************/ +#ifndef XBRAM_HW_H /* prevent circular inclusions */ +#define XBRAM_HW_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +#include "xil_types.h" +#include "xil_assert.h" +#include "xil_io.h" + +/************************** Constant Definitions *****************************/ + +/** @name Registers + * + * Register offsets for this device. + * @{ + */ + +#define XBRAM_ECC_STATUS_OFFSET 0x0 /**< ECC status Register */ +#define XBRAM_ECC_EN_IRQ_OFFSET 0x4 /**< ECC interrupt enable Register */ +#define XBRAM_ECC_ON_OFF_OFFSET 0x8 /**< ECC on/off register */ +#define XBRAM_CE_CNT_OFFSET 0xC /**< Correctable error counter Register */ + +#define XBRAM_CE_FFD_0_OFFSET 0x100 /**< Correctable error first failing + * data Register, 31-0 */ +#define XBRAM_CE_FFD_1_OFFSET 0x104 /**< Correctable error first failing + * data Register, 63-32 */ +#define XBRAM_CE_FFD_2_OFFSET 0x108 /**< Correctable error first failing + * data Register, 95-64 */ +#define XBRAM_CE_FFD_3_OFFSET 0x10C /**< Correctable error first failing + * data Register, 127-96 */ +#define XBRAM_CE_FFD_4_OFFSET 0x110 /**< Correctable error first failing + * data Register, 159-128 */ +#define XBRAM_CE_FFD_5_OFFSET 0x114 /**< Correctable error first failing + * data Register, 191-160 */ +#define XBRAM_CE_FFD_6_OFFSET 0x118 /**< Correctable error first failing + * data Register, 223-192 */ +#define XBRAM_CE_FFD_7_OFFSET 0x11C /**< Correctable error first failing + * data Register, 255-224 */ +#define XBRAM_CE_FFD_8_OFFSET 0x120 /**< Correctable error first failing + * data Register, 287-256 */ +#define XBRAM_CE_FFD_9_OFFSET 0x124 /**< Correctable error first failing + * data Register, 319-288 */ +#define XBRAM_CE_FFD_10_OFFSET 0x128 /**< Correctable error first failing + * data Register, 351-320 */ +#define XBRAM_CE_FFD_11_OFFSET 0x12C /**< Correctable error first failing + * data Register, 383-352 */ +#define XBRAM_CE_FFD_12_OFFSET 0x130 /**< Correctable error first failing + * data Register, 415-384 */ +#define XBRAM_CE_FFD_13_OFFSET 0x134 /**< Correctable error first failing + * data Register, 447-416 */ +#define XBRAM_CE_FFD_14_OFFSET 0x138 /**< Correctable error first failing + * data Register, 479-448 */ +#define XBRAM_CE_FFD_15_OFFSET 0x13C /**< Correctable error first failing + * data Register, 511-480 */ +#define XBRAM_CE_FFD_16_OFFSET 0x140 /**< Correctable error first failing + * data Register, 543-512 */ +#define XBRAM_CE_FFD_17_OFFSET 0x144 /**< Correctable error first failing + * data Register, 575-544 */ +#define XBRAM_CE_FFD_18_OFFSET 0x148 /**< Correctable error first failing + * data Register, 607-576 */ +#define XBRAM_CE_FFD_19_OFFSET 0x14C /**< Correctable error first failing + * data Register, 639-608 */ +#define XBRAM_CE_FFD_20_OFFSET 0x150 /**< Correctable error first failing + * data Register, 671-640 */ +#define XBRAM_CE_FFD_21_OFFSET 0x154 /**< Correctable error first failing + * data Register, 703-672 */ +#define XBRAM_CE_FFD_22_OFFSET 0x158 /**< Correctable error first failing + * data Register, 735-704 */ +#define XBRAM_CE_FFD_23_OFFSET 0x15C /**< Correctable error first failing + * data Register, 767-736 */ +#define XBRAM_CE_FFD_24_OFFSET 0x160 /**< Correctable error first failing + * data Register, 799-768 */ +#define XBRAM_CE_FFD_25_OFFSET 0x164 /**< Correctable error first failing + * data Register, 831-800 */ +#define XBRAM_CE_FFD_26_OFFSET 0x168 /**< Correctable error first failing + * data Register, 863-832 */ +#define XBRAM_CE_FFD_27_OFFSET 0x16C /**< Correctable error first failing + * data Register, 895-864 */ +#define XBRAM_CE_FFD_28_OFFSET 0x170 /**< Correctable error first failing + * data Register, 927-896 */ +#define XBRAM_CE_FFD_29_OFFSET 0x174 /**< Correctable error first failing + * data Register, 959-928 */ +#define XBRAM_CE_FFD_30_OFFSET 0x178 /**< Correctable error first failing + * data Register, 991-960 */ +#define XBRAM_CE_FFD_31_OFFSET 0x17C /**< Correctable error first failing + * data Register, 1023-992 */ + +#define XBRAM_CE_FFE_0_OFFSET 0x180 /**< Correctable error first failing + * ECC Register, 31-0 */ +#define XBRAM_CE_FFE_1_OFFSET 0x184 /**< Correctable error first failing + * ECC Register, 63-32 */ +#define XBRAM_CE_FFE_2_OFFSET 0x188 /**< Correctable error first failing + * ECC Register, 95-64 */ +#define XBRAM_CE_FFE_3_OFFSET 0x18C /**< Correctable error first failing + * ECC Register, 127-96 */ +#define XBRAM_CE_FFE_4_OFFSET 0x190 /**< Correctable error first failing + * ECC Register, 159-128 */ +#define XBRAM_CE_FFE_5_OFFSET 0x194 /**< Correctable error first failing + * ECC Register, 191-160 */ +#define XBRAM_CE_FFE_6_OFFSET 0x198 /**< Correctable error first failing + * ECC Register, 223-192 */ +#define XBRAM_CE_FFE_7_OFFSET 0x19C /**< Correctable error first failing + * ECC Register, 255-224 */ + +#define XBRAM_CE_FFA_0_OFFSET 0x1C0 /**< Correctable error first failing + * address Register 31-0 */ +#define XBRAM_CE_FFA_1_OFFSET 0x1C4 /**< Correctable error first failing + * address Register 63-32 */ + +#define XBRAM_UE_FFD_0_OFFSET 0x200 /**< Uncorrectable error first failing + * data Register, 31-0 */ +#define XBRAM_UE_FFD_1_OFFSET 0x204 /**< Uncorrectable error first failing + * data Register, 63-32 */ +#define XBRAM_UE_FFD_2_OFFSET 0x208 /**< Uncorrectable error first failing + * data Register, 95-64 */ +#define XBRAM_UE_FFD_3_OFFSET 0x20C /**< Uncorrectable error first failing + * data Register, 127-96 */ +#define XBRAM_UE_FFD_4_OFFSET 0x210 /**< Uncorrectable error first failing + * data Register, 159-128 */ +#define XBRAM_UE_FFD_5_OFFSET 0x214 /**< Uncorrectable error first failing + * data Register, 191-160 */ +#define XBRAM_UE_FFD_6_OFFSET 0x218 /**< Uncorrectable error first failing + * data Register, 223-192 */ +#define XBRAM_UE_FFD_7_OFFSET 0x21C /**< Uncorrectable error first failing + * data Register, 255-224 */ +#define XBRAM_UE_FFD_8_OFFSET 0x220 /**< Uncorrectable error first failing + * data Register, 287-256 */ +#define XBRAM_UE_FFD_9_OFFSET 0x224 /**< Uncorrectable error first failing + * data Register, 319-288 */ +#define XBRAM_UE_FFD_10_OFFSET 0x228 /**< Uncorrectable error first failing + * data Register, 351-320 */ +#define XBRAM_UE_FFD_11_OFFSET 0x22C /**< Uncorrectable error first failing + * data Register, 383-352 */ +#define XBRAM_UE_FFD_12_OFFSET 0x230 /**< Uncorrectable error first failing + * data Register, 415-384 */ +#define XBRAM_UE_FFD_13_OFFSET 0x234 /**< Uncorrectable error first failing + * data Register, 447-416 */ +#define XBRAM_UE_FFD_14_OFFSET 0x238 /**< Uncorrectable error first failing + * data Register, 479-448 */ +#define XBRAM_UE_FFD_15_OFFSET 0x23C /**< Uncorrectable error first failing + * data Register, 511-480 */ +#define XBRAM_UE_FFD_16_OFFSET 0x240 /**< Uncorrectable error first failing + * data Register, 543-512 */ +#define XBRAM_UE_FFD_17_OFFSET 0x244 /**< Uncorrectable error first failing + * data Register, 575-544 */ +#define XBRAM_UE_FFD_18_OFFSET 0x248 /**< Uncorrectable error first failing + * data Register, 607-576 */ +#define XBRAM_UE_FFD_19_OFFSET 0x24C /**< Uncorrectable error first failing + * data Register, 639-608 */ +#define XBRAM_UE_FFD_20_OFFSET 0x250 /**< Uncorrectable error first failing + * data Register, 671-640 */ +#define XBRAM_UE_FFD_21_OFFSET 0x254 /**< Uncorrectable error first failing + * data Register, 703-672 */ +#define XBRAM_UE_FFD_22_OFFSET 0x258 /**< Uncorrectable error first failing + * data Register, 735-704 */ +#define XBRAM_UE_FFD_23_OFFSET 0x25C /**< Uncorrectable error first failing + * data Register, 767-736 */ +#define XBRAM_UE_FFD_24_OFFSET 0x260 /**< Uncorrectable error first failing + * data Register, 799-768 */ +#define XBRAM_UE_FFD_25_OFFSET 0x264 /**< Uncorrectable error first failing + * data Register, 831-800 */ +#define XBRAM_UE_FFD_26_OFFSET 0x268 /**< Uncorrectable error first failing + * data Register, 863-832 */ +#define XBRAM_UE_FFD_27_OFFSET 0x26C /**< Uncorrectable error first failing + * data Register, 895-864 */ +#define XBRAM_UE_FFD_28_OFFSET 0x270 /**< Uncorrectable error first failing + * data Register, 927-896 */ +#define XBRAM_UE_FFD_29_OFFSET 0x274 /**< Uncorrectable error first failing + * data Register, 959-928 */ +#define XBRAM_UE_FFD_30_OFFSET 0x278 /**< Uncorrectable error first failing + * data Register, 991-960 */ +#define XBRAM_UE_FFD_31_OFFSET 0x27C /**< Uncorrectable error first failing + * data Register, 1023-992 */ + +#define XBRAM_UE_FFE_0_OFFSET 0x280 /**< Uncorrectable error first failing + * ECC Register, 31-0 */ +#define XBRAM_UE_FFE_1_OFFSET 0x284 /**< Uncorrectable error first failing + * ECC Register, 63-32 */ +#define XBRAM_UE_FFE_2_OFFSET 0x288 /**< Uncorrectable error first failing + * ECC Register, 95-64 */ +#define XBRAM_UE_FFE_3_OFFSET 0x28C /**< Uncorrectable error first failing + * ECC Register, 127-96 */ +#define XBRAM_UE_FFE_4_OFFSET 0x290 /**< Uncorrectable error first failing + * ECC Register, 159-128 */ +#define XBRAM_UE_FFE_5_OFFSET 0x294 /**< Uncorrectable error first failing + * ECC Register, 191-160 */ +#define XBRAM_UE_FFE_6_OFFSET 0x298 /**< Uncorrectable error first failing + * ECC Register, 223-192 */ +#define XBRAM_UE_FFE_7_OFFSET 0x29C /**< Uncorrectable error first failing + * ECC Register, 255-224 */ + +#define XBRAM_UE_FFA_0_OFFSET 0x2C0 /**< Uncorrectable error first failing + * address Register 31-0 */ +#define XBRAM_UE_FFA_1_OFFSET 0x2C4 /**< Uncorrectable error first failing + * address Register 63-32 */ + +#define XBRAM_FI_D_0_OFFSET 0x300 /**< Fault injection Data Register, + * 31-0 */ +#define XBRAM_FI_D_1_OFFSET 0x304 /**< Fault injection Data Register, + * 63-32 */ +#define XBRAM_FI_D_2_OFFSET 0x308 /**< Fault injection Data Register, + * 95-64 */ +#define XBRAM_FI_D_3_OFFSET 0x30C /**< Fault injection Data Register, + * 127-96 */ +#define XBRAM_FI_D_4_OFFSET 0x310 /**< Fault injection Data Register, + * 159-128 */ +#define XBRAM_FI_D_5_OFFSET 0x314 /**< Fault injection Data Register, + * 191-160 */ +#define XBRAM_FI_D_6_OFFSET 0x318 /**< Fault injection Data Register, + * 223-192 */ +#define XBRAM_FI_D_7_OFFSET 0x31C /**< Fault injection Data Register, + * 255-224 */ +#define XBRAM_FI_D_8_OFFSET 0x320 /**< Fault injection Data Register, + * 287-256 */ +#define XBRAM_FI_D_9_OFFSET 0x324 /**< Fault injection Data Register, + * 319-288 */ +#define XBRAM_FI_D_10_OFFSET 0x328 /**< Fault injection Data Register, + * 351-320 */ +#define XBRAM_FI_D_11_OFFSET 0x32C /**< Fault injection Data Register, + * 383-352 */ +#define XBRAM_FI_D_12_OFFSET 0x330 /**< Fault injection Data Register, + * 415-384 */ +#define XBRAM_FI_D_13_OFFSET 0x334 /**< Fault injection Data Register, + * 447-416 */ +#define XBRAM_FI_D_14_OFFSET 0x338 /**< Fault injection Data Register, + * 479-448 */ +#define XBRAM_FI_D_15_OFFSET 0x33C /**< Fault injection Data Register, + * 511-480 */ +#define XBRAM_FI_D_16_OFFSET 0x340 /**< Fault injection Data Register, + * 543-512 */ +#define XBRAM_FI_D_17_OFFSET 0x344 /**< Fault injection Data Register, + * 575-544 */ +#define XBRAM_FI_D_18_OFFSET 0x348 /**< Fault injection Data Register, + * 607-576 */ +#define XBRAM_FI_D_19_OFFSET 0x34C /**< Fault injection Data Register, + * 639-608 */ +#define XBRAM_FI_D_20_OFFSET 0x350 /**< Fault injection Data Register, + * 671-640 */ +#define XBRAM_FI_D_21_OFFSET 0x354 /**< Fault injection Data Register, + * 703-672 */ +#define XBRAM_FI_D_22_OFFSET 0x358 /**< Fault injection Data Register, + * 735-704 */ +#define XBRAM_FI_D_23_OFFSET 0x35C /**< Fault injection Data Register, + * 767-736 */ +#define XBRAM_FI_D_24_OFFSET 0x360 /**< Fault injection Data Register, + * 799-768 */ +#define XBRAM_FI_D_25_OFFSET 0x364 /**< Fault injection Data Register, + * 831-800 */ +#define XBRAM_FI_D_26_OFFSET 0x368 /**< Fault injection Data Register, + * 863-832 */ +#define XBRAM_FI_D_27_OFFSET 0x36C /**< Fault injection Data Register, + * 895-864 */ +#define XBRAM_FI_D_28_OFFSET 0x370 /**< Fault injection Data Register, + * 927-896 */ +#define XBRAM_FI_D_29_OFFSET 0x374 /**< Fault injection Data Register, + * 959-928 */ +#define XBRAM_FI_D_30_OFFSET 0x378 /**< Fault injection Data Register, + * 991-960 */ +#define XBRAM_FI_D_31_OFFSET 0x37C /**< Fault injection Data Register, + * 1023-992 */ + +#define XBRAM_FI_ECC_0_OFFSET 0x380 /**< Fault injection ECC Register, + * 31-0 */ +#define XBRAM_FI_ECC_1_OFFSET 0x384 /**< Fault injection ECC Register, + * 63-32 */ +#define XBRAM_FI_ECC_2_OFFSET 0x388 /**< Fault injection ECC Register, + * 95-64 */ +#define XBRAM_FI_ECC_3_OFFSET 0x38C /**< Fault injection ECC Register, + * 127-96 */ +#define XBRAM_FI_ECC_4_OFFSET 0x390 /**< Fault injection ECC Register, + * 159-128 */ +#define XBRAM_FI_ECC_5_OFFSET 0x394 /**< Fault injection ECC Register, + * 191-160 */ +#define XBRAM_FI_ECC_6_OFFSET 0x398 /**< Fault injection ECC Register, + * 223-192 */ +#define XBRAM_FI_ECC_7_OFFSET 0x39C /**< Fault injection ECC Register, + * 255-224 */ + + +/* @} */ + +/** @name Interrupt Status and Enable Register bitmaps and masks + * + * Bit definitions for the ECC status register and ECC interrupt enable register. + * @{ + */ +#define XBRAM_IR_CE_MASK 0x2 /**< Mask for the correctable error */ +#define XBRAM_IR_UE_MASK 0x1 /**< Mask for the uncorrectable error */ +#define XBRAM_IR_ALL_MASK 0x3 /**< Mask of all bits */ +/*@}*/ + + +/**************************** Type Definitions *******************************/ + + +/***************** Macros (Inline Functions) Definitions *********************/ + +#define XBram_In32 Xil_In32 +#define XBram_Out32 Xil_Out32 + +#define XBram_In16 Xil_In16 +#define XBram_Out16 Xil_Out16 + +#define XBram_In8 Xil_In8 +#define XBram_Out8 Xil_Out8 + + +/****************************************************************************/ +/** +* +* Write a value to a BRAM register. A 32 bit write is performed. +* +* @param BaseAddress is the base address of the BRAM device register. +* @param RegOffset is the register offset from the base to write to. +* @param Data is the data written to the register. +* +* @return None. +* +* @note C-style signature: +* void XBram_WriteReg(u32 BaseAddress, u32 RegOffset, u32 Data) +* +****************************************************************************/ +#define XBram_WriteReg(BaseAddress, RegOffset, Data) \ + XBram_Out32((BaseAddress) + (RegOffset), (u32)(Data)) + +/****************************************************************************/ +/** +* +* Read a value from a BRAM register. A 32 bit read is performed. +* +* @param BaseAddress is the base address of the BRAM device registers. +* @param RegOffset is the register offset from the base to read from. +* +* @return Data read from the register. +* +* @note C-style signature: +* u32 XBram_ReadReg(u32 BaseAddress, u32 RegOffset) +* +****************************************************************************/ +#define XBram_ReadReg(BaseAddress, RegOffset) \ + XBram_In32((BaseAddress) + (RegOffset)) + +/************************** Function Prototypes ******************************/ + +/************************** Variable Definitions *****************************/ + + + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xcoresightpsdcc.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xcoresightpsdcc.h new file mode 100644 index 0000000..79bde0b --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xcoresightpsdcc.h @@ -0,0 +1,74 @@ +/****************************************************************************** +* +* Copyright (C) 2015 - 2019 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xcoresightpsdcc.h +* @addtogroup coresightps_dcc_v1_5 +* @{ +* @details +* +* CoreSight driver component. +* +* The coresight is a part of debug communication channel (DCC) group. Jtag UART +* for ARM uses DCC. Each ARM core has its own DCC, so one need to select an +* ARM target in XSDB console before running the jtag terminal command. Using the +* coresight driver component, the output stream can be directed to a log file. +* +* @note None. +* +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date		Changes
+* ----- -----  -------- -----------------------------------------------
+* 1.00  kvn    02/14/15 First release
+* 1.1   kvn    06/12/15 Add support for Zynq Ultrascale+ MP.
+*       kvn    08/18/15 Modified Makefile according to compiler changes.
+* 1.3   asa    07/01/16 Made changes to ensure that the file does not compile
+*                       for MB BSPs. Instead it throws up a warning. This
+*                       fixes the CR#953056.
+* 1.5   sne    01/19/19 Fixed MISRA-C Violations CR#1025101.
+*
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ +#ifndef XCORESIGHTPSDCC_H /* prevent circular inclusions */ +#define XCORESIGHTPSDCC_H /* by using protection macros */ +#ifndef __MICROBLAZE__ +#include + +void XCoresightPs_DccSendByte(u32 BaseAddress, u8 Data); + +u8 XCoresightPs_DccRecvByte(u32 BaseAddress); +#endif +#endif +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xcpu_cortexa9.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xcpu_cortexa9.h new file mode 100644 index 0000000..e4a5e28 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xcpu_cortexa9.h @@ -0,0 +1,47 @@ +/****************************************************************************** +* +* Copyright (C) 2011 - 2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xcpu_cortexa9.h +* @addtogroup cpu_cortexa9_v2_7 +* @{ +* @details +* +* dummy file +* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ---- -------- --------------------------------------------------------- +* 2.5 ms 04/18/17 Modified tcl file to add suffix U for XPAR_CPU_ID +* parameter of cpu_cortexa9 in xparameters.h +# 2.7 mus 07/03/18 Updated tcl to not to add default flags forcefully into +# extra compiler flags. Now, user can remove default flags +# from extra compiler flags. It fixes CR#998768. +******************************************************************************/ +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xddrps.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xddrps.h new file mode 100644 index 0000000..b4d1f56 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xddrps.h @@ -0,0 +1,62 @@ +/******************************************************************************* + * + * Copyright (C) 2015 Xilinx, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of the Xilinx shall not be used + * in advertising or otherwise to promote the sale, use or other dealings in + * this Software without prior written authorization from Xilinx. + * +*******************************************************************************/ +/******************************************************************************/ +/** + * + * @file xddrps.h + * @addtogroup ddrps_v1_0 + * @{ + * @details + * + * The Xilinx DdrPs driver. This driver supports the Xilinx ddrps + * IP core. + * + * @note None. + * + *
+ * MODIFICATION HISTORY:
+ *
+ * Ver   Who  Date     Changes
+ * ----- ---- -------- -----------------------------------------------
+ * 1.0	 nsk  08/06/15 First Release
+ * 1.0	 nsk  08/20/15 Updated define_addr_params in ddrps.tcl
+ *		       to support PBD Designs (CR #876857)
+ *
+ * 
+ * +*******************************************************************************/ + +#ifndef XDDRPS_H_ +/* Prevent circular inclusions by using protection macros. */ +#define XDDRPS_H_ + +/******************************* Include Files ********************************/ + + +#endif /* XDDRPS_H_ */ +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xdebug.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xdebug.h new file mode 100644 index 0000000..b09c02d --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xdebug.h @@ -0,0 +1,40 @@ +#ifndef XDEBUG /* prevent circular inclusions */ +#define XDEBUG /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(DEBUG) && !defined(NDEBUG) + +#ifndef XDEBUG_WARNING +#define XDEBUG_WARNING +#warning DEBUG is enabled +#endif + +int printf(const char *format, ...); + +#define XDBG_DEBUG_ERROR 0x00000001U /* error condition messages */ +#define XDBG_DEBUG_GENERAL 0x00000002U /* general debug messages */ +#define XDBG_DEBUG_ALL 0xFFFFFFFFU /* all debugging data */ + +#define xdbg_current_types (XDBG_DEBUG_GENERAL) + +#define xdbg_stmnt(x) x + +#define xdbg_printf(type, ...) (((type) & xdbg_current_types) ? printf (__VA_ARGS__) : 0) + + +#else /* defined(DEBUG) && !defined(NDEBUG) */ + +#define xdbg_stmnt(x) + +#define xdbg_printf(...) + +#endif /* defined(DEBUG) && !defined(NDEBUG) */ + +#ifdef __cplusplus +} +#endif + +#endif /* XDEBUG */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xdevcfg.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xdevcfg.h new file mode 100644 index 0000000..6586370 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xdevcfg.h @@ -0,0 +1,399 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2017 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xdevcfg.h +* @addtogroup devcfg_v3_5 +* @{ +* @details +* +* The is the main header file for the Device Configuration Interface of the Zynq +* device. The device configuration interface has three main functionality. +* 1. AXI-PCAP +* 2. Security Policy +* 3. XADC +* This current version of the driver supports only the AXI-PCAP and Security +* Policy blocks. There is a separate driver for XADC. +* +* AXI-PCAP is used for download/upload an encrypted or decrypted bitstream. +* DMA embedded in the AXI PCAP provides the master interface to +* the Device configuration block for any DMA transfers. The data transfer can +* take place between the Tx/RxFIFOs of AXI-PCAP and memory (on chip +* RAM/DDR/peripheral memory). +* +* The current driver only supports the downloading the FPGA bitstream and +* readback of the decrypted image (sort of loopback). +* The driver does not know what information needs to be written to the FPGA to +* readback FPGA configuration register or memory data. The application above the +* driver should take care of creating the data that needs to be downloaded to +* the FPGA so that the bitstream can be readback. +* This driver also does not support the reading of the internal registers of the +* PCAP. The driver has no knowledge of the PCAP internals. +* +* Initialization and Configuration +* +* The device driver enables higher layer software (e.g., an application) to +* communicate with the Device Configuration device. +* +* XDcfg_CfgInitialize() API is used to initialize the Device Configuration +* Interface. The user needs to first call the XDcfg_LookupConfig() API which +* returns the Configuration structure pointer which is passed as a parameter to +* the XDcfg_CfgInitialize() API. +* +* Interrupts +* The Driver implements an interrupt handler to support the interrupts provided +* by this interface. +* +* Threads +* +* This driver is not thread safe. Any needs for threads or thread mutual +* exclusion must be satisfied by the layer above this driver. +* +* Asserts +* +* Asserts are used within all Xilinx drivers to enforce constraints on argument +* values. Asserts can be turned off on a system-wide basis by defining, at +* compile time, the NDEBUG identifier. By default, asserts are turned on and it +* is recommended that users leave asserts on during development. +* +* Building the driver +* +* The XDcfg driver is composed of several source files. This allows the user +* to build and link only those parts of the driver that are necessary. +* +*

+* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who Date     Changes
+* ----- --- -------- ---------------------------------------------
+* 1.00a hvm 02/07/11 First release
+* 2.00a nm  05/31/12 Updated the driver for CR 660835 so that input length for
+*		     source/destination to the XDcfg_InitiateDma, XDcfg_Transfer
+*		     APIs is words (32 bit) and not bytes.
+* 		     Updated the notes for XDcfg_InitiateDma/XDcfg_Transfer APIs
+*		     to add information that 2 LSBs of the Source/Destination
+*		     address when equal to 2�b01 indicate the last DMA command
+*		     of an overall transfer.
+*		     Destination Address passed to this API for secure transfers
+*		     instead of using 0xFFFFFFFF for CR 662197. This issue was
+*		     resulting in the failure of secure transfers of
+*		     non-bitstream images.
+* 2.01a nm  07/07/12 Updated the XDcfg_IntrClear function to directly
+*		     set the mask instead of oring it with the
+*		     value read from the interrupt status register
+* 		     Added defines for the PS Version bits,
+*	             removed the FIFO Flush bits from the
+*		     Miscellaneous Control Reg.
+*		     Added XDcfg_GetPsVersion, XDcfg_SelectIcapInterface
+*		     and XDcfg_SelectPcapInterface APIs for CR 643295
+*		     The user has to call the XDcfg_SelectIcapInterface API
+*		     for the PL reconfiguration using AXI HwIcap.
+*		     Updated the XDcfg_Transfer API to clear the
+*		     QUARTER_PCAP_RATE_EN bit in the control register for
+*		     non secure writes for CR 675543.
+* 2.02a nm  01/31/13 Fixed CR# 679335.
+* 		     Added Setting and Clearing the internal PCAP loopback.
+*		     Removed code for enabling/disabling AES engine as BootROM
+*		     locks down this setting.
+*		     Fixed CR# 681976.
+*		     Skip Checking the PCFG_INIT in case of non-secure DMA
+*		     loopback.
+*		     Fixed CR# 699558.
+*		     XDcfg_Transfer fails to transfer data in loopback mode.
+*		     Fixed CR# 701348.
+*                    Peripheral test fails with  Running
+* 		     DcfgSelfTestExample() in SECURE bootmode.
+* 2.03a nm  04/19/13 Fixed CR# 703728.
+*		     Updated the register definitions as per the latest TRM
+*		     version UG585 (v1.4) November 16, 2012.
+* 3.0   adk 10/12/13 Updated as per the New Tcl API's
+* 3.0   kpc 21/02/14 Added function prototype for XDcfg_ClearControlRegister
+* 3.2   sb  08/25/14 Fixed XDcfg_PcapReadback() function
+*		     updated driver code with != instead of ==,
+*		     while checking for Interrupt Status with DMA and
+*		     PCAP Done Mask
+*		     ((XDcfg_ReadReg(InstancePtr->Config.BaseAddr,
+*			XDCFG_INT_STS_OFFSET) &
+*			XDCFG_IXR_D_P_DONE_MASK) !=
+*			XDCFG_IXR_D_P_DONE_MASK);
+*		     A new example has been added to read back the
+*		     configuration registers from the PL region.
+*		     xdevcfg_reg_readback_example.c
+* 3.3   sk  04/06/15 Modified XDcfg_ReadMultiBootConfig Macro CR# 851335.
+*       ms  03/17/17 Added readme.txt file in examples folder for doxygen
+*                    generation.
+*       ms  04/10/17 Modified filename tag in interrupt and polled examples
+*                    to include them in doxygen examples.
+* 3.5   ms  04/18/17 Modified tcl file to add suffix U for all macros
+*                    definitions of devcfg in xparameters.h
+*       ms  08/07/17 Fixed compilation warnings in xdevcfg_sinit.c
+* 
+* +******************************************************************************/ +#ifndef XDCFG_H /* prevent circular inclusions */ +#define XDCFG_H /* by using protection macros */ + +/***************************** Include Files *********************************/ + +#include "xdevcfg_hw.h" +#include "xstatus.h" +#include "xil_assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/************************** Constant Definitions *****************************/ + +/* Types of PCAP transfers */ + +#define XDCFG_NON_SECURE_PCAP_WRITE 1 +#define XDCFG_SECURE_PCAP_WRITE 2 +#define XDCFG_PCAP_READBACK 3 +#define XDCFG_CONCURRENT_SECURE_READ_WRITE 4 +#define XDCFG_CONCURRENT_NONSEC_READ_WRITE 5 + + +/**************************** Type Definitions *******************************/ +/** +* The handler data type allows the user to define a callback function to +* respond to interrupt events in the system. This function is executed +* in interrupt context, so amount of processing should be minimized. +* +* @param CallBackRef is the callback reference passed in by the upper +* layer when setting the callback functions, and passed back to +* the upper layer when the callback is invoked. Its type is +* unimportant to the driver component, so it is a void pointer. +* @param Status is the Interrupt status of the XDcfg device. +*/ +typedef void (*XDcfg_IntrHandler) (void *CallBackRef, u32 Status); + +/** + * This typedef contains configuration information for the device. + */ +typedef struct { + u16 DeviceId; /**< Unique ID of device */ + u32 BaseAddr; /**< Base address of the device */ +} XDcfg_Config; + +/** + * The XDcfg driver instance data. + */ +typedef struct { + XDcfg_Config Config; /**< Hardware Configuration */ + u32 IsReady; /**< Device is initialized and ready */ + u32 IsStarted; /**< Device Configuration Interface + * is running + */ + XDcfg_IntrHandler StatusHandler; /* Event handler function */ + void *CallBackRef; /* Callback reference for event handler */ +} XDcfg; + +/****************************************************************************/ +/** +* +* Unlock the Device Config Interface block. +* +* @param InstancePtr is a pointer to the instance of XDcfg driver. +* +* @return None. +* +* @note C-style signature: +* void XDcfg_Unlock(XDcfg* InstancePtr) +* +*****************************************************************************/ +#define XDcfg_Unlock(InstancePtr) \ + XDcfg_WriteReg((InstancePtr)->Config.BaseAddr, \ + XDCFG_UNLOCK_OFFSET, XDCFG_UNLOCK_DATA) + + + +/****************************************************************************/ +/** +* +* Get the version number of the PS from the Miscellaneous Control Register. +* +* @param InstancePtr is a pointer to the instance of XDcfg driver. +* +* @return Version of the PS. +* +* @note C-style signature: +* void XDcfg_GetPsVersion(XDcfg* InstancePtr) +* +*****************************************************************************/ +#define XDcfg_GetPsVersion(InstancePtr) \ + ((XDcfg_ReadReg((InstancePtr)->Config.BaseAddr, \ + XDCFG_MCTRL_OFFSET)) & \ + XDCFG_MCTRL_PCAP_PS_VERSION_MASK) >> \ + XDCFG_MCTRL_PCAP_PS_VERSION_SHIFT + + + +/****************************************************************************/ +/** +* +* Read the multiboot config register value. +* +* @param InstancePtr is a pointer to the instance of XDcfg driver. +* +* @return None. +* +* @note C-style signature: +* u32 XDcfg_ReadMultiBootConfig(XDcfg* InstancePtr) +* +*****************************************************************************/ +#define XDcfg_ReadMultiBootConfig(InstancePtr) \ + XDcfg_ReadReg((InstancePtr)->Config.BaseAddr, \ + XDCFG_MULTIBOOT_ADDR_OFFSET) + + +/****************************************************************************/ +/** +* +* Selects ICAP interface for reconfiguration after the initial configuration +* of the PL. +* +* @param InstancePtr is a pointer to the instance of XDcfg driver. +* +* @return None. +* +* @note C-style signature: +* void XDcfg_SelectIcapInterface(XDcfg* InstancePtr) +* +*****************************************************************************/ +#define XDcfg_SelectIcapInterface(InstancePtr) \ + XDcfg_WriteReg((InstancePtr)->Config.BaseAddr, XDCFG_CTRL_OFFSET, \ + ((XDcfg_ReadReg((InstancePtr)->Config.BaseAddr, XDCFG_CTRL_OFFSET)) \ + & ( ~XDCFG_CTRL_PCAP_PR_MASK))) + +/****************************************************************************/ +/** +* +* Selects PCAP interface for reconfiguration after the initial configuration +* of the PL. +* +* @param InstancePtr is a pointer to the instance of XDcfg driver. +* +* @return None. +* +* @note C-style signature: +* void XDcfg_SelectPcapInterface(XDcfg* InstancePtr) +* +*****************************************************************************/ +#define XDcfg_SelectPcapInterface(InstancePtr) \ + XDcfg_WriteReg((InstancePtr)->Config.BaseAddr, XDCFG_CTRL_OFFSET, \ + ((XDcfg_ReadReg((InstancePtr)->Config.BaseAddr, XDCFG_CTRL_OFFSET)) \ + | XDCFG_CTRL_PCAP_PR_MASK)) + + + +/************************** Function Prototypes ******************************/ + +/* + * Lookup configuration in xdevcfg_sinit.c. + */ +XDcfg_Config *XDcfg_LookupConfig(u16 DeviceId); + +/* + * Selftest function in xdevcfg_selftest.c + */ +int XDcfg_SelfTest(XDcfg *InstancePtr); + +/* + * Interface functions in xdevcfg.c + */ +int XDcfg_CfgInitialize(XDcfg *InstancePtr, + XDcfg_Config *ConfigPtr, u32 EffectiveAddress); + +void XDcfg_EnablePCAP(XDcfg *InstancePtr); + +void XDcfg_DisablePCAP(XDcfg *InstancePtr); + +void XDcfg_SetControlRegister(XDcfg *InstancePtr, u32 Mask); + +void XDcfg_ClearControlRegister(XDcfg *InstancePtr, u32 Mask); + +u32 XDcfg_GetControlRegister(XDcfg *InstancePtr); + +void XDcfg_SetLockRegister(XDcfg *InstancePtr, u32 Data); + +u32 XDcfg_GetLockRegister(XDcfg *InstancePtr); + +void XDcfg_SetConfigRegister(XDcfg *InstancePtr, u32 Data); + +u32 XDcfg_GetConfigRegister(XDcfg *InstancePtr); + +void XDcfg_SetStatusRegister(XDcfg *InstancePtr, u32 Data); + +u32 XDcfg_GetStatusRegister(XDcfg *InstancePtr); + +void XDcfg_SetRomShadowRegister(XDcfg *InstancePtr, u32 Data); + +u32 XDcfg_GetSoftwareIdRegister(XDcfg *InstancePtr); + +void XDcfg_SetMiscControlRegister(XDcfg *InstancePtr, u32 Mask); + +u32 XDcfg_GetMiscControlRegister(XDcfg *InstancePtr); + +u32 XDcfg_IsDmaBusy(XDcfg *InstancePtr); + +void XDcfg_InitiateDma(XDcfg *InstancePtr, u32 SourcePtr, u32 DestPtr, + u32 SrcWordLength, u32 DestWordLength); + +u32 XDcfg_Transfer(XDcfg *InstancePtr, + void *SourcePtr, u32 SrcWordLength, + void *DestPtr, u32 DestWordLength, + u32 TransferType); + +/* + * Interrupt related function prototypes implemented in xdevcfg_intr.c + */ +void XDcfg_IntrEnable(XDcfg *InstancePtr, u32 Mask); + +void XDcfg_IntrDisable(XDcfg *InstancePtr, u32 Mask); + +u32 XDcfg_IntrGetEnabled(XDcfg *InstancePtr); + +u32 XDcfg_IntrGetStatus(XDcfg *InstancePtr); + +void XDcfg_IntrClear(XDcfg *InstancePtr, u32 Mask); + +void XDcfg_InterruptHandler(XDcfg *InstancePtr); + +void XDcfg_SetHandler(XDcfg *InstancePtr, void *CallBackFunc, + void *CallBackRef); + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xdevcfg_hw.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xdevcfg_hw.h new file mode 100644 index 0000000..80b6678 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xdevcfg_hw.h @@ -0,0 +1,391 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xdevcfg_hw.h +* @addtogroup devcfg_v3_3 +* @{ +* +* This file contains the hardware interface to the Device Config Interface. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who Date     Changes
+* ----- --- -------- ---------------------------------------------
+* 1.00a hvm 02/07/11 First release
+* 2.01a nm  08/01/12 Added defines for the PS Version bits,
+*	             removed the FIFO Flush bits from the
+*		     Miscellaneous Control Reg
+* 2.03a nm  04/19/13 Fixed CR# 703728.
+*		     Updated the register definitions as per the latest TRM
+*		     version UG585 (v1.4) November 16, 2012.
+* 2.04a	kpc	10/07/13 Added function prototype.
+* 3.00a	kpc	25/02/14 Corrected the XDCFG_BASE_ADDRESS macro value.
+* 
+* +******************************************************************************/ +#ifndef XDCFG_HW_H /* prevent circular inclusions */ +#define XDCFG_HW_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +#include "xil_types.h" +#include "xil_io.h" + +/************************** Constant Definitions *****************************/ + +/** @name Register Map + * Offsets of registers from the start of the device + * @{ + */ + +#define XDCFG_CTRL_OFFSET 0x00 /**< Control Register */ +#define XDCFG_LOCK_OFFSET 0x04 /**< Lock Register */ +#define XDCFG_CFG_OFFSET 0x08 /**< Configuration Register */ +#define XDCFG_INT_STS_OFFSET 0x0C /**< Interrupt Status Register */ +#define XDCFG_INT_MASK_OFFSET 0x10 /**< Interrupt Mask Register */ +#define XDCFG_STATUS_OFFSET 0x14 /**< Status Register */ +#define XDCFG_DMA_SRC_ADDR_OFFSET 0x18 /**< DMA Source Address Register */ +#define XDCFG_DMA_DEST_ADDR_OFFSET 0x1C /**< DMA Destination Address Reg */ +#define XDCFG_DMA_SRC_LEN_OFFSET 0x20 /**< DMA Source Transfer Length */ +#define XDCFG_DMA_DEST_LEN_OFFSET 0x24 /**< DMA Destination Transfer */ +#define XDCFG_ROM_SHADOW_OFFSET 0x28 /**< DMA ROM Shadow Register */ +#define XDCFG_MULTIBOOT_ADDR_OFFSET 0x2C /**< Multi BootAddress Pointer */ +#define XDCFG_SW_ID_OFFSET 0x30 /**< Software ID Register */ +#define XDCFG_UNLOCK_OFFSET 0x34 /**< Unlock Register */ +#define XDCFG_MCTRL_OFFSET 0x80 /**< Miscellaneous Control Reg */ + +/* @} */ + +/** @name Control Register Bit definitions + * @{ + */ + +#define XDCFG_CTRL_FORCE_RST_MASK 0x80000000 /**< Force into + * Secure Reset + */ +#define XDCFG_CTRL_PCFG_PROG_B_MASK 0x40000000 /**< Program signal to + * Reset FPGA + */ +#define XDCFG_CTRL_PCFG_POR_CNT_4K_MASK 0x20000000 /**< Control PL POR timer */ +#define XDCFG_CTRL_PCAP_PR_MASK 0x08000000 /**< Enable PCAP for PR */ +#define XDCFG_CTRL_PCAP_MODE_MASK 0x04000000 /**< Enable PCAP */ +#define XDCFG_CTRL_PCAP_RATE_EN_MASK 0x02000000 /**< Enable PCAP send data + * to FPGA every 4 PCAP + * cycles + */ +#define XDCFG_CTRL_MULTIBOOT_EN_MASK 0x01000000 /**< Multiboot Enable */ +#define XDCFG_CTRL_JTAG_CHAIN_DIS_MASK 0x00800000 /**< JTAG Chain Disable */ +#define XDCFG_CTRL_USER_MODE_MASK 0x00008000 /**< User Mode Mask */ +#define XDCFG_CTRL_PCFG_AES_FUSE_MASK 0x00001000 /**< AES key source */ +#define XDCFG_CTRL_PCFG_AES_EN_MASK 0x00000E00 /**< AES Enable Mask */ +#define XDCFG_CTRL_SEU_EN_MASK 0x00000100 /**< SEU Enable Mask */ +#define XDCFG_CTRL_SEC_EN_MASK 0x00000080 /**< Secure/Non Secure + * Status mask + */ +#define XDCFG_CTRL_SPNIDEN_MASK 0x00000040 /**< Secure Non Invasive + * Debug Enable + */ +#define XDCFG_CTRL_SPIDEN_MASK 0x00000020 /**< Secure Invasive + * Debug Enable + */ +#define XDCFG_CTRL_NIDEN_MASK 0x00000010 /**< Non-Invasive Debug + * Enable + */ +#define XDCFG_CTRL_DBGEN_MASK 0x00000008 /**< Invasive Debug + * Enable + */ +#define XDCFG_CTRL_DAP_EN_MASK 0x00000007 /**< DAP Enable Mask */ + +/* @} */ + +/** @name Lock register bit definitions + * @{ + */ + +#define XDCFG_LOCK_AES_EFUSE_MASK 0x00000010 /**< Lock AES Efuse bit */ +#define XDCFG_LOCK_AES_EN_MASK 0x00000008 /**< Lock AES_EN update */ +#define XDCFG_LOCK_SEU_MASK 0x00000004 /**< Lock SEU_En update */ +#define XDCFG_LOCK_SEC_MASK 0x00000002 /**< Lock SEC_EN and + * USER_MODE + */ +#define XDCFG_LOCK_DBG_MASK 0x00000001 /**< This bit locks + * security config + * including: DAP_En, + * DBGEN,, + * NIDEN, SPNIEN + */ +/*@}*/ + + + +/** @name Config Register Bit definitions + * @{ + */ +#define XDCFG_CFG_RFIFO_TH_MASK 0x00000C00 /**< Read FIFO + * Threshold Mask + */ +#define XDCFG_CFG_WFIFO_TH_MASK 0x00000300 /**< Write FIFO Threshold + * Mask + */ +#define XDCFG_CFG_RCLK_EDGE_MASK 0x00000080 /**< Read data active + * clock edge + */ +#define XDCFG_CFG_WCLK_EDGE_MASK 0x00000040 /**< Write data active + * clock edge + */ +#define XDCFG_CFG_DISABLE_SRC_INC_MASK 0x00000020 /**< Disable Source address + * increment mask + */ +#define XDCFG_CFG_DISABLE_DST_INC_MASK 0x00000010 /**< Disable Destination + * address increment + * mask + */ +/* @} */ + + +/** @name Interrupt Status/Mask Register Bit definitions + * @{ + */ +#define XDCFG_IXR_PSS_GTS_USR_B_MASK 0x80000000 /**< Tri-state IO during + * HIZ + */ +#define XDCFG_IXR_PSS_FST_CFG_B_MASK 0x40000000 /**< First configuration + * done + */ +#define XDCFG_IXR_PSS_GPWRDWN_B_MASK 0x20000000 /**< Global power down */ +#define XDCFG_IXR_PSS_GTS_CFG_B_MASK 0x10000000 /**< Tri-state IO during + * configuration + */ +#define XDCFG_IXR_PSS_CFG_RESET_B_MASK 0x08000000 /**< PL configuration + * reset + */ +#define XDCFG_IXR_AXI_WTO_MASK 0x00800000 /**< AXI Write Address + * or Data or response + * timeout + */ +#define XDCFG_IXR_AXI_WERR_MASK 0x00400000 /**< AXI Write response + * error + */ +#define XDCFG_IXR_AXI_RTO_MASK 0x00200000 /**< AXI Read Address or + * response timeout + */ +#define XDCFG_IXR_AXI_RERR_MASK 0x00100000 /**< AXI Read response + * error + */ +#define XDCFG_IXR_RX_FIFO_OV_MASK 0x00040000 /**< Rx FIFO Overflow */ +#define XDCFG_IXR_WR_FIFO_LVL_MASK 0x00020000 /**< Tx FIFO less than + * threshold */ +#define XDCFG_IXR_RD_FIFO_LVL_MASK 0x00010000 /**< Rx FIFO greater than + * threshold */ +#define XDCFG_IXR_DMA_CMD_ERR_MASK 0x00008000 /**< Illegal DMA command */ +#define XDCFG_IXR_DMA_Q_OV_MASK 0x00004000 /**< DMA command queue + * overflow + */ +#define XDCFG_IXR_DMA_DONE_MASK 0x00002000 /**< DMA Command Done */ +#define XDCFG_IXR_D_P_DONE_MASK 0x00001000 /**< DMA and PCAP + * transfers Done + */ +#define XDCFG_IXR_P2D_LEN_ERR_MASK 0x00000800 /**< PCAP to DMA transfer + * length error + */ +#define XDCFG_IXR_PCFG_HMAC_ERR_MASK 0x00000040 /**< HMAC error mask */ +#define XDCFG_IXR_PCFG_SEU_ERR_MASK 0x00000020 /**< SEU Error mask */ +#define XDCFG_IXR_PCFG_POR_B_MASK 0x00000010 /**< FPGA POR mask */ +#define XDCFG_IXR_PCFG_CFG_RST_MASK 0x00000008 /**< FPGA Reset mask */ +#define XDCFG_IXR_PCFG_DONE_MASK 0x00000004 /**< Done Signal Mask */ +#define XDCFG_IXR_PCFG_INIT_PE_MASK 0x00000002 /**< Detect Positive edge + * of Init Signal + */ +#define XDCFG_IXR_PCFG_INIT_NE_MASK 0x00000001 /**< Detect Negative edge + * of Init Signal + */ +#define XDCFG_IXR_ERROR_FLAGS_MASK (XDCFG_IXR_AXI_WTO_MASK | \ + XDCFG_IXR_AXI_WERR_MASK | \ + XDCFG_IXR_AXI_RTO_MASK | \ + XDCFG_IXR_AXI_RERR_MASK | \ + XDCFG_IXR_RX_FIFO_OV_MASK | \ + XDCFG_IXR_DMA_CMD_ERR_MASK |\ + XDCFG_IXR_DMA_Q_OV_MASK | \ + XDCFG_IXR_P2D_LEN_ERR_MASK |\ + XDCFG_IXR_PCFG_HMAC_ERR_MASK) + + +#define XDCFG_IXR_ALL_MASK 0x00F7F8EF + + + +/* @} */ + + +/** @name Status Register Bit definitions + * @{ + */ +#define XDCFG_STATUS_DMA_CMD_Q_F_MASK 0x80000000 /**< DMA command + * Queue full + */ +#define XDCFG_STATUS_DMA_CMD_Q_E_MASK 0x40000000 /**< DMA command + * Queue empty + */ +#define XDCFG_STATUS_DMA_DONE_CNT_MASK 0x30000000 /**< Number of + * completed DMA + * transfers + */ +#define XDCFG_STATUS_RX_FIFO_LVL_MASK 0x01F000000 /**< Rx FIFO level */ +#define XDCFG_STATUS_TX_FIFO_LVL_MASK 0x0007F000 /**< Tx FIFO level */ + +#define XDCFG_STATUS_PSS_GTS_USR_B 0x00000800 /**< Tri-state IO + * during HIZ + */ +#define XDCFG_STATUS_PSS_FST_CFG_B 0x00000400 /**< First PL config + * done + */ +#define XDCFG_STATUS_PSS_GPWRDWN_B 0x00000200 /**< Global power down */ +#define XDCFG_STATUS_PSS_GTS_CFG_B 0x00000100 /**< Tri-state IO during + * config + */ +#define XDCFG_STATUS_SECURE_RST_MASK 0x00000080 /**< Secure Reset + * POR Status + */ +#define XDCFG_STATUS_ILLEGAL_APB_ACCESS_MASK 0x00000040 /**< Illegal APB + * access + */ +#define XDCFG_STATUS_PSS_CFG_RESET_B 0x00000020 /**< PL config + * reset status + */ +#define XDCFG_STATUS_PCFG_INIT_MASK 0x00000010 /**< FPGA Init + * Status + */ +#define XDCFG_STATUS_EFUSE_BBRAM_KEY_DISABLE_MASK 0x00000008 + /**< BBRAM key + * disable + */ +#define XDCFG_STATUS_EFUSE_SEC_EN_MASK 0x00000004 /**< Efuse Security + * Enable Status + */ +#define XDCFG_STATUS_EFUSE_JTAG_DIS_MASK 0x00000002 /**< EFuse JTAG + * Disable + * status + */ +/* @} */ + + +/** @name DMA Source/Destination Transfer Length Register Bit definitions + * @{ + */ +#define XDCFG_DMA_LEN_MASK 0x7FFFFFF /**< Length Mask */ +/*@}*/ + + + + +/** @name Miscellaneous Control Register Bit definitions + * @{ + */ +#define XDCFG_MCTRL_PCAP_PS_VERSION_MASK 0xF0000000 /**< PS Version Mask */ +#define XDCFG_MCTRL_PCAP_PS_VERSION_SHIFT 28 /**< PS Version Shift */ +#define XDCFG_MCTRL_PCAP_LPBK_MASK 0x00000010 /**< PCAP loopback mask */ +/* @} */ + +/** @name FIFO Threshold Bit definitions + * @{ + */ + +#define XDCFG_CFG_FIFO_QUARTER 0x0 /**< Quarter empty */ +#define XDCFG_CFG_FIFO_HALF 0x1 /**< Half empty */ +#define XDCFG_CFG_FIFO_3QUARTER 0x2 /**< 3/4 empty */ +#define XDCFG_CFG_FIFO_EMPTY 0x4 /**< Empty */ +/* @}*/ + + +/* Miscellaneous constant values */ +#define XDCFG_DMA_INVALID_ADDRESS 0xFFFFFFFF /**< Invalid DMA address */ +#define XDCFG_UNLOCK_DATA 0x757BDF0D /**< First APB access data*/ +#define XDCFG_BASE_ADDRESS 0xF8007000 /**< Device Config base + * address + */ +#define XDCFG_CONFIG_RESET_VALUE 0x508 /**< Config reg reset value */ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/****************************************************************************/ +/** +* +* Read the given register. +* +* @param BaseAddr is the base address of the device +* @param RegOffset is the register offset to be read +* +* @return The 32-bit value of the register +* +* @note C-style signature: +* u32 XDcfg_ReadReg(u32 BaseAddr, u32 RegOffset) +* +*****************************************************************************/ +#define XDcfg_ReadReg(BaseAddr, RegOffset) \ + Xil_In32((BaseAddr) + (RegOffset)) + +/****************************************************************************/ +/** +* +* Write to the given register. +* +* @param BaseAddr is the base address of the device +* @param RegOffset is the register offset to be written +* @param Data is the 32-bit value to write to the register +* +* @return None. +* +* @note C-style signature: +* void XDcfg_WriteReg(u32 BaseAddr, u32 RegOffset, u32 Data) +* +*****************************************************************************/ +#define XDcfg_WriteReg(BaseAddr, RegOffset, Data) \ + Xil_Out32((BaseAddr) + (RegOffset), (Data)) + +/************************** Function Prototypes ******************************/ +/* + * Perform reset operation to the devcfg interface + */ +void XDcfg_ResetHw(u32 BaseAddr); +/************************** Variable Definitions *****************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xdmaps.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xdmaps.h new file mode 100644 index 0000000..73e2b1e --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xdmaps.h @@ -0,0 +1,349 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xdmaps.h +* @addtogroup dmaps_v2_4 +* @{ +* @details +* +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  	Date     Changes
+* ----- ------ -------- ----------------------------------------------
+* 1.00	hbm    08/19/10 First Release
+* 1.01a nm     12/20/12 Added definition XDMAPS_CHANNELS_PER_DEV which specifies
+*		        the maximum number of channels.
+*		        Replaced the usage of XPAR_XDMAPS_CHANNELS_PER_DEV
+*                       with XDMAPS_CHANNELS_PER_DEV defined in xdmaps_hw.h.
+*			Added the tcl file to automatically generate the
+*			xparameters.h
+* 1.02a sg     05/16/12 Made changes for doxygen and moved some function
+*			header from the xdmaps.h file to xdmaps.c file
+*			Other cleanup for coding guidelines and CR 657109
+*			and CR 657898
+*			The xdmaps_example_no_intr.c example is removed
+*			as it is using interrupts  and is similar to
+*			the interrupt example - CR 652477
+* 1.03a sg     07/16/2012 changed inline to __inline for CR665681
+* 1.04a nm     10/22/2012 Fixed CR# 681671.
+* 1.05a nm     04/15/2013 Fixed CR# 704396. Removed warnings when compiled
+*			  with -Wall and -Wextra option in bsp.
+*	       05/01/2013 Fixed CR# 700189. Changed XDmaPs_BuildDmaProg()
+*			  function description.
+*			  Fixed CR# 704396. Removed unused variables
+*			  UseM2MByte & MemBurstLen from XDmaPs_BuildDmaProg()
+*			  function.
+* 1.07a asa    11/02/13. Made changes to fix compilation issues for iarcc.
+*			   Removed the PDBG prints. By default they were always
+*			   defined out and never used. The PDBG is non-standard for
+*			   Xilinx drivers and no other driver does something similar.
+*			   Since there is no easy way to fix compilation issues with
+*			   the IARCC compiler around PDBG, it is better to remove it.
+*			   Users can always use xil_printfs if they want to debug.
+* 2.0   adk    10/12/13  Updated as per the New Tcl API's
+* 2.01  kpc    08/23/14  Fixed the IAR compiler reported errors
+* 2.2   mus    08/12/16  Declared all inline functions in xdmaps.c as extern, to avoid
+*                        linker error for IAR compiler
+* 2.3   ms     01/23/17 Modified xil_printf statement in main function for all
+*                       examples to ensure that "Successfully ran" and "Failed"
+*                       strings are available in all examples. This is a fix
+*                       for CR-965028.
+*       ms     03/17/17 Added readme.txt file in examples folder for doxygen
+*                       generation.
+* 2.4   adk    13/08/18 Fixed armcc compiler warnings in the driver CR-1008310.
+* 
+* +*****************************************************************************/ + +#ifndef XDMAPS_H /* prevent circular inclusions */ +#define XDMAPS_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files ********************************/ + +#include "xparameters.h" +#include "xil_types.h" +#include "xil_assert.h" +#include "xstatus.h" + +#include "xdmaps_hw.h" + +/************************** Constant Definitions ****************************/ + +/**************************** Type Definitions ******************************/ + +/** + * This typedef contains configuration information for the device. + */ +typedef struct { + u16 DeviceId; /**< Unique ID of device */ + u32 BaseAddress; /**< Base address of device (IPIF) */ +} XDmaPs_Config; + + +/** DMA channle control structure. It's for AXI bus transaction. + * This struct will be translated into a 32-bit channel control register value. + */ +typedef struct { + unsigned int EndianSwapSize; /**< Endian swap size. */ + unsigned int DstCacheCtrl; /**< Destination cache control */ + unsigned int DstProtCtrl; /**< Destination protection control */ + unsigned int DstBurstLen; /**< Destination burst length */ + unsigned int DstBurstSize; /**< Destination burst size */ + unsigned int DstInc; /**< Destination incrementing or fixed + * address */ + unsigned int SrcCacheCtrl; /**< Source cache control */ + unsigned int SrcProtCtrl; /**< Source protection control */ + unsigned int SrcBurstLen; /**< Source burst length */ + unsigned int SrcBurstSize; /**< Source burst size */ + unsigned int SrcInc; /**< Source incrementing or fixed + * address */ +} XDmaPs_ChanCtrl; + +/** DMA block descriptor stucture. + */ +typedef struct { + u32 SrcAddr; /**< Source starting address */ + u32 DstAddr; /**< Destination starting address */ + unsigned int Length; /**< Number of bytes for the block */ +} XDmaPs_BD; + +/** + * A DMA command consisits of a channel control struct, a block descriptor, + * a user defined program, a pointer pointing to generated DMA program, and + * execution result. + * + */ +typedef struct { + XDmaPs_ChanCtrl ChanCtrl; /**< Channel Control Struct */ + XDmaPs_BD BD; /**< Together with SgLength field, + * it's a scatter-gather list. + */ + void *UserDmaProg; /**< If user wants the driver to + * execute their own DMA program, + * this field points to the DMA + * program. + */ + int UserDmaProgLength; /**< The length of user defined + * DMA program. + */ + + void *GeneratedDmaProg; /**< The DMA program genreated + * by the driver. This field will be + * set if a user invokes the DMA + * program generation function. Or + * the DMA command is finished and + * a user informs the driver not to + * release the program buffer. + * This field has two purposes, one + * is to ask the driver to generate + * a DMA program while the DMAC is + * performaning DMA transactions. The + * other purpose is to debug the + * driver. + */ + int GeneratedDmaProgLength; /**< The length of the DMA program + * generated by the driver + */ + int DmaStatus; /**< 0 on success, otherwise error code + */ + u32 ChanFaultType; /**< Channel fault type in case of fault + */ + u32 ChanFaultPCAddr; /**< Channel fault PC address + */ +} XDmaPs_Cmd; + +/** + * It's the done handler a user can set for a channel + */ +typedef void (*XDmaPsDoneHandler) (unsigned int Channel, + XDmaPs_Cmd *DmaCmd, + void *CallbackRef); + +/** + * It's the fault handler a user can set for a channel + */ +typedef void (*XDmaPsFaultHandler) (unsigned int Channel, + XDmaPs_Cmd *DmaCmd, + void *CallbackRef); + +#define XDMAPS_MAX_CHAN_BUFS 2 +#define XDMAPS_CHAN_BUF_LEN 128 + +/** + * The XDmaPs_ProgBuf is the struct for a DMA program buffer. + */ +typedef struct { + char Buf[XDMAPS_CHAN_BUF_LEN]; /**< The actual buffer the holds the + * content */ + unsigned Len; /**< The actual length of the DMA + * program in bytes. */ + int Allocated; /**< A tag indicating whether the + * buffer is allocated or not */ +} XDmaPs_ProgBuf; + +/** + * The XDmaPs_ChannelData is a struct to book keep individual channel of + * the DMAC. + */ +typedef struct { + unsigned DevId; /**< Device id indicating which DMAC */ + unsigned ChanId; /**< Channel number of the DMAC */ + XDmaPs_ProgBuf ProgBufPool[XDMAPS_MAX_CHAN_BUFS]; /**< A pool of + program buffers*/ + XDmaPsDoneHandler DoneHandler; /**< Done interrupt handler */ + void *DoneRef; /**< Done interrupt callback data */ + XDmaPs_Cmd *DmaCmdToHw; /**< DMA command being executed */ + XDmaPs_Cmd *DmaCmdFromHw; /**< DMA command that is finished. + * This field is for debugging purpose + */ + int HoldDmaProg; /**< A tag indicating whether to hold the + * DMA program after the DMA is done. + */ + +} XDmaPs_ChannelData; + +/** + * The XDmaPs driver instance data structure. A pointer to an instance data + * structure is passed around by functions to refer to a specific driver + * instance. + */ +typedef struct { + XDmaPs_Config Config; /**< Configuration data structure */ + int IsReady; /**< Device is Ready */ + int CacheLength; /**< icache length */ + XDmaPsFaultHandler FaultHandler; /**< fault interrupt handler */ + void *FaultRef; /**< fault call back data */ + XDmaPs_ChannelData Chans[XDMAPS_CHANNELS_PER_DEV]; + /**< + * channel data + */ +} XDmaPs; + +/* + * Functions implemented in xdmaps.c + */ +int XDmaPs_CfgInitialize(XDmaPs *InstPtr, + XDmaPs_Config *Config, + u32 EffectiveAddr); + +int XDmaPs_Start(XDmaPs *InstPtr, unsigned int Channel, + XDmaPs_Cmd *Cmd, + int HoldDmaProg); + +int XDmaPs_IsActive(XDmaPs *InstPtr, unsigned int Channel); +int XDmaPs_GenDmaProg(XDmaPs *InstPtr, unsigned int Channel, + XDmaPs_Cmd *Cmd); +int XDmaPs_FreeDmaProg(XDmaPs *InstPtr, unsigned int Channel, + XDmaPs_Cmd *Cmd); +void XDmaPs_Print_DmaProg(XDmaPs_Cmd *Cmd); + + +int XDmaPs_ResetManager(XDmaPs *InstPtr); +int XDmaPs_ResetChannel(XDmaPs *InstPtr, unsigned int Channel); + + +int XDmaPs_SetDoneHandler(XDmaPs *InstPtr, + unsigned Channel, + XDmaPsDoneHandler DoneHandler, + void *CallbackRef); + +int XDmaPs_SetFaultHandler(XDmaPs *InstPtr, + XDmaPsFaultHandler FaultHandler, + void *CallbackRef); + +void XDmaPs_Print_DmaProg(XDmaPs_Cmd *Cmd); +int XDmaPs_Instr_DMARMB(char *DmaProg); +int XDmaPs_Instr_DMAWMB(char *DmaProg); + +/** + * To avoid linking error,Declare all inline functions as extern for + * IAR compiler + */ +#ifdef __ICCARM__ +extern INLINE int XDmaPs_Instr_DMAEND(char *DmaProg); +extern INLINE void XDmaPs_Memcpy4(char *Dst, char *Src); +extern INLINE int XDmaPs_Instr_DMAGO(char *DmaProg, unsigned int Cn, + u32 Imm, unsigned int Ns); +extern INLINE int XDmaPs_Instr_DMALD(char *DmaProg); +extern INLINE int XDmaPs_Instr_DMALP(char *DmaProg, unsigned Lc, + unsigned LoopIterations); +extern INLINE int XDmaPs_Instr_DMALPEND(char *DmaProg, char *BodyStart, unsigned Lc); +extern INLINE int XDmaPs_Instr_DMAMOV(char *DmaProg, unsigned Rd, u32 Imm); +extern INLINE int XDmaPs_Instr_DMANOP(char *DmaProg); +extern INLINE int XDmaPs_Instr_DMASEV(char *DmaProg, unsigned int EventNumber); +extern INLINE int XDmaPs_Instr_DMAST(char *DmaProg); +extern INLINE unsigned XDmaPs_ToEndianSwapSizeBits(unsigned int EndianSwapSize); +extern INLINE unsigned XDmaPs_ToBurstSizeBits(unsigned BurstSize); +#endif + +/** + * Driver done interrupt service routines for the channels. + * We need this done ISR mainly because the driver needs to release the + * DMA program buffer. This is the one that connects the GIC + */ +void XDmaPs_DoneISR_0(XDmaPs *InstPtr); +void XDmaPs_DoneISR_1(XDmaPs *InstPtr); +void XDmaPs_DoneISR_2(XDmaPs *InstPtr); +void XDmaPs_DoneISR_3(XDmaPs *InstPtr); +void XDmaPs_DoneISR_4(XDmaPs *InstPtr); +void XDmaPs_DoneISR_5(XDmaPs *InstPtr); +void XDmaPs_DoneISR_6(XDmaPs *InstPtr); +void XDmaPs_DoneISR_7(XDmaPs *InstPtr); + +/** + * Driver fault interrupt service routine + */ +void XDmaPs_FaultISR(XDmaPs *InstPtr); + + +/* + * Static loopup function implemented in xdmaps_sinit.c + */ +XDmaPs_Config *XDmaPs_LookupConfig(u16 DeviceId); + + +/* + * self-test functions in xdmaps_selftest.c + */ +int XDmaPs_SelfTest(XDmaPs *InstPtr); + + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xdmaps_hw.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xdmaps_hw.h new file mode 100644 index 0000000..42dfe69 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xdmaps_hw.h @@ -0,0 +1,289 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xdmaps_hw.h +* @addtogroup dmaps_v2_4 +* @{ +* +* This header file contains the hardware interface of an XDmaPs device. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who   Date     Changes
+* ----- ----  -------- ----------------------------------------------
+* 1.00a	hbm   08/18/10 First Release
+* 1.01a nm    12/20/12 Added definition XDMAPS_CHANNELS_PER_DEV which specifies
+*		       the maximum number of channels.
+*		       Replaced the usage of XPAR_XDMAPS_CHANNELS_PER_DEV
+*                      with XDMAPS_CHANNELS_PER_DEV defined in xdmaps_hw.h
+* 1.02a sg    05/16/12 Made changes for doxygen
+* 1.06a kpc   07/10/13 Added function prototype
+* 
+* +******************************************************************************/ + +#ifndef XDMAPS_HW_H /* prevent circular inclusions */ +#define XDMAPS_HW_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +#include "xil_types.h" +#include "xil_assert.h" +#include "xil_io.h" + +/************************** Constant Definitions *****************************/ + +/** @name Register Map + * + * Register offsets for the DMAC. + * @{ + */ + +#define XDMAPS_DS_OFFSET 0x000 /* DMA Status Register */ +#define XDMAPS_DPC_OFFSET 0x004 /* DMA Program Counter Rregister */ +#define XDMAPS_INTEN_OFFSET 0X020 /* DMA Interrupt Enable Register */ +#define XDMAPS_ES_OFFSET 0x024 /* DMA Event Status Register */ +#define XDMAPS_INTSTATUS_OFFSET 0x028 /* DMA Interrupt Status Register + */ +#define XDMAPS_INTCLR_OFFSET 0x02c /* DMA Interrupt Clear Register */ +#define XDMAPS_FSM_OFFSET 0x030 /* DMA Fault Status DMA Manager + * Register + */ +#define XDMAPS_FSC_OFFSET 0x034 /* DMA Fault Status DMA Chanel Register + */ +#define XDMAPS_FTM_OFFSET 0x038 /* DMA Fault Type DMA Manager Register */ + +#define XDMAPS_FTC0_OFFSET 0x040 /* DMA Fault Type for DMA Channel 0 */ +/* + * The offset for the rest of the FTC registers is calculated as + * FTC0 + dev_chan_num * 4 + */ +#define XDmaPs_FTCn_OFFSET(ch) (XDMAPS_FTC0_OFFSET + (ch) * 4) + +#define XDMAPS_CS0_OFFSET 0x100 /* Channel Status for DMA Channel 0 */ +/* + * The offset for the rest of the CS registers is calculated as + * CS0 + * dev_chan_num * 0x08 + */ +#define XDmaPs_CSn_OFFSET(ch) (XDMAPS_CS0_OFFSET + (ch) * 8) + +#define XDMAPS_CPC0_OFFSET 0x104 /* Channel Program Counter for DMA + * Channel 0 + */ +/* + * The offset for the rest of the CPC registers is calculated as + * CPC0 + dev_chan_num * 0x08 + */ +#define XDmaPs_CPCn_OFFSET(ch) (XDMAPS_CPC0_OFFSET + (ch) * 8) + +#define XDMAPS_SA_0_OFFSET 0x400 /* Source Address Register for DMA + * Channel 0 + */ +/* The offset for the rest of the SA registers is calculated as + * SA_0 + dev_chan_num * 0x20 + */ +#define XDmaPs_SA_n_OFFSET(ch) (XDMAPS_SA_0_OFFSET + (ch) * 0x20) + +#define XDMAPS_DA_0_OFFSET 0x404 /* Destination Address Register for + * DMA Channel 0 + */ +/* The offset for the rest of the DA registers is calculated as + * DA_0 + dev_chan_num * 0x20 + */ +#define XDmaPs_DA_n_OFFSET(ch) (XDMAPS_DA_0_OFFSET + (ch) * 0x20) + +#define XDMAPS_CC_0_OFFSET 0x408 /* Channel Control Register for + * DMA Channel 0 + */ +/* + * The offset for the rest of the CC registers is calculated as + * CC_0 + dev_chan_num * 0x20 + */ +#define XDmaPs_CC_n_OFFSET(ch) (XDMAPS_CC_0_OFFSET + (ch) * 0x20) + +#define XDMAPS_LC0_0_OFFSET 0x40C /* Loop Counter 0 for DMA Channel 0 */ +/* + * The offset for the rest of the LC0 registers is calculated as + * LC_0 + dev_chan_num * 0x20 + */ +#define XDmaPs_LC0_n_OFFSET(ch) (XDMAPS_LC0_0_OFFSET + (ch) * 0x20) +#define XDMAPS_LC1_0_OFFSET 0x410 /* Loop Counter 1 for DMA Channel 0 */ +/* + * The offset for the rest of the LC1 registers is calculated as + * LC_0 + dev_chan_num * 0x20 + */ +#define XDmaPs_LC1_n_OFFSET(ch) (XDMAPS_LC1_0_OFFSET + (ch) * 0x20) + +#define XDMAPS_DBGSTATUS_OFFSET 0xD00 /* Debug Status Register */ +#define XDMAPS_DBGCMD_OFFSET 0xD04 /* Debug Command Register */ +#define XDMAPS_DBGINST0_OFFSET 0xD08 /* Debug Instruction 0 Register */ +#define XDMAPS_DBGINST1_OFFSET 0xD0C /* Debug Instruction 1 Register */ + +#define XDMAPS_CR0_OFFSET 0xE00 /* Configuration Register 0 */ +#define XDMAPS_CR1_OFFSET 0xE04 /* Configuration Register 1 */ +#define XDMAPS_CR2_OFFSET 0xE08 /* Configuration Register 2 */ +#define XDMAPS_CR3_OFFSET 0xE0C /* Configuration Register 3 */ +#define XDMAPS_CR4_OFFSET 0xE10 /* Configuration Register 4 */ +#define XDMAPS_CRDN_OFFSET 0xE14 /* Configuration Register Dn */ + +#define XDMAPS_PERIPH_ID_0_OFFSET 0xFE0 /* Peripheral Identification + * Register 0 + */ +#define XDMAPS_PERIPH_ID_1_OFFSET 0xFE4 /* Peripheral Identification + * Register 1 + */ +#define XDMAPS_PERIPH_ID_2_OFFSET 0xFE8 /* Peripheral Identification + * Register 2 + */ +#define XDMAPS_PERIPH_ID_3_OFFSET 0xFEC /* Peripheral Identification + * Register 3 + */ +#define XDMAPS_PCELL_ID_0_OFFSET 0xFF0 /* PrimeCell Identification + * Register 0 + */ +#define XDMAPS_PCELL_ID_1_OFFSET 0xFF4 /* PrimeCell Identification + * Register 1 + */ +#define XDMAPS_PCELL_ID_2_OFFSET 0xFF8 /* PrimeCell Identification + * Register 2 + */ +#define XDMAPS_PCELL_ID_3_OFFSET 0xFFC /* PrimeCell Identification + * Register 3 + */ + +/* + * Some useful register masks + */ +#define XDMAPS_DS_DMA_STATUS 0x0F /* DMA status mask */ +#define XDMAPS_DS_DMA_STATUS_STOPPED 0x00 /* debug status busy mask */ + +#define XDMAPS_DBGSTATUS_BUSY 0x01 /* debug status busy mask */ + +#define XDMAPS_CS_ACTIVE_MASK 0x07 /* channel status active mask, + * llast 3 bits of CS register + */ + +#define XDMAPS_CR1_I_CACHE_LEN_MASK 0x07 /* i_cache_len mask */ + + +/* + * XDMAPS_DBGINST0 - constructs the word for the Debug Instruction-0 Register. + * @b1: Instruction byte 1 + * @b0: Instruction byte 0 + * @ch: Channel number + * @dbg_th: Debug thread encoding: 0 = DMA manager thread, 1 = DMA channel + */ +#define XDmaPs_DBGINST0(b1, b0, ch, dbg_th) \ + (((b1) << 24) | ((b0) << 16) | (((ch) & 0x7) << 8) | ((dbg_th & 0x1))) + +/* @} */ + +/** @name Control Register + * + * The Control register (CR) controls the major functions of the device. + * + * Control Register Bit Definition + */ + +/* @}*/ + + +#define XDMAPS_CHANNELS_PER_DEV 8 + + +/** @name Mode Register + * + * The mode register (MR) defines the mode of transfer as well as the data + * format. If this register is modified during transmission or reception, + * data validity cannot be guaranteed. + * + * Mode Register Bit Definition + * @{ + */ + +/* @} */ + + +/** @name Interrupt Registers + * + * Interrupt control logic uses the interrupt enable register (IER) and the + * interrupt disable register (IDR) to set the value of the bits in the + * interrupt mask register (IMR). The IMR determines whether to pass an + * interrupt to the interrupt status register (ISR). + * Writing a 1 to IER Enbables an interrupt, writing a 1 to IDR disables an + * interrupt. IMR and ISR are read only, and IER and IDR are write only. + * Reading either IER or IDR returns 0x00. + * + * All four registers have the same bit definitions. + * + * @{ + */ + +/* @} */ +#define XDMAPS_INTCLR_ALL_MASK 0xFF + +#define XDmaPs_ReadReg(BaseAddress, RegOffset) \ + Xil_In32((BaseAddress) + (RegOffset)) + +/***************************************************************************/ +/** +* Write a DMAC register. +* +* @param BaseAddress contains the base address of the device. +* @param RegOffset contains the offset from the base address of the device. +* @param RegisterValue is the value to be written to the register. +* +* @return None. +* +* @note +* C-Style signature: +* void XDmaPs_WriteReg(u32 BaseAddress, int RegOffset, +* u32 RegisterValue) +******************************************************************************/ +#define XDmaPs_WriteReg(BaseAddress, RegOffset, RegisterValue) \ + Xil_Out32((BaseAddress) + (RegOffset), (RegisterValue)) +/************************** Variable Definitions *****************************/ + +/************************** Function Prototypes *****************************/ +/* + * Perform reset operation to the dmaps interface + */ +void XDmaPs_ResetHw(u32 BaseAddr); +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xenv.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xenv.h new file mode 100644 index 0000000..9c7c4c3 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xenv.h @@ -0,0 +1,183 @@ +/****************************************************************************** +* +* Copyright (C) 2002 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xenv.h +* +* Defines common services that are typically found in a host operating. +* environment. This include file simply includes an OS specific file based +* on the compile-time constant BUILD_ENV_*, where * is the name of the target +* environment. +* +* All services are defined as macros. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00b ch   10/24/02 Added XENV_LINUX
+* 1.00a rmm  04/17/02 First release
+* 
+* +******************************************************************************/ + +#ifndef XENV_H /* prevent circular inclusions */ +#define XENV_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Select which target environment we are operating under + */ + +/* VxWorks target environment */ +#if defined XENV_VXWORKS +#include "xenv_vxworks.h" + +/* Linux target environment */ +#elif defined XENV_LINUX +#include "xenv_linux.h" + +/* Unit test environment */ +#elif defined XENV_UNITTEST +#include "ut_xenv.h" + +/* Integration test environment */ +#elif defined XENV_INTTEST +#include "int_xenv.h" + +/* Standalone environment selected */ +#else +#include "xenv_standalone.h" +#endif + + +/* + * The following comments specify the types and macro wrappers that are + * expected to be defined by the target specific header files + */ + +/**************************** Type Definitions *******************************/ + +/*****************************************************************************/ +/** + * + * XENV_TIME_STAMP + * + * A structure that contains a time stamp used by other time stamp macros + * defined below. This structure is processor dependent. + */ + + +/***************** Macros (Inline Functions) Definitions *********************/ + +/*****************************************************************************/ +/** + * + * XENV_MEM_COPY(void *DestPtr, void *SrcPtr, unsigned Bytes) + * + * Copies a non-overlapping block of memory. + * + * @param DestPtr is the destination address to copy data to. + * @param SrcPtr is the source address to copy data from. + * @param Bytes is the number of bytes to copy. + * + * @return None + */ + +/*****************************************************************************/ +/** + * + * XENV_MEM_FILL(void *DestPtr, char Data, unsigned Bytes) + * + * Fills an area of memory with constant data. + * + * @param DestPtr is the destination address to set. + * @param Data contains the value to set. + * @param Bytes is the number of bytes to set. + * + * @return None + */ +/*****************************************************************************/ +/** + * + * XENV_TIME_STAMP_GET(XTIME_STAMP *StampPtr) + * + * Samples the processor's or external timer's time base counter. + * + * @param StampPtr is the storage for the retrieved time stamp. + * + * @return None + */ + +/*****************************************************************************/ +/** + * + * XENV_TIME_STAMP_DELTA_US(XTIME_STAMP *Stamp1Ptr, XTIME_STAMP* Stamp2Ptr) + * + * Computes the delta between the two time stamps. + * + * @param Stamp1Ptr - First sampled time stamp. + * @param Stamp1Ptr - Sedond sampled time stamp. + * + * @return An unsigned int value with units of microseconds. + */ + +/*****************************************************************************/ +/** + * + * XENV_TIME_STAMP_DELTA_MS(XTIME_STAMP *Stamp1Ptr, XTIME_STAMP* Stamp2Ptr) + * + * Computes the delta between the two time stamps. + * + * @param Stamp1Ptr - First sampled time stamp. + * @param Stamp1Ptr - Sedond sampled time stamp. + * + * @return An unsigned int value with units of milliseconds. + */ + +/*****************************************************************************//** + * + * XENV_USLEEP(unsigned delay) + * + * Delay the specified number of microseconds. + * + * @param delay is the number of microseconds to delay. + * + * @return None + */ + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xenv_standalone.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xenv_standalone.h new file mode 100644 index 0000000..ef905af --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xenv_standalone.h @@ -0,0 +1,364 @@ +/****************************************************************************** +* +* Copyright (C) 2002 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xenv_standalone.h +* +* Defines common services specified by xenv.h. +* +* @note +* This file is not intended to be included directly by driver code. +* Instead, the generic xenv.h file is intended to be included by driver +* code. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a wgr  02/28/07 Added cache handling macros.
+* 1.00a wgr  02/27/07 Simplified code. Deprecated old-style macro names.
+* 1.00a rmm  01/24/06 Implemented XENV_USLEEP. Assume implementation is being
+*                     used under Xilinx standalone BSP.
+* 1.00a xd   11/03/04 Improved support for doxygen.
+* 1.00a rmm  03/21/02 First release
+* 1.00a wgr  03/22/07 Converted to new coding style.
+* 1.00a rpm  06/29/07 Added udelay macro for standalone
+* 1.00a xd   07/19/07 Included xparameters.h as XPAR_ constants are referred
+*                     to in MICROBLAZE section
+* 1.00a ecm  09/19/08 updated for v7.20 of Microblaze, new functionality
+*
+* 
+* +* +******************************************************************************/ + +#ifndef XENV_STANDALONE_H +#define XENV_STANDALONE_H + +#include "xil_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ +/****************************************************************************** + * + * Get the processor dependent includes + * + ******************************************************************************/ + +#include + +#if defined __MICROBLAZE__ +# include "mb_interface.h" +# include "xparameters.h" /* XPAR constants used below in MB section */ + +#elif defined __PPC__ +# include "sleep.h" +# include "xcache_l.h" /* also include xcache_l.h for caching macros */ +#endif + +/****************************************************************************** + * + * MEMCPY / MEMSET related macros. + * + * The following are straight forward implementations of memset and memcpy. + * + * NOTE: memcpy may not work if source and target memory area are overlapping. + * + ******************************************************************************/ +/*****************************************************************************/ +/** + * + * Copies a non-overlapping block of memory. + * + * @param DestPtr + * Destination address to copy data to. + * + * @param SrcPtr + * Source address to copy data from. + * + * @param Bytes + * Number of bytes to copy. + * + * @return None. + * + * @note + * The use of XENV_MEM_COPY is deprecated. Use memcpy() instead. + * + * @note + * This implemention MAY BREAK work if source and target memory + * area are overlapping. + * + *****************************************************************************/ + +#define XENV_MEM_COPY(DestPtr, SrcPtr, Bytes) \ + memcpy((void *) DestPtr, (const void *) SrcPtr, (size_t) Bytes) + + + +/*****************************************************************************/ +/** + * + * Fills an area of memory with constant data. + * + * @param DestPtr + * Destination address to copy data to. + * + * @param Data + * Value to set. + * + * @param Bytes + * Number of bytes to copy. + * + * @return None. + * + * @note + * The use of XENV_MEM_FILL is deprecated. Use memset() instead. + * + *****************************************************************************/ + +#define XENV_MEM_FILL(DestPtr, Data, Bytes) \ + memset((void *) DestPtr, (s32) Data, (size_t) Bytes) + + + +/****************************************************************************** + * + * TIME related macros + * + ******************************************************************************/ + +/** + * A structure that contains a time stamp used by other time stamp macros + * defined below. This structure is processor dependent. + */ +typedef s32 XENV_TIME_STAMP; + +/*****************************************************************************/ +/** + * + * Time is derived from the 64 bit PPC timebase register + * + * @param StampPtr is the storage for the retrieved time stamp. + * + * @return None. + * + * @note + * + * Signature: void XENV_TIME_STAMP_GET(XTIME_STAMP *StampPtr) + *

+ * This macro must be implemented by the user. + * + *****************************************************************************/ +#define XENV_TIME_STAMP_GET(StampPtr) + +/*****************************************************************************/ +/** + * + * This macro is not yet implemented and always returns 0. + * + * @param Stamp1Ptr is the first sampled time stamp. + * @param Stamp2Ptr is the second sampled time stamp. + * + * @return 0 + * + * @note + * + * This macro must be implemented by the user. + * + *****************************************************************************/ +#define XENV_TIME_STAMP_DELTA_US(Stamp1Ptr, Stamp2Ptr) (0) + +/*****************************************************************************/ +/** + * + * This macro is not yet implemented and always returns 0. + * + * @param Stamp1Ptr is the first sampled time stamp. + * @param Stamp2Ptr is the second sampled time stamp. + * + * @return 0 + * + * @note + * + * This macro must be implemented by the user. + * + *****************************************************************************/ +#define XENV_TIME_STAMP_DELTA_MS(Stamp1Ptr, Stamp2Ptr) (0) + +/*****************************************************************************/ +/** + * XENV_USLEEP(unsigned delay) + * + * Delay the specified number of microseconds. Not implemented without OS + * support. + * + * @param delay + * Number of microseconds to delay. + * + * @return None. + * + *****************************************************************************/ + +#ifdef __PPC__ +#define XENV_USLEEP(delay) usleep(delay) +#define udelay(delay) usleep(delay) +#else +#define XENV_USLEEP(delay) +#define udelay(delay) +#endif + + +/****************************************************************************** + * + * CACHE handling macros / mappings + * + ******************************************************************************/ +/****************************************************************************** + * + * Processor independent macros + * + ******************************************************************************/ + +#define XCACHE_ENABLE_CACHE() \ + { XCACHE_ENABLE_DCACHE(); XCACHE_ENABLE_ICACHE(); } + +#define XCACHE_DISABLE_CACHE() \ + { XCACHE_DISABLE_DCACHE(); XCACHE_DISABLE_ICACHE(); } + + +/****************************************************************************** + * + * MicroBlaze case + * + * NOTE: Currently the following macros will only work on systems that contain + * only ONE MicroBlaze processor. Also, the macros will only be enabled if the + * system is built using a xparameters.h file. + * + ******************************************************************************/ + +#if defined __MICROBLAZE__ + +/* Check if MicroBlaze data cache was built into the core. + */ +#if (XPAR_MICROBLAZE_USE_DCACHE == 1) +# define XCACHE_ENABLE_DCACHE() microblaze_enable_dcache() +# define XCACHE_DISABLE_DCACHE() microblaze_disable_dcache() +# define XCACHE_INVALIDATE_DCACHE() microblaze_invalidate_dcache() + +# define XCACHE_INVALIDATE_DCACHE_RANGE(Addr, Len) \ + microblaze_invalidate_dcache_range((s32)(Addr), (s32)(Len)) + +#if (XPAR_MICROBLAZE_DCACHE_USE_WRITEBACK == 1) +# define XCACHE_FLUSH_DCACHE() microblaze_flush_dcache() +# define XCACHE_FLUSH_DCACHE_RANGE(Addr, Len) \ + microblaze_flush_dcache_range((s32)(Addr), (s32)(Len)) +#else +# define XCACHE_FLUSH_DCACHE() microblaze_invalidate_dcache() +# define XCACHE_FLUSH_DCACHE_RANGE(Addr, Len) \ + microblaze_invalidate_dcache_range((s32)(Addr), (s32)(Len)) +#endif /*XPAR_MICROBLAZE_DCACHE_USE_WRITEBACK*/ + +#else +# define XCACHE_ENABLE_DCACHE() +# define XCACHE_DISABLE_DCACHE() +# define XCACHE_INVALIDATE_DCACHE_RANGE(Addr, Len) +# define XCACHE_FLUSH_DCACHE_RANGE(Addr, Len) +#endif /*XPAR_MICROBLAZE_USE_DCACHE*/ + + +/* Check if MicroBlaze instruction cache was built into the core. + */ +#if (XPAR_MICROBLAZE_USE_ICACHE == 1) +# define XCACHE_ENABLE_ICACHE() microblaze_enable_icache() +# define XCACHE_DISABLE_ICACHE() microblaze_disable_icache() + +# define XCACHE_INVALIDATE_ICACHE() microblaze_invalidate_icache() + +# define XCACHE_INVALIDATE_ICACHE_RANGE(Addr, Len) \ + microblaze_invalidate_icache_range((s32)(Addr), (s32)(Len)) + +#else +# define XCACHE_ENABLE_ICACHE() +# define XCACHE_DISABLE_ICACHE() +#endif /*XPAR_MICROBLAZE_USE_ICACHE*/ + + +/****************************************************************************** + * + * PowerPC case + * + * Note that the XCACHE_ENABLE_xxx functions are hardcoded to enable a + * specific memory region (0x80000001). Each bit (0-30) in the regions + * bitmask stands for 128MB of memory. Bit 31 stands for the upper 2GB + * range. + * + * regions --> cached address range + * ------------|-------------------------------------------------- + * 0x80000000 | [0, 0x7FFFFFF] + * 0x00000001 | [0xF8000000, 0xFFFFFFFF] + * 0x80000001 | [0, 0x7FFFFFF],[0xF8000000, 0xFFFFFFFF] + * + ******************************************************************************/ + +#elif defined __PPC__ + +#define XCACHE_ENABLE_DCACHE() XCache_EnableDCache(0x80000001) +#define XCACHE_DISABLE_DCACHE() XCache_DisableDCache() +#define XCACHE_ENABLE_ICACHE() XCache_EnableICache(0x80000001) +#define XCACHE_DISABLE_ICACHE() XCache_DisableICache() + +#define XCACHE_INVALIDATE_DCACHE_RANGE(Addr, Len) \ + XCache_InvalidateDCacheRange((u32)(Addr), (u32)(Len)) + +#define XCACHE_FLUSH_DCACHE_RANGE(Addr, Len) \ + XCache_FlushDCacheRange((u32)(Addr), (u32)(Len)) + +#define XCACHE_INVALIDATE_ICACHE() XCache_InvalidateICache() + + +/****************************************************************************** + * + * Unknown processor / architecture + * + ******************************************************************************/ + +#else +/* #error "Unknown processor / architecture. Must be MicroBlaze or PowerPC." */ +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /* #ifndef XENV_STANDALONE_H */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xgpiops.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xgpiops.h new file mode 100644 index 0000000..d0ff132 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xgpiops.h @@ -0,0 +1,283 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2019 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xgpiops.h +* @addtogroup gpiops_v3_5 +* @{ +* @details +* +* The Xilinx PS GPIO driver. This driver supports the Xilinx PS GPIO +* Controller. +* +* The GPIO Controller supports the following features: +* - 4 banks +* - Masked writes (There are no masked reads) +* - Bypass mode +* - Configurable Interrupts (Level/Edge) +* +* This driver is intended to be RTOS and processor independent. Any needs for +* dynamic memory management, threads or thread mutual exclusion, virtual +* memory, or cache control must be satisfied by the layer above this driver. + +* This driver supports all the features listed above, if applicable. +* +* Driver Description +* +* The device driver enables higher layer software (e.g., an application) to +* communicate to the GPIO. +* +* Interrupts +* +* The driver provides interrupt management functions and an interrupt handler. +* Users of this driver need to provide callback functions. An interrupt handler +* example is available with the driver. +* +* Threads +* +* This driver is not thread safe. Any needs for threads or thread mutual +* exclusion must be satisfied by the layer above this driver. +* +* Asserts +* +* Asserts are used within all Xilinx drivers to enforce constraints on argument +* values. Asserts can be turned off on a system-wide basis by defining, at +* compile time, the NDEBUG identifier. By default, asserts are turned on and it +* is recommended that users leave asserts on during development. +* +* Building the driver +* +* The XGpioPs driver is composed of several source files. This allows the user +* to build and link only those parts of the driver that are necessary. +*

+* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a sv   01/15/10 First Release
+* 1.01a sv   04/15/12 Removed the APIs XGpioPs_SetMode, XGpioPs_SetModePin
+*                     XGpioPs_GetMode, XGpioPs_GetModePin as they are not
+*		      relevant to Zynq device.The interrupts are disabled
+*		      for output pins on all banks during initialization.
+* 1.02a hk   08/22/13 Added low level reset API
+* 2.1   hk   04/29/14 Use Input data register DATA_RO for read. CR# 771667.
+* 2.2	sk	 10/13/14 Used Pin number in Bank instead of pin number
+* 					  passed to APIs. CR# 822636
+* 3.00  kvn  02/13/15 Modified code for MISRA-C:2012 compliance.
+* 3.1	kvn  04/13/15 Add support for Zynq Ultrascale+ MP. CR# 856980.
+*       ms   03/17/17 Added readme.txt file in examples folder for doxygen
+*                     generation.
+*       ms   04/05/17 Added tabspace for return statements in functions of
+*                     gpiops examples for proper documentation while
+*                     generating doxygen.
+* 3.3   ms   04/17/17 Added notes about gpio input and output pin description
+*                     for zcu102 and zc702 boards in polled and interrupt
+*                     example, configured Interrupt pin to input pin for
+*                     proper functioning of interrupt example.
+* 3.4   aru  08/17/18 Resolved MISRA-C mandatory violations. CR# 1007751
+* 3.5   sne  03/01/19 Fixes violations according to MISRAC-2012
+*                     in saftey mode and modified the code such as
+*                     Use of mixed mode arithmetic,Declared the poiner param
+*                     as Pointer to const,Casting operation to a pointer,
+*                     Literal value requires a U suffix.
+* 3.5   sne  03/14/19 Added Versal support.
+* 
+* +******************************************************************************/ +#ifndef XGPIOPS_H /* prevent circular inclusions */ +#define XGPIOPS_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +#include "xstatus.h" +#include "xgpiops_hw.h" +#include "xplatform_info.h" + +/************************** Constant Definitions *****************************/ + +/** @name Interrupt types + * @{ + * The following constants define the interrupt types that can be set for each + * GPIO pin. + */ +#define XGPIOPS_IRQ_TYPE_EDGE_RISING 0x00U /**< Interrupt on Rising edge */ +#define XGPIOPS_IRQ_TYPE_EDGE_FALLING 0x01U /**< Interrupt Falling edge */ +#define XGPIOPS_IRQ_TYPE_EDGE_BOTH 0x02U /**< Interrupt on both edges */ +#define XGPIOPS_IRQ_TYPE_LEVEL_HIGH 0x03U /**< Interrupt on high level */ +#define XGPIOPS_IRQ_TYPE_LEVEL_LOW 0x04U /**< Interrupt on low level */ +/*@}*/ + +#define XGPIOPS_BANK_MAX_PINS (u32)32 /**< Max pins in a GPIO bank */ +#define XGPIOPS_BANK0 0x00U /**< GPIO Bank 0 */ +#define XGPIOPS_BANK1 0x01U /**< GPIO Bank 1 */ +#define XGPIOPS_BANK2 0x02U /**< GPIO Bank 2 */ +#define XGPIOPS_BANK3 0x03U /**< GPIO Bank 3 */ + +#ifdef XPAR_PSU_GPIO_0_BASEADDR +#define XGPIOPS_BANK4 0x04U /**< GPIO Bank 4 */ +#define XGPIOPS_BANK5 0x05U /**< GPIO Bank 5 */ +#endif + +#define XGPIOPS_MAX_BANKS_ZYNQMP 0x06U /**< Max banks in a + * Zynq Ultrascale+ MP GPIO device + */ +#define XGPIOPS_MAX_BANKS 0x04U /**< Max banks in a Zynq GPIO device */ + +#define XGPIOPS_DEVICE_MAX_PIN_NUM_ZYNQMP (u32)174 /**< Max pins in the + * Zynq Ultrascale+ MP GPIO device + * 0 - 25, Bank 0 + * 26 - 51, Bank 1 + * 52 - 77, Bank 2 + * 78 - 109, Bank 3 + * 110 - 141, Bank 4 + * 142 - 173, Bank 5 + */ +#define XGPIOPS_DEVICE_MAX_PIN_NUM (u32)118 /**< Max pins in the Zynq GPIO device + * 0 - 31, Bank 0 + * 32 - 53, Bank 1 + * 54 - 85, Bank 2 + * 86 - 117, Bank 3 + */ + +/**************************** Type Definitions *******************************/ + +/****************************************************************************/ +/** + * This handler data type allows the user to define a callback function to + * handle the interrupts for the GPIO device. The application using this + * driver is expected to define a handler of this type, to support interrupt + * driven mode. The handler executes in an interrupt context such that minimal + * processing should be performed. + * + * @param CallBackRef is a callback reference passed in by the upper layer + * when setting the callback functions for a GPIO bank. It is + * passed back to the upper layer when the callback is invoked. Its + * type is not important to the driver component, so it is a void + * pointer. + * @param Bank is the bank for which the interrupt status has changed. + * @param Status is the Interrupt status of the GPIO bank. + * + *****************************************************************************/ +typedef void (*XGpioPs_Handler) (void *CallBackRef, u32 Bank, u32 Status); + +/** + * This typedef contains configuration information for a device. + */ +typedef struct { + u16 DeviceId; /**< Unique ID of device */ + u32 BaseAddr; /**< Register base address */ +} XGpioPs_Config; + +/** + * The XGpioPs driver instance data. The user is required to allocate a + * variable of this type for the GPIO device in the system. A pointer + * to a variable of this type is then passed to the driver API functions. + */ +typedef struct { + XGpioPs_Config GpioConfig; /**< Device configuration */ + u32 IsReady; /**< Device is initialized and ready */ + XGpioPs_Handler Handler; /**< Status handlers for all banks */ + void *CallBackRef; /**< Callback ref for bank handlers */ + u32 Platform; /**< Platform data */ + u32 MaxPinNum; /**< Max pins in the GPIO device */ + u8 MaxBanks; /**< Max banks in a GPIO device */ + u32 PmcGpio; /**< Flag for accessing PS GPIO for versal*/ +} XGpioPs; + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/* Functions in xgpiops.c */ +s32 XGpioPs_CfgInitialize(XGpioPs *InstancePtr, const XGpioPs_Config *ConfigPtr, + u32 EffectiveAddr); + +/* Bank APIs in xgpiops.c */ +u32 XGpioPs_Read(const XGpioPs *InstancePtr, u8 Bank); +void XGpioPs_Write(const XGpioPs *InstancePtr, u8 Bank, u32 Data); +void XGpioPs_SetDirection(const XGpioPs *InstancePtr, u8 Bank, u32 Direction); +u32 XGpioPs_GetDirection(const XGpioPs *InstancePtr, u8 Bank); +void XGpioPs_SetOutputEnable(const XGpioPs *InstancePtr, u8 Bank, u32 OpEnable); +u32 XGpioPs_GetOutputEnable(const XGpioPs *InstancePtr, u8 Bank); +#ifdef versal +void XGpioPs_GetBankPin(const XGpioPs *InstancePtr,u8 PinNumber,u8 *BankNumber, u8 *PinNumberInBank); +#else +void XGpioPs_GetBankPin(u8 PinNumber,u8 *BankNumber, u8 *PinNumberInBank); +#endif + +/* Pin APIs in xgpiops.c */ +u32 XGpioPs_ReadPin(const XGpioPs *InstancePtr, u32 Pin); +void XGpioPs_WritePin(const XGpioPs *InstancePtr, u32 Pin, u32 Data); +void XGpioPs_SetDirectionPin(const XGpioPs *InstancePtr, u32 Pin, u32 Direction); +u32 XGpioPs_GetDirectionPin(const XGpioPs *InstancePtr, u32 Pin); +void XGpioPs_SetOutputEnablePin(const XGpioPs *InstancePtr, u32 Pin, u32 OpEnable); +u32 XGpioPs_GetOutputEnablePin(const XGpioPs *InstancePtr, u32 Pin); + +/* Diagnostic functions in xgpiops_selftest.c */ +s32 XGpioPs_SelfTest(const XGpioPs *InstancePtr); + +/* Functions in xgpiops_intr.c */ +/* Bank APIs in xgpiops_intr.c */ +void XGpioPs_IntrEnable(const XGpioPs *InstancePtr, u8 Bank, u32 Mask); +void XGpioPs_IntrDisable(const XGpioPs *InstancePtr, u8 Bank, u32 Mask); +u32 XGpioPs_IntrGetEnabled(const XGpioPs *InstancePtr, u8 Bank); +u32 XGpioPs_IntrGetStatus(const XGpioPs *InstancePtr, u8 Bank); +void XGpioPs_IntrClear(const XGpioPs *InstancePtr, u8 Bank, u32 Mask); +void XGpioPs_SetIntrType(const XGpioPs *InstancePtr, u8 Bank, u32 IntrType, + u32 IntrPolarity, u32 IntrOnAny); +void XGpioPs_GetIntrType(const XGpioPs *InstancePtr, u8 Bank, u32 *IntrType, + u32 *IntrPolarity, u32 *IntrOnAny); +void XGpioPs_SetCallbackHandler(XGpioPs *InstancePtr, void *CallBackRef, + XGpioPs_Handler FuncPointer); +void XGpioPs_IntrHandler(const XGpioPs *InstancePtr); + +/* Pin APIs in xgpiops_intr.c */ +void XGpioPs_SetIntrTypePin(const XGpioPs *InstancePtr, u32 Pin, u8 IrqType); +u8 XGpioPs_GetIntrTypePin(const XGpioPs *InstancePtr, u32 Pin); + +void XGpioPs_IntrEnablePin(const XGpioPs *InstancePtr, u32 Pin); +void XGpioPs_IntrDisablePin(const XGpioPs *InstancePtr, u32 Pin); +u32 XGpioPs_IntrGetEnabledPin(const XGpioPs *InstancePtr, u32 Pin); +u32 XGpioPs_IntrGetStatusPin(const XGpioPs *InstancePtr, u32 Pin); +void XGpioPs_IntrClearPin(const XGpioPs *InstancePtr, u32 Pin); + +/* Functions in xgpiops_sinit.c */ +XGpioPs_Config *XGpioPs_LookupConfig(u16 DeviceId); +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xgpiops_hw.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xgpiops_hw.h new file mode 100644 index 0000000..599c7db --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xgpiops_hw.h @@ -0,0 +1,168 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2019 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xgpiops_hw.h +* @addtogroup gpiops_v3_5 +* @{ +* +* This header file contains the identifiers and basic driver functions (or +* macros) that can be used to access the device. Other driver functions +* are defined in xgpiops.h. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -------------------------------------------------
+* 1.00a sv   01/15/10 First Release
+* 1.02a hk   08/22/13 Added low level reset API function prototype and
+*                     related constant definitions
+* 3.00  kvn  02/13/15 Modified code for MISRA-C:2012 compliance.
+* 3.1	kvn  04/13/15 Corrected reset values of banks.
+* 3.5   sne  03/14/19 Added versal support.
+* 
+* +******************************************************************************/ +#ifndef XGPIOPS_HW_H /* prevent circular inclusions */ +#define XGPIOPS_HW_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/***************************** Include Files *********************************/ + +#include "xil_types.h" +#include "xil_assert.h" +#include "xil_io.h" + +/************************** Constant Definitions *****************************/ + +/** @name Register offsets for the GPIO. Each register is 32 bits. + * @{ + */ +#define XGPIOPS_DATA_LSW_OFFSET 0x00000000U /* Mask and Data Register LSW, WO */ +#define XGPIOPS_DATA_MSW_OFFSET 0x00000004U /* Mask and Data Register MSW, WO */ +#define XGPIOPS_DATA_OFFSET 0x00000040U /* Data Register, RW */ +#define XGPIOPS_DATA_RO_OFFSET 0x00000060U /* Data Register - Input, RO */ +#define XGPIOPS_DIRM_OFFSET 0x00000204U /* Direction Mode Register, RW */ +#define XGPIOPS_OUTEN_OFFSET 0x00000208U /* Output Enable Register, RW */ +#define XGPIOPS_INTMASK_OFFSET 0x0000020CU /* Interrupt Mask Register, RO */ +#define XGPIOPS_INTEN_OFFSET 0x00000210U /* Interrupt Enable Register, WO */ +#define XGPIOPS_INTDIS_OFFSET 0x00000214U /* Interrupt Disable Register, WO*/ +#define XGPIOPS_INTSTS_OFFSET 0x00000218U /* Interrupt Status Register, RO */ +#define XGPIOPS_INTTYPE_OFFSET 0x0000021CU /* Interrupt Type Register, RW */ +#define XGPIOPS_INTPOL_OFFSET 0x00000220U /* Interrupt Polarity Register, RW */ +#define XGPIOPS_INTANY_OFFSET 0x00000224U /* Interrupt On Any Register, RW */ +/* @} */ + +/** @name Register offsets for each Bank. + * @{ + */ +#define XGPIOPS_DATA_MASK_OFFSET 0x00000008U /* Data/Mask Registers offset */ +#define XGPIOPS_DATA_BANK_OFFSET 0x00000004U /* Data Registers offset */ +#define XGPIOPS_REG_MASK_OFFSET 0x00000040U /* Registers offset */ +/* @} */ + +/* For backwards compatibility */ +#define XGPIOPS_BYPM_MASK_OFFSET (u32)0x40 + +/** @name Interrupt type reset values for each bank + * @{ + */ +#ifdef XPAR_PSU_GPIO_0_BASEADDR +#define XGPIOPS_INTTYPE_BANK0_RESET 0x03FFFFFFU /* Resets specific to Zynq Ultrascale+ MP */ +#define XGPIOPS_INTTYPE_BANK1_RESET 0x03FFFFFFU +#define XGPIOPS_INTTYPE_BANK2_RESET 0x03FFFFFFU +#else +#define XGPIOPS_INTTYPE_BANK0_RESET 0xFFFFFFFFU /* Resets specific to Zynq */ +#define XGPIOPS_INTTYPE_BANK1_RESET 0x003FFFFFU +#define XGPIOPS_INTTYPE_BANK2_RESET 0xFFFFFFFFU +#endif + +#define XGPIOPS_INTTYPE_BANK3_RESET 0xFFFFFFFFU /* Reset common to both platforms */ +#define XGPIOPS_INTTYPE_BANK4_RESET 0xFFFFFFFFU /* Resets specific to Zynq Ultrascale+ MP */ +#define XGPIOPS_INTTYPE_BANK5_RESET 0xFFFFFFFFU +/* @} */ +#define XGPIOPS_PS_GPIO_BASEADDR 0xFF0B0000U /* Flag for Base Address for PS_GPIO in Versal */ +#define XGPIOPS_ZERO 0U /* Flag for 0 Value */ +#define XGPIOPS_ONE 1U /* Flag for 1 Value */ +#define XGPIOPS_TWO 2U /* Flag for 2 Value */ +#define XGPIOPS_THREE 3U /* Flag for 3 Value */ +#define XGPIOPS_FOUR 4U /* Flag for 4 Value */ +#define XGPIOPS_SIX 6U /* Flag for 6 Value */ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/****************************************************************************/ +/** +* +* This macro reads the given register. +* +* @param BaseAddr is the base address of the device. +* @param RegOffset is the register offset to be read. +* +* @return The 32-bit value of the register +* +* @note None. +* +*****************************************************************************/ +#define XGpioPs_ReadReg(BaseAddr, RegOffset) \ + Xil_In32((BaseAddr) + (u32)(RegOffset)) + +/****************************************************************************/ +/** +* +* This macro writes to the given register. +* +* @param BaseAddr is the base address of the device. +* @param RegOffset is the offset of the register to be written. +* @param Data is the 32-bit value to write to the register. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +#define XGpioPs_WriteReg(BaseAddr, RegOffset, Data) \ + Xil_Out32((BaseAddr) + (u32)(RegOffset), (u32)(Data)) + +/************************** Function Prototypes ******************************/ + +void XGpioPs_ResetHw(u32 BaseAddress); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* XGPIOPS_HW_H */ +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_assert.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_assert.h new file mode 100644 index 0000000..917de31 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_assert.h @@ -0,0 +1,191 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xil_assert.h +* +* @addtogroup common_assert_apis Assert APIs and Macros +* +* The xil_assert.h file contains assert related functions and macros. +* Assert APIs/Macros specifies that a application program satisfies certain +* conditions at particular points in its execution. These function can be +* used by application programs to ensure that, application code is satisfying +* certain conditions. +* +* @{ +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date   Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a hbm  07/14/09 First release
+* 6.0   kvn  05/31/16 Make Xil_AsserWait a global variable
+* 
+* +******************************************************************************/ + +#ifndef XIL_ASSERT_H /* prevent circular inclusions */ +#define XIL_ASSERT_H /* by using protection macros */ + +#include "xil_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/***************************** Include Files *********************************/ + + +/************************** Constant Definitions *****************************/ + +#define XIL_ASSERT_NONE 0U +#define XIL_ASSERT_OCCURRED 1U +#define XNULL NULL + +extern u32 Xil_AssertStatus; +extern s32 Xil_AssertWait; +extern void Xil_Assert(const char8 *File, s32 Line); +void XNullHandler(void *NullParameter); + +/** + * This data type defines a callback to be invoked when an + * assert occurs. The callback is invoked only when asserts are enabled + */ +typedef void (*Xil_AssertCallback) (const char8 *File, s32 Line); + +/***************** Macros (Inline Functions) Definitions *********************/ + +#ifndef NDEBUG + +/*****************************************************************************/ +/** +* @brief This assert macro is to be used for void functions. This in +* conjunction with the Xil_AssertWait boolean can be used to +* accomodate tests so that asserts which fail allow execution to +* continue. +* +* @param Expression: expression to be evaluated. If it evaluates to +* false, the assert occurs. +* +* @return Returns void unless the Xil_AssertWait variable is true, in which +* case no return is made and an infinite loop is entered. +* +******************************************************************************/ +#define Xil_AssertVoid(Expression) \ +{ \ + if (Expression) { \ + Xil_AssertStatus = XIL_ASSERT_NONE; \ + } else { \ + Xil_Assert(__FILE__, __LINE__); \ + Xil_AssertStatus = XIL_ASSERT_OCCURRED; \ + return; \ + } \ +} + +/*****************************************************************************/ +/** +* @brief This assert macro is to be used for functions that do return a +* value. This in conjunction with the Xil_AssertWait boolean can be +* used to accomodate tests so that asserts which fail allow execution +* to continue. +* +* @param Expression: expression to be evaluated. If it evaluates to false, +* the assert occurs. +* +* @return Returns 0 unless the Xil_AssertWait variable is true, in which +* case no return is made and an infinite loop is entered. +* +******************************************************************************/ +#define Xil_AssertNonvoid(Expression) \ +{ \ + if (Expression) { \ + Xil_AssertStatus = XIL_ASSERT_NONE; \ + } else { \ + Xil_Assert(__FILE__, __LINE__); \ + Xil_AssertStatus = XIL_ASSERT_OCCURRED; \ + return 0; \ + } \ +} + +/*****************************************************************************/ +/** +* @brief Always assert. This assert macro is to be used for void functions. +* Use for instances where an assert should always occur. +* +* @return Returns void unless the Xil_AssertWait variable is true, in which +* case no return is made and an infinite loop is entered. +* +******************************************************************************/ +#define Xil_AssertVoidAlways() \ +{ \ + Xil_Assert(__FILE__, __LINE__); \ + Xil_AssertStatus = XIL_ASSERT_OCCURRED; \ + return; \ +} + +/*****************************************************************************/ +/** +* @brief Always assert. This assert macro is to be used for functions that +* do return a value. Use for instances where an assert should always +* occur. +* +* @return Returns void unless the Xil_AssertWait variable is true, in which +* case no return is made and an infinite loop is entered. +* +******************************************************************************/ +#define Xil_AssertNonvoidAlways() \ +{ \ + Xil_Assert(__FILE__, __LINE__); \ + Xil_AssertStatus = XIL_ASSERT_OCCURRED; \ + return 0; \ +} + + +#else + +#define Xil_AssertVoid(Expression) +#define Xil_AssertVoidAlways() +#define Xil_AssertNonvoid(Expression) +#define Xil_AssertNonvoidAlways() + +#endif + +/************************** Function Prototypes ******************************/ + +void Xil_AssertSetCallback(Xil_AssertCallback Routine); + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** +* @} End of "addtogroup common_assert_apis". +*/ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_cache.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_cache.h new file mode 100644 index 0000000..ce6fcf4 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_cache.h @@ -0,0 +1,118 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xil_cache.h +* +* @addtogroup a9_cache_apis Cortex A9 Processor Cache Functions +* +* Cache functions provide access to cache related operations such as flush +* and invalidate for instruction and data caches. It gives option to perform +* the cache operations on a single cacheline, a range of memory and an entire +* cache. +* +* @{ +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a ecm  01/29/10 First release
+* 3.04a sdm  01/02/12 Remove redundant dsb/dmb instructions in cache maintenance
+*		      APIs.
+* 6.8   aru  09/06/18 Removed compilation warnings for ARMCC toolchain.
+* 
+* +******************************************************************************/ +#ifndef XIL_CACHE_H +#define XIL_CACHE_H + +#include "xil_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __GNUC__ + +#define asm_cp15_inval_dc_line_mva_poc(param) __asm__ __volatile__("mcr " \ + XREG_CP15_INVAL_DC_LINE_MVA_POC :: "r" (param)); + +#define asm_cp15_clean_inval_dc_line_mva_poc(param) __asm__ __volatile__("mcr " \ + XREG_CP15_CLEAN_INVAL_DC_LINE_MVA_POC :: "r" (param)); + +#define asm_cp15_inval_ic_line_mva_pou(param) __asm__ __volatile__("mcr " \ + XREG_CP15_INVAL_IC_LINE_MVA_POU :: "r" (param)); + +#define asm_cp15_inval_dc_line_sw(param) __asm__ __volatile__("mcr " \ + XREG_CP15_INVAL_DC_LINE_SW :: "r" (param)); + +#define asm_cp15_clean_inval_dc_line_sw(param) __asm__ __volatile__("mcr " \ + XREG_CP15_CLEAN_INVAL_DC_LINE_SW :: "r" (param)); + +#elif defined (__ICCARM__) + +#define asm_cp15_inval_dc_line_mva_poc(param) __asm volatile ("mcr " \ + XREG_CP15_INVAL_DC_LINE_MVA_POC :: "r" (param)); + +#define asm_cp15_clean_inval_dc_line_mva_poc(param) __asm volatile ("mcr " \ + XREG_CP15_CLEAN_INVAL_DC_LINE_MVA_POC :: "r" (param)); + +#define asm_cp15_inval_ic_line_mva_pou(param) __asm volatile ("mcr " \ + XREG_CP15_INVAL_IC_LINE_MVA_POU :: "r" (param)); + +#define asm_cp15_inval_dc_line_sw(param) __asm volatile ("mcr " \ + XREG_CP15_INVAL_DC_LINE_SW :: "r" (param)); + +#define asm_cp15_clean_inval_dc_line_sw(param) __asm volatile ("mcr " \ + XREG_CP15_CLEAN_INVAL_DC_LINE_SW :: "r" (param)); + +#endif + +void Xil_DCacheEnable(void); +void Xil_DCacheDisable(void); +void Xil_DCacheInvalidate(void); +void Xil_DCacheInvalidateRange(INTPTR adr, u32 len); +void Xil_DCacheFlush(void); +void Xil_DCacheFlushRange(INTPTR adr, u32 len); + +void Xil_ICacheEnable(void); +void Xil_ICacheDisable(void); +void Xil_ICacheInvalidate(void); +void Xil_ICacheInvalidateRange(INTPTR adr, u32 len); + +#ifdef __cplusplus +} +#endif + +#endif +/** +* @} End of "addtogroup a9_cache_apis". +*/ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_cache_l.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_cache_l.h new file mode 100644 index 0000000..b6ff809 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_cache_l.h @@ -0,0 +1,97 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xil_cache_l.h +* +* Contains L1 and L2 specific functions for the ARM cache functionality +* used by xcache.c. This functionality is being made available here for +* more sophisticated users. +* +* @addtogroup a9_cache_apis +* @{ +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a ecm  01/24/10 First release
+* 6.8   aru  09/06/18 Removed compilation warnings for ARMCC toolchain.
+* 
+* +******************************************************************************/ +#ifndef XIL_CACHE_MACH_H +#define XIL_CACHE_MACH_H + +#include "xil_types.h" +#ifdef __cplusplus +extern "C" { +#endif + +/************************** Function Prototypes ******************************/ + +void Xil_DCacheInvalidateLine(u32 adr); +void Xil_DCacheFlushLine(u32 adr); +void Xil_DCacheStoreLine(u32 adr); +void Xil_ICacheInvalidateLine(u32 adr); + +void Xil_L1DCacheEnable(void); +void Xil_L1DCacheDisable(void); +void Xil_L1DCacheInvalidate(void); +void Xil_L1DCacheInvalidateLine(u32 adr); +void Xil_L1DCacheInvalidateRange(u32 adr, u32 len); +void Xil_L1DCacheFlush(void); +void Xil_L1DCacheFlushLine(u32 adr); +void Xil_L1DCacheFlushRange(u32 adr, u32 len); +void Xil_L1DCacheStoreLine(u32 adr); + +void Xil_L1ICacheEnable(void); +void Xil_L1ICacheDisable(void); +void Xil_L1ICacheInvalidate(void); +void Xil_L1ICacheInvalidateLine(u32 adr); +void Xil_L1ICacheInvalidateRange(u32 adr, u32 len); + +void Xil_L2CacheEnable(void); +void Xil_L2CacheDisable(void); +void Xil_L2CacheInvalidate(void); +void Xil_L2CacheInvalidateLine(u32 adr); +void Xil_L2CacheInvalidateRange(u32 adr, u32 len); +void Xil_L2CacheFlush(void); +void Xil_L2CacheFlushLine(u32 adr); +void Xil_L2CacheFlushRange(u32 adr, u32 len); +void Xil_L2CacheStoreLine(u32 adr); + +#ifdef __cplusplus +} +#endif + +#endif +/** +* @} End of "addtogroup a9_cache_apis". +*/ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_cache_vxworks.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_cache_vxworks.h new file mode 100644 index 0000000..7e2a7d9 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_cache_vxworks.h @@ -0,0 +1,89 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xil_cache_vxworks.h +* +* Contains the cache related functions for VxWorks that is wrapped by +* xil_cache. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date	 Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a hbm  12/11/09 Initial release
+*
+* 
+* +* @note +* +******************************************************************************/ + +#ifndef XIL_CACHE_VXWORKS_H +#define XIL_CACHE_VXWORKS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "vxWorks.h" +#include "vxLib.h" +#include "sysLibExtra.h" +#include "cacheLib.h" + +#if (CPU_FAMILY==PPC) + +#define Xil_DCacheEnable() cacheEnable(DATA_CACHE) + +#define Xil_DCacheDisable() cacheDisable(DATA_CACHE) + +#define Xil_DCacheInvalidateRange(Addr, Len) \ + cacheInvalidate(DATA_CACHE, (void *)(Addr), (Len)) + +#define Xil_DCacheFlushRange(Addr, Len) \ + cacheFlush(DATA_CACHE, (void *)(Addr), (Len)) + +#define Xil_ICacheEnable() cacheEnable(INSTRUCTION_CACHE) + +#define Xil_ICacheDisable() cacheDisable(INSTRUCTION_CACHE) + +#define Xil_ICacheInvalidateRange(Addr, Len) \ + cacheInvalidate(INSTRUCTION_CACHE, (void *)(Addr), (Len)) + + +#else +#error "Unknown processor / architecture. Must be PPC for VxWorks." +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_errata.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_errata.h new file mode 100644 index 0000000..c839b63 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_errata.h @@ -0,0 +1,127 @@ +/****************************************************************************** +* +* Copyright (C) 2013 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xil_errata.h +* +* @addtogroup a9_errata Cortex A9 Processor and pl310 Errata Support +* @{ +* Various ARM errata are handled in the standalone BSP. The implementation for +* errata handling follows ARM guidelines and is based on the open source Linux +* support for these errata. +* +* @note +* The errata handling is enabled by default. To disable handling of all the +* errata globally, un-define the macro ENABLE_ARM_ERRATA in xil_errata.h. To +* disable errata on a per-erratum basis, un-define relevant macros in +* xil_errata.h. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a srt  04/18/13 First release
+* 6.6   mus  12/07/17 Removed errata 753970, It fixes CR#989132.
+* 
+* +******************************************************************************/ +#ifndef XIL_ERRATA_H +#define XIL_ERRATA_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @name errata_definitions + * + * The errata conditions handled in the standalone BSP are listed below + * @{ + */ + +#define ENABLE_ARM_ERRATA 1 + +#ifdef ENABLE_ARM_ERRATA + +/** + * Errata No: 742230 + * Description: DMB operation may be faulty + */ +#define CONFIG_ARM_ERRATA_742230 1 + +/** + * Errata No: 743622 + * Description: Faulty hazard checking in the Store Buffer may lead + * to data corruption. + */ +#define CONFIG_ARM_ERRATA_743622 1 + +/** + * Errata No: 775420 + * Description: A data cache maintenance operation which aborts, + * might lead to deadlock + */ +#define CONFIG_ARM_ERRATA_775420 1 + +/** + * Errata No: 794073 + * Description: Speculative instruction fetches with MMU disabled + * might not comply with architectural requirements + */ +#define CONFIG_ARM_ERRATA_794073 1 + + +/** PL310 L2 Cache Errata */ + +/** + * Errata No: 588369 + * Description: Clean & Invalidate maintenance operations do not + * invalidate clean lines + */ +#define CONFIG_PL310_ERRATA_588369 1 + +/** + * Errata No: 727915 + * Description: Background Clean and Invalidate by Way operation + * can cause data corruption + */ +#define CONFIG_PL310_ERRATA_727915 1 + +/*@}*/ +#endif /* ENABLE_ARM_ERRATA */ + +#ifdef __cplusplus +} +#endif + +#endif /* XIL_ERRATA_H */ +/** +* @} End of "addtogroup a9_errata". +*/ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_exception.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_exception.h new file mode 100644 index 0000000..807f310 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_exception.h @@ -0,0 +1,285 @@ +/****************************************************************************** +* +* Copyright (C) 2015 - 2016 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xil_exception.h +* +* This header file contains ARM Cortex A53,A9,R5 specific exception related APIs. +* For exception related functions that can be used across all Xilinx supported +* processors, please use xil_exception.h. +* +* @addtogroup arm_exception_apis ARM Processor Exception Handling +* @{ +* ARM processors specific exception related APIs for cortex A53,A9 and R5 can +* utilized for enabling/disabling IRQ, registering/removing handler for +* exceptions or initializing exception vector table with null handler. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who      Date     Changes
+* ----- -------- -------- -----------------------------------------------
+* 5.2	pkp  	 28/05/15 First release
+* 6.0   mus      27/07/16 Consolidated file for a53,a9 and r5 processors
+* 6.7   mna      26/04/18 Add API Xil_GetExceptionRegisterHandler.
+* 6.7   asa      18/05/18 Update signature of API Xil_GetExceptionRegisterHandler.
+* 7.0   mus      01/03/19 Tweak Xil_ExceptionEnableMask and
+*                         Xil_ExceptionDisableMask macros to support legacy
+*                         examples for Cortexa72 EL3 exception level.
+* 
+* +******************************************************************************/ + +#ifndef XIL_EXCEPTION_H /* prevent circular inclusions */ +#define XIL_EXCEPTION_H /* by using protection macros */ + +/***************************** Include Files ********************************/ + +#include "xil_types.h" +#include "xpseudo_asm.h" +#include "bspconfig.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/************************** Constant Definitions ****************************/ + +#define XIL_EXCEPTION_FIQ XREG_CPSR_FIQ_ENABLE +#define XIL_EXCEPTION_IRQ XREG_CPSR_IRQ_ENABLE +#define XIL_EXCEPTION_ALL (XREG_CPSR_FIQ_ENABLE | XREG_CPSR_IRQ_ENABLE) + +#define XIL_EXCEPTION_ID_FIRST 0U +#if defined (__aarch64__) +#define XIL_EXCEPTION_ID_SYNC_INT 1U +#define XIL_EXCEPTION_ID_IRQ_INT 2U +#define XIL_EXCEPTION_ID_FIQ_INT 3U +#define XIL_EXCEPTION_ID_SERROR_ABORT_INT 4U +#define XIL_EXCEPTION_ID_LAST 5U +#else +#define XIL_EXCEPTION_ID_RESET 0U +#define XIL_EXCEPTION_ID_UNDEFINED_INT 1U +#define XIL_EXCEPTION_ID_SWI_INT 2U +#define XIL_EXCEPTION_ID_PREFETCH_ABORT_INT 3U +#define XIL_EXCEPTION_ID_DATA_ABORT_INT 4U +#define XIL_EXCEPTION_ID_IRQ_INT 5U +#define XIL_EXCEPTION_ID_FIQ_INT 6U +#define XIL_EXCEPTION_ID_LAST 6U +#endif + +/* + * XIL_EXCEPTION_ID_INT is defined for all Xilinx processors. + */ +#if defined (versal) && !defined(ARMR5) && EL3 +#define XIL_EXCEPTION_ID_INT XIL_EXCEPTION_ID_FIQ_INT +#else +#define XIL_EXCEPTION_ID_INT XIL_EXCEPTION_ID_IRQ_INT +#endif + +/**************************** Type Definitions ******************************/ + +/** + * This typedef is the exception handler function. + */ +typedef void (*Xil_ExceptionHandler)(void *data); +typedef void (*Xil_InterruptHandler)(void *data); + +/***************** Macros (Inline Functions) Definitions ********************/ + +/****************************************************************************/ +/** +* @brief Enable Exceptions. +* +* @param Mask: Value for enabling the exceptions. +* +* @return None. +* +* @note If bit is 0, exception is enabled. +* C-Style signature: void Xil_ExceptionEnableMask(Mask) +* +******************************************************************************/ +#if defined (versal) && !defined(ARMR5) && EL3 +/* + * Cortexa72 processor in versal is coupled with GIC-500, and GIC-500 supports + * only FIQ at EL3. Hence, tweaking this macro to always enable FIQ + * ignoring argument passed by user. + */ +#define Xil_ExceptionEnableMask(Mask) \ + mtcpsr(mfcpsr() & ~ ((XIL_EXCEPTION_FIQ) & XIL_EXCEPTION_ALL)) +#elif defined (__GNUC__) || defined (__ICCARM__) +#define Xil_ExceptionEnableMask(Mask) \ + mtcpsr(mfcpsr() & ~ ((Mask) & XIL_EXCEPTION_ALL)) +#else +#define Xil_ExceptionEnableMask(Mask) \ + { \ + register u32 Reg __asm("cpsr"); \ + mtcpsr((Reg) & (~((Mask) & XIL_EXCEPTION_ALL))); \ + } +#endif +/****************************************************************************/ +/** +* @brief Enable the IRQ exception. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +#if defined (versal) && !defined(ARMR5) && EL3 +#define Xil_ExceptionEnable() \ + Xil_ExceptionEnableMask(XIL_EXCEPTION_FIQ) +#else +#define Xil_ExceptionEnable() \ + Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ) +#endif + +/****************************************************************************/ +/** +* @brief Disable Exceptions. +* +* @param Mask: Value for disabling the exceptions. +* +* @return None. +* +* @note If bit is 1, exception is disabled. +* C-Style signature: Xil_ExceptionDisableMask(Mask) +* +******************************************************************************/ +#if defined (versal) && !defined(ARMR5) && EL3 +/* + * Cortexa72 processor in versal is coupled with GIC-500, and GIC-500 supports + * only FIQ at EL3. Hence, tweaking this macro to always disable FIQ + * ignoring argument passed by user. + */ +#define Xil_ExceptionDisableMask(Mask) \ + mtcpsr(mfcpsr() | ((XIL_EXCEPTION_FIQ) & XIL_EXCEPTION_ALL)) +#elif defined (__GNUC__) || defined (__ICCARM__) +#define Xil_ExceptionDisableMask(Mask) \ + mtcpsr(mfcpsr() | ((Mask) & XIL_EXCEPTION_ALL)) +#else +#define Xil_ExceptionDisableMask(Mask) \ + { \ + register u32 Reg __asm("cpsr"); \ + mtcpsr((Reg) | ((Mask) & XIL_EXCEPTION_ALL)); \ + } +#endif +/****************************************************************************/ +/** +* Disable the IRQ exception. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +#define Xil_ExceptionDisable() \ + Xil_ExceptionDisableMask(XIL_EXCEPTION_IRQ) + +#if !defined (__aarch64__) && !defined (ARMA53_32) +/****************************************************************************/ +/** +* @brief Enable nested interrupts by clearing the I and F bits in CPSR. This +* API is defined for cortex-a9 and cortex-r5. +* +* @return None. +* +* @note This macro is supposed to be used from interrupt handlers. In the +* interrupt handler the interrupts are disabled by default (I and F +* are 1). To allow nesting of interrupts, this macro should be +* used. It clears the I and F bits by changing the ARM mode to +* system mode. Once these bits are cleared and provided the +* preemption of interrupt conditions are met in the GIC, nesting of +* interrupts will start happening. +* Caution: This macro must be used with caution. Before calling this +* macro, the user must ensure that the source of the current IRQ +* is appropriately cleared. Otherwise, as soon as we clear the I and +* F bits, there can be an infinite loop of interrupts with an +* eventual crash (all the stack space getting consumed). +******************************************************************************/ +#define Xil_EnableNestedInterrupts() \ + __asm__ __volatile__ ("stmfd sp!, {lr}"); \ + __asm__ __volatile__ ("mrs lr, spsr"); \ + __asm__ __volatile__ ("stmfd sp!, {lr}"); \ + __asm__ __volatile__ ("msr cpsr_c, #0x1F"); \ + __asm__ __volatile__ ("stmfd sp!, {lr}"); + +/****************************************************************************/ +/** +* @brief Disable the nested interrupts by setting the I and F bits. This API +* is defined for cortex-a9 and cortex-r5. +* +* @return None. +* +* @note This macro is meant to be called in the interrupt service routines. +* This macro cannot be used independently. It can only be used when +* nesting of interrupts have been enabled by using the macro +* Xil_EnableNestedInterrupts(). In a typical flow, the user first +* calls the Xil_EnableNestedInterrupts in the ISR at the appropriate +* point. The user then must call this macro before exiting the interrupt +* service routine. This macro puts the ARM back in IRQ/FIQ mode and +* hence sets back the I and F bits. +******************************************************************************/ +#define Xil_DisableNestedInterrupts() \ + __asm__ __volatile__ ("ldmfd sp!, {lr}"); \ + __asm__ __volatile__ ("msr cpsr_c, #0x92"); \ + __asm__ __volatile__ ("ldmfd sp!, {lr}"); \ + __asm__ __volatile__ ("msr spsr_cxsf, lr"); \ + __asm__ __volatile__ ("ldmfd sp!, {lr}"); \ + +#endif +/************************** Variable Definitions ****************************/ + +/************************** Function Prototypes *****************************/ + +extern void Xil_ExceptionRegisterHandler(u32 Exception_id, + Xil_ExceptionHandler Handler, + void *Data); + +extern void Xil_ExceptionRemoveHandler(u32 Exception_id); +extern void Xil_GetExceptionRegisterHandler(u32 Exception_id, + Xil_ExceptionHandler *Handler, void **Data); + +extern void Xil_ExceptionInit(void); +#if defined (__aarch64__) +void Xil_SyncAbortHandler(void *CallBackRef); +void Xil_SErrorAbortHandler(void *CallBackRef); +#else +extern void Xil_DataAbortHandler(void *CallBackRef); +extern void Xil_PrefetchAbortHandler(void *CallBackRef); +extern void Xil_UndefinedExceptionHandler(void *CallBackRef); +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* XIL_EXCEPTION_H */ +/** +* @} End of "addtogroup arm_exception_apis". +*/ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_hal.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_hal.h new file mode 100644 index 0000000..e8971c9 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_hal.h @@ -0,0 +1,65 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xil_hal.h +* +* Contains all the HAL header files. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date	 Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a hbm  07/28/09 Initial release
+*
+* 
+* +* @note +* +******************************************************************************/ + +#ifndef XIL_HAL_H +#define XIL_HAL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "xil_cache.h" +#include "xil_io.h" +#include "xil_assert.h" +#include "xil_exception.h" +#include "xil_types.h" + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_io.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_io.h new file mode 100644 index 0000000..00207cf --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_io.h @@ -0,0 +1,341 @@ +/****************************************************************************** +* +* Copyright (C) 2014 - 2016 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xil_io.h +* +* @addtogroup common_io_interfacing_apis Register IO interfacing APIs +* +* The xil_io.h file contains the interface for the general I/O component, which +* encapsulates the Input/Output functions for the processors that do not +* require any special I/O handling. +* +* @{ +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who      Date     Changes
+* ----- -------- -------- -----------------------------------------------
+* 5.00 	pkp  	 05/29/14 First release
+* 6.00  mus      08/19/16 Remove checking of __LITTLE_ENDIAN__ flag for
+*                         ARM processors
+* 
+******************************************************************************/ + +#ifndef XIL_IO_H /* prevent circular inclusions */ +#define XIL_IO_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +#include "xil_types.h" +#include "xil_printf.h" + +#if defined (__MICROBLAZE__) +#include "mb_interface.h" +#else +#include "xpseudo_asm.h" +#endif + +/************************** Function Prototypes ******************************/ +u16 Xil_EndianSwap16(u16 Data); +u32 Xil_EndianSwap32(u32 Data); +#ifdef ENABLE_SAFETY +extern u32 XStl_RegUpdate(u32 RegAddr, u32 RegVal); +#endif + +/***************** Macros (Inline Functions) Definitions *********************/ +#if defined __GNUC__ +#if defined (__MICROBLAZE__) +# define INST_SYNC mbar(0) +# define DATA_SYNC mbar(1) +# else +# define SYNCHRONIZE_IO dmb() +# define INST_SYNC isb() +# define DATA_SYNC dsb() +# endif +#else +# define SYNCHRONIZE_IO +# define INST_SYNC +# define DATA_SYNC +# define INST_SYNC +# define DATA_SYNC +#endif + +#if defined (__GNUC__) || defined (__ICCARM__) || defined (__MICROBLAZE__) +#define INLINE inline +#else +#define INLINE __inline +#endif + +/*****************************************************************************/ +/** +* +* @brief Performs an input operation for a memory location by reading +* from the specified address and returning the 8 bit Value read from +* that address. +* +* @param Addr: contains the address to perform the input operation +* +* @return The 8 bit Value read from the specified input address. + +* +******************************************************************************/ +static INLINE u8 Xil_In8(UINTPTR Addr) +{ + return *(volatile u8 *) Addr; +} + +/*****************************************************************************/ +/** +* +* @brief Performs an input operation for a memory location by reading from +* the specified address and returning the 16 bit Value read from that +* address. +* +* @param Addr: contains the address to perform the input operation +* +* @return The 16 bit Value read from the specified input address. +* +******************************************************************************/ +static INLINE u16 Xil_In16(UINTPTR Addr) +{ + return *(volatile u16 *) Addr; +} + +/*****************************************************************************/ +/** +* +* @brief Performs an input operation for a memory location by +* reading from the specified address and returning the 32 bit Value +* read from that address. +* +* @param Addr: contains the address to perform the input operation +* +* @return The 32 bit Value read from the specified input address. +* +******************************************************************************/ +static INLINE u32 Xil_In32(UINTPTR Addr) +{ + return *(volatile u32 *) Addr; +} + +/*****************************************************************************/ +/** +* +* @brief Performs an input operation for a memory location by reading the +* 64 bit Value read from that address. +* +* +* @param Addr: contains the address to perform the input operation +* +* @return The 64 bit Value read from the specified input address. +* +******************************************************************************/ +static INLINE u64 Xil_In64(UINTPTR Addr) +{ + return *(volatile u64 *) Addr; +} + +/*****************************************************************************/ +/** +* +* @brief Performs an output operation for an memory location by +* writing the 8 bit Value to the the specified address. +* +* @param Addr: contains the address to perform the output operation +* @param Value: contains the 8 bit Value to be written at the specified +* address. +* +* @return None. +* +******************************************************************************/ +static INLINE void Xil_Out8(UINTPTR Addr, u8 Value) +{ + volatile u8 *LocalAddr = (volatile u8 *)Addr; + *LocalAddr = Value; +} + +/*****************************************************************************/ +/** +* +* @brief Performs an output operation for a memory location by writing the +* 16 bit Value to the the specified address. +* +* @param Addr contains the address to perform the output operation +* @param Value contains the Value to be written at the specified address. +* +* @return None. +* +******************************************************************************/ +static INLINE void Xil_Out16(UINTPTR Addr, u16 Value) +{ + volatile u16 *LocalAddr = (volatile u16 *)Addr; + *LocalAddr = Value; +} + +/*****************************************************************************/ +/** +* +* @brief Performs an output operation for a memory location by writing the +* 32 bit Value to the the specified address. +* +* @param Addr contains the address to perform the output operation +* @param Value contains the 32 bit Value to be written at the specified +* address. +* +* @return None. +* +******************************************************************************/ +static INLINE void Xil_Out32(UINTPTR Addr, u32 Value) +{ +#ifndef ENABLE_SAFETY + volatile u32 *LocalAddr = (volatile u32 *)Addr; + *LocalAddr = Value; +#else + XStl_RegUpdate(Addr, Value); +#endif +} + +/*****************************************************************************/ +/** +* +* @brief Performs an output operation for a memory location by writing the +* 64 bit Value to the the specified address. +* +* @param Addr contains the address to perform the output operation +* @param Value contains 64 bit Value to be written at the specified address. +* +* @return None. +* +******************************************************************************/ +static INLINE void Xil_Out64(UINTPTR Addr, u64 Value) +{ + volatile u64 *LocalAddr = (volatile u64 *)Addr; + *LocalAddr = Value; +} + +#if defined (__MICROBLAZE__) +#ifdef __LITTLE_ENDIAN__ +# define Xil_In16LE Xil_In16 +# define Xil_In32LE Xil_In32 +# define Xil_Out16LE Xil_Out16 +# define Xil_Out32LE Xil_Out32 +# define Xil_Htons Xil_EndianSwap16 +# define Xil_Htonl Xil_EndianSwap32 +# define Xil_Ntohs Xil_EndianSwap16 +# define Xil_Ntohl Xil_EndianSwap32 +# else +# define Xil_In16BE Xil_In16 +# define Xil_In32BE Xil_In32 +# define Xil_Out16BE Xil_Out16 +# define Xil_Out32BE Xil_Out32 +# define Xil_Htons(Data) (Data) +# define Xil_Htonl(Data) (Data) +# define Xil_Ntohs(Data) (Data) +# define Xil_Ntohl(Data) (Data) +#endif +#else +# define Xil_In16LE Xil_In16 +# define Xil_In32LE Xil_In32 +# define Xil_Out16LE Xil_Out16 +# define Xil_Out32LE Xil_Out32 +# define Xil_Htons Xil_EndianSwap16 +# define Xil_Htonl Xil_EndianSwap32 +# define Xil_Ntohs Xil_EndianSwap16 +# define Xil_Ntohl Xil_EndianSwap32 +#endif + +#if defined (__MICROBLAZE__) +#ifdef __LITTLE_ENDIAN__ +static INLINE u16 Xil_In16BE(UINTPTR Addr) +#else +static INLINE u16 Xil_In16LE(UINTPTR Addr) +#endif +#else +static INLINE u16 Xil_In16BE(UINTPTR Addr) +#endif +{ + u16 value = Xil_In16(Addr); + return Xil_EndianSwap16(value); +} + +#if defined (__MICROBLAZE__) +#ifdef __LITTLE_ENDIAN__ +static INLINE u32 Xil_In32BE(UINTPTR Addr) +#else +static INLINE u32 Xil_In32LE(UINTPTR Addr) +#endif +#else +static INLINE u32 Xil_In32BE(UINTPTR Addr) +#endif +{ + u32 value = Xil_In32(Addr); + return Xil_EndianSwap32(value); +} + +#if defined (__MICROBLAZE__) +#ifdef __LITTLE_ENDIAN__ +static INLINE void Xil_Out16BE(UINTPTR Addr, u16 Value) +#else +static INLINE void Xil_Out16LE(UINTPTR Addr, u16 Value) +#endif +#else +static INLINE void Xil_Out16BE(UINTPTR Addr, u16 Value) +#endif +{ + Value = Xil_EndianSwap16(Value); + Xil_Out16(Addr, Value); +} + +#if defined (__MICROBLAZE__) +#ifdef __LITTLE_ENDIAN__ +static INLINE void Xil_Out32BE(UINTPTR Addr, u32 Value) +#else +static INLINE void Xil_Out32LE(UINTPTR Addr, u32 Value) +#endif +#else +static INLINE void Xil_Out32BE(UINTPTR Addr, u32 Value) +#endif +{ + Value = Xil_EndianSwap32(Value); + Xil_Out32(Addr, Value); +} + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** +* @} End of "addtogroup common_io_interfacing_apis". +*/ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_macroback.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_macroback.h new file mode 100644 index 0000000..b245c18 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_macroback.h @@ -0,0 +1,1056 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ + +/*********************************************************************/ +/** + * @file xil_macroback.h + * + * This header file is meant to bring back the removed _m macros. + * This header file must be included last. + * The following macros are not defined here due to the driver change: + * XGpio_mSetDataDirection + * XGpio_mGetDataReg + * XGpio_mSetDataReg + * XIIC_RESET + * XIIC_CLEAR_STATS + * XSpi_mReset + * XSysAce_mSetCfgAddr + * XSysAce_mIsCfgDone + * XTft_mSetPixel + * XTft_mGetPixel + * XWdtTb_mEnableWdt + * XWdtTb_mDisbleWdt + * XWdtTb_mRestartWdt + * XWdtTb_mGetTimebaseReg + * XWdtTb_mHasReset + * + * Please refer the corresonding driver document for replacement. + * + *********************************************************************/ + +#ifndef XIL_MACROBACK_H +#define XIL_MACROBACK_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*********************************************************************/ +/** + * Macros for Driver XCan + * + *********************************************************************/ +#ifndef XCan_mReadReg +#define XCan_mReadReg XCan_ReadReg +#endif + +#ifndef XCan_mWriteReg +#define XCan_mWriteReg XCan_WriteReg +#endif + +#ifndef XCan_mIsTxDone +#define XCan_mIsTxDone XCan_IsTxDone +#endif + +#ifndef XCan_mIsTxFifoFull +#define XCan_mIsTxFifoFull XCan_IsTxFifoFull +#endif + +#ifndef XCan_mIsHighPriorityBufFull +#define XCan_mIsHighPriorityBufFull XCan_IsHighPriorityBufFull +#endif + +#ifndef XCan_mIsRxEmpty +#define XCan_mIsRxEmpty XCan_IsRxEmpty +#endif + +#ifndef XCan_mIsAcceptFilterBusy +#define XCan_mIsAcceptFilterBusy XCan_IsAcceptFilterBusy +#endif + +#ifndef XCan_mCreateIdValue +#define XCan_mCreateIdValue XCan_CreateIdValue +#endif + +#ifndef XCan_mCreateDlcValue +#define XCan_mCreateDlcValue XCan_CreateDlcValue +#endif + +/*********************************************************************/ +/** + * Macros for Driver XDmaCentral + * + *********************************************************************/ +#ifndef XDmaCentral_mWriteReg +#define XDmaCentral_mWriteReg XDmaCentral_WriteReg +#endif + +#ifndef XDmaCentral_mReadReg +#define XDmaCentral_mReadReg XDmaCentral_ReadReg +#endif + +/*********************************************************************/ +/** + * Macros for Driver XDsAdc + * + *********************************************************************/ +#ifndef XDsAdc_mWriteReg +#define XDsAdc_mWriteReg XDsAdc_WriteReg +#endif + +#ifndef XDsAdc_mReadReg +#define XDsAdc_mReadReg XDsAdc_ReadReg +#endif + +#ifndef XDsAdc_mIsEmpty +#define XDsAdc_mIsEmpty XDsAdc_IsEmpty +#endif + +#ifndef XDsAdc_mSetFstmReg +#define XDsAdc_mSetFstmReg XDsAdc_SetFstmReg +#endif + +#ifndef XDsAdc_mGetFstmReg +#define XDsAdc_mGetFstmReg XDsAdc_GetFstmReg +#endif + +#ifndef XDsAdc_mEnableConversion +#define XDsAdc_mEnableConversion XDsAdc_EnableConversion +#endif + +#ifndef XDsAdc_mDisableConversion +#define XDsAdc_mDisableConversion XDsAdc_DisableConversion +#endif + +#ifndef XDsAdc_mGetFifoOccyReg +#define XDsAdc_mGetFifoOccyReg XDsAdc_GetFifoOccyReg +#endif + +/*********************************************************************/ +/** + * Macros for Driver XDsDac + * + *********************************************************************/ +#ifndef XDsDac_mWriteReg +#define XDsDac_mWriteReg XDsDac_WriteReg +#endif + +#ifndef XDsDac_mReadReg +#define XDsDac_mReadReg XDsDac_ReadReg +#endif + +#ifndef XDsDac_mIsEmpty +#define XDsDac_mIsEmpty XDsDac_IsEmpty +#endif + +#ifndef XDsDac_mFifoIsFull +#define XDsDac_mFifoIsFull XDsDac_FifoIsFull +#endif + +#ifndef XDsDac_mGetVacancy +#define XDsDac_mGetVacancy XDsDac_GetVacancy +#endif + +/*********************************************************************/ +/** + * Macros for Driver XEmacLite + * + *********************************************************************/ +#ifndef XEmacLite_mReadReg +#define XEmacLite_mReadReg XEmacLite_ReadReg +#endif + +#ifndef XEmacLite_mWriteReg +#define XEmacLite_mWriteReg XEmacLite_WriteReg +#endif + +#ifndef XEmacLite_mGetTxStatus +#define XEmacLite_mGetTxStatus XEmacLite_GetTxStatus +#endif + +#ifndef XEmacLite_mSetTxStatus +#define XEmacLite_mSetTxStatus XEmacLite_SetTxStatus +#endif + +#ifndef XEmacLite_mGetRxStatus +#define XEmacLite_mGetRxStatus XEmacLite_GetRxStatus +#endif + +#ifndef XEmacLite_mSetRxStatus +#define XEmacLite_mSetRxStatus XEmacLite_SetRxStatus +#endif + +#ifndef XEmacLite_mIsTxDone +#define XEmacLite_mIsTxDone XEmacLite_IsTxDone +#endif + +#ifndef XEmacLite_mIsRxEmpty +#define XEmacLite_mIsRxEmpty XEmacLite_IsRxEmpty +#endif + +#ifndef XEmacLite_mNextTransmitAddr +#define XEmacLite_mNextTransmitAddr XEmacLite_NextTransmitAddr +#endif + +#ifndef XEmacLite_mNextReceiveAddr +#define XEmacLite_mNextReceiveAddr XEmacLite_NextReceiveAddr +#endif + +#ifndef XEmacLite_mIsMdioConfigured +#define XEmacLite_mIsMdioConfigured XEmacLite_IsMdioConfigured +#endif + +#ifndef XEmacLite_mIsLoopbackConfigured +#define XEmacLite_mIsLoopbackConfigured XEmacLite_IsLoopbackConfigured +#endif + +#ifndef XEmacLite_mGetReceiveDataLength +#define XEmacLite_mGetReceiveDataLength XEmacLite_GetReceiveDataLength +#endif + +#ifndef XEmacLite_mGetTxActive +#define XEmacLite_mGetTxActive XEmacLite_GetTxActive +#endif + +#ifndef XEmacLite_mSetTxActive +#define XEmacLite_mSetTxActive XEmacLite_SetTxActive +#endif + +/*********************************************************************/ +/** + * Macros for Driver XGpio + * + *********************************************************************/ +#ifndef XGpio_mWriteReg +#define XGpio_mWriteReg XGpio_WriteReg +#endif + +#ifndef XGpio_mReadReg +#define XGpio_mReadReg XGpio_ReadReg +#endif + +/*********************************************************************/ +/** + * Macros for Driver XHwIcap + * + *********************************************************************/ +#ifndef XHwIcap_mFifoWrite +#define XHwIcap_mFifoWrite XHwIcap_FifoWrite +#endif + +#ifndef XHwIcap_mFifoRead +#define XHwIcap_mFifoRead XHwIcap_FifoRead +#endif + +#ifndef XHwIcap_mSetSizeReg +#define XHwIcap_mSetSizeReg XHwIcap_SetSizeReg +#endif + +#ifndef XHwIcap_mGetControlReg +#define XHwIcap_mGetControlReg XHwIcap_GetControlReg +#endif + +#ifndef XHwIcap_mStartConfig +#define XHwIcap_mStartConfig XHwIcap_StartConfig +#endif + +#ifndef XHwIcap_mStartReadBack +#define XHwIcap_mStartReadBack XHwIcap_StartReadBack +#endif + +#ifndef XHwIcap_mGetStatusReg +#define XHwIcap_mGetStatusReg XHwIcap_GetStatusReg +#endif + +#ifndef XHwIcap_mIsTransferDone +#define XHwIcap_mIsTransferDone XHwIcap_IsTransferDone +#endif + +#ifndef XHwIcap_mIsDeviceBusy +#define XHwIcap_mIsDeviceBusy XHwIcap_IsDeviceBusy +#endif + +#ifndef XHwIcap_mIntrGlobalEnable +#define XHwIcap_mIntrGlobalEnable XHwIcap_IntrGlobalEnable +#endif + +#ifndef XHwIcap_mIntrGlobalDisable +#define XHwIcap_mIntrGlobalDisable XHwIcap_IntrGlobalDisable +#endif + +#ifndef XHwIcap_mIntrGetStatus +#define XHwIcap_mIntrGetStatus XHwIcap_IntrGetStatus +#endif + +#ifndef XHwIcap_mIntrDisable +#define XHwIcap_mIntrDisable XHwIcap_IntrDisable +#endif + +#ifndef XHwIcap_mIntrEnable +#define XHwIcap_mIntrEnable XHwIcap_IntrEnable +#endif + +#ifndef XHwIcap_mIntrGetEnabled +#define XHwIcap_mIntrGetEnabled XHwIcap_IntrGetEnabled +#endif + +#ifndef XHwIcap_mIntrClear +#define XHwIcap_mIntrClear XHwIcap_IntrClear +#endif + +#ifndef XHwIcap_mGetWrFifoVacancy +#define XHwIcap_mGetWrFifoVacancy XHwIcap_GetWrFifoVacancy +#endif + +#ifndef XHwIcap_mGetRdFifoOccupancy +#define XHwIcap_mGetRdFifoOccupancy XHwIcap_GetRdFifoOccupancy +#endif + +#ifndef XHwIcap_mSliceX2Col +#define XHwIcap_mSliceX2Col XHwIcap_SliceX2Col +#endif + +#ifndef XHwIcap_mSliceY2Row +#define XHwIcap_mSliceY2Row XHwIcap_SliceY2Row +#endif + +#ifndef XHwIcap_mSliceXY2Slice +#define XHwIcap_mSliceXY2Slice XHwIcap_SliceXY2Slice +#endif + +#ifndef XHwIcap_mReadReg +#define XHwIcap_mReadReg XHwIcap_ReadReg +#endif + +#ifndef XHwIcap_mWriteReg +#define XHwIcap_mWriteReg XHwIcap_WriteReg +#endif + +/*********************************************************************/ +/** + * Macros for Driver XIic + * + *********************************************************************/ +#ifndef XIic_mReadReg +#define XIic_mReadReg XIic_ReadReg +#endif + +#ifndef XIic_mWriteReg +#define XIic_mWriteReg XIic_WriteReg +#endif + +#ifndef XIic_mEnterCriticalRegion +#define XIic_mEnterCriticalRegion XIic_IntrGlobalDisable +#endif + +#ifndef XIic_mExitCriticalRegion +#define XIic_mExitCriticalRegion XIic_IntrGlobalEnable +#endif + +#ifndef XIIC_GINTR_DISABLE +#define XIIC_GINTR_DISABLE XIic_IntrGlobalDisable +#endif + +#ifndef XIIC_GINTR_ENABLE +#define XIIC_GINTR_ENABLE XIic_IntrGlobalEnable +#endif + +#ifndef XIIC_IS_GINTR_ENABLED +#define XIIC_IS_GINTR_ENABLED XIic_IsIntrGlobalEnabled +#endif + +#ifndef XIIC_WRITE_IISR +#define XIIC_WRITE_IISR XIic_WriteIisr +#endif + +#ifndef XIIC_READ_IISR +#define XIIC_READ_IISR XIic_ReadIisr +#endif + +#ifndef XIIC_WRITE_IIER +#define XIIC_WRITE_IIER XIic_WriteIier +#endif + +#ifndef XIic_mClearIisr +#define XIic_mClearIisr XIic_ClearIisr +#endif + +#ifndef XIic_mSend7BitAddress +#define XIic_mSend7BitAddress XIic_Send7BitAddress +#endif + +#ifndef XIic_mDynSend7BitAddress +#define XIic_mDynSend7BitAddress XIic_DynSend7BitAddress +#endif + +#ifndef XIic_mDynSendStartStopAddress +#define XIic_mDynSendStartStopAddress XIic_DynSendStartStopAddress +#endif + +#ifndef XIic_mDynSendStop +#define XIic_mDynSendStop XIic_DynSendStop +#endif + +#ifndef XIic_mSend10BitAddrByte1 +#define XIic_mSend10BitAddrByte1 XIic_Send10BitAddrByte1 +#endif + +#ifndef XIic_mSend10BitAddrByte2 +#define XIic_mSend10BitAddrByte2 XIic_Send10BitAddrByte2 +#endif + +#ifndef XIic_mSend7BitAddr +#define XIic_mSend7BitAddr XIic_Send7BitAddr +#endif + +#ifndef XIic_mDisableIntr +#define XIic_mDisableIntr XIic_DisableIntr +#endif + +#ifndef XIic_mEnableIntr +#define XIic_mEnableIntr XIic_EnableIntr +#endif + +#ifndef XIic_mClearIntr +#define XIic_mClearIntr XIic_ClearIntr +#endif + +#ifndef XIic_mClearEnableIntr +#define XIic_mClearEnableIntr XIic_ClearEnableIntr +#endif + +#ifndef XIic_mFlushRxFifo +#define XIic_mFlushRxFifo XIic_FlushRxFifo +#endif + +#ifndef XIic_mFlushTxFifo +#define XIic_mFlushTxFifo XIic_FlushTxFifo +#endif + +#ifndef XIic_mReadRecvByte +#define XIic_mReadRecvByte XIic_ReadRecvByte +#endif + +#ifndef XIic_mWriteSendByte +#define XIic_mWriteSendByte XIic_WriteSendByte +#endif + +#ifndef XIic_mSetControlRegister +#define XIic_mSetControlRegister XIic_SetControlRegister +#endif + +/*********************************************************************/ +/** + * Macros for Driver XIntc + * + *********************************************************************/ +#ifndef XIntc_mMasterEnable +#define XIntc_mMasterEnable XIntc_MasterEnable +#endif + +#ifndef XIntc_mMasterDisable +#define XIntc_mMasterDisable XIntc_MasterDisable +#endif + +#ifndef XIntc_mEnableIntr +#define XIntc_mEnableIntr XIntc_EnableIntr +#endif + +#ifndef XIntc_mDisableIntr +#define XIntc_mDisableIntr XIntc_DisableIntr +#endif + +#ifndef XIntc_mAckIntr +#define XIntc_mAckIntr XIntc_AckIntr +#endif + +#ifndef XIntc_mGetIntrStatus +#define XIntc_mGetIntrStatus XIntc_GetIntrStatus +#endif + +/*********************************************************************/ +/** + * Macros for Driver XLlDma + * + *********************************************************************/ +#ifndef XLlDma_mBdRead +#define XLlDma_mBdRead XLlDma_BdRead +#endif + +#ifndef XLlDma_mBdWrite +#define XLlDma_mBdWrite XLlDma_BdWrite +#endif + +#ifndef XLlDma_mWriteReg +#define XLlDma_mWriteReg XLlDma_WriteReg +#endif + +#ifndef XLlDma_mReadReg +#define XLlDma_mReadReg XLlDma_ReadReg +#endif + +#ifndef XLlDma_mBdClear +#define XLlDma_mBdClear XLlDma_BdClear +#endif + +#ifndef XLlDma_mBdSetStsCtrl +#define XLlDma_mBdSetStsCtrl XLlDma_BdSetStsCtrl +#endif + +#ifndef XLlDma_mBdGetStsCtrl +#define XLlDma_mBdGetStsCtrl XLlDma_BdGetStsCtrl +#endif + +#ifndef XLlDma_mBdSetLength +#define XLlDma_mBdSetLength XLlDma_BdSetLength +#endif + +#ifndef XLlDma_mBdGetLength +#define XLlDma_mBdGetLength XLlDma_BdGetLength +#endif + +#ifndef XLlDma_mBdSetId +#define XLlDma_mBdSetId XLlDma_BdSetId +#endif + +#ifndef XLlDma_mBdGetId +#define XLlDma_mBdGetId XLlDma_BdGetId +#endif + +#ifndef XLlDma_mBdSetBufAddr +#define XLlDma_mBdSetBufAddr XLlDma_BdSetBufAddr +#endif + +#ifndef XLlDma_mBdGetBufAddr +#define XLlDma_mBdGetBufAddr XLlDma_BdGetBufAddr +#endif + +#ifndef XLlDma_mBdGetLength +#define XLlDma_mBdGetLength XLlDma_BdGetLength +#endif + +#ifndef XLlDma_mGetTxRing +#define XLlDma_mGetTxRing XLlDma_GetTxRing +#endif + +#ifndef XLlDma_mGetRxRing +#define XLlDma_mGetRxRing XLlDma_GetRxRing +#endif + +#ifndef XLlDma_mGetCr +#define XLlDma_mGetCr XLlDma_GetCr +#endif + +#ifndef XLlDma_mSetCr +#define XLlDma_mSetCr XLlDma_SetCr +#endif + +#ifndef XLlDma_mBdRingCntCalc +#define XLlDma_mBdRingCntCalc XLlDma_BdRingCntCalc +#endif + +#ifndef XLlDma_mBdRingMemCalc +#define XLlDma_mBdRingMemCalc XLlDma_BdRingMemCalc +#endif + +#ifndef XLlDma_mBdRingGetCnt +#define XLlDma_mBdRingGetCnt XLlDma_BdRingGetCnt +#endif + +#ifndef XLlDma_mBdRingGetFreeCnt +#define XLlDma_mBdRingGetFreeCnt XLlDma_BdRingGetFreeCnt +#endif + +#ifndef XLlDma_mBdRingSnapShotCurrBd +#define XLlDma_mBdRingSnapShotCurrBd XLlDma_BdRingSnapShotCurrBd +#endif + +#ifndef XLlDma_mBdRingNext +#define XLlDma_mBdRingNext XLlDma_BdRingNext +#endif + +#ifndef XLlDma_mBdRingPrev +#define XLlDma_mBdRingPrev XLlDma_BdRingPrev +#endif + +#ifndef XLlDma_mBdRingGetSr +#define XLlDma_mBdRingGetSr XLlDma_BdRingGetSr +#endif + +#ifndef XLlDma_mBdRingSetSr +#define XLlDma_mBdRingSetSr XLlDma_BdRingSetSr +#endif + +#ifndef XLlDma_mBdRingGetCr +#define XLlDma_mBdRingGetCr XLlDma_BdRingGetCr +#endif + +#ifndef XLlDma_mBdRingSetCr +#define XLlDma_mBdRingSetCr XLlDma_BdRingSetCr +#endif + +#ifndef XLlDma_mBdRingBusy +#define XLlDma_mBdRingBusy XLlDma_BdRingBusy +#endif + +#ifndef XLlDma_mBdRingIntEnable +#define XLlDma_mBdRingIntEnable XLlDma_BdRingIntEnable +#endif + +#ifndef XLlDma_mBdRingIntDisable +#define XLlDma_mBdRingIntDisable XLlDma_BdRingIntDisable +#endif + +#ifndef XLlDma_mBdRingIntGetEnabled +#define XLlDma_mBdRingIntGetEnabled XLlDma_BdRingIntGetEnabled +#endif + +#ifndef XLlDma_mBdRingGetIrq +#define XLlDma_mBdRingGetIrq XLlDma_BdRingGetIrq +#endif + +#ifndef XLlDma_mBdRingAckIrq +#define XLlDma_mBdRingAckIrq XLlDma_BdRingAckIrq +#endif + +/*********************************************************************/ +/** + * Macros for Driver XMbox + * + *********************************************************************/ +#ifndef XMbox_mWriteReg +#define XMbox_mWriteReg XMbox_WriteReg +#endif + +#ifndef XMbox_mReadReg +#define XMbox_mReadReg XMbox_ReadReg +#endif + +#ifndef XMbox_mWriteMBox +#define XMbox_mWriteMBox XMbox_WriteMBox +#endif + +#ifndef XMbox_mReadMBox +#define XMbox_mReadMBox XMbox_ReadMBox +#endif + +#ifndef XMbox_mFSLReadMBox +#define XMbox_mFSLReadMBox XMbox_FSLReadMBox +#endif + +#ifndef XMbox_mFSLWriteMBox +#define XMbox_mFSLWriteMBox XMbox_FSLWriteMBox +#endif + +#ifndef XMbox_mFSLIsEmpty +#define XMbox_mFSLIsEmpty XMbox_FSLIsEmpty +#endif + +#ifndef XMbox_mFSLIsFull +#define XMbox_mFSLIsFull XMbox_FSLIsFull +#endif + +#ifndef XMbox_mIsEmpty +#define XMbox_mIsEmpty XMbox_IsEmptyHw +#endif + +#ifndef XMbox_mIsFull +#define XMbox_mIsFull XMbox_IsFullHw +#endif + +/*********************************************************************/ +/** + * Macros for Driver XMpmc + * + *********************************************************************/ +#ifndef XMpmc_mReadReg +#define XMpmc_mReadReg XMpmc_ReadReg +#endif + +#ifndef XMpmc_mWriteReg +#define XMpmc_mWriteReg XMpmc_WriteReg +#endif + +/*********************************************************************/ +/** + * Macros for Driver XMutex + * + *********************************************************************/ +#ifndef XMutex_mWriteReg +#define XMutex_mWriteReg XMutex_WriteReg +#endif + +#ifndef XMutex_mReadReg +#define XMutex_mReadReg XMutex_ReadReg +#endif + +/*********************************************************************/ +/** + * Macros for Driver XPcie + * + *********************************************************************/ +#ifndef XPcie_mReadReg +#define XPcie_mReadReg XPcie_ReadReg +#endif + +#ifndef XPcie_mWriteReg +#define XPcie_mWriteReg XPcie_WriteReg +#endif + +/*********************************************************************/ +/** + * Macros for Driver XSpi + * + *********************************************************************/ +#ifndef XSpi_mIntrGlobalEnable +#define XSpi_mIntrGlobalEnable XSpi_IntrGlobalEnable +#endif + +#ifndef XSpi_mIntrGlobalDisable +#define XSpi_mIntrGlobalDisable XSpi_IntrGlobalDisable +#endif + +#ifndef XSpi_mIsIntrGlobalEnabled +#define XSpi_mIsIntrGlobalEnabled XSpi_IsIntrGlobalEnabled +#endif + +#ifndef XSpi_mIntrGetStatus +#define XSpi_mIntrGetStatus XSpi_IntrGetStatus +#endif + +#ifndef XSpi_mIntrClear +#define XSpi_mIntrClear XSpi_IntrClear +#endif + +#ifndef XSpi_mIntrEnable +#define XSpi_mIntrEnable XSpi_IntrEnable +#endif + +#ifndef XSpi_mIntrDisable +#define XSpi_mIntrDisable XSpi_IntrDisable +#endif + +#ifndef XSpi_mIntrGetEnabled +#define XSpi_mIntrGetEnabled XSpi_IntrGetEnabled +#endif + +#ifndef XSpi_mSetControlReg +#define XSpi_mSetControlReg XSpi_SetControlReg +#endif + +#ifndef XSpi_mGetControlReg +#define XSpi_mGetControlReg XSpi_GetControlReg +#endif + +#ifndef XSpi_mGetStatusReg +#define XSpi_mGetStatusReg XSpi_GetStatusReg +#endif + +#ifndef XSpi_mSetSlaveSelectReg +#define XSpi_mSetSlaveSelectReg XSpi_SetSlaveSelectReg +#endif + +#ifndef XSpi_mGetSlaveSelectReg +#define XSpi_mGetSlaveSelectReg XSpi_GetSlaveSelectReg +#endif + +#ifndef XSpi_mEnable +#define XSpi_mEnable XSpi_Enable +#endif + +#ifndef XSpi_mDisable +#define XSpi_mDisable XSpi_Disable +#endif + +/*********************************************************************/ +/** + * Macros for Driver XSysAce + * + *********************************************************************/ +#ifndef XSysAce_mGetControlReg +#define XSysAce_mGetControlReg XSysAce_GetControlReg +#endif + +#ifndef XSysAce_mSetControlReg +#define XSysAce_mSetControlReg XSysAce_SetControlReg +#endif + +#ifndef XSysAce_mOrControlReg +#define XSysAce_mOrControlReg XSysAce_OrControlReg +#endif + +#ifndef XSysAce_mAndControlReg +#define XSysAce_mAndControlReg XSysAce_AndControlReg +#endif + +#ifndef XSysAce_mGetErrorReg +#define XSysAce_mGetErrorReg XSysAce_GetErrorReg +#endif + +#ifndef XSysAce_mGetStatusReg +#define XSysAce_mGetStatusReg XSysAce_GetStatusReg +#endif + +#ifndef XSysAce_mWaitForLock +#define XSysAce_mWaitForLock XSysAce_WaitForLock +#endif + +#ifndef XSysAce_mEnableIntr +#define XSysAce_mEnableIntr XSysAce_EnableIntr +#endif + +#ifndef XSysAce_mDisableIntr +#define XSysAce_mDisableIntr XSysAce_DisableIntr +#endif + +#ifndef XSysAce_mIsReadyForCmd +#define XSysAce_mIsReadyForCmd XSysAce_IsReadyForCmd +#endif + +#ifndef XSysAce_mIsMpuLocked +#define XSysAce_mIsMpuLocked XSysAce_IsMpuLocked +#endif + +#ifndef XSysAce_mIsIntrEnabled +#define XSysAce_mIsIntrEnabled XSysAce_IsIntrEnabled +#endif + +/*********************************************************************/ +/** + * Macros for Driver XSysMon + * + *********************************************************************/ +#ifndef XSysMon_mIsEventSamplingModeSet +#define XSysMon_mIsEventSamplingModeSet XSysMon_IsEventSamplingModeSet +#endif + +#ifndef XSysMon_mIsDrpBusy +#define XSysMon_mIsDrpBusy XSysMon_IsDrpBusy +#endif + +#ifndef XSysMon_mIsDrpLocked +#define XSysMon_mIsDrpLocked XSysMon_IsDrpLocked +#endif + +#ifndef XSysMon_mRawToTemperature +#define XSysMon_mRawToTemperature XSysMon_RawToTemperature +#endif + +#ifndef XSysMon_mRawToVoltage +#define XSysMon_mRawToVoltage XSysMon_RawToVoltage +#endif + +#ifndef XSysMon_mTemperatureToRaw +#define XSysMon_mTemperatureToRaw XSysMon_TemperatureToRaw +#endif + +#ifndef XSysMon_mVoltageToRaw +#define XSysMon_mVoltageToRaw XSysMon_VoltageToRaw +#endif + +#ifndef XSysMon_mReadReg +#define XSysMon_mReadReg XSysMon_ReadReg +#endif + +#ifndef XSysMon_mWriteReg +#define XSysMon_mWriteReg XSysMon_WriteReg +#endif + +/*********************************************************************/ +/** + * Macros for Driver XTmrCtr + * + *********************************************************************/ +#ifndef XTimerCtr_mReadReg +#define XTimerCtr_mReadReg XTimerCtr_ReadReg +#endif + +#ifndef XTmrCtr_mWriteReg +#define XTmrCtr_mWriteReg XTmrCtr_WriteReg +#endif + +#ifndef XTmrCtr_mSetControlStatusReg +#define XTmrCtr_mSetControlStatusReg XTmrCtr_SetControlStatusReg +#endif + +#ifndef XTmrCtr_mGetControlStatusReg +#define XTmrCtr_mGetControlStatusReg XTmrCtr_GetControlStatusReg +#endif + +#ifndef XTmrCtr_mGetTimerCounterReg +#define XTmrCtr_mGetTimerCounterReg XTmrCtr_GetTimerCounterReg +#endif + +#ifndef XTmrCtr_mSetLoadReg +#define XTmrCtr_mSetLoadReg XTmrCtr_SetLoadReg +#endif + +#ifndef XTmrCtr_mGetLoadReg +#define XTmrCtr_mGetLoadReg XTmrCtr_GetLoadReg +#endif + +#ifndef XTmrCtr_mEnable +#define XTmrCtr_mEnable XTmrCtr_Enable +#endif + +#ifndef XTmrCtr_mDisable +#define XTmrCtr_mDisable XTmrCtr_Disable +#endif + +#ifndef XTmrCtr_mEnableIntr +#define XTmrCtr_mEnableIntr XTmrCtr_EnableIntr +#endif + +#ifndef XTmrCtr_mDisableIntr +#define XTmrCtr_mDisableIntr XTmrCtr_DisableIntr +#endif + +#ifndef XTmrCtr_mLoadTimerCounterReg +#define XTmrCtr_mLoadTimerCounterReg XTmrCtr_LoadTimerCounterReg +#endif + +#ifndef XTmrCtr_mHasEventOccurred +#define XTmrCtr_mHasEventOccurred XTmrCtr_HasEventOccurred +#endif + +/*********************************************************************/ +/** + * Macros for Driver XUartLite + * + *********************************************************************/ +#ifndef XUartLite_mUpdateStats +#define XUartLite_mUpdateStats XUartLite_UpdateStats +#endif + +#ifndef XUartLite_mWriteReg +#define XUartLite_mWriteReg XUartLite_WriteReg +#endif + +#ifndef XUartLite_mReadReg +#define XUartLite_mReadReg XUartLite_ReadReg +#endif + +#ifndef XUartLite_mClearStats +#define XUartLite_mClearStats XUartLite_ClearStats +#endif + +#ifndef XUartLite_mSetControlReg +#define XUartLite_mSetControlReg XUartLite_SetControlReg +#endif + +#ifndef XUartLite_mGetStatusReg +#define XUartLite_mGetStatusReg XUartLite_GetStatusReg +#endif + +#ifndef XUartLite_mIsReceiveEmpty +#define XUartLite_mIsReceiveEmpty XUartLite_IsReceiveEmpty +#endif + +#ifndef XUartLite_mIsTransmitFull +#define XUartLite_mIsTransmitFull XUartLite_IsTransmitFull +#endif + +#ifndef XUartLite_mIsIntrEnabled +#define XUartLite_mIsIntrEnabled XUartLite_IsIntrEnabled +#endif + +#ifndef XUartLite_mEnableIntr +#define XUartLite_mEnableIntr XUartLite_EnableIntr +#endif + +#ifndef XUartLite_mDisableIntr +#define XUartLite_mDisableIntr XUartLite_DisableIntr +#endif + +/*********************************************************************/ +/** + * Macros for Driver XUartNs550 + * + *********************************************************************/ +#ifndef XUartNs550_mUpdateStats +#define XUartNs550_mUpdateStats XUartNs550_UpdateStats +#endif + +#ifndef XUartNs550_mReadReg +#define XUartNs550_mReadReg XUartNs550_ReadReg +#endif + +#ifndef XUartNs550_mWriteReg +#define XUartNs550_mWriteReg XUartNs550_WriteReg +#endif + +#ifndef XUartNs550_mClearStats +#define XUartNs550_mClearStats XUartNs550_ClearStats +#endif + +#ifndef XUartNs550_mGetLineStatusReg +#define XUartNs550_mGetLineStatusReg XUartNs550_GetLineStatusReg +#endif + +#ifndef XUartNs550_mGetLineControlReg +#define XUartNs550_mGetLineControlReg XUartNs550_GetLineControlReg +#endif + +#ifndef XUartNs550_mSetLineControlReg +#define XUartNs550_mSetLineControlReg XUartNs550_SetLineControlReg +#endif + +#ifndef XUartNs550_mEnableIntr +#define XUartNs550_mEnableIntr XUartNs550_EnableIntr +#endif + +#ifndef XUartNs550_mDisableIntr +#define XUartNs550_mDisableIntr XUartNs550_DisableIntr +#endif + +#ifndef XUartNs550_mIsReceiveData +#define XUartNs550_mIsReceiveData XUartNs550_IsReceiveData +#endif + +#ifndef XUartNs550_mIsTransmitEmpty +#define XUartNs550_mIsTransmitEmpty XUartNs550_IsTransmitEmpty +#endif + +/*********************************************************************/ +/** + * Macros for Driver XUsb + * + *********************************************************************/ +#ifndef XUsb_mReadReg +#define XUsb_mReadReg XUsb_ReadReg +#endif + +#ifndef XUsb_mWriteReg +#define XUsb_mWriteReg XUsb_WriteReg +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_mem.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_mem.h new file mode 100644 index 0000000..9aae942 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_mem.h @@ -0,0 +1,68 @@ +/******************************************************************************/ +/** +* Copyright (C) 2015 - 2019 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* @file xil_mem.h +* +* @addtogroup common_mem_operation_api Customized APIs for Memory Operations +* +* The xil_mem.h file contains prototype for functions related +* to memory operations. These APIs are applicable for all processors supported +* by Xilinx. +* +* @{ +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who      Date     Changes
+* ----- -------- -------- -----------------------------------------------
+* 6.1   nsk      11/07/16 First release.
+* 7.0   mus      01/07/19 Add cpp extern macro
+*
+* 
+* +*****************************************************************************/ +#ifndef XIL_MEM_H /* prevent circular inclusions */ +#define XIL_MEM_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/************************** Function Prototypes *****************************/ + +void Xil_MemCpy(void* dst, const void* src, u32 cnt); + +#ifdef __cplusplus +} +#endif + +#endif /* XIL_MEM_H */ +/** +* @} End of "addtogroup common_mem_operation_api". +*/ \ No newline at end of file diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_misc_psreset_api.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_misc_psreset_api.h new file mode 100644 index 0000000..3a26175 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_misc_psreset_api.h @@ -0,0 +1,273 @@ +/****************************************************************************** +* +* Copyright (C) 2013 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* @file xil_misc_psreset_api.h +* +* This file contains the various register defintions and function prototypes for +* implementing the reset functionality of zynq ps devices +* +* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ---- -------- ------------------------------------------------------- +* 1.00b kpc 03/07/13 First release. +* +* +******************************************************************************/ + +#ifndef XIL_MISC_RESET_H /* prevent circular inclusions */ +#define XIL_MISC_RESET_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/***************************** Include Files *********************************/ +#include "xil_types.h" +#include "xil_io.h" + +/************************** Constant Definitions *****************************/ +#define XDDRC_CTRL_BASEADDR 0xF8006000U +#define XSLCR_BASEADDR 0xF8000000U +/**< OCM configuration register */ +#define XSLCR_OCM_CFG_ADDR (XSLCR_BASEADDR + 0x00000910U) +/**< SLCR unlock register */ +#define XSLCR_UNLOCK_ADDR (XSLCR_BASEADDR + 0x00000008U) +/**< SLCR GEM0 rx clock control register */ +#define XSLCR_GEM0_RCLK_CTRL_ADDR (XSLCR_BASEADDR + 0x00000138U) +/**< SLCR GEM1 rx clock control register */ +#define XSLCR_GEM1_RCLK_CTRL_ADDR (XSLCR_BASEADDR + 0x0000013CU) +/**< SLCR GEM0 clock control register */ +#define XSLCR_GEM0_CLK_CTRL_ADDR (XSLCR_BASEADDR + 0x00000140U) +/**< SLCR GEM1 clock control register */ +#define XSLCR_GEM1_CLK_CTRL_ADDR (XSLCR_BASEADDR + 0x00000144U) +/**< SLCR SMC clock control register */ +#define XSLCR_SMC_CLK_CTRL_ADDR (XSLCR_BASEADDR + 0x00000148U) +/**< SLCR GEM reset control register */ +#define XSLCR_GEM_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x00000214U) +/**< SLCR USB0 clock control register */ +#define XSLCR_USB0_CLK_CTRL_ADDR (XSLCR_BASEADDR + 0x00000130U) +/**< SLCR USB1 clock control register */ +#define XSLCR_USB1_CLK_CTRL_ADDR (XSLCR_BASEADDR + 0x00000134U) +/**< SLCR USB1 reset control register */ +#define XSLCR_USB_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x00000210U) +/**< SLCR SMC reset control register */ +#define XSLCR_SMC_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x00000234U) +/**< SLCR Level shifter enable register */ +#define XSLCR_LVL_SHFTR_EN_ADDR (XSLCR_BASEADDR + 0x00000900U) +/**< SLCR ARM pll control register */ +#define XSLCR_ARM_PLL_CTRL_ADDR (XSLCR_BASEADDR + 0x00000100U) +/**< SLCR DDR pll control register */ +#define XSLCR_DDR_PLL_CTRL_ADDR (XSLCR_BASEADDR + 0x00000104U) +/**< SLCR IO pll control register */ +#define XSLCR_IO_PLL_CTRL_ADDR (XSLCR_BASEADDR + 0x00000108U) +/**< SLCR ARM pll configuration register */ +#define XSLCR_ARM_PLL_CFG_ADDR (XSLCR_BASEADDR + 0x00000110U) +/**< SLCR DDR pll configuration register */ +#define XSLCR_DDR_PLL_CFG_ADDR (XSLCR_BASEADDR + 0x00000114U) +/**< SLCR IO pll configuration register */ +#define XSLCR_IO_PLL_CFG_ADDR (XSLCR_BASEADDR + 0x00000118U) +/**< SLCR ARM clock control register */ +#define XSLCR_ARM_CLK_CTRL_ADDR (XSLCR_BASEADDR + 0x00000120U) +/**< SLCR DDR clock control register */ +#define XSLCR_DDR_CLK_CTRL_ADDR (XSLCR_BASEADDR + 0x00000124U) +/**< SLCR MIO pin address register */ +#define XSLCR_MIO_PIN_00_ADDR (XSLCR_BASEADDR + 0x00000700U) +/**< SLCR DMAC reset control address register */ +#define XSLCR_DMAC_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x0000020CU) +/**< SLCR USB reset control address register */ +/*#define XSLCR_USB_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x00000210U)*/ +/**< SLCR GEM reset control address register */ +/*#define XSLCR_GEM_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x00000214U)*/ +/**< SLCR SDIO reset control address register */ +#define XSLCR_SDIO_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x00000218U) +/**< SLCR SPI reset control address register */ +#define XSLCR_SPI_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x0000021CU) +/**< SLCR CAN reset control address register */ +#define XSLCR_CAN_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x00000220U) +/**< SLCR I2C reset control address register */ +#define XSLCR_I2C_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x00000224U) +/**< SLCR UART reset control address register */ +#define XSLCR_UART_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x00000228U) +/**< SLCR GPIO reset control address register */ +#define XSLCR_GPIO_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x0000022CU) +/**< SLCR LQSPI reset control address register */ +#define XSLCR_LQSPI_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x00000230U) +/**< SLCR SMC reset control address register */ +/*#define XSLCR_SMC_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x00000234U)*/ +/**< SLCR OCM reset control address register */ +#define XSLCR_OCM_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x00000238U) + +/**< SMC mem controller clear config register */ +#define XSMC_MEMC_CLR_CONFIG_OFFSET 0x0000000CU +/**< SMC idlecount configuration register */ +#define XSMC_REFRESH_PERIOD_0_OFFSET 0x00000020U +#define XSMC_REFRESH_PERIOD_1_OFFSET 0x00000024U +/**< SMC ECC configuration register */ +#define XSMC_ECC_MEMCFG1_OFFSET 0x00000404U +/**< SMC ECC command 1 register */ +#define XSMC_ECC_MEMCMD1_OFFSET 0x00000404U +/**< SMC ECC command 2 register */ +#define XSMC_ECC_MEMCMD2_OFFSET 0x00000404U + +/**< SLCR unlock code */ +#define XSLCR_UNLOCK_CODE 0x0000DF0DU + +/**< SMC mem clear configuration mask */ +#define XSMC_MEMC_CLR_CONFIG_MASK 0x000005FU +/**< SMC ECC memconfig 1 reset value */ +#define XSMC_ECC_MEMCFG1_RESET_VAL 0x0000043U +/**< SMC ECC memcommand 1 reset value */ +#define XSMC_ECC_MEMCMD1_RESET_VAL 0x01300080U +/**< SMC ECC memcommand 2 reset value */ +#define XSMC_ECC_MEMCMD2_RESET_VAL 0x01E00585U + +/**< DDR controller reset bit mask */ +#define XDDRPS_CTRL_RESET_MASK 0x00000001U +/**< SLCR OCM configuration reset value*/ +#define XSLCR_OCM_CFG_RESETVAL 0x00000008U +/**< SLCR OCM bank selection mask*/ +#define XSLCR_OCM_CFG_HIADDR_MASK 0x0000000FU +/**< SLCR level shifter enable mask*/ +#define XSLCR_LVL_SHFTR_EN_MASK 0x0000000FU + +/**< SLCR PLL register reset values */ +#define XSLCR_ARM_PLL_CTRL_RESET_VAL 0x0001A008U +#define XSLCR_DDR_PLL_CTRL_RESET_VAL 0x0001A008U +#define XSLCR_IO_PLL_CTRL_RESET_VAL 0x0001A008U +#define XSLCR_ARM_PLL_CFG_RESET_VAL 0x00177EA0U +#define XSLCR_DDR_PLL_CFG_RESET_VAL 0x00177EA0U +#define XSLCR_IO_PLL_CFG_RESET_VAL 0x00177EA0U +#define XSLCR_ARM_CLK_CTRL_RESET_VAL 0x1F000400U +#define XSLCR_DDR_CLK_CTRL_RESET_VAL 0x18400003U + +/**< SLCR MIO register default values */ +#define XSLCR_MIO_PIN_00_RESET_VAL 0x00001601U +#define XSLCR_MIO_PIN_02_RESET_VAL 0x00000601U + +/**< SLCR Reset control registers default values */ +#define XSLCR_DMAC_RST_CTRL_VAL 0x00000001U +#define XSLCR_GEM_RST_CTRL_VAL 0x000000F3U +#define XSLCR_USB_RST_CTRL_VAL 0x00000003U +#define XSLCR_I2C_RST_CTRL_VAL 0x00000003U +#define XSLCR_SPI_RST_CTRL_VAL 0x0000000FU +#define XSLCR_UART_RST_CTRL_VAL 0x0000000FU +#define XSLCR_QSPI_RST_CTRL_VAL 0x00000003U +#define XSLCR_GPIO_RST_CTRL_VAL 0x00000001U +#define XSLCR_SMC_RST_CTRL_VAL 0x00000003U +#define XSLCR_OCM_RST_CTRL_VAL 0x00000001U +#define XSLCR_SDIO_RST_CTRL_VAL 0x00000033U +#define XSLCR_CAN_RST_CTRL_VAL 0x00000003U +/**************************** Type Definitions *******************************/ + +/* the following data type is used to hold a null terminated version string + * consisting of the following format, "X.YYX" + */ + + +/***************** Macros (Inline Functions) Definitions *********************/ + + +/************************** Function Prototypes ******************************/ +/* + * Performs reset operation to the ddr interface + */ +void XDdr_ResetHw(void); +/* + * Map the ocm region to post bootrom state + */ +void XOcm_Remap(void); +/* + * Performs the smc interface reset + */ +void XSmc_ResetHw(u32 BaseAddress); +/* + * updates the MIO registers with reset values + */ +void XSlcr_MioWriteResetValues(void); +/* + * updates the PLL and clock registers with reset values + */ +void XSlcr_PllWriteResetValues(void); +/* + * Disables the level shifters + */ +void XSlcr_DisableLevelShifters(void); +/* + * provides softreset to the GPIO interface + */ +void XSlcr_GpioPsReset(void); +/* + * provides softreset to the DMA interface + */ +void XSlcr_DmaPsReset(void); +/* + * provides softreset to the SMC interface + */ +void XSlcr_SmcPsReset(void); +/* + * provides softreset to the CAN interface + */ +void XSlcr_CanPsReset(void); +/* + * provides softreset to the Uart interface + */ +void XSlcr_UartPsReset(void); +/* + * provides softreset to the I2C interface + */ +void XSlcr_I2cPsReset(void); +/* + * provides softreset to the SPI interface + */ +void XSlcr_SpiPsReset(void); +/* + * provides softreset to the QSPI interface + */ +void XSlcr_QspiPsReset(void); +/* + * provides softreset to the USB interface + */ +void XSlcr_UsbPsReset(void); +/* + * provides softreset to the GEM interface + */ +void XSlcr_EmacPsReset(void); +/* + * provides softreset to the OCM interface + */ +void XSlcr_OcmReset(void); + + +#ifdef __cplusplus +} +#endif + +#endif /* XIL_MISC_RESET_H */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_mmu.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_mmu.h new file mode 100644 index 0000000..3b63c0b --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_mmu.h @@ -0,0 +1,106 @@ +/****************************************************************************** +* +* Copyright (C) 2012 - 2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* @file xil_mmu.h +* +* @addtogroup a9_mmu_apis Cortex A9 Processor MMU Functions +* +* MMU functions equip users to enable MMU, disable MMU and modify default +* memory attributes of MMU table as per the need. +* +* @{ +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- ---------------------------------------------------
+* 1.00a sdm  01/12/12 Initial version
+* 4.2	pkp	 07/21/14 Included xil_types.h file which contains definition for
+*					  u32 which resolves issue of CR#805869
+* 5.4	pkp	 23/11/15 Added attribute definitions for Xil_SetTlbAttributes API
+* 6.8   aru  09/06/18 Removed compilation warnings for ARMCC toolchain.
+* 
+* +* +******************************************************************************/ + +#ifndef XIL_MMU_H +#define XIL_MMU_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/***************************** Include Files *********************************/ + +#include "xil_types.h" + +/***************** Macros (Inline Functions) Definitions *********************/ + +/**************************** Type Definitions *******************************/ + +/************************** Constant Definitions *****************************/ + +/* Memory type */ +#define NORM_NONCACHE 0x11DE2 /* Normal Non-cacheable */ +#define STRONG_ORDERED 0xC02 /* Strongly ordered */ +#define DEVICE_MEMORY 0xC06 /* Device memory */ +#define RESERVED 0x0 /* reserved memory */ + +/* Normal write-through cacheable shareable */ +#define NORM_WT_CACHE 0x16DEA + +/* Normal write back cacheable shareable */ +#define NORM_WB_CACHE 0x15DE6 + +/* shareability attribute */ +#define SHAREABLE (0x1 << 16) +#define NON_SHAREABLE (~(0x1 << 16)) + +/* Execution type */ +#define EXECUTE_NEVER ((0x1 << 4) | (0x1 << 0)) + +/************************** Variable Definitions *****************************/ + +/************************** Function Prototypes ******************************/ + +void Xil_SetTlbAttributes(INTPTR Addr, u32 attrib); +void Xil_EnableMMU(void); +void Xil_DisableMMU(void); +void* Xil_MemMap(UINTPTR PhysAddr, size_t size, u32 flags); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* XIL_MMU_H */ +/** +* @} End of "addtogroup a9_mmu_apis". +*/ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_printf.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_printf.h new file mode 100644 index 0000000..a0177fc --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_printf.h @@ -0,0 +1,48 @@ + #ifndef XIL_PRINTF_H + #define XIL_PRINTF_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include "xil_types.h" +#include "xparameters.h" +#include "bspconfig.h" +#if defined (__aarch64__) && HYP_GUEST && EL1_NONSECURE && XEN_USE_PV_CONSOLE +#include "xen_console.h" +#endif + +/*----------------------------------------------------*/ +/* Use the following parameter passing structure to */ +/* make xil_printf re-entrant. */ +/*----------------------------------------------------*/ + +struct params_s; + + +/*---------------------------------------------------*/ +/* The purpose of this routine is to output data the */ +/* same as the standard printf function without the */ +/* overhead most run-time libraries involve. Usually */ +/* the printf brings in many kilobytes of code and */ +/* that is unacceptable in most embedded systems. */ +/*---------------------------------------------------*/ + +typedef char8* charptr; +typedef s32 (*func_ptr)(int c); + +/* */ + +void xil_printf( const char8 *ctrl1, ...); +void print( const char8 *ptr); +extern void outbyte (char8 c); +extern char8 inbyte(void); + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_sleeptimer.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_sleeptimer.h new file mode 100644 index 0000000..08f64ba --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_sleeptimer.h @@ -0,0 +1,128 @@ +/****************************************************************************** +* +* Copyright (C) 2017 - 2019 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xil_sleeptimer.h +* +* This header file contains ARM Cortex A53,A9,R5 specific sleep related APIs. +* For sleep related functions that can be used across all Xilinx supported +* processors, please use xil_sleeptimer.h. +* +* +*
+* MODIFICATION HISTORY :
+*
+* Ver   Who  Date	 Changes
+* ----- ---- -------- -------------------------------------------------------
+* 6.6	srm  10/18/17 First Release.
+* 7.0   mus  01/07/19 Add cpp extern macro
+*
+* 
+*****************************************************************************/ + +#ifndef XIL_SLEEPTIMER_H /* prevent circular inclusions */ +#define XIL_SLEEPTIMER_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/**************************** Include Files ********************************/ + +#include "xil_io.h" +#include "xparameters.h" +#include "bspconfig.h" + +/************************** Constant Definitions *****************************/ + +#if defined (ARMR5) || (__aarch64__) || (ARMA53_32) +#define XSLEEP_TIMER_REG_SHIFT 32U +#define XSleep_ReadCounterVal Xil_In32 +#define XCntrVal u32 +#else +#define XSLEEP_TIMER_REG_SHIFT 16U +#define XSleep_ReadCounterVal Xil_In16 +#define XCntrVal u16 +#endif + +#if defined(ARMR5) || (defined (__aarch64__) && EL3==1) || defined (ARMA53_32) +#if defined (versal) +#define CRL_TTC_RST 0xFF5E0344U +#define CRL_TTC_BASE_RST_MASK 0x1U +#else +#define RST_LPD_IOU2 0xFF5E0238U +#define RST_LPD_IOU2_TTC_BASE_RESET_MASK 0x00000800U +#endif +#endif + +#if defined (SLEEP_TIMER_BASEADDR) +/** @name Register Map +* +* Register offsets from the base address of the TTC device +* +* @{ +*/ + #define XSLEEP_TIMER_TTC_CLK_CNTRL_OFFSET 0x00000000U + /**< Clock Control Register */ + #define XSLEEP_TIMER_TTC_CNT_CNTRL_OFFSET 0x0000000CU + /**< Counter Control Register*/ + #define XSLEEP_TIMER_TTC_COUNT_VALUE_OFFSET 0x00000018U + /**< Current Counter Value */ +/* @} */ +/** @name Clock Control Register +* Clock Control Register definitions of TTC +* @{ +*/ + #define XSLEEP_TIMER_TTC_CLK_CNTRL_PS_EN_MASK 0x00000001U + /**< Prescale enable */ +/* @} */ +/** @name Counter Control Register +* Counter Control Register definitions of TTC +* @{ +*/ +#define XSLEEP_TIMER_TTC_CNT_CNTRL_DIS_MASK 0x00000001U + /**< Disable the counter */ +#define XSLEEP_TIMER_TTC_CNT_CNTRL_RST_MASK 0x00000010U + /**< Reset counter */ +/* @} */ + +/**************************** Type Definitions *******************************/ + +/************************** Function Prototypes ******************************/ + +void Xil_SleepTTCCommon(u32 delay, u64 frequency); +void XTime_StartTTCTimer(); + +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* XIL_SLEEPTIMER_H */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_testcache.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_testcache.h new file mode 100644 index 0000000..8289ca9 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_testcache.h @@ -0,0 +1,67 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xil_testcache.h +* +* @addtogroup common_test_utils +*

Cache test

+* The xil_testcache.h file contains utility functions to test cache. +* +* @{ +*
+* Ver    Who    Date    Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a hbm  07/29/09 First release
+* 
+* +******************************************************************************/ + +#ifndef XIL_TESTCACHE_H /* prevent circular inclusions */ +#define XIL_TESTCACHE_H /* by using protection macros */ + +#include "xil_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern s32 Xil_TestDCacheRange(void); +extern s32 Xil_TestDCacheAll(void); +extern s32 Xil_TestICacheRange(void); +extern s32 Xil_TestICacheAll(void); + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** +* @} End of "addtogroup common_test_utils". +*/ \ No newline at end of file diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_testio.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_testio.h new file mode 100644 index 0000000..6f0fc1c --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_testio.h @@ -0,0 +1,90 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xil_testio.h +* +* @addtogroup common_test_utils Test Utilities +*

I/O test

+* The xil_testio.h file contains utility functions to test endian related memory +* IO functions. +* +* A subset of the memory tests can be selected or all of the tests can be run +* in order. If there is an error detected by a subtest, the test stops and the +* failure code is returned. Further tests are not run even if all of the tests +* are selected. +* +* @{ +*
+* MODIFICATION HISTORY:
+*
+* Ver    Who    Date    Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00 hbm  08/05/09 First release
+* 
+* +******************************************************************************/ + +#ifndef XIL_TESTIO_H /* prevent circular inclusions */ +#define XIL_TESTIO_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ +#include "xil_types.h" + +/************************** Constant Definitions *****************************/ + + +#define XIL_TESTIO_DEFAULT 0 +#define XIL_TESTIO_LE 1 +#define XIL_TESTIO_BE 2 + +/**************************** Type Definitions *******************************/ + + +/***************** Macros (Inline Functions) Definitions *********************/ + + +/************************** Function Prototypes ******************************/ + +extern s32 Xil_TestIO8(u8 *Addr, s32 Length, u8 Value); +extern s32 Xil_TestIO16(u16 *Addr, s32 Length, u16 Value, s32 Kind, s32 Swap); +extern s32 Xil_TestIO32(u32 *Addr, s32 Length, u32 Value, s32 Kind, s32 Swap); + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** +* @} End of "addtogroup common_test_utils". +*/ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_testmem.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_testmem.h new file mode 100644 index 0000000..ecce6b7 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_testmem.h @@ -0,0 +1,154 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xil_testmem.h +* @addtogroup common_test_utils +* +*

Memory test

+* +* The xil_testmem.h file contains utility functions to test memory. +* A subset of the memory tests can be selected or all of the tests can be run +* in order. If there is an error detected by a subtest, the test stops and the +* failure code is returned. Further tests are not run even if all of the tests +* are selected. +* Following list describes the supported memory tests: +* +* - XIL_TESTMEM_ALLMEMTESTS: This test runs all of the subtests. +* +* - XIL_TESTMEM_INCREMENT: This test +* starts at 'XIL_TESTMEM_INIT_VALUE' and uses the incrementing value as the +* test value for memory. +* +* - XIL_TESTMEM_WALKONES: Also known as the Walking ones test. This test +* uses a walking '1' as the test value for memory. +* @code +* location 1 = 0x00000001 +* location 2 = 0x00000002 +* ... +* @endcode +* +* - XIL_TESTMEM_WALKZEROS: Also known as the Walking zero's test. +* This test uses the inverse value of the walking ones test +* as the test value for memory. +* @code +* location 1 = 0xFFFFFFFE +* location 2 = 0xFFFFFFFD +* ... +*@endcode +* +* - XIL_TESTMEM_INVERSEADDR: Also known as the inverse address test. +* This test uses the inverse of the address of the location under test +* as the test value for memory. +* +* - XIL_TESTMEM_FIXEDPATTERN: Also known as the fixed pattern test. +* This test uses the provided patters as the test value for memory. +* If zero is provided as the pattern the test uses '0xDEADBEEF". +* +* @warning +* The tests are DESTRUCTIVE. Run before any initialized memory spaces +* have been set up. +* The address provided to the memory tests is not checked for +* validity except for the NULL case. It is possible to provide a code-space +* pointer for this test to start with and ultimately destroy executable code +* causing random failures. +* +* @note +* Used for spaces where the address range of the region is smaller than +* the data width. If the memory range is greater than 2 ** width, +* the patterns used in XIL_TESTMEM_WALKONES and XIL_TESTMEM_WALKZEROS will +* repeat on a boundry of a power of two making it more difficult to detect +* addressing errors. The XIL_TESTMEM_INCREMENT and XIL_TESTMEM_INVERSEADDR +* tests suffer the same problem. Ideally, if large blocks of memory are to be +* tested, break them up into smaller regions of memory to allow the test +* patterns used not to repeat over the region tested. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver    Who    Date    Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a hbm  08/25/09 First release
+* 
+* +******************************************************************************/ + +#ifndef XIL_TESTMEM_H /* prevent circular inclusions */ +#define XIL_TESTMEM_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ +#include "xil_types.h" + +/************************** Constant Definitions *****************************/ + + +/**************************** Type Definitions *******************************/ + +/* xutil_memtest defines */ + +#define XIL_TESTMEM_INIT_VALUE 1U + +/** @name Memory subtests + * @{ + */ +/** + * See the detailed description of the subtests in the file description. + */ +#define XIL_TESTMEM_ALLMEMTESTS 0x00U +#define XIL_TESTMEM_INCREMENT 0x01U +#define XIL_TESTMEM_WALKONES 0x02U +#define XIL_TESTMEM_WALKZEROS 0x03U +#define XIL_TESTMEM_INVERSEADDR 0x04U +#define XIL_TESTMEM_FIXEDPATTERN 0x05U +#define XIL_TESTMEM_MAXTEST XIL_TESTMEM_FIXEDPATTERN +/* @} */ + +/***************** Macros (Inline Functions) Definitions *********************/ + + +/************************** Function Prototypes ******************************/ + +/* xutil_testmem prototypes */ + +extern s32 Xil_TestMem32(u32 *Addr, u32 Words, u32 Pattern, u8 Subtest); +extern s32 Xil_TestMem16(u16 *Addr, u32 Words, u16 Pattern, u8 Subtest); +extern s32 Xil_TestMem8(u8 *Addr, u32 Words, u8 Pattern, u8 Subtest); + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** +* @} End of "addtogroup common_test_utils". +*/ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_types.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_types.h new file mode 100644 index 0000000..625ff8c --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_types.h @@ -0,0 +1,214 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2019 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xil_types.h +* +* @addtogroup common_types Basic Data types for Xilinx® Software IP +* +* The xil_types.h file contains basic types for Xilinx software IP. These data types +* are applicable for all processors supported by Xilinx. +* @{ +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date   Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a hbm  07/14/09 First release
+* 3.03a sdm  05/30/11 Added Xuint64 typedef and XUINT64_MSW/XUINT64_LSW macros
+* 5.00 	pkp  05/29/14 Made changes for 64 bit architecture
+*	srt  07/14/14 Use standard definitions from stdint.h and stddef.h
+*		      Define LONG and ULONG datatypes and mask values
+* 7.00  mus  01/07/19 Add cpp extern macro
+* 
+* +******************************************************************************/ + +#ifndef XIL_TYPES_H /* prevent circular inclusions */ +#define XIL_TYPES_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/************************** Constant Definitions *****************************/ + +#ifndef TRUE +# define TRUE 1U +#endif + +#ifndef FALSE +# define FALSE 0U +#endif + +#ifndef NULL +#define NULL 0U +#endif + +#define XIL_COMPONENT_IS_READY 0x11111111U /**< In device drivers, This macro will be + assigend to "IsReady" member of driver + instance to indicate that driver + instance is initialized and ready to use. */ +#define XIL_COMPONENT_IS_STARTED 0x22222222U /**< In device drivers, This macro will be assigend to + "IsStarted" member of driver instance + to indicate that driver instance is + started and it can be enabled. */ + +/* @name New types + * New simple types. + * @{ + */ +#ifndef __KERNEL__ +#ifndef XBASIC_TYPES_H +/* + * guarded against xbasic_types.h. + */ +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +/** @}*/ +#define __XUINT64__ +typedef struct +{ + u32 Upper; + u32 Lower; +} Xuint64; + + +/*****************************************************************************/ +/** +* @brief Return the most significant half of the 64 bit data type. +* +* @param x is the 64 bit word. +* +* @return The upper 32 bits of the 64 bit word. +* +******************************************************************************/ +#define XUINT64_MSW(x) ((x).Upper) + +/*****************************************************************************/ +/** +* @brief Return the least significant half of the 64 bit data type. +* +* @param x is the 64 bit word. +* +* @return The lower 32 bits of the 64 bit word. +* +******************************************************************************/ +#define XUINT64_LSW(x) ((x).Lower) + +#endif /* XBASIC_TYPES_H */ + +/* + * xbasic_types.h does not typedef s* or u64 + */ +/** @{ */ +typedef char char8; +typedef int8_t s8; +typedef int16_t s16; +typedef int32_t s32; +typedef int64_t s64; +typedef uint64_t u64; +typedef int sint32; + +typedef intptr_t INTPTR; +typedef uintptr_t UINTPTR; +typedef ptrdiff_t PTRDIFF; +/** @}*/ +#if !defined(LONG) || !defined(ULONG) +typedef long LONG; +typedef unsigned long ULONG; +#endif + +#define ULONG64_HI_MASK 0xFFFFFFFF00000000U +#define ULONG64_LO_MASK ~ULONG64_HI_MASK + +#else +#include +#endif + +/** @{ */ +/** + * This data type defines an interrupt handler for a device. + * The argument points to the instance of the component + */ +typedef void (*XInterruptHandler) (void *InstancePtr); + +/** + * This data type defines an exception handler for a processor. + * The argument points to the instance of the component + */ +typedef void (*XExceptionHandler) (void *InstancePtr); + +/** + * @brief Returns 32-63 bits of a number. + * @param n : Number being accessed. + * @return Bits 32-63 of number. + * + * @note A basic shift-right of a 64- or 32-bit quantity. + * Use this to suppress the "right shift count >= width of type" + * warning when that quantity is 32-bits. + */ +#define UPPER_32_BITS(n) ((u32)(((n) >> 16) >> 16)) + +/** + * @brief Returns 0-31 bits of a number + * @param n : Number being accessed. + * @return Bits 0-31 of number + */ +#define LOWER_32_BITS(n) ((u32)(n)) + + + + +/************************** Constant Definitions *****************************/ + +#ifndef TRUE +#define TRUE 1U +#endif + +#ifndef FALSE +#define FALSE 0U +#endif + +#ifndef NULL +#define NULL 0U +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** +* @} End of "addtogroup common_types". +*/ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_util.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_util.h new file mode 100644 index 0000000..194c425 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xil_util.h @@ -0,0 +1,57 @@ +/******************************************************************************/ +/** +* Copyright (C) 2019 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* @file xil_util.h +* +* This file contains xil utility functions declaration +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who      Date     Changes
+* ----- -------- -------- -----------------------------------------------
+* 6.4   mmd      04/21/19 First release.
+*
+* 
+* +*****************************************************************************/ + +#ifndef XIL_UTIL_H_ +#define XIL_UTIL_H_ + +/* Converts input character to nibble */ +u32 Xil_ConvertCharToNibble(u8 InChar, u8 *Num); + +/* Conver input hex string to array of 32-bits integers */ +u32 Xil_ConvertStringToHex(const char *Str, u32 *buf, u8 Len); + +/* Waits for specified event */ +u32 Xil_WaitForEvent(u32 RegAddr, u32 EventMask, u32 Event, u32 Timeout); + +#endif /* XIL_UTIL_H_ */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xl2cc.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xl2cc.h new file mode 100644 index 0000000..22373c1 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xl2cc.h @@ -0,0 +1,168 @@ +/****************************************************************************** +* +* Copyright (C) 2011 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* @file xl2cc.h +* +* This file contains the address definitions for the PL310 Level-2 Cache +* Controller. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- ---------------------------------------------------
+* 1.00a sdm  02/01/10 Initial version
+* 3.10a srt 04/18/13 Implemented ARM Erratas. Please refer to file
+*		      'xil_errata.h' for errata description
+* 
+* +* @note +* +* None. +* +******************************************************************************/ + +#ifndef _XL2CC_H_ +#define _XL2CC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/************************** Constant Definitions *****************************/ +/* L2CC Register Offsets */ +#define XPS_L2CC_ID_OFFSET 0x0000U +#define XPS_L2CC_TYPE_OFFSET 0x0004U +#define XPS_L2CC_CNTRL_OFFSET 0x0100U +#define XPS_L2CC_AUX_CNTRL_OFFSET 0x0104U +#define XPS_L2CC_TAG_RAM_CNTRL_OFFSET 0x0108U +#define XPS_L2CC_DATA_RAM_CNTRL_OFFSET 0x010CU + +#define XPS_L2CC_EVNT_CNTRL_OFFSET 0x0200U +#define XPS_L2CC_EVNT_CNT1_CTRL_OFFSET 0x0204U +#define XPS_L2CC_EVNT_CNT0_CTRL_OFFSET 0x0208U +#define XPS_L2CC_EVNT_CNT1_VAL_OFFSET 0x020CU +#define XPS_L2CC_EVNT_CNT0_VAL_OFFSET 0x0210U + +#define XPS_L2CC_IER_OFFSET 0x0214U /* Interrupt Mask */ +#define XPS_L2CC_IPR_OFFSET 0x0218U /* Masked interrupt status */ +#define XPS_L2CC_ISR_OFFSET 0x021CU /* Raw Interrupt Status */ +#define XPS_L2CC_IAR_OFFSET 0x0220U /* Interrupt Clear */ + +#define XPS_L2CC_CACHE_SYNC_OFFSET 0x0730U /* Cache Sync */ +#define XPS_L2CC_DUMMY_CACHE_SYNC_OFFSET 0x0740U /* Dummy Register for Cache Sync */ +#define XPS_L2CC_CACHE_INVLD_PA_OFFSET 0x0770U /* Cache Invalid by PA */ +#define XPS_L2CC_CACHE_INVLD_WAY_OFFSET 0x077CU /* Cache Invalid by Way */ +#define XPS_L2CC_CACHE_CLEAN_PA_OFFSET 0x07B0U /* Cache Clean by PA */ +#define XPS_L2CC_CACHE_CLEAN_INDX_OFFSET 0x07B8U /* Cache Clean by Index */ +#define XPS_L2CC_CACHE_CLEAN_WAY_OFFSET 0x07BCU /* Cache Clean by Way */ +#define XPS_L2CC_CACHE_INV_CLN_PA_OFFSET 0x07F0U /* Cache Invalidate and Clean by PA */ +#define XPS_L2CC_CACHE_INV_CLN_INDX_OFFSET 0x07F8U /* Cache Invalidate and Clean by Index */ +#define XPS_L2CC_CACHE_INV_CLN_WAY_OFFSET 0x07FCU /* Cache Invalidate and Clean by Way */ + +#define XPS_L2CC_CACHE_DLCKDWN_0_WAY_OFFSET 0x0900U /* Cache Data Lockdown 0 by Way */ +#define XPS_L2CC_CACHE_ILCKDWN_0_WAY_OFFSET 0x0904U /* Cache Instruction Lockdown 0 by Way */ +#define XPS_L2CC_CACHE_DLCKDWN_1_WAY_OFFSET 0x0908U /* Cache Data Lockdown 1 by Way */ +#define XPS_L2CC_CACHE_ILCKDWN_1_WAY_OFFSET 0x090CU /* Cache Instruction Lockdown 1 by Way */ +#define XPS_L2CC_CACHE_DLCKDWN_2_WAY_OFFSET 0x0910U /* Cache Data Lockdown 2 by Way */ +#define XPS_L2CC_CACHE_ILCKDWN_2_WAY_OFFSET 0x0914U /* Cache Instruction Lockdown 2 by Way */ +#define XPS_L2CC_CACHE_DLCKDWN_3_WAY_OFFSET 0x0918U /* Cache Data Lockdown 3 by Way */ +#define XPS_L2CC_CACHE_ILCKDWN_3_WAY_OFFSET 0x091CU /* Cache Instruction Lockdown 3 by Way */ +#define XPS_L2CC_CACHE_DLCKDWN_4_WAY_OFFSET 0x0920U /* Cache Data Lockdown 4 by Way */ +#define XPS_L2CC_CACHE_ILCKDWN_4_WAY_OFFSET 0x0924U /* Cache Instruction Lockdown 4 by Way */ +#define XPS_L2CC_CACHE_DLCKDWN_5_WAY_OFFSET 0x0928U /* Cache Data Lockdown 5 by Way */ +#define XPS_L2CC_CACHE_ILCKDWN_5_WAY_OFFSET 0x092CU /* Cache Instruction Lockdown 5 by Way */ +#define XPS_L2CC_CACHE_DLCKDWN_6_WAY_OFFSET 0x0930U /* Cache Data Lockdown 6 by Way */ +#define XPS_L2CC_CACHE_ILCKDWN_6_WAY_OFFSET 0x0934U /* Cache Instruction Lockdown 6 by Way */ +#define XPS_L2CC_CACHE_DLCKDWN_7_WAY_OFFSET 0x0938U /* Cache Data Lockdown 7 by Way */ +#define XPS_L2CC_CACHE_ILCKDWN_7_WAY_OFFSET 0x093CU /* Cache Instruction Lockdown 7 by Way */ + +#define XPS_L2CC_CACHE_LCKDWN_LINE_ENABLE_OFFSET 0x0950U /* Cache Lockdown Line Enable */ +#define XPS_L2CC_CACHE_UUNLOCK_ALL_WAY_OFFSET 0x0954U /* Cache Unlock All Lines by Way */ + +#define XPS_L2CC_ADDR_FILTER_START_OFFSET 0x0C00U /* Start of address filtering */ +#define XPS_L2CC_ADDR_FILTER_END_OFFSET 0x0C04U /* Start of address filtering */ + +#define XPS_L2CC_DEBUG_CTRL_OFFSET 0x0F40U /* Debug Control Register */ + +/* XPS_L2CC_CNTRL_OFFSET bit masks */ +#define XPS_L2CC_ENABLE_MASK 0x00000001U /* enables the L2CC */ + +/* XPS_L2CC_AUX_CNTRL_OFFSET bit masks */ +#define XPS_L2CC_AUX_EBRESPE_MASK 0x40000000U /* Early BRESP Enable */ +#define XPS_L2CC_AUX_IPFE_MASK 0x20000000U /* Instruction Prefetch Enable */ +#define XPS_L2CC_AUX_DPFE_MASK 0x10000000U /* Data Prefetch Enable */ +#define XPS_L2CC_AUX_NSIC_MASK 0x08000000U /* Non-secure interrupt access control */ +#define XPS_L2CC_AUX_NSLE_MASK 0x04000000U /* Non-secure lockdown enable */ +#define XPS_L2CC_AUX_CRP_MASK 0x02000000U /* Cache replacement policy */ +#define XPS_L2CC_AUX_FWE_MASK 0x01800000U /* Force write allocate */ +#define XPS_L2CC_AUX_SAOE_MASK 0x00400000U /* Shared attribute override enable */ +#define XPS_L2CC_AUX_PE_MASK 0x00200000U /* Parity enable */ +#define XPS_L2CC_AUX_EMBE_MASK 0x00100000U /* Event monitor bus enable */ +#define XPS_L2CC_AUX_WAY_SIZE_MASK 0x000E0000U /* Way-size */ +#define XPS_L2CC_AUX_ASSOC_MASK 0x00010000U /* Associativity */ +#define XPS_L2CC_AUX_SAIE_MASK 0x00002000U /* Shared attribute invalidate enable */ +#define XPS_L2CC_AUX_EXCL_CACHE_MASK 0x00001000U /* Exclusive cache configuration */ +#define XPS_L2CC_AUX_SBDLE_MASK 0x00000800U /* Store buffer device limitation Enable */ +#define XPS_L2CC_AUX_HPSODRE_MASK 0x00000400U /* High Priority for SO and Dev Reads Enable */ +#define XPS_L2CC_AUX_FLZE_MASK 0x00000001U /* Full line of zero enable */ + +#define XPS_L2CC_AUX_REG_DEFAULT_MASK 0x72360000U /* Enable all prefetching, */ + /* Cache replacement policy, Parity enable, */ + /* Event monitor bus enable and Way Size (64 KB) */ +#define XPS_L2CC_AUX_REG_ZERO_MASK 0xFFF1FFFFU /* */ + +#define XPS_L2CC_TAG_RAM_DEFAULT_MASK 0x00000111U /* latency for TAG RAM */ +#define XPS_L2CC_DATA_RAM_DEFAULT_MASK 0x00000121U /* latency for DATA RAM */ + +/* Interrupt bit masks */ +#define XPS_L2CC_IXR_DECERR_MASK 0x00000100U /* DECERR from L3 */ +#define XPS_L2CC_IXR_SLVERR_MASK 0x00000080U /* SLVERR from L3 */ +#define XPS_L2CC_IXR_ERRRD_MASK 0x00000040U /* Error on L2 data RAM (Read) */ +#define XPS_L2CC_IXR_ERRRT_MASK 0x00000020U /* Error on L2 tag RAM (Read) */ +#define XPS_L2CC_IXR_ERRWD_MASK 0x00000010U /* Error on L2 data RAM (Write) */ +#define XPS_L2CC_IXR_ERRWT_MASK 0x00000008U /* Error on L2 tag RAM (Write) */ +#define XPS_L2CC_IXR_PARRD_MASK 0x00000004U /* Parity Error on L2 data RAM (Read) */ +#define XPS_L2CC_IXR_PARRT_MASK 0x00000002U /* Parity Error on L2 tag RAM (Read) */ +#define XPS_L2CC_IXR_ECNTR_MASK 0x00000001U /* Event Counter1/0 Overflow Increment */ + +/* Address filtering mask and enable bit */ +#define XPS_L2CC_ADDR_FILTER_VALID_MASK 0xFFF00000U /* Address filtering valid bits*/ +#define XPS_L2CC_ADDR_FILTER_ENABLE_MASK 0x00000001U /* Address filtering enable bit*/ + +/* Debug control bits */ +#define XPS_L2CC_DEBUG_SPIDEN_MASK 0x00000004U /* Debug SPIDEN bit */ +#define XPS_L2CC_DEBUG_DWB_MASK 0x00000002U /* Debug DWB bit, forces write through */ +#define XPS_L2CC_DEBUG_DCL_MASK 0x00000002U /* Debug DCL bit, disables cache line fill */ + +#ifdef __cplusplus +} +#endif + +#endif /* protection macro */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xl2cc_counter.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xl2cc_counter.h new file mode 100644 index 0000000..b8d768f --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xl2cc_counter.h @@ -0,0 +1,110 @@ +/****************************************************************************** +* +* Copyright (C) 2011 - 2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xl2cc_counter.h +* +* @addtogroup l2_event_counter_apis PL310 L2 Event Counters Functions +* +* xl2cc_counter.h contains APIs for configuring and controlling the event +* counters in PL310 L2 cache controller. +* PL310 has two event counters which can be used to count variety of events +* like DRHIT, DRREQ, DWHIT, DWREQ, etc. xl2cc_counter.h contains definitions +* for different configurations which can be used for the event counters to +* count a set of events. +* +* +* @{ +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a sdm  07/11/11 First release
+* 3.07a asa  08/30/12 Updated for CR 675636 to provide the L2 Base Address
+*		      inside the APIs
+* 6.8   aru  09/06/18 Removed compilation warnings for ARMCC toolchain.
+* 
+* +******************************************************************************/ + +#ifndef L2CCCOUNTER_H /* prevent circular inclusions */ +#define L2CCCOUNTER_H /* by using protection macros */ + +/***************************** Include Files ********************************/ + +#include "xpseudo_asm.h" +#include "xil_types.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/************************** Constant Definitions ****************************/ + +/* + * The following constants define the event codes for the event counters. + */ +#define XL2CC_CO 0x1 +#define XL2CC_DRHIT 0x2 +#define XL2CC_DRREQ 0x3 +#define XL2CC_DWHIT 0x4 +#define XL2CC_DWREQ 0x5 +#define XL2CC_DWTREQ 0x6 +#define XL2CC_IRHIT 0x7 +#define XL2CC_IRREQ 0x8 +#define XL2CC_WA 0x9 +#define XL2CC_IPFALLOC 0xa +#define XL2CC_EPFHIT 0xb +#define XL2CC_EPFALLOC 0xc +#define XL2CC_SRRCVD 0xd +#define XL2CC_SRCONF 0xe +#define XL2CC_EPFRCVD 0xf + +/**************************** Type Definitions ******************************/ + +/***************** Macros (Inline Functions) Definitions ********************/ + +/************************** Variable Definitions ****************************/ + +/************************** Function Prototypes *****************************/ + +void XL2cc_EventCtrInit(s32 Event0, s32 Event1); +void XL2cc_EventCtrStart(void); +void XL2cc_EventCtrStop(u32 *EveCtr0, u32 *EveCtr1); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* L2CCCOUNTER_H */ +/** +* @} End of "addtogroup l2_event_counter_apis". +*/ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xparameters.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xparameters.h new file mode 100644 index 0000000..76605c7 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xparameters.h @@ -0,0 +1,470 @@ +#ifndef XPARAMETERS_H /* prevent circular inclusions */ +#define XPARAMETERS_H /* by using protection macros */ + +/* Definition for CPU ID */ +#define XPAR_CPU_ID 0U + +/* Definitions for peripheral PS7_CORTEXA9_0 */ +#define XPAR_PS7_CORTEXA9_0_CPU_CLK_FREQ_HZ 666666687 + + +/******************************************************************/ + +/* Canonical definitions for peripheral PS7_CORTEXA9_0 */ +#define XPAR_CPU_CORTEXA9_0_CPU_CLK_FREQ_HZ 666666687 + + +/******************************************************************/ + + +/* Definitions for interface PHY */ +#define XPAR_PHY_BASEADDR 0x43C20000 +#define XPAR_PHY_HIGHADDR 0x43C20FFF + +#include "xparameters_ps.h" + +#define STDIN_BASEADDRESS 0xE0000000 +#define STDOUT_BASEADDRESS 0xE0000000 + +/******************************************************************/ + +/* Platform specific definitions */ +#define PLATFORM_ZYNQ + +/* Definitions for sleep timer configuration */ +#define XSLEEP_TIMER_IS_DEFAULT_TIMER + + +/******************************************************************/ +/* Definitions for driver BRAM */ +#define XPAR_XBRAM_NUM_INSTANCES 3U + +/* Definitions for peripheral PHY_DATA_INTERFACE_ANT_CONFIG_AXI_BRAM_CTRL */ +#define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_AXI_BRAM_CTRL_DEVICE_ID 0U +#define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_AXI_BRAM_CTRL_DATA_WIDTH 32U +#define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_AXI_BRAM_CTRL_ECC 0U +#define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_AXI_BRAM_CTRL_FAULT_INJECT 0U +#define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_AXI_BRAM_CTRL_CE_FAILING_REGISTERS 0U +#define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_AXI_BRAM_CTRL_UE_FAILING_REGISTERS 0U +#define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_AXI_BRAM_CTRL_ECC_STATUS_REGISTERS 0U +#define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_AXI_BRAM_CTRL_CE_COUNTER_WIDTH 0U +#define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_AXI_BRAM_CTRL_ECC_ONOFF_REGISTER 0U +#define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_AXI_BRAM_CTRL_ECC_ONOFF_RESET_VALUE 0U +#define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_AXI_BRAM_CTRL_WRITE_ACCESS 0U +#define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_AXI_BRAM_CTRL_S_AXI_BASEADDR 0x44000000U +#define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_AXI_BRAM_CTRL_S_AXI_HIGHADDR 0x44001FFFU +#define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_AXI_BRAM_CTRL_S_AXI_CTRL_BASEADDR 0xFFFFFFFFU +#define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_AXI_BRAM_CTRL_S_AXI_CTRL_HIGHADDR 0xFFFFFFFFU + + +/* Definitions for peripheral PHY_DATA_INTERFACE_PHY_RX_BUFF_AXI_BRAM_CTRL */ +#define XPAR_PHY_DATA_INTERFACE_PHY_RX_BUFF_AXI_BRAM_CTRL_DEVICE_ID 1U +#define XPAR_PHY_DATA_INTERFACE_PHY_RX_BUFF_AXI_BRAM_CTRL_DATA_WIDTH 32U +#define XPAR_PHY_DATA_INTERFACE_PHY_RX_BUFF_AXI_BRAM_CTRL_ECC 0U +#define XPAR_PHY_DATA_INTERFACE_PHY_RX_BUFF_AXI_BRAM_CTRL_FAULT_INJECT 0U +#define XPAR_PHY_DATA_INTERFACE_PHY_RX_BUFF_AXI_BRAM_CTRL_CE_FAILING_REGISTERS 0U +#define XPAR_PHY_DATA_INTERFACE_PHY_RX_BUFF_AXI_BRAM_CTRL_UE_FAILING_REGISTERS 0U +#define XPAR_PHY_DATA_INTERFACE_PHY_RX_BUFF_AXI_BRAM_CTRL_ECC_STATUS_REGISTERS 0U +#define XPAR_PHY_DATA_INTERFACE_PHY_RX_BUFF_AXI_BRAM_CTRL_CE_COUNTER_WIDTH 0U +#define XPAR_PHY_DATA_INTERFACE_PHY_RX_BUFF_AXI_BRAM_CTRL_ECC_ONOFF_REGISTER 0U +#define XPAR_PHY_DATA_INTERFACE_PHY_RX_BUFF_AXI_BRAM_CTRL_ECC_ONOFF_RESET_VALUE 0U +#define XPAR_PHY_DATA_INTERFACE_PHY_RX_BUFF_AXI_BRAM_CTRL_WRITE_ACCESS 0U +#define XPAR_PHY_DATA_INTERFACE_PHY_RX_BUFF_AXI_BRAM_CTRL_S_AXI_BASEADDR 0x40000000U +#define XPAR_PHY_DATA_INTERFACE_PHY_RX_BUFF_AXI_BRAM_CTRL_S_AXI_HIGHADDR 0x40000FFFU +#define XPAR_PHY_DATA_INTERFACE_PHY_RX_BUFF_AXI_BRAM_CTRL_S_AXI_CTRL_BASEADDR 0xFFFFFFFFU +#define XPAR_PHY_DATA_INTERFACE_PHY_RX_BUFF_AXI_BRAM_CTRL_S_AXI_CTRL_HIGHADDR 0xFFFFFFFFU + + +/* Definitions for peripheral PHY_DATA_INTERFACE_PHY_TX_BUFF_AXI_BRAM_CTRL */ +#define XPAR_PHY_DATA_INTERFACE_PHY_TX_BUFF_AXI_BRAM_CTRL_DEVICE_ID 2U +#define XPAR_PHY_DATA_INTERFACE_PHY_TX_BUFF_AXI_BRAM_CTRL_DATA_WIDTH 32U +#define XPAR_PHY_DATA_INTERFACE_PHY_TX_BUFF_AXI_BRAM_CTRL_ECC 0U +#define XPAR_PHY_DATA_INTERFACE_PHY_TX_BUFF_AXI_BRAM_CTRL_FAULT_INJECT 0U +#define XPAR_PHY_DATA_INTERFACE_PHY_TX_BUFF_AXI_BRAM_CTRL_CE_FAILING_REGISTERS 0U +#define XPAR_PHY_DATA_INTERFACE_PHY_TX_BUFF_AXI_BRAM_CTRL_UE_FAILING_REGISTERS 0U +#define XPAR_PHY_DATA_INTERFACE_PHY_TX_BUFF_AXI_BRAM_CTRL_ECC_STATUS_REGISTERS 0U +#define XPAR_PHY_DATA_INTERFACE_PHY_TX_BUFF_AXI_BRAM_CTRL_CE_COUNTER_WIDTH 0U +#define XPAR_PHY_DATA_INTERFACE_PHY_TX_BUFF_AXI_BRAM_CTRL_ECC_ONOFF_REGISTER 0U +#define XPAR_PHY_DATA_INTERFACE_PHY_TX_BUFF_AXI_BRAM_CTRL_ECC_ONOFF_RESET_VALUE 0U +#define XPAR_PHY_DATA_INTERFACE_PHY_TX_BUFF_AXI_BRAM_CTRL_WRITE_ACCESS 0U +#define XPAR_PHY_DATA_INTERFACE_PHY_TX_BUFF_AXI_BRAM_CTRL_S_AXI_BASEADDR 0x42000000U +#define XPAR_PHY_DATA_INTERFACE_PHY_TX_BUFF_AXI_BRAM_CTRL_S_AXI_HIGHADDR 0x42000FFFU +#define XPAR_PHY_DATA_INTERFACE_PHY_TX_BUFF_AXI_BRAM_CTRL_S_AXI_CTRL_BASEADDR 0xFFFFFFFFU +#define XPAR_PHY_DATA_INTERFACE_PHY_TX_BUFF_AXI_BRAM_CTRL_S_AXI_CTRL_HIGHADDR 0xFFFFFFFFU + + +/******************************************************************/ + +/* Canonical definitions for peripheral PHY_DATA_INTERFACE_ANT_CONFIG_AXI_BRAM_CTRL */ +#define XPAR_BRAM_0_DEVICE_ID XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_AXI_BRAM_CTRL_DEVICE_ID +#define XPAR_BRAM_0_DATA_WIDTH 32U +#define XPAR_BRAM_0_ECC 0U +#define XPAR_BRAM_0_FAULT_INJECT 0U +#define XPAR_BRAM_0_CE_FAILING_REGISTERS 0U +#define XPAR_BRAM_0_UE_FAILING_REGISTERS 0U +#define XPAR_BRAM_0_ECC_STATUS_REGISTERS 0U +#define XPAR_BRAM_0_CE_COUNTER_WIDTH 0U +#define XPAR_BRAM_0_ECC_ONOFF_REGISTER 0U +#define XPAR_BRAM_0_ECC_ONOFF_RESET_VALUE 0U +#define XPAR_BRAM_0_WRITE_ACCESS 0U +#define XPAR_BRAM_0_BASEADDR 0x44000000U +#define XPAR_BRAM_0_HIGHADDR 0x44001FFFU +#define XPAR_BRAM_0_CTRL_BASEADDR 0xFFFFFFFFU +#define XPAR_BRAM_0_CTRL_HIGHADDR 0xFFFFFFFEU + +/* Canonical definitions for peripheral PHY_DATA_INTERFACE_PHY_RX_BUFF_AXI_BRAM_CTRL */ +#define XPAR_BRAM_1_DEVICE_ID XPAR_PHY_DATA_INTERFACE_PHY_RX_BUFF_AXI_BRAM_CTRL_DEVICE_ID +#define XPAR_BRAM_1_DATA_WIDTH 32U +#define XPAR_BRAM_1_ECC 0U +#define XPAR_BRAM_1_FAULT_INJECT 0U +#define XPAR_BRAM_1_CE_FAILING_REGISTERS 0U +#define XPAR_BRAM_1_UE_FAILING_REGISTERS 0U +#define XPAR_BRAM_1_ECC_STATUS_REGISTERS 0U +#define XPAR_BRAM_1_CE_COUNTER_WIDTH 0U +#define XPAR_BRAM_1_ECC_ONOFF_REGISTER 0U +#define XPAR_BRAM_1_ECC_ONOFF_RESET_VALUE 0U +#define XPAR_BRAM_1_WRITE_ACCESS 0U +#define XPAR_BRAM_1_BASEADDR 0x40000000U +#define XPAR_BRAM_1_HIGHADDR 0x40000FFFU +#define XPAR_BRAM_1_CTRL_BASEADDR 0xFFFFFFFFU +#define XPAR_BRAM_1_CTRL_HIGHADDR 0xFFFFFFFEU + +/* Canonical definitions for peripheral PHY_DATA_INTERFACE_PHY_TX_BUFF_AXI_BRAM_CTRL */ +#define XPAR_BRAM_2_DEVICE_ID XPAR_PHY_DATA_INTERFACE_PHY_TX_BUFF_AXI_BRAM_CTRL_DEVICE_ID +#define XPAR_BRAM_2_DATA_WIDTH 32U +#define XPAR_BRAM_2_ECC 0U +#define XPAR_BRAM_2_FAULT_INJECT 0U +#define XPAR_BRAM_2_CE_FAILING_REGISTERS 0U +#define XPAR_BRAM_2_UE_FAILING_REGISTERS 0U +#define XPAR_BRAM_2_ECC_STATUS_REGISTERS 0U +#define XPAR_BRAM_2_CE_COUNTER_WIDTH 0U +#define XPAR_BRAM_2_ECC_ONOFF_REGISTER 0U +#define XPAR_BRAM_2_ECC_ONOFF_RESET_VALUE 0U +#define XPAR_BRAM_2_WRITE_ACCESS 0U +#define XPAR_BRAM_2_BASEADDR 0x42000000U +#define XPAR_BRAM_2_HIGHADDR 0x42000FFFU +#define XPAR_BRAM_2_CTRL_BASEADDR 0xFFFFFFFFU +#define XPAR_BRAM_2_CTRL_HIGHADDR 0xFFFFFFFEU + + +/******************************************************************/ + + +/* Definitions for peripheral PS7_DDR_0 */ +#define XPAR_PS7_DDR_0_S_AXI_BASEADDR 0x00100000 +#define XPAR_PS7_DDR_0_S_AXI_HIGHADDR 0x1FFFFFFF + + +/******************************************************************/ + +/* Definitions for driver DEVCFG */ +#define XPAR_XDCFG_NUM_INSTANCES 1U + +/* Definitions for peripheral PS7_DEV_CFG_0 */ +#define XPAR_PS7_DEV_CFG_0_DEVICE_ID 0U +#define XPAR_PS7_DEV_CFG_0_BASEADDR 0xF8007000U +#define XPAR_PS7_DEV_CFG_0_HIGHADDR 0xF80070FFU + + +/******************************************************************/ + +/* Canonical definitions for peripheral PS7_DEV_CFG_0 */ +#define XPAR_XDCFG_0_DEVICE_ID XPAR_PS7_DEV_CFG_0_DEVICE_ID +#define XPAR_XDCFG_0_BASEADDR 0xF8007000U +#define XPAR_XDCFG_0_HIGHADDR 0xF80070FFU + + +/******************************************************************/ + +/* Definitions for driver DMAPS */ +#define XPAR_XDMAPS_NUM_INSTANCES 2 + +/* Definitions for peripheral PS7_DMA_NS */ +#define XPAR_PS7_DMA_NS_DEVICE_ID 0 +#define XPAR_PS7_DMA_NS_BASEADDR 0xF8004000 +#define XPAR_PS7_DMA_NS_HIGHADDR 0xF8004FFF + + +/* Definitions for peripheral PS7_DMA_S */ +#define XPAR_PS7_DMA_S_DEVICE_ID 1 +#define XPAR_PS7_DMA_S_BASEADDR 0xF8003000 +#define XPAR_PS7_DMA_S_HIGHADDR 0xF8003FFF + + +/******************************************************************/ + +/* Canonical definitions for peripheral PS7_DMA_NS */ +#define XPAR_XDMAPS_0_DEVICE_ID XPAR_PS7_DMA_NS_DEVICE_ID +#define XPAR_XDMAPS_0_BASEADDR 0xF8004000 +#define XPAR_XDMAPS_0_HIGHADDR 0xF8004FFF + +/* Canonical definitions for peripheral PS7_DMA_S */ +#define XPAR_XDMAPS_1_DEVICE_ID XPAR_PS7_DMA_S_DEVICE_ID +#define XPAR_XDMAPS_1_BASEADDR 0xF8003000 +#define XPAR_XDMAPS_1_HIGHADDR 0xF8003FFF + + +/******************************************************************/ + + +/* Definitions for peripheral AXI_SPI_ENGINE_AXI_SPI_ENGINE */ +#define XPAR_AXI_SPI_ENGINE_AXI_SPI_ENGINE_BASEADDR 0x43C00000 +#define XPAR_AXI_SPI_ENGINE_AXI_SPI_ENGINE_HIGHADDR 0x43C0FFFF + + +/* Definitions for peripheral PS7_AFI_0 */ +#define XPAR_PS7_AFI_0_S_AXI_BASEADDR 0xF8008000 +#define XPAR_PS7_AFI_0_S_AXI_HIGHADDR 0xF8008FFF + + +/* Definitions for peripheral PS7_AFI_1 */ +#define XPAR_PS7_AFI_1_S_AXI_BASEADDR 0xF8009000 +#define XPAR_PS7_AFI_1_S_AXI_HIGHADDR 0xF8009FFF + + +/* Definitions for peripheral PS7_AFI_2 */ +#define XPAR_PS7_AFI_2_S_AXI_BASEADDR 0xF800A000 +#define XPAR_PS7_AFI_2_S_AXI_HIGHADDR 0xF800AFFF + + +/* Definitions for peripheral PS7_AFI_3 */ +#define XPAR_PS7_AFI_3_S_AXI_BASEADDR 0xF800B000 +#define XPAR_PS7_AFI_3_S_AXI_HIGHADDR 0xF800BFFF + + +/* Definitions for peripheral PS7_DDRC_0 */ +#define XPAR_PS7_DDRC_0_S_AXI_BASEADDR 0xF8006000 +#define XPAR_PS7_DDRC_0_S_AXI_HIGHADDR 0xF8006FFF + + +/* Definitions for peripheral PS7_GLOBALTIMER_0 */ +#define XPAR_PS7_GLOBALTIMER_0_S_AXI_BASEADDR 0xF8F00200 +#define XPAR_PS7_GLOBALTIMER_0_S_AXI_HIGHADDR 0xF8F002FF + + +/* Definitions for peripheral PS7_GPV_0 */ +#define XPAR_PS7_GPV_0_S_AXI_BASEADDR 0xF8900000 +#define XPAR_PS7_GPV_0_S_AXI_HIGHADDR 0xF89FFFFF + + +/* Definitions for peripheral PS7_INTC_DIST_0 */ +#define XPAR_PS7_INTC_DIST_0_S_AXI_BASEADDR 0xF8F01000 +#define XPAR_PS7_INTC_DIST_0_S_AXI_HIGHADDR 0xF8F01FFF + + +/* Definitions for peripheral PS7_IOP_BUS_CONFIG_0 */ +#define XPAR_PS7_IOP_BUS_CONFIG_0_S_AXI_BASEADDR 0xE0200000 +#define XPAR_PS7_IOP_BUS_CONFIG_0_S_AXI_HIGHADDR 0xE0200FFF + + +/* Definitions for peripheral PS7_L2CACHEC_0 */ +#define XPAR_PS7_L2CACHEC_0_S_AXI_BASEADDR 0xF8F02000 +#define XPAR_PS7_L2CACHEC_0_S_AXI_HIGHADDR 0xF8F02FFF + + +/* Definitions for peripheral PS7_OCMC_0 */ +#define XPAR_PS7_OCMC_0_S_AXI_BASEADDR 0xF800C000 +#define XPAR_PS7_OCMC_0_S_AXI_HIGHADDR 0xF800CFFF + + +/* Definitions for peripheral PS7_PL310_0 */ +#define XPAR_PS7_PL310_0_S_AXI_BASEADDR 0xF8F02000 +#define XPAR_PS7_PL310_0_S_AXI_HIGHADDR 0xF8F02FFF + + +/* Definitions for peripheral PS7_PMU_0 */ +#define XPAR_PS7_PMU_0_S_AXI_BASEADDR 0xF8891000 +#define XPAR_PS7_PMU_0_S_AXI_HIGHADDR 0xF8891FFF +#define XPAR_PS7_PMU_0_PMU1_S_AXI_BASEADDR 0xF8893000 +#define XPAR_PS7_PMU_0_PMU1_S_AXI_HIGHADDR 0xF8893FFF + + +/* Definitions for peripheral PS7_QSPI_LINEAR_0 */ +#define XPAR_PS7_QSPI_LINEAR_0_S_AXI_BASEADDR 0xFC000000 +#define XPAR_PS7_QSPI_LINEAR_0_S_AXI_HIGHADDR 0xFCFFFFFF + + +/* Definitions for peripheral PS7_RAM_0 */ +#define XPAR_PS7_RAM_0_S_AXI_BASEADDR 0x00000000 +#define XPAR_PS7_RAM_0_S_AXI_HIGHADDR 0x0003FFFF + + +/* Definitions for peripheral PS7_RAM_1 */ +#define XPAR_PS7_RAM_1_S_AXI_BASEADDR 0xFFFC0000 +#define XPAR_PS7_RAM_1_S_AXI_HIGHADDR 0xFFFFFFFF + + +/* Definitions for peripheral PS7_SCUC_0 */ +#define XPAR_PS7_SCUC_0_S_AXI_BASEADDR 0xF8F00000 +#define XPAR_PS7_SCUC_0_S_AXI_HIGHADDR 0xF8F000FC + + +/* Definitions for peripheral PS7_SLCR_0 */ +#define XPAR_PS7_SLCR_0_S_AXI_BASEADDR 0xF8000000 +#define XPAR_PS7_SLCR_0_S_AXI_HIGHADDR 0xF8000FFF + + +/* Definitions for peripheral SYSTEMBUS */ +#define XPAR_SYSTEMBUS_BASEADDR 0x43C10000 +#define XPAR_SYSTEMBUS_HIGHADDR 0x43C11FFF + + +/******************************************************************/ + +/* Definitions for driver GPIOPS */ +#define XPAR_XGPIOPS_NUM_INSTANCES 1 + +/* Definitions for peripheral PS7_GPIO_0 */ +#define XPAR_PS7_GPIO_0_DEVICE_ID 0 +#define XPAR_PS7_GPIO_0_BASEADDR 0xE000A000 +#define XPAR_PS7_GPIO_0_HIGHADDR 0xE000AFFF + + +/******************************************************************/ + +/* Canonical definitions for peripheral PS7_GPIO_0 */ +#define XPAR_XGPIOPS_0_DEVICE_ID XPAR_PS7_GPIO_0_DEVICE_ID +#define XPAR_XGPIOPS_0_BASEADDR 0xE000A000 +#define XPAR_XGPIOPS_0_HIGHADDR 0xE000AFFF + + +/******************************************************************/ + +/* Definitions for driver QSPIPS */ +#define XPAR_XQSPIPS_NUM_INSTANCES 1 + +/* Definitions for peripheral PS7_QSPI_0 */ +#define XPAR_PS7_QSPI_0_DEVICE_ID 0 +#define XPAR_PS7_QSPI_0_BASEADDR 0xE000D000 +#define XPAR_PS7_QSPI_0_HIGHADDR 0xE000DFFF +#define XPAR_PS7_QSPI_0_QSPI_CLK_FREQ_HZ 200000000 +#define XPAR_PS7_QSPI_0_QSPI_MODE 0 +#define XPAR_PS7_QSPI_0_QSPI_BUS_WIDTH 2 + + +/******************************************************************/ + +/* Canonical definitions for peripheral PS7_QSPI_0 */ +#define XPAR_XQSPIPS_0_DEVICE_ID XPAR_PS7_QSPI_0_DEVICE_ID +#define XPAR_XQSPIPS_0_BASEADDR 0xE000D000 +#define XPAR_XQSPIPS_0_HIGHADDR 0xE000DFFF +#define XPAR_XQSPIPS_0_QSPI_CLK_FREQ_HZ 200000000 +#define XPAR_XQSPIPS_0_QSPI_MODE 0 +#define XPAR_XQSPIPS_0_QSPI_BUS_WIDTH 2 + + +/******************************************************************/ + +/* Definitions for Fabric interrupts connected to ps7_scugic_0 */ +#define XPAR_FABRIC_SYSTEMBUS_TX_DONE_INTR 62U +#define XPAR_FABRIC_SYSTEMBUS_RX_DONE_INTR 63U +#define XPAR_FABRIC_PHY_IRQ_INTR 64U + +/******************************************************************/ + +/* Canonical definitions for Fabric interrupts connected to ps7_scugic_0 */ + +/******************************************************************/ + +/* Definitions for driver SCUGIC */ +#define XPAR_XSCUGIC_NUM_INSTANCES 1U + +/* Definitions for peripheral PS7_SCUGIC_0 */ +#define XPAR_PS7_SCUGIC_0_DEVICE_ID 0U +#define XPAR_PS7_SCUGIC_0_BASEADDR 0xF8F00100U +#define XPAR_PS7_SCUGIC_0_HIGHADDR 0xF8F001FFU +#define XPAR_PS7_SCUGIC_0_DIST_BASEADDR 0xF8F01000U + + +/******************************************************************/ + +/* Canonical definitions for peripheral PS7_SCUGIC_0 */ +#define XPAR_SCUGIC_0_DEVICE_ID 0U +#define XPAR_SCUGIC_0_CPU_BASEADDR 0xF8F00100U +#define XPAR_SCUGIC_0_CPU_HIGHADDR 0xF8F001FFU +#define XPAR_SCUGIC_0_DIST_BASEADDR 0xF8F01000U + + +/******************************************************************/ + +/* Definitions for driver SCUTIMER */ +#define XPAR_XSCUTIMER_NUM_INSTANCES 1 + +/* Definitions for peripheral PS7_SCUTIMER_0 */ +#define XPAR_PS7_SCUTIMER_0_DEVICE_ID 0 +#define XPAR_PS7_SCUTIMER_0_BASEADDR 0xF8F00600 +#define XPAR_PS7_SCUTIMER_0_HIGHADDR 0xF8F0061F + + +/******************************************************************/ + +/* Canonical definitions for peripheral PS7_SCUTIMER_0 */ +#define XPAR_XSCUTIMER_0_DEVICE_ID XPAR_PS7_SCUTIMER_0_DEVICE_ID +#define XPAR_XSCUTIMER_0_BASEADDR 0xF8F00600 +#define XPAR_XSCUTIMER_0_HIGHADDR 0xF8F0061F + + +/******************************************************************/ + +/* Definitions for driver SCUWDT */ +#define XPAR_XSCUWDT_NUM_INSTANCES 1 + +/* Definitions for peripheral PS7_SCUWDT_0 */ +#define XPAR_PS7_SCUWDT_0_DEVICE_ID 0 +#define XPAR_PS7_SCUWDT_0_BASEADDR 0xF8F00620 +#define XPAR_PS7_SCUWDT_0_HIGHADDR 0xF8F006FF + + +/******************************************************************/ + +/* Canonical definitions for peripheral PS7_SCUWDT_0 */ +#define XPAR_SCUWDT_0_DEVICE_ID XPAR_PS7_SCUWDT_0_DEVICE_ID +#define XPAR_SCUWDT_0_BASEADDR 0xF8F00620 +#define XPAR_SCUWDT_0_HIGHADDR 0xF8F006FF + + +/******************************************************************/ + +/* Definitions for driver UARTPS */ +#define XPAR_XUARTPS_NUM_INSTANCES 1 + +/* Definitions for peripheral PS7_UART_0 */ +#define XPAR_PS7_UART_0_DEVICE_ID 0 +#define XPAR_PS7_UART_0_BASEADDR 0xE0000000 +#define XPAR_PS7_UART_0_HIGHADDR 0xE0000FFF +#define XPAR_PS7_UART_0_UART_CLK_FREQ_HZ 100000000 +#define XPAR_PS7_UART_0_HAS_MODEM 0 + + +/******************************************************************/ + +/* Canonical definitions for peripheral PS7_UART_0 */ +#define XPAR_XUARTPS_0_DEVICE_ID XPAR_PS7_UART_0_DEVICE_ID +#define XPAR_XUARTPS_0_BASEADDR 0xE0000000 +#define XPAR_XUARTPS_0_HIGHADDR 0xE0000FFF +#define XPAR_XUARTPS_0_UART_CLK_FREQ_HZ 100000000 +#define XPAR_XUARTPS_0_HAS_MODEM 0 + + +/******************************************************************/ + +/* Definitions for driver XADCPS */ +#define XPAR_XADCPS_NUM_INSTANCES 1 + +/* Definitions for peripheral PS7_XADC_0 */ +#define XPAR_PS7_XADC_0_DEVICE_ID 0 +#define XPAR_PS7_XADC_0_BASEADDR 0xF8007100 +#define XPAR_PS7_XADC_0_HIGHADDR 0xF8007120 + + +/******************************************************************/ + +/* Canonical definitions for peripheral PS7_XADC_0 */ +#define XPAR_XADCPS_0_DEVICE_ID XPAR_PS7_XADC_0_DEVICE_ID +#define XPAR_XADCPS_0_BASEADDR 0xF8007100 +#define XPAR_XADCPS_0_HIGHADDR 0xF8007120 + + +/******************************************************************/ + +#endif /* end of protection macro */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xparameters_ps.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xparameters_ps.h new file mode 100644 index 0000000..2a6a0e0 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xparameters_ps.h @@ -0,0 +1,334 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2017 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* @file xparameters_ps.h +* +* This file contains the address definitions for the hard peripherals +* attached to the ARM Cortex A9 core. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who     Date     Changes
+* ----- ------- -------- ---------------------------------------------------
+* 1.00a ecm/sdm 02/01/10 Initial version
+* 3.04a sdm     02/02/12 Removed some of the defines as they are being generated through
+*                        driver tcl
+* 5.0	pkp		01/16/15 Added interrupt ID definition of ttc for TEST APP
+* 6.6   srm     10/18/17 Added ARMA9 macro to identify CortexA9
+*
+* 
+* +* @note +* +* None. +* +******************************************************************************/ + +#ifndef _XPARAMETERS_PS_H_ +#define _XPARAMETERS_PS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/**************************** Include Files *******************************/ + + +/************************** Constant Definitions *****************************/ + +/* + * This block contains constant declarations for the peripherals + * within the hardblock + */ + +/* Canonical definitions for DDR MEMORY */ +#define XPAR_DDR_MEM_BASEADDR 0x00000000U +#define XPAR_DDR_MEM_HIGHADDR 0x3FFFFFFFU + +/* Canonical definitions for Interrupts */ +#define XPAR_XUARTPS_0_INTR XPS_UART0_INT_ID +#define XPAR_XUARTPS_1_INTR XPS_UART1_INT_ID +#define XPAR_XUSBPS_0_INTR XPS_USB0_INT_ID +#define XPAR_XUSBPS_1_INTR XPS_USB1_INT_ID +#define XPAR_XIICPS_0_INTR XPS_I2C0_INT_ID +#define XPAR_XIICPS_1_INTR XPS_I2C1_INT_ID +#define XPAR_XSPIPS_0_INTR XPS_SPI0_INT_ID +#define XPAR_XSPIPS_1_INTR XPS_SPI1_INT_ID +#define XPAR_XCANPS_0_INTR XPS_CAN0_INT_ID +#define XPAR_XCANPS_1_INTR XPS_CAN1_INT_ID +#define XPAR_XGPIOPS_0_INTR XPS_GPIO_INT_ID +#define XPAR_XEMACPS_0_INTR XPS_GEM0_INT_ID +#define XPAR_XEMACPS_0_WAKE_INTR XPS_GEM0_WAKE_INT_ID +#define XPAR_XEMACPS_1_INTR XPS_GEM1_INT_ID +#define XPAR_XEMACPS_1_WAKE_INTR XPS_GEM1_WAKE_INT_ID +#define XPAR_XSDIOPS_0_INTR XPS_SDIO0_INT_ID +#define XPAR_XQSPIPS_0_INTR XPS_QSPI_INT_ID +#define XPAR_XSDIOPS_1_INTR XPS_SDIO1_INT_ID +#define XPAR_XWDTPS_0_INTR XPS_WDT_INT_ID +#define XPAR_XDCFG_0_INTR XPS_DVC_INT_ID +#define XPAR_SCUTIMER_INTR XPS_SCU_TMR_INT_ID +#define XPAR_SCUWDT_INTR XPS_SCU_WDT_INT_ID +#define XPAR_XTTCPS_0_INTR XPS_TTC0_0_INT_ID +#define XPAR_XTTCPS_1_INTR XPS_TTC0_1_INT_ID +#define XPAR_XTTCPS_2_INTR XPS_TTC0_2_INT_ID +#define XPAR_XTTCPS_3_INTR XPS_TTC1_0_INT_ID +#define XPAR_XTTCPS_4_INTR XPS_TTC1_1_INT_ID +#define XPAR_XTTCPS_5_INTR XPS_TTC1_2_INT_ID +#define XPAR_XDMAPS_0_FAULT_INTR XPS_DMA0_ABORT_INT_ID +#define XPAR_XDMAPS_0_DONE_INTR_0 XPS_DMA0_INT_ID +#define XPAR_XDMAPS_0_DONE_INTR_1 XPS_DMA1_INT_ID +#define XPAR_XDMAPS_0_DONE_INTR_2 XPS_DMA2_INT_ID +#define XPAR_XDMAPS_0_DONE_INTR_3 XPS_DMA3_INT_ID +#define XPAR_XDMAPS_0_DONE_INTR_4 XPS_DMA4_INT_ID +#define XPAR_XDMAPS_0_DONE_INTR_5 XPS_DMA5_INT_ID +#define XPAR_XDMAPS_0_DONE_INTR_6 XPS_DMA6_INT_ID +#define XPAR_XDMAPS_0_DONE_INTR_7 XPS_DMA7_INT_ID + + +#define XPAR_XQSPIPS_0_LINEAR_BASEADDR XPS_QSPI_LINEAR_BASEADDR +#define XPAR_XPARPORTPS_CTRL_BASEADDR XPS_PARPORT_CRTL_BASEADDR + + + +/* Canonical definitions for DMAC */ + + +/* Canonical definitions for WDT */ + +/* Canonical definitions for SLCR */ +#define XPAR_XSLCR_NUM_INSTANCES 1U +#define XPAR_XSLCR_0_DEVICE_ID 0U +#define XPAR_XSLCR_0_BASEADDR XPS_SYS_CTRL_BASEADDR + +/* Canonical definitions for SCU GIC */ +#define XPAR_SCUGIC_NUM_INSTANCES 1U +#define XPAR_SCUGIC_SINGLE_DEVICE_ID 0U +#define XPAR_SCUGIC_CPU_BASEADDR (XPS_SCU_PERIPH_BASE + 0x00000100U) +#define XPAR_SCUGIC_DIST_BASEADDR (XPS_SCU_PERIPH_BASE + 0x00001000U) +#define XPAR_SCUGIC_ACK_BEFORE 0U + +/* Canonical definitions for Global Timer */ +#define XPAR_GLOBAL_TMR_NUM_INSTANCES 1U +#define XPAR_GLOBAL_TMR_DEVICE_ID 0U +#define XPAR_GLOBAL_TMR_BASEADDR (XPS_SCU_PERIPH_BASE + 0x00000200U) +#define XPAR_GLOBAL_TMR_INTR XPS_GLOBAL_TMR_INT_ID + + +/* Xilinx Parallel Flash Library (XilFlash) User Settings */ +#define XPAR_AXI_EMC + + +#define XPAR_CPU_CORTEXA9_CORE_CLOCK_FREQ_HZ XPAR_CPU_CORTEXA9_0_CPU_CLK_FREQ_HZ + + +/* + * This block contains constant declarations for the peripherals + * within the hardblock. These have been put for bacwards compatibilty + */ + +#define XPS_PERIPHERAL_BASEADDR 0xE0000000U +#define XPS_UART0_BASEADDR 0xE0000000U +#define XPS_UART1_BASEADDR 0xE0001000U +#define XPS_USB0_BASEADDR 0xE0002000U +#define XPS_USB1_BASEADDR 0xE0003000U +#define XPS_I2C0_BASEADDR 0xE0004000U +#define XPS_I2C1_BASEADDR 0xE0005000U +#define XPS_SPI0_BASEADDR 0xE0006000U +#define XPS_SPI1_BASEADDR 0xE0007000U +#define XPS_CAN0_BASEADDR 0xE0008000U +#define XPS_CAN1_BASEADDR 0xE0009000U +#define XPS_GPIO_BASEADDR 0xE000A000U +#define XPS_GEM0_BASEADDR 0xE000B000U +#define XPS_GEM1_BASEADDR 0xE000C000U +#define XPS_QSPI_BASEADDR 0xE000D000U +#define XPS_PARPORT_CRTL_BASEADDR 0xE000E000U +#define XPS_SDIO0_BASEADDR 0xE0100000U +#define XPS_SDIO1_BASEADDR 0xE0101000U +#define XPS_IOU_BUS_CFG_BASEADDR 0xE0200000U +#define XPS_NAND_BASEADDR 0xE1000000U +#define XPS_PARPORT0_BASEADDR 0xE2000000U +#define XPS_PARPORT1_BASEADDR 0xE4000000U +#define XPS_QSPI_LINEAR_BASEADDR 0xFC000000U +#define XPS_SYS_CTRL_BASEADDR 0xF8000000U /* AKA SLCR */ +#define XPS_TTC0_BASEADDR 0xF8001000U +#define XPS_TTC1_BASEADDR 0xF8002000U +#define XPS_DMAC0_SEC_BASEADDR 0xF8003000U +#define XPS_DMAC0_NON_SEC_BASEADDR 0xF8004000U +#define XPS_WDT_BASEADDR 0xF8005000U +#define XPS_DDR_CTRL_BASEADDR 0xF8006000U +#define XPS_DEV_CFG_APB_BASEADDR 0xF8007000U +#define XPS_AFI0_BASEADDR 0xF8008000U +#define XPS_AFI1_BASEADDR 0xF8009000U +#define XPS_AFI2_BASEADDR 0xF800A000U +#define XPS_AFI3_BASEADDR 0xF800B000U +#define XPS_OCM_BASEADDR 0xF800C000U +#define XPS_EFUSE_BASEADDR 0xF800D000U +#define XPS_CORESIGHT_BASEADDR 0xF8800000U +#define XPS_TOP_BUS_CFG_BASEADDR 0xF8900000U +#define XPS_SCU_PERIPH_BASE 0xF8F00000U +#define XPS_L2CC_BASEADDR 0xF8F02000U +#define XPS_SAM_RAM_BASEADDR 0xFFFC0000U +#define XPS_FPGA_AXI_S0_BASEADDR 0x40000000U +#define XPS_FPGA_AXI_S1_BASEADDR 0x80000000U +#define XPS_IOU_S_SWITCH_BASEADDR 0xE0000000U +#define XPS_PERIPH_APB_BASEADDR 0xF8000000U + +/* Shared Peripheral Interrupts (SPI) */ +#define XPS_CORE_PARITY0_INT_ID 32U +#define XPS_CORE_PARITY1_INT_ID 33U +#define XPS_L2CC_INT_ID 34U +#define XPS_OCMINTR_INT_ID 35U +#define XPS_ECC_INT_ID 36U +#define XPS_PMU0_INT_ID 37U +#define XPS_PMU1_INT_ID 38U +#define XPS_SYSMON_INT_ID 39U +#define XPS_DVC_INT_ID 40U +#define XPS_WDT_INT_ID 41U +#define XPS_TTC0_0_INT_ID 42U +#define XPS_TTC0_1_INT_ID 43U +#define XPS_TTC0_2_INT_ID 44U +#define XPS_DMA0_ABORT_INT_ID 45U +#define XPS_DMA0_INT_ID 46U +#define XPS_DMA1_INT_ID 47U +#define XPS_DMA2_INT_ID 48U +#define XPS_DMA3_INT_ID 49U +#define XPS_SMC_INT_ID 50U +#define XPS_QSPI_INT_ID 51U +#define XPS_GPIO_INT_ID 52U +#define XPS_USB0_INT_ID 53U +#define XPS_GEM0_INT_ID 54U +#define XPS_GEM0_WAKE_INT_ID 55U +#define XPS_SDIO0_INT_ID 56U +#define XPS_I2C0_INT_ID 57U +#define XPS_SPI0_INT_ID 58U +#define XPS_UART0_INT_ID 59U +#define XPS_CAN0_INT_ID 60U +#define XPS_FPGA0_INT_ID 61U +#define XPS_FPGA1_INT_ID 62U +#define XPS_FPGA2_INT_ID 63U +#define XPS_FPGA3_INT_ID 64U +#define XPS_FPGA4_INT_ID 65U +#define XPS_FPGA5_INT_ID 66U +#define XPS_FPGA6_INT_ID 67U +#define XPS_FPGA7_INT_ID 68U +#define XPS_TTC1_0_INT_ID 69U +#define XPS_TTC1_1_INT_ID 70U +#define XPS_TTC1_2_INT_ID 71U +#define XPS_DMA4_INT_ID 72U +#define XPS_DMA5_INT_ID 73U +#define XPS_DMA6_INT_ID 74U +#define XPS_DMA7_INT_ID 75U +#define XPS_USB1_INT_ID 76U +#define XPS_GEM1_INT_ID 77U +#define XPS_GEM1_WAKE_INT_ID 78U +#define XPS_SDIO1_INT_ID 79U +#define XPS_I2C1_INT_ID 80U +#define XPS_SPI1_INT_ID 81U +#define XPS_UART1_INT_ID 82U +#define XPS_CAN1_INT_ID 83U +#define XPS_FPGA8_INT_ID 84U +#define XPS_FPGA9_INT_ID 85U +#define XPS_FPGA10_INT_ID 86U +#define XPS_FPGA11_INT_ID 87U +#define XPS_FPGA12_INT_ID 88U +#define XPS_FPGA13_INT_ID 89U +#define XPS_FPGA14_INT_ID 90U +#define XPS_FPGA15_INT_ID 91U + +/* Private Peripheral Interrupts (PPI) */ +#define XPS_GLOBAL_TMR_INT_ID 27U /* SCU Global Timer interrupt */ +#define XPS_FIQ_INT_ID 28U /* FIQ from FPGA fabric */ +#define XPS_SCU_TMR_INT_ID 29U /* SCU Private Timer interrupt */ +#define XPS_SCU_WDT_INT_ID 30U /* SCU Private WDT interrupt */ +#define XPS_IRQ_INT_ID 31U /* IRQ from FPGA fabric */ + + +/* REDEFINES for TEST APP */ +/* Definitions for UART */ +#define XPAR_PS7_UART_0_INTR XPS_UART0_INT_ID +#define XPAR_PS7_UART_1_INTR XPS_UART1_INT_ID +#define XPAR_PS7_USB_0_INTR XPS_USB0_INT_ID +#define XPAR_PS7_USB_1_INTR XPS_USB1_INT_ID +#define XPAR_PS7_I2C_0_INTR XPS_I2C0_INT_ID +#define XPAR_PS7_I2C_1_INTR XPS_I2C1_INT_ID +#define XPAR_PS7_SPI_0_INTR XPS_SPI0_INT_ID +#define XPAR_PS7_SPI_1_INTR XPS_SPI1_INT_ID +#define XPAR_PS7_CAN_0_INTR XPS_CAN0_INT_ID +#define XPAR_PS7_CAN_1_INTR XPS_CAN1_INT_ID +#define XPAR_PS7_GPIO_0_INTR XPS_GPIO_INT_ID +#define XPAR_PS7_ETHERNET_0_INTR XPS_GEM0_INT_ID +#define XPAR_PS7_ETHERNET_0_WAKE_INTR XPS_GEM0_WAKE_INT_ID +#define XPAR_PS7_ETHERNET_1_INTR XPS_GEM1_INT_ID +#define XPAR_PS7_ETHERNET_1_WAKE_INTR XPS_GEM1_WAKE_INT_ID +#define XPAR_PS7_QSPI_0_INTR XPS_QSPI_INT_ID +#define XPAR_PS7_WDT_0_INTR XPS_WDT_INT_ID +#define XPAR_PS7_SCUWDT_0_INTR XPS_SCU_WDT_INT_ID +#define XPAR_PS7_SCUTIMER_0_INTR XPS_SCU_TMR_INT_ID +#define XPAR_PS7_XADC_0_INTR XPS_SYSMON_INT_ID +#define XPAR_PS7_TTC_0_INTR XPS_TTC0_0_INT_ID +#define XPAR_PS7_TTC_1_INTR XPS_TTC0_1_INT_ID +#define XPAR_PS7_TTC_2_INTR XPS_TTC0_2_INT_ID +#define XPAR_PS7_TTC_3_INTR XPS_TTC1_0_INT_ID +#define XPAR_PS7_TTC_4_INTR XPS_TTC1_1_INT_ID +#define XPAR_PS7_TTC_5_INTR XPS_TTC1_2_INT_ID + +#define XPAR_XADCPS_INT_ID XPS_SYSMON_INT_ID + +/* For backwards compatibilty */ +#define XPAR_XUARTPS_0_CLOCK_HZ XPAR_XUARTPS_0_UART_CLK_FREQ_HZ +#define XPAR_XUARTPS_1_CLOCK_HZ XPAR_XUARTPS_1_UART_CLK_FREQ_HZ +#define XPAR_XTTCPS_0_CLOCK_HZ XPAR_XTTCPS_0_TTC_CLK_FREQ_HZ +#define XPAR_XTTCPS_1_CLOCK_HZ XPAR_XTTCPS_1_TTC_CLK_FREQ_HZ +#define XPAR_XTTCPS_2_CLOCK_HZ XPAR_XTTCPS_2_TTC_CLK_FREQ_HZ +#define XPAR_XTTCPS_3_CLOCK_HZ XPAR_XTTCPS_3_TTC_CLK_FREQ_HZ +#define XPAR_XTTCPS_4_CLOCK_HZ XPAR_XTTCPS_4_TTC_CLK_FREQ_HZ +#define XPAR_XTTCPS_5_CLOCK_HZ XPAR_XTTCPS_5_TTC_CLK_FREQ_HZ +#define XPAR_XIICPS_0_CLOCK_HZ XPAR_XIICPS_0_I2C_CLK_FREQ_HZ +#define XPAR_XIICPS_1_CLOCK_HZ XPAR_XIICPS_1_I2C_CLK_FREQ_HZ + +#define XPAR_XQSPIPS_0_CLOCK_HZ XPAR_XQSPIPS_0_QSPI_CLK_FREQ_HZ + +#ifdef XPAR_CPU_CORTEXA9_0_CPU_CLK_FREQ_HZ +#define XPAR_CPU_CORTEXA9_CORE_CLOCK_FREQ_HZ XPAR_CPU_CORTEXA9_0_CPU_CLK_FREQ_HZ +#endif + +#ifdef XPAR_CPU_CORTEXA9_1_CPU_CLK_FREQ_HZ +#define XPAR_CPU_CORTEXA9_CORE_CLOCK_FREQ_HZ XPAR_CPU_CORTEXA9_1_CPU_CLK_FREQ_HZ +#endif + +#define XPAR_SCUTIMER_DEVICE_ID 0U +#define XPAR_SCUWDT_DEVICE_ID 0U + + +#ifdef __cplusplus +} +#endif + +#endif /* protection macro */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xplatform_info.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xplatform_info.h new file mode 100644 index 0000000..88851bb --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xplatform_info.h @@ -0,0 +1,120 @@ +/****************************************************************************** +* +* Copyright (C) 2014 - 2017 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xplatform_info.h +* +* @addtogroup common_platform_info APIs to Get Platform Information +* +* The xplatform_info.h file contains definitions for various available Xilinx® +* platforms. Also, it contains prototype of APIs, which can be used to get the +* platform information. +* +* @{ +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date    Changes
+* ----- ---- --------- -------------------------------------------------------
+* 6.4    ms   05/23/17 Added PSU_PMU macro to support XGetPSVersion_Info
+*                      function for PMUFW.
+* 
+* +******************************************************************************/ + +#ifndef XPLATFORM_INFO_H /* prevent circular inclusions */ +#define XPLATFORM_INFO_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +#include "xil_types.h" + +/************************** Constant Definitions *****************************/ +#if defined (versal) +#define XPAR_PMC_TAP_BASEADDR 0xF11A0000U +#define XPAR_PMC_TAP_VERSION_OFFSET 0x00000004U +#define XPLAT_PS_VERSION_ADDRESS (XPAR_PMC_TAP_BASEADDR + \ + XPAR_PMC_TAP_VERSION_OFFSET) +#else +#define XPAR_CSU_BASEADDR 0xFFCA0000U +#define XPAR_CSU_VER_OFFSET 0x00000044U +#define XPLAT_PS_VERSION_ADDRESS (XPAR_CSU_BASEADDR + \ + XPAR_CSU_VER_OFFSET) +#endif +#define XPLAT_ZYNQ_ULTRA_MP_SILICON 0x0 +#define XPLAT_ZYNQ_ULTRA_MP 0x1 +#define XPLAT_ZYNQ_ULTRA_MPVEL 0x2 +#define XPLAT_ZYNQ_ULTRA_MPQEMU 0x3 +#define XPLAT_ZYNQ 0x4 +#define XPLAT_MICROBLAZE 0x5 +#define XPLAT_versal 0x6U + +#define XPS_VERSION_1 0x0 +#define XPS_VERSION_2 0x1 +#define XPLAT_INFO_MASK (0xF) + +#if defined (versal) +#define XPS_VERSION_INFO_MASK 0xFF00U +#define XPS_VERSION_INFO_SHIFT 0x8U +#define XPLAT_INFO_SHIFT 0x18U +#else +#define XPS_VERSION_INFO_MASK (0xF) +#define XPS_VERSION_INFO_SHIFT 0x0U +#define XPLAT_INFO_SHIFT 0xCU +#endif + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + + +u32 XGetPlatform_Info(void); + +#if defined (ARMR5) || (__aarch64__) || (ARMA53_32) || (PSU_PMU) +u32 XGetPSVersion_Info(); +#endif + +#if defined (ARMR5) || (__aarch64__) || (ARMA53_32) +u32 XGet_Zynq_UltraMp_Platform_info(); +#endif +/************************** Function Prototypes ******************************/ + + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** +* @} End of "addtogroup common_platform_info". +*/ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xpm_counter.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xpm_counter.h new file mode 100644 index 0000000..39db7d8 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xpm_counter.h @@ -0,0 +1,572 @@ +/****************************************************************************** +* +* Copyright (C) 2011 - 2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xpm_counter.h +* +* @addtogroup a9_event_counter_apis Cortex A9 Event Counters Functions +* +* Cortex A9 event counter functions can be utilized to configure and control +* the Cortex-A9 performance monitor events. +* +* Cortex-A9 performance monitor has six event counters which can be used to +* count a variety of events described in Coretx-A9 TRM. xpm_counter.h defines +* configurations XPM_CNTRCFGx which can be used to program the event counters +* to count a set of events. +* +* @note +* It doesn't handle the Cortex-A9 cycle counter, as the cycle counter is +* being used for time keeping. +* +* @{ +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a sdm  07/11/11 First release
+* 6.8   aru  09/06/18 Removed compilation warnings for ARMCC toolchain.
+* 
+* +******************************************************************************/ + +#ifndef XPMCOUNTER_H /* prevent circular inclusions */ +#define XPMCOUNTER_H /* by using protection macros */ + +/***************************** Include Files ********************************/ + +#include +#include "xpseudo_asm.h" +#include "xil_types.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/************************** Constant Definitions ****************************/ + +/* Number of performance counters */ +#define XPM_CTRCOUNT 6U + +/* The following constants define the Cortex-A9 Performance Monitor Events */ + +/* + * Software increment. The register is incremented only on writes to the + * Software Increment Register + */ +#define XPM_EVENT_SOFTINCR 0x00U + +/* + * Instruction fetch that causes a refill at (at least) the lowest level(s) of + * instruction or unified cache. Includes the speculative linefills in the + * count + */ +#define XPM_EVENT_INSRFETCH_CACHEREFILL 0x01U + +/* + * Instruction fetch that causes a TLB refill at (at least) the lowest level of + * TLB. Includes the speculative requests in the count + */ +#define XPM_EVENT_INSTRFECT_TLBREFILL 0x02U + +/* + * Data read or write operation that causes a refill at (at least) the lowest + * level(s)of data or unified cache. Counts the number of allocations performed + * in the Data Cache due to a read or a write + */ +#define XPM_EVENT_DATA_CACHEREFILL 0x03U + +/* + * Data read or write operation that causes a cache access at (at least) the + * lowest level(s) of data or unified cache. This includes speculative reads + */ +#define XPM_EVENT_DATA_CACHEACCESS 0x04U + +/* + * Data read or write operation that causes a TLB refill at (at least) the + * lowest level of TLB. This does not include micro TLB misses due to PLD, PLI, + * CP15 Cache operation by MVA and CP15 VA to PA operations + */ +#define XPM_EVENT_DATA_TLBREFILL 0x05U + +/* + * Data read architecturally executed. Counts the number of data read + * instructions accepted by the Load Store Unit. This includes counting the + * speculative and aborted LDR/LDM, as well as the reads due to the SWP + * instructions + */ +#define XPM_EVENT_DATA_READS 0x06U + +/* + * Data write architecturally executed. Counts the number of data write + * instructions accepted by the Load Store Unit. This includes counting the + * speculative and aborted STR/STM, as well as the writes due to the SWP + * instructions + */ +#define XPM_EVENT_DATA_WRITE 0x07U + +/* Exception taken. Counts the number of exceptions architecturally taken.*/ +#define XPM_EVENT_EXCEPTION 0x09U + +/* Exception return architecturally executed.*/ +#define XPM_EVENT_EXCEPRETURN 0x0AU + +/* + * Change to ContextID retired. Counts the number of instructions + * architecturally executed writing into the ContextID Register + */ +#define XPM_EVENT_CHANGECONTEXT 0x0BU + +/* + * Software change of PC, except by an exception, architecturally executed. + * Count the number of PC changes architecturally executed, excluding the PC + * changes due to taken exceptions + */ +#define XPM_EVENT_SW_CHANGEPC 0x0CU + +/* + * Immediate branch architecturally executed (taken or not taken). This includes + * the branches which are flushed due to a previous load/store which aborts + * late + */ +#define XPM_EVENT_IMMEDBRANCH 0x0DU + +/* + * Unaligned access architecturally executed. Counts the number of aborted + * unaligned accessed architecturally executed, and the number of not-aborted + * unaligned accesses, including the speculative ones + */ +#define XPM_EVENT_UNALIGNEDACCESS 0x0FU + +/* + * Branch mispredicted/not predicted. Counts the number of mispredicted or + * not-predicted branches executed. This includes the branches which are flushed + * due to a previous load/store which aborts late + */ +#define XPM_EVENT_BRANCHMISS 0x10U + +/* + * Counts clock cycles when the Cortex-A9 processor is not in WFE/WFI. This + * event is not exported on the PMUEVENT bus + */ +#define XPM_EVENT_CLOCKCYCLES 0x11U + +/* + * Branches or other change in program flow that could have been predicted by + * the branch prediction resources of the processor. This includes the branches + * which are flushed due to a previous load/store which aborts late + */ +#define XPM_EVENT_BRANCHPREDICT 0x12U + +/* + * Java bytecode execute. Counts the number of Java bytecodes being decoded, + * including speculative ones + */ +#define XPM_EVENT_JAVABYTECODE 0x40U + +/* + * Software Java bytecode executed. Counts the number of software java bytecodes + * being decoded, including speculative ones + */ +#define XPM_EVENT_SWJAVABYTECODE 0x41U + +/* + * Jazelle backward branches executed. Counts the number of Jazelle taken + * branches being executed. This includes the branches which are flushed due + * to a previous load/store which aborts late + */ +#define XPM_EVENT_JAVABACKBRANCH 0x42U + +/* + * Coherent linefill miss Counts the number of coherent linefill requests + * performed by the Cortex-A9 processor which also miss in all the other + * Cortex-A9 processors, meaning that the request is sent to the external + * memory + */ +#define XPM_EVENT_COHERLINEMISS 0x50U + +/* + * Coherent linefill hit. Counts the number of coherent linefill requests + * performed by the Cortex-A9 processor which hit in another Cortex-A9 + * processor, meaning that the linefill data is fetched directly from the + * relevant Cortex-A9 cache + */ +#define XPM_EVENT_COHERLINEHIT 0x51U + +/* + * Instruction cache dependent stall cycles. Counts the number of cycles where + * the processor is ready to accept new instructions, but does not receive any + * due to the instruction side not being able to provide any and the + * instruction cache is currently performing at least one linefill + */ +#define XPM_EVENT_INSTRSTALL 0x60U + +/* + * Data cache dependent stall cycles. Counts the number of cycles where the core + * has some instructions that it cannot issue to any pipeline, and the Load + * Store unit has at least one pending linefill request, and no pending + */ +#define XPM_EVENT_DATASTALL 0x61U + +/* + * Main TLB miss stall cycles. Counts the number of cycles where the processor + * is stalled waiting for the completion of translation table walks from the + * main TLB. The processor stalls can be due to the instruction side not being + * able to provide the instructions, or to the data side not being able to + * provide the necessary data, due to them waiting for the main TLB translation + * table walk to complete + */ +#define XPM_EVENT_MAINTLBSTALL 0x62U + +/* + * Counts the number of STREX instructions architecturally executed and + * passed + */ +#define XPM_EVENT_STREXPASS 0x63U + +/* + * Counts the number of STREX instructions architecturally executed and + * failed + */ +#define XPM_EVENT_STREXFAIL 0x64U + +/* + * Data eviction. Counts the number of eviction requests due to a linefill in + * the data cache + */ +#define XPM_EVENT_DATAEVICT 0x65U + +/* + * Counts the number of cycles where the issue stage does not dispatch any + * instruction because it is empty or cannot dispatch any instructions + */ +#define XPM_EVENT_NODISPATCH 0x66U + +/* + * Counts the number of cycles where the issue stage is empty + */ +#define XPM_EVENT_ISSUEEMPTY 0x67U + +/* + * Counts the number of instructions going through the Register Renaming stage. + * This number is an approximate number of the total number of instructions + * speculatively executed, and even more approximate of the total number of + * instructions architecturally executed. The approximation depends mainly on + * the branch misprediction rate. + * The renaming stage can handle two instructions in the same cycle so the event + * is two bits long: + * - b00 no instructions renamed + * - b01 one instruction renamed + * - b10 two instructions renamed + */ +#define XPM_EVENT_INSTRRENAME 0x68U + +/* + * Counts the number of procedure returns whose condition codes do not fail, + * excluding all returns from exception. This count includes procedure returns + * which are flushed due to a previous load/store which aborts late. + * Only the following instructions are reported: + * - BX R14 + * - MOV PC LR + * - POP {..,pc} + * - LDR pc,[sp],#offset + * The following instructions are not reported: + * - LDMIA R9!,{..,PC} (ThumbEE state only) + * - LDR PC,[R9],#offset (ThumbEE state only) + * - BX R0 (Rm != R14) + * - MOV PC,R0 (Rm != R14) + * - LDM SP,{...,PC} (writeback not specified) + * - LDR PC,[SP,#offset] (wrong addressing mode) + */ +#define XPM_EVENT_PREDICTFUNCRET 0x6EU + +/* + * Counts the number of instructions being executed in the main execution + * pipeline of the processor, the multiply pipeline and arithmetic logic unit + * pipeline. The counted instructions are still speculative + */ +#define XPM_EVENT_MAINEXEC 0x70U + +/* + * Counts the number of instructions being executed in the processor second + * execution pipeline (ALU). The counted instructions are still speculative + */ +#define XPM_EVENT_SECEXEC 0x71U + +/* + * Counts the number of instructions being executed in the Load/Store unit. The + * counted instructions are still speculative + */ +#define XPM_EVENT_LDRSTR 0x72U + +/* + * Counts the number of Floating-point instructions going through the Register + * Rename stage. Instructions are still speculative in this stage. + *Two floating-point instructions can be renamed in the same cycle so the event + * is two bitslong: + *0b00 no floating-point instruction renamed + *0b01 one floating-point instruction renamed + *0b10 two floating-point instructions renamed + */ +#define XPM_EVENT_FLOATRENAME 0x73U + +/* + * Counts the number of Neon instructions going through the Register Rename + * stage.Instructions are still speculative in this stage. + * Two NEON instructions can be renamed in the same cycle so the event is two + * bits long: + *0b00 no NEON instruction renamed + *0b01 one NEON instruction renamed + *0b10 two NEON instructions renamed + */ +#define XPM_EVENT_NEONRENAME 0x74U + +/* + * Counts the number of cycles where the processor is stalled because PLD slots + * are all full + */ +#define XPM_EVENT_PLDSTALL 0x80U + +/* + * Counts the number of cycles when the processor is stalled and the data side + * is stalled too because it is full and executing writes to the external + * memory + */ +#define XPM_EVENT_WRITESTALL 0x81U + +/* + * Counts the number of stall cycles due to main TLB misses on requests issued + * by the instruction side + */ +#define XPM_EVENT_INSTRTLBSTALL 0x82U + +/* + * Counts the number of stall cycles due to main TLB misses on requests issued + * by the data side + */ +#define XPM_EVENT_DATATLBSTALL 0x83U + +/* + * Counts the number of stall cycles due to micro TLB misses on the instruction + * side. This event does not include main TLB miss stall cycles that are already + * counted in the corresponding main TLB event + */ +#define XPM_EVENT_INSTR_uTLBSTALL 0x84U + +/* + * Counts the number of stall cycles due to micro TLB misses on the data side. + * This event does not include main TLB miss stall cycles that are already + * counted in the corresponding main TLB event + */ +#define XPM_EVENT_DATA_uTLBSTALL 0x85U + +/* + * Counts the number of stall cycles because of the execution of a DMB memory + * barrier. This includes all DMB instructions being executed, even + * speculatively + */ +#define XPM_EVENT_DMB_STALL 0x86U + +/* + * Counts the number of cycles during which the integer core clock is enabled + */ +#define XPM_EVENT_INT_CLKEN 0x8AU + +/* + * Counts the number of cycles during which the Data Engine clock is enabled + */ +#define XPM_EVENT_DE_CLKEN 0x8BU + +/* + * Counts the number of ISB instructions architecturally executed + */ +#define XPM_EVENT_INSTRISB 0x90U + +/* + * Counts the number of DSB instructions architecturally executed + */ +#define XPM_EVENT_INSTRDSB 0x91U + +/* + * Counts the number of DMB instructions speculatively executed + */ +#define XPM_EVENT_INSTRDMB 0x92U + +/* + * Counts the number of external interrupts executed by the processor + */ +#define XPM_EVENT_EXTINT 0x93U + +/* + * PLE cache line request completed + */ +#define XPM_EVENT_PLE_LRC 0xA0U + +/* + * PLE cache line request skipped + */ +#define XPM_EVENT_PLE_LRS 0xA1U + +/* + * PLE FIFO flush + */ +#define XPM_EVENT_PLE_FLUSH 0xA2U + +/* + * PLE request complete + */ +#define XPM_EVENT_PLE_CMPL 0xA3U + +/* + * PLE FIFO overflow + */ +#define XPM_EVENT_PLE_OVFL 0xA4U + +/* + * PLE request programmed + */ +#define XPM_EVENT_PLE_PROG 0xA5U + +/* + * The following constants define the configurations for Cortex-A9 Performance + * Monitor Events. Each configuration configures the event counters for a set + * of events. + * ----------------------------------------------- + * Config PmCtr0... PmCtr5 + * ----------------------------------------------- + * XPM_CNTRCFG1 { XPM_EVENT_SOFTINCR, + * XPM_EVENT_INSRFETCH_CACHEREFILL, + * XPM_EVENT_INSTRFECT_TLBREFILL, + * XPM_EVENT_DATA_CACHEREFILL, + * XPM_EVENT_DATA_CACHEACCESS, + * XPM_EVENT_DATA_TLBREFILL } + * + * XPM_CNTRCFG2 { XPM_EVENT_DATA_READS, + * XPM_EVENT_DATA_WRITE, + * XPM_EVENT_EXCEPTION, + * XPM_EVENT_EXCEPRETURN, + * XPM_EVENT_CHANGECONTEXT, + * XPM_EVENT_SW_CHANGEPC } + * + * XPM_CNTRCFG3 { XPM_EVENT_IMMEDBRANCH, + * XPM_EVENT_UNALIGNEDACCESS, + * XPM_EVENT_BRANCHMISS, + * XPM_EVENT_CLOCKCYCLES, + * XPM_EVENT_BRANCHPREDICT, + * XPM_EVENT_JAVABYTECODE } + * + * XPM_CNTRCFG4 { XPM_EVENT_SWJAVABYTECODE, + * XPM_EVENT_JAVABACKBRANCH, + * XPM_EVENT_COHERLINEMISS, + * XPM_EVENT_COHERLINEHIT, + * XPM_EVENT_INSTRSTALL, + * XPM_EVENT_DATASTALL } + * + * XPM_CNTRCFG5 { XPM_EVENT_MAINTLBSTALL, + * XPM_EVENT_STREXPASS, + * XPM_EVENT_STREXFAIL, + * XPM_EVENT_DATAEVICT, + * XPM_EVENT_NODISPATCH, + * XPM_EVENT_ISSUEEMPTY } + * + * XPM_CNTRCFG6 { XPM_EVENT_INSTRRENAME, + * XPM_EVENT_PREDICTFUNCRET, + * XPM_EVENT_MAINEXEC, + * XPM_EVENT_SECEXEC, + * XPM_EVENT_LDRSTR, + * XPM_EVENT_FLOATRENAME } + * + * XPM_CNTRCFG7 { XPM_EVENT_NEONRENAME, + * XPM_EVENT_PLDSTALL, + * XPM_EVENT_WRITESTALL, + * XPM_EVENT_INSTRTLBSTALL, + * XPM_EVENT_DATATLBSTALL, + * XPM_EVENT_INSTR_uTLBSTALL } + * + * XPM_CNTRCFG8 { XPM_EVENT_DATA_uTLBSTALL, + * XPM_EVENT_DMB_STALL, + * XPM_EVENT_INT_CLKEN, + * XPM_EVENT_DE_CLKEN, + * XPM_EVENT_INSTRISB, + * XPM_EVENT_INSTRDSB } + * + * XPM_CNTRCFG9 { XPM_EVENT_INSTRDMB, + * XPM_EVENT_EXTINT, + * XPM_EVENT_PLE_LRC, + * XPM_EVENT_PLE_LRS, + * XPM_EVENT_PLE_FLUSH, + * XPM_EVENT_PLE_CMPL } + * + * XPM_CNTRCFG10 { XPM_EVENT_PLE_OVFL, + * XPM_EVENT_PLE_PROG, + * XPM_EVENT_PLE_LRC, + * XPM_EVENT_PLE_LRS, + * XPM_EVENT_PLE_FLUSH, + * XPM_EVENT_PLE_CMPL } + * + * XPM_CNTRCFG11 { XPM_EVENT_DATASTALL, + * XPM_EVENT_INSRFETCH_CACHEREFILL, + * XPM_EVENT_INSTRFECT_TLBREFILL, + * XPM_EVENT_DATA_CACHEREFILL, + * XPM_EVENT_DATA_CACHEACCESS, + * XPM_EVENT_DATA_TLBREFILL } + */ +#define XPM_CNTRCFG1 0 +#define XPM_CNTRCFG2 1 +#define XPM_CNTRCFG3 2 +#define XPM_CNTRCFG4 3 +#define XPM_CNTRCFG5 4 +#define XPM_CNTRCFG6 5 +#define XPM_CNTRCFG7 6 +#define XPM_CNTRCFG8 7 +#define XPM_CNTRCFG9 8 +#define XPM_CNTRCFG10 9 +#define XPM_CNTRCFG11 10 + +/**************************** Type Definitions ******************************/ + +/***************** Macros (Inline Functions) Definitions ********************/ + +/************************** Variable Definitions ****************************/ + +/************************** Function Prototypes *****************************/ + +/* Interface fuctions to access perfromance counters from abstraction layer */ +void Xpm_SetEvents(s32 PmcrCfg); +void Xpm_GetEventCounters(u32 *PmCtrValue); + +#ifdef __cplusplus +} +#endif + +#endif +/** +* @} End of "addtogroup a9_event_counter_apis". +*/ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xpseudo_asm.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xpseudo_asm.h new file mode 100644 index 0000000..c7123a0 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xpseudo_asm.h @@ -0,0 +1,82 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xpseudo_asm.h +* +* @addtogroup a9_specific Cortex A9 Processor Specific Include Files +* +* The xpseudo_asm.h includes xreg_cortexa9.h and xpseudo_asm_gcc.h. +* +* The xreg_cortexa9.h file contains definitions for inline assembler code. +* It provides inline definitions for Cortex A9 GPRs, SPRs, MPE registers, +* co-processor registers and Debug registers. +* +* The xpseudo_asm_gcc.h contains the definitions for the most often used inline +* assembler instructions, available as macros. These can be very useful for +* tasks such as setting or getting special purpose registers, synchronization, +* or cache manipulation etc. These inline assembler instructions can be used +* from drivers and user applications written in C. +* +* @{ +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a ecm  10/18/09 First release
+* 3.04a sdm  01/02/12 Remove redundant dsb in mcr instruction.
+* 6.8   aru  09/06/18 Removed compilation warnings for ARMCC toolchain.
+* 
+* +******************************************************************************/ +#ifndef XPSEUDO_ASM_H +#define XPSEUDO_ASM_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "xreg_cortexa9.h" +#ifdef __GNUC__ + #include "xpseudo_asm_gcc.h" +#elif defined (__ICCARM__) + #include "xpseudo_asm_iccarm.h" +#else + #include "xpseudo_asm_rvct.h" +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* XPSEUDO_ASM_H */ +/** +* @} End of "addtogroup a9_specific". +*/ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xpseudo_asm_gcc.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xpseudo_asm_gcc.h new file mode 100644 index 0000000..85b067d --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xpseudo_asm_gcc.h @@ -0,0 +1,252 @@ +/****************************************************************************** +* +* Copyright (C) 2014 - 2016 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xpseudo_asm_gcc.h +* +* This header file contains macros for using inline assembler code. It is +* written specifically for the GNU compiler. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who      Date     Changes
+* ----- -------- -------- -----------------------------------------------
+* 5.00 	pkp		 05/21/14 First release
+* 6.0   mus      07/27/16 Consolidated file for a53,a9 and r5 processors
+* 
+* +******************************************************************************/ + +#ifndef XPSEUDO_ASM_GCC_H /* prevent circular inclusions */ +#define XPSEUDO_ASM_GCC_H /* by using protection macros */ + +/***************************** Include Files ********************************/ + +#include "xil_types.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/************************** Constant Definitions ****************************/ + +/**************************** Type Definitions ******************************/ + +/***************** Macros (Inline Functions) Definitions ********************/ + +/* necessary for pre-processor */ +#define stringify(s) tostring(s) +#define tostring(s) #s + +#if defined (__aarch64__) +/* pseudo assembler instructions */ +#define mfcpsr() ({u32 rval = 0U; \ + asm volatile("mrs %0, DAIF" : "=r" (rval));\ + rval;\ + }) + +#define mtcpsr(v) __asm__ __volatile__ ("msr DAIF, %0" : : "r" (v)) + +#define cpsiei() //__asm__ __volatile__("cpsie i\n") +#define cpsidi() //__asm__ __volatile__("cpsid i\n") + +#define cpsief() //__asm__ __volatile__("cpsie f\n") +#define cpsidf() //__asm__ __volatile__("cpsid f\n") + + + +#define mtgpr(rn, v) /*__asm__ __volatile__(\ + "mov r" stringify(rn) ", %0 \n"\ + : : "r" (v)\ + )*/ + +#define mfgpr(rn) /*({u32 rval; \ + __asm__ __volatile__(\ + "mov %0,r" stringify(rn) "\n"\ + : "=r" (rval)\ + );\ + rval;\ + })*/ + +/* memory synchronization operations */ + +/* Instruction Synchronization Barrier */ +#define isb() __asm__ __volatile__ ("isb sy") + +/* Data Synchronization Barrier */ +#define dsb() __asm__ __volatile__("dsb sy") + +/* Data Memory Barrier */ +#define dmb() __asm__ __volatile__("dmb sy") + + +/* Memory Operations */ +#define ldr(adr) ({u64 rval; \ + __asm__ __volatile__(\ + "ldr %0,[%1]"\ + : "=r" (rval) : "r" (adr)\ + );\ + rval;\ + }) + +#define mfelrel3() ({u64 rval = 0U; \ + asm volatile("mrs %0, ELR_EL3" : "=r" (rval));\ + rval;\ + }) + +#define mtelrel3(v) __asm__ __volatile__ ("msr ELR_EL3, %0" : : "r" (v)) + +#else + +/* pseudo assembler instructions */ +#define mfcpsr() ({u32 rval = 0U; \ + __asm__ __volatile__(\ + "mrs %0, cpsr\n"\ + : "=r" (rval)\ + );\ + rval;\ + }) + +#define mtcpsr(v) __asm__ __volatile__(\ + "msr cpsr,%0\n"\ + : : "r" (v)\ + ) + +#define cpsiei() __asm__ __volatile__("cpsie i\n") +#define cpsidi() __asm__ __volatile__("cpsid i\n") + +#define cpsief() __asm__ __volatile__("cpsie f\n") +#define cpsidf() __asm__ __volatile__("cpsid f\n") + + + +#define mtgpr(rn, v) __asm__ __volatile__(\ + "mov r" stringify(rn) ", %0 \n"\ + : : "r" (v)\ + ) + +#define mfgpr(rn) ({u32 rval; \ + __asm__ __volatile__(\ + "mov %0,r" stringify(rn) "\n"\ + : "=r" (rval)\ + );\ + rval;\ + }) + +/* memory synchronization operations */ + +/* Instruction Synchronization Barrier */ +#define isb() __asm__ __volatile__ ("isb" : : : "memory") + +/* Data Synchronization Barrier */ +#define dsb() __asm__ __volatile__ ("dsb" : : : "memory") + +/* Data Memory Barrier */ +#define dmb() __asm__ __volatile__ ("dmb" : : : "memory") + + +/* Memory Operations */ +#define ldr(adr) ({u32 rval; \ + __asm__ __volatile__(\ + "ldr %0,[%1]"\ + : "=r" (rval) : "r" (adr)\ + );\ + rval;\ + }) + +#endif + +#define ldrb(adr) ({u8 rval; \ + __asm__ __volatile__(\ + "ldrb %0,[%1]"\ + : "=r" (rval) : "r" (adr)\ + );\ + rval;\ + }) + +#define str(adr, val) __asm__ __volatile__(\ + "str %0,[%1]\n"\ + : : "r" (val), "r" (adr)\ + ) + +#define strb(adr, val) __asm__ __volatile__(\ + "strb %0,[%1]\n"\ + : : "r" (val), "r" (adr)\ + ) + +/* Count leading zeroes (clz) */ +#define clz(arg) ({u8 rval; \ + __asm__ __volatile__(\ + "clz %0,%1"\ + : "=r" (rval) : "r" (arg)\ + );\ + rval;\ + }) + +#if defined (__aarch64__) +#define mtcpdc(reg,val) __asm__ __volatile__("dc " #reg ",%0" : : "r" (val)) +#define mtcpic(reg,val) __asm__ __volatile__("ic " #reg ",%0" : : "r" (val)) + +#define mtcpicall(reg) __asm__ __volatile__("ic " #reg) +#define mtcptlbi(reg) __asm__ __volatile__("tlbi " #reg) +#define mtcpat(reg,val) __asm__ __volatile__("at " #reg ",%0" : : "r" (val)) +/* CP15 operations */ +#define mfcp(reg) ({u64 rval = 0U;\ + __asm__ __volatile__("mrs %0, " #reg : "=r" (rval));\ + rval;\ + }) + +#define mtcp(reg,val) __asm__ __volatile__("msr " #reg ",%0" : : "r" (val)) + +#else +/* CP15 operations */ +#define mtcp(rn, v) __asm__ __volatile__(\ + "mcr " rn "\n"\ + : : "r" (v)\ + ); + +#define mfcp(rn) ({u32 rval = 0U; \ + __asm__ __volatile__(\ + "mrc " rn "\n"\ + : "=r" (rval)\ + );\ + rval;\ + }) +#endif + +/************************** Variable Definitions ****************************/ + +/************************** Function Prototypes *****************************/ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* XPSEUDO_ASM_GCC_H */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xqspips.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xqspips.h new file mode 100644 index 0000000..0255bc2 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xqspips.h @@ -0,0 +1,804 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2019 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xqspips.h +* @addtogroup qspips_v3_6 +* @{ +* @details +* +* This file contains the implementation of the XQspiPs driver. It supports only +* master mode. User documentation for the driver functions is contained in this +* file in the form of comment blocks at the front of each function. +* +* A QSPI device connects to an QSPI bus through a 4-wire serial interface. +* The QSPI bus is a full-duplex, synchronous bus that facilitates communication +* between one master and one slave. The device is always full-duplex, +* which means that for every byte sent, one is received, and vice-versa. +* The master controls the clock, so it can regulate when it wants to +* send or receive data. The slave is under control of the master, it must +* respond quickly since it has no control of the clock and must send/receive +* data as fast or as slow as the master does. +* +* Linear Mode +* The Linear Quad-SPI Controller extends the existing Quad-SPI Controller�s +* functionality by adding a linear addressing scheme that allows the SPI flash +* memory subsystem to behave like a typical ROM device. The new feature hides +* the normal SPI protocol from a master reading from the SPI flash memory. The +* feature improves both the user friendliness and the overall read memory +* throughput over that of the current Quad-SPI Controller by lessening the +* amount of software overheads required and by the use of the faster AXI +* interface. +* +* Initialization & Configuration +* +* The XQspiPs_Config structure is used by the driver to configure itself. This +* configuration structure is typically created by the tool-chain based on HW +* build properties. +* +* To support multiple runtime loading and initialization strategies employed by +* various operating systems, the driver instance can be initialized in the +* following way: +* - XQspiPs_LookupConfig(DeviceId) - Use the device identifier to find +* static configuration structure defined in xqspips_g.c. This is setup +* by the tools. For some operating systems the config structure will be +* initialized by the software and this call is not needed. +* - XQspiPs_CfgInitialize(InstancePtr, CfgPtr, EffectiveAddr) - Uses a +* configuration structure provided by the caller. If running in a system +* with address translation, the provided virtual memory base address +* replaces the physical address present in the configuration structure. +* +* Multiple Masters +* +* More than one master can exist, but arbitration is the responsibility of +* the higher layer software. The device driver does not perform any type of +* arbitration. +* +* Modes of Operation +* +* There are four modes to perform a data transfer and the selection of a mode +* is based on Chip Select(CS) and Start. These two options individually, can +* be controlled either by software(Manual) or hardware(Auto). +* - Auto CS: Chip select is automatically asserted as soon as the first word +* is written into the TXFIFO and de asserted when the TXFIFO becomes +* empty +* - Manual CS: Software must assert and de assert CS. +* - Auto Start: Data transmission starts as soon as there is data in the +* TXFIFO and stalls when the TXFIFO is empty +* - Manual Start: Software must start data transmission at the beginning of +* the transaction or whenever the TXFIFO has become empty +* +* The preferred combination is Manual CS and Auto Start. +* In this combination, the software asserts CS before loading any data into +* TXFIFO. In Auto Start mode, whenever data is in TXFIFO, controller sends it +* out until TXFIFO becomes empty. The software reads the RXFIFO whenever the +* data is available. If no further data, software disables CS. +* +* Risks/challenges of other combinations: +* - Manual CS and Manual Start: Manual Start bit should be set after each +* TXFIFO write otherwise there could be a race condition where the TXFIFO +* becomes empty before the new word is written. In that case the +* transmission stops. +* - Auto CS with Manual or Auto Start: It is very difficult for software to +* keep the TXFIFO filled. Whenever the TXFIFO runs empty, CS is de asserted. +* This results in a single transaction to be split into multiple pieces each +* with its own chip select. This will result in garbage data to be sent. +* +* Interrupts +* +* The user must connect the interrupt handler of the driver, +* XQspiPs_InterruptHandler, to an interrupt system such that it will be +* called when an interrupt occurs. This function does not save and restore +* the processor context such that the user must provide this processing. +* +* The driver handles the following interrupts: +* - Data Transmit Register/FIFO Underflow +* - Data Receive Register/FIFO Not Empty +* - Data Transmit Register/FIFO Overwater +* - Data Receive Register/FIFO Overrun +* +* The Data Transmit Register/FIFO Overwater interrupt -- indicates that the +* QSPI device has transmitted the data available to transmit, and now its data +* register and FIFO is ready to accept more data. The driver uses this +* interrupt to indicate progress while sending data. The driver may have +* more data to send, in which case the data transmit register and FIFO is +* filled for subsequent transmission. When this interrupt arrives and all +* the data has been sent, the driver invokes the status callback with a +* value of XST_SPI_TRANSFER_DONE to inform the upper layer software that +* all data has been sent. +* +* The Data Transmit Register/FIFO Underflow interrupt -- indicates that, +* as slave, the QSPI device was required to transmit but there was no data +* available to transmit in the transmit register (or FIFO). This may not +* be an error if the master is not expecting data. But in the case where +* the master is expecting data, this serves as a notification of such a +* condition. The driver reports this condition to the upper layer +* software through the status handler. +* +* The Data Receive Register/FIFO Overrun interrupt -- indicates that the QSPI +* device received data and subsequently dropped the data because the data +* receive register and FIFO was full. The driver reports this condition to the +* upper layer software through the status handler. This likely indicates a +* problem with the higher layer protocol, or a problem with the slave +* performance. +* +* +* Polled Operation +* +* Transfer in polled mode is supported through a separate interface function +* XQspiPs_PolledTransfer(). Unlike the transfer function in the interrupt mode, +* this function blocks until all data has been sent/received. +* +* Device Busy +* +* Some operations are disallowed when the device is busy. The driver tracks +* whether a device is busy. The device is considered busy when a data transfer +* request is outstanding, and is considered not busy only when that transfer +* completes (or is aborted with a mode fault error). +* +* Device Configuration +* +* The device can be configured in various ways during the FPGA implementation +* process. Configuration parameters are stored in the xqspips_g.c file or +* passed in via XQspiPs_CfgInitialize(). A table is defined where each entry +* contains configuration information for an QSPI device, including the base +* address for the device. +* +* RTOS Independence +* +* This driver is intended to be RTOS and processor independent. It works with +* physical addresses only. Any needs for dynamic memory management, threads or +* thread mutual exclusion, virtual memory, or cache control must be satisfied +* by the layer above this driver. +* +* NOTE: This driver was always tested with endianess set to little-endian. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who Date     Changes
+* ----- --- -------- -----------------------------------------------
+* 1.00a sdm 11/25/10 First release, based on the PS SPI driver...
+* 1.01a sdm 11/22/11 Added TCL file for generating QSPI parameters
+*		     in xparameters.h
+* 2.00a kka 07/25/12 Added a few register defines for CR 670297
+* 		     Removed code related to mode fault for CR 671468
+*		     The XQspiPs_SetSlaveSelect has been modified to remove
+*		     the argument of the slave select as the QSPI controller
+*		     only supports one slave.
+* 		     XQspiPs_GetSlaveSelect API has been removed
+* 		     Added a flag ShiftReadData to the instance structure
+*.		     and is used in the XQspiPs_GetReadData API.
+*		     The ShiftReadData Flag indicates whether the data
+*		     read from the Rx FIFO needs to be shifted
+*		     in cases where the data is less than 4  bytes
+* 		     Removed the selection for the following options:
+*		     Master mode (XQSPIPS_MASTER_OPTION) and
+*		     Flash interface mode (XQSPIPS_FLASH_MODE_OPTION) option
+*		     as the QSPI driver supports the Master mode
+*		     and Flash Interface mode and doesnot support
+*		     Slave mode or the legacy mode.
+*		     Modified the XQspiPs_PolledTransfer and XQspiPs_Transfer
+*		     APIs so that the last argument (IsInst) specifying whether
+*		     it is instruction or data has been removed. The first byte
+*		     in the SendBufPtr argument of these APIs specify the
+*		     instruction to be sent to the Flash Device.
+*		     This version of the driver fixes CRs 670197/663787/
+*		     670297/671468.
+* 		     Added the option for setting the Holdb_dr bit in the
+*		     configuration options, XQSPIPS_HOLD_B_DRIVE_OPTION
+*		     is the option to be used for setting this bit in the
+*		     configuration register.
+*		     The XQspiPs_PolledTransfer function has been updated
+*		     to fill the data to fifo depth.
+* 2.01a sg  02/03/13 Added flash opcodes for DUAL_IO_READ,QUAD_IO_READ.
+*		     Added macros for Set/Get Rx Watermark. Changed QSPI
+*		     Enable/Disable macro argument from BaseAddress to
+*		     Instance Pointer. Added DelayNss argument to SetDelays
+*		     and GetDelays API's.
+*		     Created macros XQspiPs_IsManualStart and
+*		     XQspiPs_IsManualChipSelect.
+*		     Changed QSPI transfer logic for polled and interrupt
+*		     modes to be based on filled tx fifo count and receive
+*		     based on it. RXNEMPTY interrupt is not used.
+*		     Added assertions to XQspiPs_LqspiRead function.
+*		     SetDelays and GetDelays API's include DelayNss parameter.
+*		     Added defines for DelayNss,Rx Watermark,Interrupts
+*		     which need write to clear. Removed Read zeros mask from
+*		     LQSPI Config register. Renamed Fixed burst error to
+*		     data FSM error in  LQSPI Status register.
+*
+* 2.02a hk  05/07/13 Added ConnectionMode to config structure.
+*			 Corresponds to C_QSPI_MODE - 0:Single, 1:Stacked, 2:Parallel
+*			 Added enable and disable to the XQspiPs_LqspiRead() function
+*			 Removed XQspi_Reset() in Set_Options() function when
+*			 LQSPI_MODE_OPTION is set.
+*            Added instructions for bank selection, die erase and
+*            flag status register to the flash instruction table
+*            Handling for instructions not in flash instruction
+*			 table added. Checking for Tx FIFO empty when switching from
+*			 TXD1/2/3 to TXD0 added. If WRSR instruction is sent with
+*            byte count 3 (spansion), instruction size and TXD register
+*			 changed accordingly. CR# 712502 and 703869.
+*            Added prefix to constant definitions for ConnectionMode
+*            Added (#ifdef linear base address) in the Linear read function.
+*            Changed  XPAR_XQSPIPS_0_LINEAR_BASEADDR to
+*            XPAR_PS7_QSPI_LINEAR_0_S_AXI_BASEADDR in
+*            XQspiPs_LqspiRead function. Fix for CR#718141.
+*
+* 2.03a hk  09/17/13 Modified polled and interrupt transfers to make use of
+*                    thresholds. This is to improve performance.
+*                    Added API's for QSPI reset and
+*                    linear mode initialization for boot.
+*                    Added RX and TX threshold reset to one in XQspiPs_Abort.
+*                    Added RX threshold reset(1) after transfer in polled and
+*                    interrupt transfers. Made changes to make sure threshold
+*                    change is done only when no transfer is in progress.
+*                    Updated linear init API for parallel and stacked modes.
+*                    CR#737760.
+* 3.1   hk  08/13/14 When writing to the configuration register, set/reset
+*                    required bits leaving reserved bits untouched. CR# 796813.
+* 3.2	sk	02/05/15 Add SLCR reset in abort function as a workaround because
+* 					 controller does not update FIFO status flags as expected
+* 					 when thresholds are used.
+* 3.3   sk  11/07/15 Modified the API prototypes according to MISRAC standards
+*                    to remove compilation warnings. CR# 868893.
+*       ms  03/17/17 Added readme.txt file in examples folder for doxygen
+*                    generation.
+*       ms  04/05/17 Modified Comment lines in functions of qspips
+*                    examples to recognize it as documentation block
+*                    and modified filename tag in
+*                    xqspips_dual_flash_stack_lqspi_example.c to include it in
+*                    doxygen examples.
+* 3.4   nsk 31/07/17 Added QSPI_BUS_WIDTH parameter in xparameters.h file
+* 3.5	tjs 08/21/18 Fixed compilation warnings for the ARMCC.
+* 3.5	tjs 07/16/18 Added support for low density ISSI flash parts.
+* 3.6   akm 03/28/19 Fixed memory leak issue while reading from qspi.(CR#1016357)
+* 3.6   akm 04/15/19 Modified FlashQuadEnable, FlashWrie and FlashErase APIs,
+*                    to wait for the on going operation to complete before
+*                    performing the next operation.
+* 3.6   akm 04/15/19 Modified the mask in XQspiPs_GetReadData() API to retrieve
+*                    configuration register values of both the Flashes in dual
+*                    parellel connection.
+*
+* 
+* +******************************************************************************/ +#ifndef XQSPIPS_H /* prevent circular inclusions */ +#define XQSPIPS_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +#include "xstatus.h" +#include "xqspips_hw.h" +#include + +/************************** Constant Definitions *****************************/ + +/** @name Configuration options + * + * The following options are supported to enable/disable certain features of + * an QSPI device. Each of the options is a bit mask, so more than one may be + * specified. + * + * + * The Active Low Clock option configures the device's clock polarity. + * Setting this option means the clock is active low and the SCK signal idles + * high. By default, the clock is active high and SCK idles low. + * + * The Clock Phase option configures the QSPI device for one of two + * transfer formats. A clock phase of 0, the default, means data is valid on + * the first SCK edge (rising or falling) after the slave select (SS) signal + * has been asserted. A clock phase of 1 means data is valid on the second SCK + * edge (rising or falling) after SS has been asserted. + * + * + * The QSPI Force Slave Select option is used to enable manual control of + * the slave select signal. + * 0: The SPI_SS signal is controlled by the QSPI controller during + * transfers. (Default) + * 1: The SPI_SS signal is forced active (driven low) regardless of any + * transfers in progress. + * + * NOTE: The driver will handle setting and clearing the Slave Select when + * the user sets the "FORCE_SSELECT_OPTION". Using this option will allow the + * QSPI clock to be set to a faster speed. If the QSPI clock is too fast, the + * processor cannot empty and refill the FIFOs before the TX FIFO is empty + * When the QSPI hardware is controlling the Slave Select signals, this + * will cause slave to be de-selected and terminate the transfer. + * + * The Manual Start option is used to enable manual control of + * the Start command to perform data transfer. + * 0: The Start command is controlled by the QSPI controller during + * transfers(Default). Data transmission starts as soon as there is data in + * the TXFIFO and stalls when the TXFIFO is empty + * 1: The Start command must be issued by software to perform data transfer. + * Bit 15 of Configuration register is used to issue Start command. This bit + * must be set whenever TXFIFO is filled with new data. + * + * NOTE: The driver will set the Manual Start Enable bit in Configuration + * Register, if Manual Start option is selected. Software will issue + * Manual Start command whenever TXFIFO is filled with data. When there is + * no further data, driver will clear the Manual Start Enable bit. + * + * @{ + */ +#define XQSPIPS_CLK_ACTIVE_LOW_OPTION 0x2 /**< Active Low Clock option */ +#define XQSPIPS_CLK_PHASE_1_OPTION 0x4 /**< Clock Phase one option */ +#define XQSPIPS_FORCE_SSELECT_OPTION 0x10 /**< Force Slave Select */ +#define XQSPIPS_MANUAL_START_OPTION 0x20 /**< Manual Start enable */ +#define XQSPIPS_LQSPI_MODE_OPTION 0x80 /**< Linear QPSI mode */ +#define XQSPIPS_HOLD_B_DRIVE_OPTION 0x100 /**< Drive HOLD_B Pin */ +/*@}*/ + + +/** @name QSPI Clock Prescaler options + * The QSPI Clock Prescaler Configuration bits are used to program master mode + * bit rate. The bit rate can be programmed in divide-by-two decrements from + * pclk/2 to pclk/256. + * + * @{ + */ +#define XQSPIPS_CLK_PRESCALE_2 0x00 /**< PCLK/2 Prescaler */ +#define XQSPIPS_CLK_PRESCALE_4 0x01 /**< PCLK/4 Prescaler */ +#define XQSPIPS_CLK_PRESCALE_8 0x02 /**< PCLK/8 Prescaler */ +#define XQSPIPS_CLK_PRESCALE_16 0x03 /**< PCLK/16 Prescaler */ +#define XQSPIPS_CLK_PRESCALE_32 0x04 /**< PCLK/32 Prescaler */ +#define XQSPIPS_CLK_PRESCALE_64 0x05 /**< PCLK/64 Prescaler */ +#define XQSPIPS_CLK_PRESCALE_128 0x06 /**< PCLK/128 Prescaler */ +#define XQSPIPS_CLK_PRESCALE_256 0x07 /**< PCLK/256 Prescaler */ + +/*@}*/ + + +/** @name Callback events + * + * These constants specify the handler events that are passed to + * a handler from the driver. These constants are not bit masks such that + * only one will be passed at a time to the handler. + * + * @{ + */ +#define XQSPIPS_EVENT_TRANSFER_DONE 2 /**< Transfer done */ +#define XQSPIPS_EVENT_TRANSMIT_UNDERRUN 3 /**< TX FIFO empty */ +#define XQSPIPS_EVENT_RECEIVE_OVERRUN 4 /**< Receive data loss because + * RX FIFO full + */ +/*@}*/ + +/** @name Flash commands + * + * The following constants define most of the commands supported by flash + * devices. Users can add more commands supported by the flash devices + * + * @{ + */ +#define XQSPIPS_FLASH_OPCODE_WRSR 0x01 /* Write status register */ +#define XQSPIPS_FLASH_OPCODE_PP 0x02 /* Page program */ +#define XQSPIPS_FLASH_OPCODE_NORM_READ 0x03 /* Normal read data bytes */ +#define XQSPIPS_FLASH_OPCODE_WRDS 0x04 /* Write disable */ +#define XQSPIPS_FLASH_OPCODE_RDSR1 0x05 /* Read status register 1 */ +#define XQSPIPS_FLASH_OPCODE_WREN 0x06 /* Write enable */ +#define XQSPIPS_FLASH_OPCODE_FAST_READ 0x0B /* Fast read data bytes */ +#define XQSPIPS_FLASH_OPCODE_BE_4K 0x20 /* Erase 4KiB block */ +#define XQSPIPS_FLASH_OPCODE_RDSR2 0x35 /* Read status register 2 */ +#define XQSPIPS_FLASH_OPCODE_DUAL_READ 0x3B /* Dual read data bytes */ +#define XQSPIPS_FLASH_OPCODE_BE_32K 0x52 /* Erase 32KiB block */ +#define XQSPIPS_FLASH_OPCODE_QUAD_READ 0x6B /* Quad read data bytes */ +#define XQSPIPS_FLASH_OPCODE_ERASE_SUS 0x75 /* Erase suspend */ +#define XQSPIPS_FLASH_OPCODE_ERASE_RES 0x7A /* Erase resume */ +#define XQSPIPS_FLASH_OPCODE_RDID 0x9F /* Read JEDEC ID */ +#define XQSPIPS_FLASH_OPCODE_BE 0xC7 /* Erase whole flash block */ +#define XQSPIPS_FLASH_OPCODE_SE 0xD8 /* Sector erase (usually 64KB)*/ +#define XQSPIPS_FLASH_OPCODE_DUAL_IO_READ 0xBB /* Read data using Dual I/O */ +#define XQSPIPS_FLASH_OPCODE_QUAD_IO_READ 0xEB /* Read data using Quad I/O */ +#define XQSPIPS_FLASH_OPCODE_BRWR 0x17 /* Bank Register Write */ +#define XQSPIPS_FLASH_OPCODE_BRRD 0x16 /* Bank Register Read */ +/* Extende Address Register Write - Micron's equivalent of Bank Register */ +#define XQSPIPS_FLASH_OPCODE_EARWR 0xC5 +/* Extende Address Register Read - Micron's equivalent of Bank Register */ +#define XQSPIPS_FLASH_OPCODE_EARRD 0xC8 +#define XQSPIPS_FLASH_OPCODE_DIE_ERASE 0xC4 +#define XQSPIPS_FLASH_OPCODE_READ_FLAG_SR 0x70 +#define XQSPIPS_FLASH_OPCODE_CLEAR_FLAG_SR 0x50 +#define XQSPIPS_FLASH_OPCODE_READ_LOCK_REG 0xE8 /* Lock Reg Read */ +#define XQSPIPS_FLASH_OPCODE_WRITE_LOCK_REG 0xE5 /* Lock Reg Write */ + +/*@}*/ + +/** @name Instruction size + * + * The following constants define numbers 1 to 4. + * Used to identify whether TXD0,1,2 or 3 is to be used. + * + * @{ + */ +#define XQSPIPS_SIZE_ONE 1 +#define XQSPIPS_SIZE_TWO 2 +#define XQSPIPS_SIZE_THREE 3 +#define XQSPIPS_SIZE_FOUR 4 + +/*@}*/ + +/** @name ConnectionMode + * + * The following constants are the possible values of ConnectionMode in + * Config structure. + * + * @{ + */ +#define XQSPIPS_CONNECTION_MODE_SINGLE 0 +#define XQSPIPS_CONNECTION_MODE_STACKED 1 +#define XQSPIPS_CONNECTION_MODE_PARALLEL 2 + +/*@}*/ + +/** @name FIFO threshold value + * + * This is the Rx FIFO threshold (in words) that was found to be most + * optimal in terms of performance + * + * @{ + */ +#define XQSPIPS_RXFIFO_THRESHOLD_OPT 32 + +/*@}*/ + +/**************************** Type Definitions *******************************/ +/** + * The handler data type allows the user to define a callback function to + * handle the asynchronous processing for the QSPI device. The application + * using this driver is expected to define a handler of this type to support + * interrupt driven mode. The handler executes in an interrupt context, so + * only minimal processing should be performed. + * + * @param CallBackRef is the callback reference passed in by the upper + * layer when setting the callback functions, and passed back to + * the upper layer when the callback is invoked. Its type is + * not important to the driver, so it is a void pointer. + * @param StatusEvent holds one or more status events that have occurred. + * See the XQspiPs_SetStatusHandler() for details on the status + * events that can be passed in the callback. + * @param ByteCount indicates how many bytes of data were successfully + * transferred. This may be less than the number of bytes + * requested if the status event indicates an error. + */ +typedef void (*XQspiPs_StatusHandler) (void *CallBackRef, u32 StatusEvent, + unsigned ByteCount); + +/** + * This typedef contains configuration information for the device. + */ +typedef struct { + u16 DeviceId; /**< Unique ID of device */ + u32 BaseAddress; /**< Base address of the device */ + u32 InputClockHz; /**< Input clock frequency */ + u8 ConnectionMode; /**< Single, Stacked and Parallel mode */ +} XQspiPs_Config; + +/** + * The XQspiPs driver instance data. The user is required to allocate a + * variable of this type for every QSPI device in the system. A pointer + * to a variable of this type is then passed to the driver API functions. + */ +typedef struct { + XQspiPs_Config Config; /**< Configuration structure */ + u32 IsReady; /**< Device is initialized and ready */ + + u8 *SendBufferPtr; /**< Buffer to send (state) */ + u8 *RecvBufferPtr; /**< Buffer to receive (state) */ + int RequestedBytes; /**< Number of bytes to transfer (state) */ + int RemainingBytes; /**< Number of bytes left to transfer(state) */ + u32 IsBusy; /**< A transfer is in progress (state) */ + XQspiPs_StatusHandler StatusHandler; + void *StatusRef; /**< Callback reference for status handler */ + u32 ShiftReadData; /**< Flag to indicate whether the data + * read from the Rx FIFO needs to be shifted + * in cases where the data is less than 4 + * bytes + */ +} XQspiPs; + +/***************** Macros (Inline Functions) Definitions *********************/ + +/****************************************************************************/ +/* +* +* Check in OptionsTable if Manual Start Option is enabled or disabled. +* +* @param InstancePtr is a pointer to the XQspiPs instance. +* +* @return +* - TRUE if option is set +* - FALSE if option is not set +* +* @note C-Style signature: +* u8 XQspiPs_IsManualStart(XQspiPs *InstancePtr); +* +*****************************************************************************/ +#define XQspiPs_IsManualStart(InstancePtr) \ + ((XQspiPs_GetOptions(InstancePtr) & \ + XQSPIPS_MANUAL_START_OPTION) ? TRUE : FALSE) + +/****************************************************************************/ +/* +* +* Check in OptionsTable if Manual Chip Select Option is enabled or disabled. +* +* @param InstancePtr is a pointer to the XSpiPs instance. +* +* @return +* - TRUE if option is set +* - FALSE if option is not set +* +* @note C-Style signature: +* u8 XQspiPs_IsManualChipSelect(XQspiPs *InstancePtr); +* +*****************************************************************************/ +#define XQspiPs_IsManualChipSelect(InstancePtr) \ + ((XQspiPs_GetOptions(InstancePtr) & \ + XQSPIPS_FORCE_SSELECT_OPTION) ? TRUE : FALSE) + +/****************************************************************************/ +/** +* +* Set the contents of the slave idle count register. +* +* @param InstancePtr is a pointer to the XQspiPs instance. +* @param RegisterValue is the value to be written, valid values are +* 0-255. +* +* @return None +* +* @note C-Style signature: +* void XQspiPs_SetSlaveIdle(XQspiPs *InstancePtr, +* u32 RegisterValue) +* +*****************************************************************************/ +#define XQspiPs_SetSlaveIdle(InstancePtr, RegisterValue) \ + XQspiPs_Out32(((InstancePtr)->Config.BaseAddress) + \ + XQSPIPS_SICR_OFFSET, (RegisterValue)) + +/****************************************************************************/ +/** +* +* Get the contents of the slave idle count register. Use the XQSPIPS_SICR_* +* constants defined in xqspips_hw.h to interpret the bit-mask returned. +* +* @param InstancePtr is a pointer to the XQspiPs instance. +* +* @return An 8-bit value representing Slave Idle Count. +* +* @note C-Style signature: +* u32 XQspiPs_GetSlaveIdle(XQspiPs *InstancePtr) +* +*****************************************************************************/ +#define XQspiPs_GetSlaveIdle(InstancePtr) \ + XQspiPs_In32(((InstancePtr)->Config.BaseAddress) + \ + XQSPIPS_SICR_OFFSET) + +/****************************************************************************/ +/** +* +* Set the contents of the transmit FIFO watermark register. +* +* @param InstancePtr is a pointer to the XQspiPs instance. +* @param RegisterValue is the value to be written, valid values are 1-63. +* +* @return None. +* +* @note C-Style signature: +* void XQspiPs_SetTXWatermark(XQspiPs *InstancePtr, +* u32 RegisterValue) +* +*****************************************************************************/ +#define XQspiPs_SetTXWatermark(InstancePtr, RegisterValue) \ + XQspiPs_Out32(((InstancePtr)->Config.BaseAddress) + \ + XQSPIPS_TXWR_OFFSET, (RegisterValue)) + +/****************************************************************************/ +/** +* +* Get the contents of the transmit FIFO watermark register. +* Valid values are in the range 1-63. +* +* @param InstancePtr is a pointer to the XQspiPs instance. +* +* @return A 6-bit value representing Tx Watermark level. +* +* @note C-Style signature: +* u32 XQspiPs_GetTXWatermark(XQspiPs *InstancePtr) +* +*****************************************************************************/ +#define XQspiPs_GetTXWatermark(InstancePtr) \ + XQspiPs_In32((InstancePtr->Config.BaseAddress) + XQSPIPS_TXWR_OFFSET) + +/****************************************************************************/ +/** +* +* Set the contents of the receive FIFO watermark register. +* +* @param InstancePtr is a pointer to the XQspiPs instance. +* @param RegisterValue is the value to be written, valid values are 1-63. +* +* @return None. +* +* @note C-Style signature: +* void XQspiPs_SetRXWatermark(XQspiPs *InstancePtr, +* u32 RegisterValue) +* +*****************************************************************************/ +#define XQspiPs_SetRXWatermark(InstancePtr, RegisterValue) \ + XQspiPs_Out32(((InstancePtr)->Config.BaseAddress) + \ + XQSPIPS_RXWR_OFFSET, (RegisterValue)) + +/****************************************************************************/ +/** +* +* Get the contents of the receive FIFO watermark register. +* Valid values are in the range 1-63. +* +* @param InstancePtr is a pointer to the XQspiPs instance. +* +* @return A 6-bit value representing Rx Watermark level. +* +* @note C-Style signature: +* u32 XQspiPs_GetRXWatermark(XQspiPs *InstancePtr) +* +*****************************************************************************/ +#define XQspiPs_GetRXWatermark(InstancePtr) \ + XQspiPs_In32((InstancePtr->Config.BaseAddress) + XQSPIPS_RXWR_OFFSET) + +/****************************************************************************/ +/** +* +* Enable the device and uninhibit master transactions. +* +* @param InstancePtr is a pointer to the XQspiPs instance. +* +* @return None. +* +* @note C-Style signature: +* void XQspiPs_Enable(XQspiPs *InstancePtr) +* +*****************************************************************************/ +#define XQspiPs_Enable(InstancePtr) \ + XQspiPs_Out32((InstancePtr->Config.BaseAddress) + XQSPIPS_ER_OFFSET, \ + XQSPIPS_ER_ENABLE_MASK) + +/****************************************************************************/ +/** +* +* Disable the device. +* +* @param InstancePtr is a pointer to the XQspiPs instance. +* +* @return None. +* +* @note C-Style signature: +* void XQspiPs_Disable(XQspiPs *InstancePtr) +* +*****************************************************************************/ +#define XQspiPs_Disable(InstancePtr) \ + XQspiPs_Out32((InstancePtr->Config.BaseAddress) + XQSPIPS_ER_OFFSET, 0) + +/****************************************************************************/ +/** +* +* Set the contents of the Linear QSPI Configuration register. +* +* @param InstancePtr is a pointer to the XQspiPs instance. +* @param RegisterValue is the value to be written to the Linear QSPI +* configuration register. +* +* @return None. +* +* @note C-Style signature: +* void XQspiPs_SetLqspiConfigReg(XQspiPs *InstancePtr, +* u32 RegisterValue) +* +*****************************************************************************/ +#define XQspiPs_SetLqspiConfigReg(InstancePtr, RegisterValue) \ + XQspiPs_Out32(((InstancePtr)->Config.BaseAddress) + \ + XQSPIPS_LQSPI_CR_OFFSET, (RegisterValue)) + +/****************************************************************************/ +/** +* +* Get the contents of the Linear QSPI Configuration register. +* +* @param InstancePtr is a pointer to the XQspiPs instance. +* +* @return A 32-bit value representing the contents of the LQSPI Config +* register. +* +* @note C-Style signature: +* u32 XQspiPs_GetLqspiConfigReg(u32 *InstancePtr) +* +*****************************************************************************/ +#define XQspiPs_GetLqspiConfigReg(InstancePtr) \ + XQspiPs_In32((InstancePtr->Config.BaseAddress) + \ + XQSPIPS_LQSPI_CR_OFFSET) + +/************************** Function Prototypes ******************************/ + +/* + * Initialization function, implemented in xqspips_sinit.c + */ +XQspiPs_Config *XQspiPs_LookupConfig(u16 DeviceId); + +/* + * Functions implemented in xqspips.c + */ +int XQspiPs_CfgInitialize(XQspiPs *InstancePtr, XQspiPs_Config *Config, + u32 EffectiveAddr); +void XQspiPs_Reset(XQspiPs *InstancePtr); +void XQspiPs_Abort(XQspiPs *InstancePtr); + +s32 XQspiPs_Transfer(XQspiPs *InstancePtr, u8 *SendBufPtr, u8 *RecvBufPtr, + u32 ByteCount); +s32 XQspiPs_PolledTransfer(XQspiPs *InstancePtr, u8 *SendBufPtr, + u8 *RecvBufPtr, u32 ByteCount); +int XQspiPs_LqspiRead(XQspiPs *InstancePtr, u8 *RecvBufPtr, + u32 Address, unsigned ByteCount); + +int XQspiPs_SetSlaveSelect(XQspiPs *InstancePtr); + +void XQspiPs_SetStatusHandler(XQspiPs *InstancePtr, void *CallBackRef, + XQspiPs_StatusHandler FuncPtr); +void XQspiPs_InterruptHandler(void *InstancePtr); + +/* + * Functions for selftest, in xqspips_selftest.c + */ +int XQspiPs_SelfTest(XQspiPs *InstancePtr); + +/* + * Functions for options, in xqspips_options.c + */ +s32 XQspiPs_SetOptions(XQspiPs *InstancePtr, u32 Options); +u32 XQspiPs_GetOptions(XQspiPs *InstancePtr); + +s32 XQspiPs_SetClkPrescaler(XQspiPs *InstancePtr, u8 Prescaler); +u8 XQspiPs_GetClkPrescaler(XQspiPs *InstancePtr); + +int XQspiPs_SetDelays(XQspiPs *InstancePtr, u8 DelayNss, u8 DelayBtwn, + u8 DelayAfter, u8 DelayInit); +void XQspiPs_GetDelays(XQspiPs *InstancePtr, u8 *DelayNss, u8 *DelayBtwn, + u8 *DelayAfter, u8 *DelayInit); +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xqspips_hw.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xqspips_hw.h new file mode 100644 index 0000000..88c232e --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xqspips_hw.h @@ -0,0 +1,421 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2019 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xqspips_hw.h +* @addtogroup qspips_v3_6 +* @{ +* +* This header file contains the identifiers and basic HW access driver +* functions (or macros) that can be used to access the device. Other driver +* functions are defined in xqspips.h. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who Date     Changes
+* ----- --- -------- -----------------------------------------------
+* 1.00  sdm 11/25/10 First release
+* 2.00a ka  07/25/12 Added a few register defines for CR 670297
+*		     and removed some defines of reserved fields for
+*		     CR 671468
+*		     Added define XQSPIPS_CR_HOLD_B_MASK for Holdb_dr
+*		     bit in Configuration register.
+* 2.01a sg  02/03/13 Added defines for DelayNss,Rx Watermark,Interrupts
+*		     which need write to clear. Removed Read zeros mask from
+*		     LQSPI Config register.
+* 2.03a hk  08/22/13 Added prototypes of API's for QSPI reset and
+*                    linear mode initialization for boot. Added related
+*                    constant definitions.
+* 3.1   hk  08/13/14 Changed definition of CR reset value masks to set/reset
+*                    required bits leaving reserved bits untouched. CR# 796813.
+* 3.2	sk	02/05/15 Add SLCR reset in abort function as a workaround because
+* 					 controller does not update FIFO status flags as expected
+* 					 when thresholds are used.
+* 3.6   akm 03/28/19 Fixed memory leak issue while reading from qspi.(CR#1016357)
+*
+* 
+* +******************************************************************************/ +#ifndef XQSPIPS_HW_H /* prevent circular inclusions */ +#define XQSPIPS_HW_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +#include "xil_types.h" +#include "xil_assert.h" +#include "xil_io.h" +#include "xparameters.h" + +/************************** Constant Definitions *****************************/ + +/** @name Register Map + * + * Register offsets from the base address of an QSPI device. + * @{ + */ +#define XQSPIPS_CR_OFFSET 0x00 /**< Configuration Register */ +#define XQSPIPS_SR_OFFSET 0x04 /**< Interrupt Status */ +#define XQSPIPS_IER_OFFSET 0x08 /**< Interrupt Enable */ +#define XQSPIPS_IDR_OFFSET 0x0c /**< Interrupt Disable */ +#define XQSPIPS_IMR_OFFSET 0x10 /**< Interrupt Enabled Mask */ +#define XQSPIPS_ER_OFFSET 0x14 /**< Enable/Disable Register */ +#define XQSPIPS_DR_OFFSET 0x18 /**< Delay Register */ +#define XQSPIPS_TXD_00_OFFSET 0x1C /**< Transmit 4-byte inst/data */ +#define XQSPIPS_RXD_OFFSET 0x20 /**< Data Receive Register */ +#define XQSPIPS_SICR_OFFSET 0x24 /**< Slave Idle Count */ +#define XQSPIPS_TXWR_OFFSET 0x28 /**< Transmit FIFO Watermark */ +#define XQSPIPS_RXWR_OFFSET 0x2C /**< Receive FIFO Watermark */ +#define XQSPIPS_GPIO_OFFSET 0x30 /**< GPIO Register */ +#define XQSPIPS_LPBK_DLY_ADJ_OFFSET 0x38 /**< Loopback Delay Adjust Reg */ +#define XQSPIPS_TXD_01_OFFSET 0x80 /**< Transmit 1-byte inst */ +#define XQSPIPS_TXD_10_OFFSET 0x84 /**< Transmit 2-byte inst */ +#define XQSPIPS_TXD_11_OFFSET 0x88 /**< Transmit 3-byte inst */ +#define XQSPIPS_LQSPI_CR_OFFSET 0xA0 /**< Linear QSPI config register */ +#define XQSPIPS_LQSPI_SR_OFFSET 0xA4 /**< Linear QSPI status register */ +#define XQSPIPS_MOD_ID_OFFSET 0xFC /**< Module ID register */ + +/* @} */ + +/** @name Configuration Register + * + * This register contains various control bits that + * affect the operation of the QSPI device. Read/Write. + * @{ + */ + +#define XQSPIPS_CR_IFMODE_MASK 0x80000000 /**< Flash mem interface mode */ +#define XQSPIPS_CR_ENDIAN_MASK 0x04000000 /**< Tx/Rx FIFO endianness */ +#define XQSPIPS_CR_MANSTRT_MASK 0x00010000 /**< Manual Transmission Start */ +#define XQSPIPS_CR_MANSTRTEN_MASK 0x00008000 /**< Manual Transmission Start + Enable */ +#define XQSPIPS_CR_SSFORCE_MASK 0x00004000 /**< Force Slave Select */ +#define XQSPIPS_CR_SSCTRL_MASK 0x00000400 /**< Slave Select Decode */ +#define XQSPIPS_CR_SSCTRL_SHIFT 10 /**< Slave Select Decode shift */ +#define XQSPIPS_CR_DATA_SZ_MASK 0x000000C0 /**< Size of word to be + transferred */ +#define XQSPIPS_CR_PRESC_MASK 0x00000038 /**< Prescaler Setting */ +#define XQSPIPS_CR_PRESC_SHIFT 3 /**< Prescaler shift */ +#define XQSPIPS_CR_PRESC_MAXIMUM 0x07 /**< Prescaler maximum value */ + +#define XQSPIPS_CR_CPHA_MASK 0x00000004 /**< Phase Configuration */ +#define XQSPIPS_CR_CPOL_MASK 0x00000002 /**< Polarity Configuration */ + +#define XQSPIPS_CR_MSTREN_MASK 0x00000001 /**< Master Mode Enable */ + +#define XQSPIPS_CR_HOLD_B_MASK 0x00080000 /**< HOLD_B Pin Drive Enable */ + +#define XQSPIPS_CR_REF_CLK_MASK 0x00000100 /**< Ref clk bit - should be 0 */ + +/* Deselect the Slave select line and set the transfer size to 32 at reset */ +#define XQSPIPS_CR_RESET_MASK_SET XQSPIPS_CR_IFMODE_MASK | \ + XQSPIPS_CR_SSCTRL_MASK | \ + XQSPIPS_CR_DATA_SZ_MASK | \ + XQSPIPS_CR_MSTREN_MASK | \ + XQSPIPS_CR_SSFORCE_MASK | \ + XQSPIPS_CR_HOLD_B_MASK +#define XQSPIPS_CR_RESET_MASK_CLR XQSPIPS_CR_CPOL_MASK | \ + XQSPIPS_CR_CPHA_MASK | \ + XQSPIPS_CR_PRESC_MASK | \ + XQSPIPS_CR_MANSTRTEN_MASK | \ + XQSPIPS_CR_MANSTRT_MASK | \ + XQSPIPS_CR_ENDIAN_MASK | \ + XQSPIPS_CR_REF_CLK_MASK +/* @} */ + + +/** @name QSPI Interrupt Registers + * + * QSPI Status Register + * + * This register holds the interrupt status flags for an QSPI device. Some + * of the flags are level triggered, which means that they are set as long + * as the interrupt condition exists. Other flags are edge triggered, + * which means they are set once the interrupt condition occurs and remain + * set until they are cleared by software. The interrupts are cleared by + * writing a '1' to the interrupt bit position in the Status Register. + * Read/Write. + * + * QSPI Interrupt Enable Register + * + * This register is used to enable chosen interrupts for an QSPI device. + * Writing a '1' to a bit in this register sets the corresponding bit in the + * QSPI Interrupt Mask register. Write only. + * + * QSPI Interrupt Disable Register + * + * This register is used to disable chosen interrupts for an QSPI device. + * Writing a '1' to a bit in this register clears the corresponding bit in the + * QSPI Interrupt Mask register. Write only. + * + * QSPI Interrupt Mask Register + * + * This register shows the enabled/disabled interrupts of an QSPI device. + * Read only. + * + * All four registers have the same bit definitions. They are only defined once + * for each of the Interrupt Enable Register, Interrupt Disable Register, + * Interrupt Mask Register, and Channel Interrupt Status Register + * @{ + */ + +#define XQSPIPS_IXR_TXUF_MASK 0x00000040 /**< QSPI Tx FIFO Underflow */ +#define XQSPIPS_IXR_RXFULL_MASK 0x00000020 /**< QSPI Rx FIFO Full */ +#define XQSPIPS_IXR_RXNEMPTY_MASK 0x00000010 /**< QSPI Rx FIFO Not Empty */ +#define XQSPIPS_IXR_TXFULL_MASK 0x00000008 /**< QSPI Tx FIFO Full */ +#define XQSPIPS_IXR_TXOW_MASK 0x00000004 /**< QSPI Tx FIFO Overwater */ +#define XQSPIPS_IXR_RXOVR_MASK 0x00000001 /**< QSPI Rx FIFO Overrun */ +#define XQSPIPS_IXR_DFLT_MASK 0x00000025 /**< QSPI default interrupts + mask */ +#define XQSPIPS_IXR_WR_TO_CLR_MASK 0x00000041 /**< Interrupts which + need write to clear */ +#define XQSPIPS_ISR_RESET_STATE 0x00000004 /**< Default to tx/rx empty */ +#define XQSPIPS_IXR_DISABLE_ALL 0x0000007D /**< Disable all interrupts */ +/* @} */ + + +/** @name Enable Register + * + * This register is used to enable or disable an QSPI device. + * Read/Write + * @{ + */ +#define XQSPIPS_ER_ENABLE_MASK 0x00000001 /**< QSPI Enable Bit Mask */ +/* @} */ + + +/** @name Delay Register + * + * This register is used to program timing delays in + * slave mode. Read/Write + * @{ + */ +#define XQSPIPS_DR_NSS_MASK 0xFF000000 /**< Delay to de-assert slave select + between two words mask */ +#define XQSPIPS_DR_NSS_SHIFT 24 /**< Delay to de-assert slave select + between two words shift */ +#define XQSPIPS_DR_BTWN_MASK 0x00FF0000 /**< Delay Between Transfers + mask */ +#define XQSPIPS_DR_BTWN_SHIFT 16 /**< Delay Between Transfers shift */ +#define XQSPIPS_DR_AFTER_MASK 0x0000FF00 /**< Delay After Transfers mask */ +#define XQSPIPS_DR_AFTER_SHIFT 8 /**< Delay After Transfers shift */ +#define XQSPIPS_DR_INIT_MASK 0x000000FF /**< Delay Initially mask */ +/* @} */ + +/** @name Slave Idle Count Registers + * + * This register defines the number of pclk cycles the slave waits for a the + * QSPI clock to become stable in quiescent state before it can detect the start + * of the next transfer in CPHA = 1 mode. + * Read/Write + * + * @{ + */ +#define XQSPIPS_SICR_MASK 0x000000FF /**< Slave Idle Count Mask */ +/* @} */ + + +/** @name Transmit FIFO Watermark Register + * + * This register defines the watermark setting for the Transmit FIFO. + * + * @{ + */ +#define XQSPIPS_TXWR_MASK 0x0000003F /**< Transmit Watermark Mask */ +#define XQSPIPS_TXWR_RESET_VALUE 0x00000001 /**< Transmit Watermark + * register reset value */ + +/* @} */ + +/** @name Receive FIFO Watermark Register + * + * This register defines the watermark setting for the Receive FIFO. + * + * @{ + */ +#define XQSPIPS_RXWR_MASK 0x0000003F /**< Receive Watermark Mask */ +#define XQSPIPS_RXWR_RESET_VALUE 0x00000001 /**< Receive Watermark + * register reset value */ + +/* @} */ + +/** @name FIFO Depth + * + * This macro provides the depth of transmit FIFO and receive FIFO. + * + * @{ + */ +#define XQSPIPS_FIFO_DEPTH 63 /**< FIFO depth (words) */ +/* @} */ + + +/** @name Linear QSPI Configuration Register + * + * This register contains various control bits that + * affect the operation of the Linear QSPI controller. Read/Write. + * + * @{ + */ +#define XQSPIPS_LQSPI_CR_LINEAR_MASK 0x80000000 /**< LQSPI mode enable */ +#define XQSPIPS_LQSPI_CR_TWO_MEM_MASK 0x40000000 /**< Both memories or one */ +#define XQSPIPS_LQSPI_CR_SEP_BUS_MASK 0x20000000 /**< Seperate memory bus */ +#define XQSPIPS_LQSPI_CR_U_PAGE_MASK 0x10000000 /**< Upper memory page */ +#define XQSPIPS_LQSPI_CR_MODE_EN_MASK 0x02000000 /**< Enable mode bits */ +#define XQSPIPS_LQSPI_CR_MODE_ON_MASK 0x01000000 /**< Mode on */ +#define XQSPIPS_LQSPI_CR_MODE_BITS_MASK 0x00FF0000 /**< Mode value for dual I/O + or quad I/O */ +#define XQSPIPS_LQSPI_CR_DUMMY_MASK 0x00000700 /**< Number of dummy bytes + between addr and return + read data */ +#define XQSPIPS_LQSPI_CR_INST_MASK 0x000000FF /**< Read instr code */ +#define XQSPIPS_LQSPI_CR_RST_STATE 0x8000016B /**< Default CR value */ +/* @} */ + +/** @name Linear QSPI Status Register + * + * This register contains various status bits of the Linear QSPI controller. + * Read/Write. + * + * @{ + */ +#define XQSPIPS_LQSPI_SR_D_FSM_ERR_MASK 0x00000004 /**< AXI Data FSM Error + received */ +#define XQSPIPS_LQSPI_SR_WR_RECVD_MASK 0x00000002 /**< AXI write command + received */ +/* @} */ + + +/** @name Loopback Delay Adjust Register + * + * This register contains various bit masks of Loopback Delay Adjust Register. + * + * @{ + */ + +#define XQSPIPS_LPBK_DLY_ADJ_USE_LPBK_MASK 0x00000020 /**< Loopback Bit */ + +/* @} */ + + +/** @name SLCR Register + * + * Register offsets from SLCR base address. + * + * @{ + */ + +#define SLCR_LOCK 0x00000004 /**< SLCR Write Protection Lock */ +#define SLCR_UNLOCK 0x00000008 /**< SLCR Write Protection Unlock */ +#define LQSPI_RST_CTRL 0x00000230 /**< Quad SPI Software Reset Control */ +#define SLCR_LOCKSTA 0x0000000C /**< SLCR Write Protection status */ + +/* @} */ + + +/** @name SLCR Register + * + * Bit Masks of above SLCR Registers . + * + * @{ + */ + +#ifndef XPAR_XSLCR_0_BASEADDR +#define XPAR_XSLCR_0_BASEADDR 0xF8000000 +#endif +#define SLCR_LOCK_MASK 0x767B /**< Write Protection Lock mask*/ +#define SLCR_UNLOCK_MASK 0xDF0D /**< SLCR Write Protection Unlock */ +#define LQSPI_RST_CTRL_MASK 0x3 /**< Quad SPI Software Reset Control */ + +/* @} */ + + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +#define XQspiPs_In32 Xil_In32 +#define XQspiPs_Out32 Xil_Out32 +#define XQSPIPS_DUMMY_TX_DATA 0xFFFFFFFF + +/****************************************************************************/ +/** +* Read a register. +* +* @param BaseAddress contains the base address of the device. +* @param RegOffset contains the offset from the 1st register of the +* device to the target register. +* +* @return The value read from the register. +* +* @note C-Style signature: +* u32 XQspiPs_ReadReg(u32 BaseAddress. int RegOffset) +* +******************************************************************************/ +#define XQspiPs_ReadReg(BaseAddress, RegOffset) \ + XQspiPs_In32((BaseAddress) + (RegOffset)) + +/***************************************************************************/ +/** +* Write to a register. +* +* @param BaseAddress contains the base address of the device. +* @param RegOffset contains the offset from the 1st register of the +* device to target register. +* @param RegisterValue is the value to be written to the register. +* +* @return None. +* +* @note C-Style signature: +* void XQspiPs_WriteReg(u32 BaseAddress, int RegOffset, +* u32 RegisterValue) +* +******************************************************************************/ +#define XQspiPs_WriteReg(BaseAddress, RegOffset, RegisterValue) \ + XQspiPs_Out32((BaseAddress) + (RegOffset), (RegisterValue)) + +/************************** Function Prototypes ******************************/ + +/* + * Functions implemented in xqspips_hw.c + */ +void XQspiPs_ResetHw(u32 BaseAddress); +void XQspiPs_LinearInit(u32 BaseAddress); + +/************************** Variable Definitions *****************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xreg_cortexa9.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xreg_cortexa9.h new file mode 100644 index 0000000..ad93665 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xreg_cortexa9.h @@ -0,0 +1,587 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xreg_cortexa9.h +* +* This header file contains definitions for using inline assembler code. It is +* written specifically for the GNU, ARMCC compiler. +* +* All of the ARM Cortex A9 GPRs, SPRs, and Debug Registers are defined along +* with the positions of the bits within the registers. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who      Date     Changes
+* ----- -------- -------- -----------------------------------------------
+* 1.00a ecm/sdm  10/20/09 First release
+* 
+* +******************************************************************************/ +#ifndef XREG_CORTEXA9_H +#define XREG_CORTEXA9_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* GPRs */ +#define XREG_GPR0 r0 +#define XREG_GPR1 r1 +#define XREG_GPR2 r2 +#define XREG_GPR3 r3 +#define XREG_GPR4 r4 +#define XREG_GPR5 r5 +#define XREG_GPR6 r6 +#define XREG_GPR7 r7 +#define XREG_GPR8 r8 +#define XREG_GPR9 r9 +#define XREG_GPR10 r10 +#define XREG_GPR11 r11 +#define XREG_GPR12 r12 +#define XREG_GPR13 r13 +#define XREG_GPR14 r14 +#define XREG_GPR15 r15 +#define XREG_CPSR cpsr + +/* Coprocessor number defines */ +#define XREG_CP0 0 +#define XREG_CP1 1 +#define XREG_CP2 2 +#define XREG_CP3 3 +#define XREG_CP4 4 +#define XREG_CP5 5 +#define XREG_CP6 6 +#define XREG_CP7 7 +#define XREG_CP8 8 +#define XREG_CP9 9 +#define XREG_CP10 10 +#define XREG_CP11 11 +#define XREG_CP12 12 +#define XREG_CP13 13 +#define XREG_CP14 14 +#define XREG_CP15 15 + +/* Coprocessor control register defines */ +#define XREG_CR0 cr0 +#define XREG_CR1 cr1 +#define XREG_CR2 cr2 +#define XREG_CR3 cr3 +#define XREG_CR4 cr4 +#define XREG_CR5 cr5 +#define XREG_CR6 cr6 +#define XREG_CR7 cr7 +#define XREG_CR8 cr8 +#define XREG_CR9 cr9 +#define XREG_CR10 cr10 +#define XREG_CR11 cr11 +#define XREG_CR12 cr12 +#define XREG_CR13 cr13 +#define XREG_CR14 cr14 +#define XREG_CR15 cr15 + +/* Current Processor Status Register (CPSR) Bits */ +#define XREG_CPSR_THUMB_MODE 0x20 +#define XREG_CPSR_MODE_BITS 0x1F +#define XREG_CPSR_SYSTEM_MODE 0x1F +#define XREG_CPSR_UNDEFINED_MODE 0x1B +#define XREG_CPSR_DATA_ABORT_MODE 0x17 +#define XREG_CPSR_SVC_MODE 0x13 +#define XREG_CPSR_IRQ_MODE 0x12 +#define XREG_CPSR_FIQ_MODE 0x11 +#define XREG_CPSR_USER_MODE 0x10 + +#define XREG_CPSR_IRQ_ENABLE 0x80 +#define XREG_CPSR_FIQ_ENABLE 0x40 + +#define XREG_CPSR_N_BIT 0x80000000 +#define XREG_CPSR_Z_BIT 0x40000000 +#define XREG_CPSR_C_BIT 0x20000000 +#define XREG_CPSR_V_BIT 0x10000000 + + +/* CP15 defines */ +#if defined (__GNUC__) || defined (__ICCARM__) +/* C0 Register defines */ +#define XREG_CP15_MAIN_ID "p15, 0, %0, c0, c0, 0" +#define XREG_CP15_CACHE_TYPE "p15, 0, %0, c0, c0, 1" +#define XREG_CP15_TCM_TYPE "p15, 0, %0, c0, c0, 2" +#define XREG_CP15_TLB_TYPE "p15, 0, %0, c0, c0, 3" +#define XREG_CP15_MULTI_PROC_AFFINITY "p15, 0, %0, c0, c0, 5" + +#define XREG_CP15_PROC_FEATURE_0 "p15, 0, %0, c0, c1, 0" +#define XREG_CP15_PROC_FEATURE_1 "p15, 0, %0, c0, c1, 1" +#define XREG_CP15_DEBUG_FEATURE_0 "p15, 0, %0, c0, c1, 2" +#define XREG_CP15_MEMORY_FEATURE_0 "p15, 0, %0, c0, c1, 4" +#define XREG_CP15_MEMORY_FEATURE_1 "p15, 0, %0, c0, c1, 5" +#define XREG_CP15_MEMORY_FEATURE_2 "p15, 0, %0, c0, c1, 6" +#define XREG_CP15_MEMORY_FEATURE_3 "p15, 0, %0, c0, c1, 7" + +#define XREG_CP15_INST_FEATURE_0 "p15, 0, %0, c0, c2, 0" +#define XREG_CP15_INST_FEATURE_1 "p15, 0, %0, c0, c2, 1" +#define XREG_CP15_INST_FEATURE_2 "p15, 0, %0, c0, c2, 2" +#define XREG_CP15_INST_FEATURE_3 "p15, 0, %0, c0, c2, 3" +#define XREG_CP15_INST_FEATURE_4 "p15, 0, %0, c0, c2, 4" + +#define XREG_CP15_CACHE_SIZE_ID "p15, 1, %0, c0, c0, 0" +#define XREG_CP15_CACHE_LEVEL_ID "p15, 1, %0, c0, c0, 1" +#define XREG_CP15_AUXILARY_ID "p15, 1, %0, c0, c0, 7" + +#define XREG_CP15_CACHE_SIZE_SEL "p15, 2, %0, c0, c0, 0" + +/* C1 Register Defines */ +#define XREG_CP15_SYS_CONTROL "p15, 0, %0, c1, c0, 0" +#define XREG_CP15_AUX_CONTROL "p15, 0, %0, c1, c0, 1" +#define XREG_CP15_CP_ACCESS_CONTROL "p15, 0, %0, c1, c0, 2" + +#define XREG_CP15_SECURE_CONFIG "p15, 0, %0, c1, c1, 0" +#define XREG_CP15_SECURE_DEBUG_ENABLE "p15, 0, %0, c1, c1, 1" +#define XREG_CP15_NS_ACCESS_CONTROL "p15, 0, %0, c1, c1, 2" +#define XREG_CP15_VIRTUAL_CONTROL "p15, 0, %0, c1, c1, 3" + +#else /* RVCT */ +/* C0 Register defines */ +#define XREG_CP15_MAIN_ID "cp15:0:c0:c0:0" +#define XREG_CP15_CACHE_TYPE "cp15:0:c0:c0:1" +#define XREG_CP15_TCM_TYPE "cp15:0:c0:c0:2" +#define XREG_CP15_TLB_TYPE "cp15:0:c0:c0:3" +#define XREG_CP15_MULTI_PROC_AFFINITY "cp15:0:c0:c0:5" + +#define XREG_CP15_PROC_FEATURE_0 "cp15:0:c0:c1:0" +#define XREG_CP15_PROC_FEATURE_1 "cp15:0:c0:c1:1" +#define XREG_CP15_DEBUG_FEATURE_0 "cp15:0:c0:c1:2" +#define XREG_CP15_MEMORY_FEATURE_0 "cp15:0:c0:c1:4" +#define XREG_CP15_MEMORY_FEATURE_1 "cp15:0:c0:c1:5" +#define XREG_CP15_MEMORY_FEATURE_2 "cp15:0:c0:c1:6" +#define XREG_CP15_MEMORY_FEATURE_3 "cp15:0:c0:c1:7" + +#define XREG_CP15_INST_FEATURE_0 "cp15:0:c0:c2:0" +#define XREG_CP15_INST_FEATURE_1 "cp15:0:c0:c2:1" +#define XREG_CP15_INST_FEATURE_2 "cp15:0:c0:c2:2" +#define XREG_CP15_INST_FEATURE_3 "cp15:0:c0:c2:3" +#define XREG_CP15_INST_FEATURE_4 "cp15:0:c0:c2:4" + +#define XREG_CP15_CACHE_SIZE_ID "cp15:1:c0:c0:0" +#define XREG_CP15_CACHE_LEVEL_ID "cp15:1:c0:c0:1" +#define XREG_CP15_AUXILARY_ID "cp15:1:c0:c0:7" + +#define XREG_CP15_CACHE_SIZE_SEL "cp15:2:c0:c0:0" + +/* C1 Register Defines */ +#define XREG_CP15_SYS_CONTROL "cp15:0:c1:c0:0" +#define XREG_CP15_AUX_CONTROL "cp15:0:c1:c0:1" +#define XREG_CP15_CP_ACCESS_CONTROL "cp15:0:c1:c0:2" + +#define XREG_CP15_SECURE_CONFIG "cp15:0:c1:c1:0" +#define XREG_CP15_SECURE_DEBUG_ENABLE "cp15:0:c1:c1:1" +#define XREG_CP15_NS_ACCESS_CONTROL "cp15:0:c1:c1:2" +#define XREG_CP15_VIRTUAL_CONTROL "cp15:0:c1:c1:3" +#endif + +/* XREG_CP15_CONTROL bit defines */ +#define XREG_CP15_CONTROL_TE_BIT 0x40000000U +#define XREG_CP15_CONTROL_AFE_BIT 0x20000000U +#define XREG_CP15_CONTROL_TRE_BIT 0x10000000U +#define XREG_CP15_CONTROL_NMFI_BIT 0x08000000U +#define XREG_CP15_CONTROL_EE_BIT 0x02000000U +#define XREG_CP15_CONTROL_HA_BIT 0x00020000U +#define XREG_CP15_CONTROL_RR_BIT 0x00004000U +#define XREG_CP15_CONTROL_V_BIT 0x00002000U +#define XREG_CP15_CONTROL_I_BIT 0x00001000U +#define XREG_CP15_CONTROL_Z_BIT 0x00000800U +#define XREG_CP15_CONTROL_SW_BIT 0x00000400U +#define XREG_CP15_CONTROL_B_BIT 0x00000080U +#define XREG_CP15_CONTROL_C_BIT 0x00000004U +#define XREG_CP15_CONTROL_A_BIT 0x00000002U +#define XREG_CP15_CONTROL_M_BIT 0x00000001U + +#if defined (__GNUC__) || defined (__ICCARM__) +/* C2 Register Defines */ +#define XREG_CP15_TTBR0 "p15, 0, %0, c2, c0, 0" +#define XREG_CP15_TTBR1 "p15, 0, %0, c2, c0, 1" +#define XREG_CP15_TTB_CONTROL "p15, 0, %0, c2, c0, 2" + +/* C3 Register Defines */ +#define XREG_CP15_DOMAIN_ACCESS_CTRL "p15, 0, %0, c3, c0, 0" + +/* C4 Register Defines */ +/* Not Used */ + +/* C5 Register Defines */ +#define XREG_CP15_DATA_FAULT_STATUS "p15, 0, %0, c5, c0, 0" +#define XREG_CP15_INST_FAULT_STATUS "p15, 0, %0, c5, c0, 1" + +#define XREG_CP15_AUX_DATA_FAULT_STATUS "p15, 0, %0, c5, c1, 0" +#define XREG_CP15_AUX_INST_FAULT_STATUS "p15, 0, %0, c5, c1, 1" + +/* C6 Register Defines */ +#define XREG_CP15_DATA_FAULT_ADDRESS "p15, 0, %0, c6, c0, 0" +#define XREG_CP15_INST_FAULT_ADDRESS "p15, 0, %0, c6, c0, 2" + +/* C7 Register Defines */ +#define XREG_CP15_NOP "p15, 0, %0, c7, c0, 4" + +#define XREG_CP15_INVAL_IC_POU_IS "p15, 0, %0, c7, c1, 0" +#define XREG_CP15_INVAL_BRANCH_ARRAY_IS "p15, 0, %0, c7, c1, 6" + +#define XREG_CP15_PHYS_ADDR "p15, 0, %0, c7, c4, 0" + +#define XREG_CP15_INVAL_IC_POU "p15, 0, %0, c7, c5, 0" +#define XREG_CP15_INVAL_IC_LINE_MVA_POU "p15, 0, %0, c7, c5, 1" + +/* The CP15 register access below has been deprecated in favor of the new + * isb instruction in Cortex A9. + */ +#define XREG_CP15_INST_SYNC_BARRIER "p15, 0, %0, c7, c5, 4" +#define XREG_CP15_INVAL_BRANCH_ARRAY "p15, 0, %0, c7, c5, 6" + +#define XREG_CP15_INVAL_DC_LINE_MVA_POC "p15, 0, %0, c7, c6, 1" +#define XREG_CP15_INVAL_DC_LINE_SW "p15, 0, %0, c7, c6, 2" + +#define XREG_CP15_VA_TO_PA_CURRENT_0 "p15, 0, %0, c7, c8, 0" +#define XREG_CP15_VA_TO_PA_CURRENT_1 "p15, 0, %0, c7, c8, 1" +#define XREG_CP15_VA_TO_PA_CURRENT_2 "p15, 0, %0, c7, c8, 2" +#define XREG_CP15_VA_TO_PA_CURRENT_3 "p15, 0, %0, c7, c8, 3" + +#define XREG_CP15_VA_TO_PA_OTHER_0 "p15, 0, %0, c7, c8, 4" +#define XREG_CP15_VA_TO_PA_OTHER_1 "p15, 0, %0, c7, c8, 5" +#define XREG_CP15_VA_TO_PA_OTHER_2 "p15, 0, %0, c7, c8, 6" +#define XREG_CP15_VA_TO_PA_OTHER_3 "p15, 0, %0, c7, c8, 7" + +#define XREG_CP15_CLEAN_DC_LINE_MVA_POC "p15, 0, %0, c7, c10, 1" +#define XREG_CP15_CLEAN_DC_LINE_SW "p15, 0, %0, c7, c10, 2" + +/* The next two CP15 register accesses below have been deprecated in favor + * of the new dsb and dmb instructions in Cortex A9. + */ +#define XREG_CP15_DATA_SYNC_BARRIER "p15, 0, %0, c7, c10, 4" +#define XREG_CP15_DATA_MEMORY_BARRIER "p15, 0, %0, c7, c10, 5" + +#define XREG_CP15_CLEAN_DC_LINE_MVA_POU "p15, 0, %0, c7, c11, 1" + +#define XREG_CP15_NOP2 "p15, 0, %0, c7, c13, 1" + +#define XREG_CP15_CLEAN_INVAL_DC_LINE_MVA_POC "p15, 0, %0, c7, c14, 1" +#define XREG_CP15_CLEAN_INVAL_DC_LINE_SW "p15, 0, %0, c7, c14, 2" + +/* C8 Register Defines */ +#define XREG_CP15_INVAL_TLB_IS "p15, 0, %0, c8, c3, 0" +#define XREG_CP15_INVAL_TLB_MVA_IS "p15, 0, %0, c8, c3, 1" +#define XREG_CP15_INVAL_TLB_ASID_IS "p15, 0, %0, c8, c3, 2" +#define XREG_CP15_INVAL_TLB_MVA_ASID_IS "p15, 0, %0, c8, c3, 3" + +#define XREG_CP15_INVAL_ITLB_UNLOCKED "p15, 0, %0, c8, c5, 0" +#define XREG_CP15_INVAL_ITLB_MVA "p15, 0, %0, c8, c5, 1" +#define XREG_CP15_INVAL_ITLB_ASID "p15, 0, %0, c8, c5, 2" + +#define XREG_CP15_INVAL_DTLB_UNLOCKED "p15, 0, %0, c8, c6, 0" +#define XREG_CP15_INVAL_DTLB_MVA "p15, 0, %0, c8, c6, 1" +#define XREG_CP15_INVAL_DTLB_ASID "p15, 0, %0, c8, c6, 2" + +#define XREG_CP15_INVAL_UTLB_UNLOCKED "p15, 0, %0, c8, c7, 0" +#define XREG_CP15_INVAL_UTLB_MVA "p15, 0, %0, c8, c7, 1" +#define XREG_CP15_INVAL_UTLB_ASID "p15, 0, %0, c8, c7, 2" +#define XREG_CP15_INVAL_UTLB_MVA_ASID "p15, 0, %0, c8, c7, 3" + +/* C9 Register Defines */ +#define XREG_CP15_PERF_MONITOR_CTRL "p15, 0, %0, c9, c12, 0" +#define XREG_CP15_COUNT_ENABLE_SET "p15, 0, %0, c9, c12, 1" +#define XREG_CP15_COUNT_ENABLE_CLR "p15, 0, %0, c9, c12, 2" +#define XREG_CP15_V_FLAG_STATUS "p15, 0, %0, c9, c12, 3" +#define XREG_CP15_SW_INC "p15, 0, %0, c9, c12, 4" +#define XREG_CP15_EVENT_CNTR_SEL "p15, 0, %0, c9, c12, 5" + +#define XREG_CP15_PERF_CYCLE_COUNTER "p15, 0, %0, c9, c13, 0" +#define XREG_CP15_EVENT_TYPE_SEL "p15, 0, %0, c9, c13, 1" +#define XREG_CP15_PERF_MONITOR_COUNT "p15, 0, %0, c9, c13, 2" + +#define XREG_CP15_USER_ENABLE "p15, 0, %0, c9, c14, 0" +#define XREG_CP15_INTR_ENABLE_SET "p15, 0, %0, c9, c14, 1" +#define XREG_CP15_INTR_ENABLE_CLR "p15, 0, %0, c9, c14, 2" + +/* C10 Register Defines */ +#define XREG_CP15_TLB_LOCKDWN "p15, 0, %0, c10, c0, 0" + +#define XREG_CP15_PRI_MEM_REMAP "p15, 0, %0, c10, c2, 0" +#define XREG_CP15_NORM_MEM_REMAP "p15, 0, %0, c10, c2, 1" + +/* C11 Register Defines */ +/* Not used */ + +/* C12 Register Defines */ +#define XREG_CP15_VEC_BASE_ADDR "p15, 0, %0, c12, c0, 0" +#define XREG_CP15_MONITOR_VEC_BASE_ADDR "p15, 0, %0, c12, c0, 1" + +#define XREG_CP15_INTERRUPT_STATUS "p15, 0, %0, c12, c1, 0" +#define XREG_CP15_VIRTUALIZATION_INTR "p15, 0, %0, c12, c1, 1" + +/* C13 Register Defines */ +#define XREG_CP15_CONTEXT_ID "p15, 0, %0, c13, c0, 1" +#define USER_RW_THREAD_PID "p15, 0, %0, c13, c0, 2" +#define USER_RO_THREAD_PID "p15, 0, %0, c13, c0, 3" +#define USER_PRIV_THREAD_PID "p15, 0, %0, c13, c0, 4" + +/* C14 Register Defines */ +/* not used */ + +/* C15 Register Defines */ +#define XREG_CP15_POWER_CTRL "p15, 0, %0, c15, c0, 0" +#define XREG_CP15_CONFIG_BASE_ADDR "p15, 4, %0, c15, c0, 0" + +#define XREG_CP15_READ_TLB_ENTRY "p15, 5, %0, c15, c4, 2" +#define XREG_CP15_WRITE_TLB_ENTRY "p15, 5, %0, c15, c4, 4" + +#define XREG_CP15_MAIN_TLB_VA "p15, 5, %0, c15, c5, 2" + +#define XREG_CP15_MAIN_TLB_PA "p15, 5, %0, c15, c6, 2" + +#define XREG_CP15_MAIN_TLB_ATTR "p15, 5, %0, c15, c7, 2" + +#else +/* C2 Register Defines */ +#define XREG_CP15_TTBR0 "cp15:0:c2:c0:0" +#define XREG_CP15_TTBR1 "cp15:0:c2:c0:1" +#define XREG_CP15_TTB_CONTROL "cp15:0:c2:c0:2" + +/* C3 Register Defines */ +#define XREG_CP15_DOMAIN_ACCESS_CTRL "cp15:0:c3:c0:0" + +/* C4 Register Defines */ +/* Not Used */ + +/* C5 Register Defines */ +#define XREG_CP15_DATA_FAULT_STATUS "cp15:0:c5:c0:0" +#define XREG_CP15_INST_FAULT_STATUS "cp15:0:c5:c0:1" + +#define XREG_CP15_AUX_DATA_FAULT_STATUS "cp15:0:c5:c1:0" +#define XREG_CP15_AUX_INST_FAULT_STATUS "cp15:0:c5:c1:1" + +/* C6 Register Defines */ +#define XREG_CP15_DATA_FAULT_ADDRESS "cp15:0:c6:c0:0" +#define XREG_CP15_INST_FAULT_ADDRESS "cp15:0:c6:c0:2" + +/* C7 Register Defines */ +#define XREG_CP15_NOP "cp15:0:c7:c0:4" + +#define XREG_CP15_INVAL_IC_POU_IS "cp15:0:c7:c1:0" +#define XREG_CP15_INVAL_BRANCH_ARRAY_IS "cp15:0:c7:c1:6" + +#define XREG_CP15_PHYS_ADDR "cp15:0:c7:c4:0" + +#define XREG_CP15_INVAL_IC_POU "cp15:0:c7:c5:0" +#define XREG_CP15_INVAL_IC_LINE_MVA_POU "cp15:0:c7:c5:1" + +/* The CP15 register access below has been deprecated in favor of the new + * isb instruction in Cortex A9. + */ +#define XREG_CP15_INST_SYNC_BARRIER "cp15:0:c7:c5:4" +#define XREG_CP15_INVAL_BRANCH_ARRAY "cp15:0:c7:c5:6" + +#define XREG_CP15_INVAL_DC_LINE_MVA_POC "cp15:0:c7:c6:1" +#define XREG_CP15_INVAL_DC_LINE_SW "cp15:0:c7:c6:2" + +#define XREG_CP15_VA_TO_PA_CURRENT_0 "cp15:0:c7:c8:0" +#define XREG_CP15_VA_TO_PA_CURRENT_1 "cp15:0:c7:c8:1" +#define XREG_CP15_VA_TO_PA_CURRENT_2 "cp15:0:c7:c8:2" +#define XREG_CP15_VA_TO_PA_CURRENT_3 "cp15:0:c7:c8:3" + +#define XREG_CP15_VA_TO_PA_OTHER_0 "cp15:0:c7:c8:4" +#define XREG_CP15_VA_TO_PA_OTHER_1 "cp15:0:c7:c8:5" +#define XREG_CP15_VA_TO_PA_OTHER_2 "cp15:0:c7:c8:6" +#define XREG_CP15_VA_TO_PA_OTHER_3 "cp15:0:c7:c8:7" + +#define XREG_CP15_CLEAN_DC_LINE_MVA_POC "cp15:0:c7:c10:1" +#define XREG_CP15_CLEAN_DC_LINE_SW "cp15:0:c7:c10:2" + +/* The next two CP15 register accesses below have been deprecated in favor + * of the new dsb and dmb instructions in Cortex A9. + */ +#define XREG_CP15_DATA_SYNC_BARRIER "cp15:0:c7:c10:4" +#define XREG_CP15_DATA_MEMORY_BARRIER "cp15:0:c7:c10:5" + +#define XREG_CP15_CLEAN_DC_LINE_MVA_POU "cp15:0:c7:c11:1" + +#define XREG_CP15_NOP2 "cp15:0:c7:c13:1" + +#define XREG_CP15_CLEAN_INVAL_DC_LINE_MVA_POC "cp15:0:c7:c14:1" +#define XREG_CP15_CLEAN_INVAL_DC_LINE_SW "cp15:0:c7:c14:2" + +/* C8 Register Defines */ +#define XREG_CP15_INVAL_TLB_IS "cp15:0:c8:c3:0" +#define XREG_CP15_INVAL_TLB_MVA_IS "cp15:0:c8:c3:1" +#define XREG_CP15_INVAL_TLB_ASID_IS "cp15:0:c8:c3:2" +#define XREG_CP15_INVAL_TLB_MVA_ASID_IS "cp15:0:c8:c3:3" + +#define XREG_CP15_INVAL_ITLB_UNLOCKED "cp15:0:c8:c5:0" +#define XREG_CP15_INVAL_ITLB_MVA "cp15:0:c8:c5:1" +#define XREG_CP15_INVAL_ITLB_ASID "cp15:0:c8:c5:2" + +#define XREG_CP15_INVAL_DTLB_UNLOCKED "cp15:0:c8:c6:0" +#define XREG_CP15_INVAL_DTLB_MVA "cp15:0:c8:c6:1" +#define XREG_CP15_INVAL_DTLB_ASID "cp15:0:c8:c6:2" + +#define XREG_CP15_INVAL_UTLB_UNLOCKED "cp15:0:c8:c7:0" +#define XREG_CP15_INVAL_UTLB_MVA "cp15:0:c8:c7:1" +#define XREG_CP15_INVAL_UTLB_ASID "cp15:0:c8:c7:2" +#define XREG_CP15_INVAL_UTLB_MVA_ASID "cp15:0:c8:c7:3" + +/* C9 Register Defines */ +#define XREG_CP15_PERF_MONITOR_CTRL "cp15:0:c9:c12:0" +#define XREG_CP15_COUNT_ENABLE_SET "cp15:0:c9:c12:1" +#define XREG_CP15_COUNT_ENABLE_CLR "cp15:0:c9:c12:2" +#define XREG_CP15_V_FLAG_STATUS "cp15:0:c9:c12:3" +#define XREG_CP15_SW_INC "cp15:0:c9:c12:4" +#define XREG_CP15_EVENT_CNTR_SEL "cp15:0:c9:c12:5" + +#define XREG_CP15_PERF_CYCLE_COUNTER "cp15:0:c9:c13:0" +#define XREG_CP15_EVENT_TYPE_SEL "cp15:0:c9:c13:1" +#define XREG_CP15_PERF_MONITOR_COUNT "cp15:0:c9:c13:2" + +#define XREG_CP15_USER_ENABLE "cp15:0:c9:c14:0" +#define XREG_CP15_INTR_ENABLE_SET "cp15:0:c9:c14:1" +#define XREG_CP15_INTR_ENABLE_CLR "cp15:0:c9:c14:2" + +/* C10 Register Defines */ +#define XREG_CP15_TLB_LOCKDWN "cp15:0:c10:c0:0" + +#define XREG_CP15_PRI_MEM_REMAP "cp15:0:c10:c2:0" +#define XREG_CP15_NORM_MEM_REMAP "cp15:0:c10:c2:1" + +/* C11 Register Defines */ +/* Not used */ + +/* C12 Register Defines */ +#define XREG_CP15_VEC_BASE_ADDR "cp15:0:c12:c0:0" +#define XREG_CP15_MONITOR_VEC_BASE_ADDR "cp15:0:c12:c0:1" + +#define XREG_CP15_INTERRUPT_STATUS "cp15:0:c12:c1:0" +#define XREG_CP15_VIRTUALIZATION_INTR "cp15:0:c12:c1:1" + +/* C13 Register Defines */ +#define XREG_CP15_CONTEXT_ID "cp15:0:c13:c0:1" +#define USER_RW_THREAD_PID "cp15:0:c13:c0:2" +#define USER_RO_THREAD_PID "cp15:0:c13:c0:3" +#define USER_PRIV_THREAD_PID "cp15:0:c13:c0:4" + +/* C14 Register Defines */ +/* not used */ + +/* C15 Register Defines */ +#define XREG_CP15_POWER_CTRL "cp15:0:c15:c0:0" +#define XREG_CP15_CONFIG_BASE_ADDR "cp15:4:c15:c0:0" + +#define XREG_CP15_READ_TLB_ENTRY "cp15:5:c15:c4:2" +#define XREG_CP15_WRITE_TLB_ENTRY "cp15:5:c15:c4:4" + +#define XREG_CP15_MAIN_TLB_VA "cp15:5:c15:c5:2" + +#define XREG_CP15_MAIN_TLB_PA "cp15:5:c15:c6:2" + +#define XREG_CP15_MAIN_TLB_ATTR "cp15:5:c15:c7:2" +#endif + + +/* MPE register definitions */ +#define XREG_FPSID c0 +#define XREG_FPSCR c1 +#define XREG_MVFR1 c6 +#define XREG_MVFR0 c7 +#define XREG_FPEXC c8 +#define XREG_FPINST c9 +#define XREG_FPINST2 c10 + +/* FPSID bits */ +#define XREG_FPSID_IMPLEMENTER_BIT (24) +#define XREG_FPSID_IMPLEMENTER_MASK (0xFF << FPSID_IMPLEMENTER_BIT) +#define XREG_FPSID_SOFTWARE (1<<23) +#define XREG_FPSID_ARCH_BIT (16) +#define XREG_FPSID_ARCH_MASK (0xF << FPSID_ARCH_BIT) +#define XREG_FPSID_PART_BIT (8) +#define XREG_FPSID_PART_MASK (0xFF << FPSID_PART_BIT) +#define XREG_FPSID_VARIANT_BIT (4) +#define XREG_FPSID_VARIANT_MASK (0xF << FPSID_VARIANT_BIT) +#define XREG_FPSID_REV_BIT (0) +#define XREG_FPSID_REV_MASK (0xF << FPSID_REV_BIT) + +/* FPSCR bits */ +#define XREG_FPSCR_N_BIT (1 << 31) +#define XREG_FPSCR_Z_BIT (1 << 30) +#define XREG_FPSCR_C_BIT (1 << 29) +#define XREG_FPSCR_V_BIT (1 << 28) +#define XREG_FPSCR_QC (1 << 27) +#define XREG_FPSCR_AHP (1 << 26) +#define XREG_FPSCR_DEFAULT_NAN (1 << 25) +#define XREG_FPSCR_FLUSHTOZERO (1 << 24) +#define XREG_FPSCR_ROUND_NEAREST (0 << 22) +#define XREG_FPSCR_ROUND_PLUSINF (1 << 22) +#define XREG_FPSCR_ROUND_MINUSINF (2 << 22) +#define XREG_FPSCR_ROUND_TOZERO (3 << 22) +#define XREG_FPSCR_RMODE_BIT (22) +#define XREG_FPSCR_RMODE_MASK (3 << FPSCR_RMODE_BIT) +#define XREG_FPSCR_STRIDE_BIT (20) +#define XREG_FPSCR_STRIDE_MASK (3 << FPSCR_STRIDE_BIT) +#define XREG_FPSCR_LENGTH_BIT (16) +#define XREG_FPSCR_LENGTH_MASK (7 << FPSCR_LENGTH_BIT) +#define XREG_FPSCR_IDC (1 << 7) +#define XREG_FPSCR_IXC (1 << 4) +#define XREG_FPSCR_UFC (1 << 3) +#define XREG_FPSCR_OFC (1 << 2) +#define XREG_FPSCR_DZC (1 << 1) +#define XREG_FPSCR_IOC (1 << 0) + +/* MVFR0 bits */ +#define XREG_MVFR0_RMODE_BIT (28) +#define XREG_MVFR0_RMODE_MASK (0xF << XREG_MVFR0_RMODE_BIT) +#define XREG_MVFR0_SHORT_VEC_BIT (24) +#define XREG_MVFR0_SHORT_VEC_MASK (0xF << XREG_MVFR0_SHORT_VEC_BIT) +#define XREG_MVFR0_SQRT_BIT (20) +#define XREG_MVFR0_SQRT_MASK (0xF << XREG_MVFR0_SQRT_BIT) +#define XREG_MVFR0_DIVIDE_BIT (16) +#define XREG_MVFR0_DIVIDE_MASK (0xF << XREG_MVFR0_DIVIDE_BIT) +#define XREG_MVFR0_EXEC_TRAP_BIT (12) +#define XREG_MVFR0_EXEC_TRAP_MASK (0xF << XREG_MVFR0_EXEC_TRAP_BIT) +#define XREG_MVFR0_DP_BIT (8) +#define XREG_MVFR0_DP_MASK (0xF << XREG_MVFR0_DP_BIT) +#define XREG_MVFR0_SP_BIT (4) +#define XREG_MVFR0_SP_MASK (0xF << XREG_MVFR0_SP_BIT) +#define XREG_MVFR0_A_SIMD_BIT (0) +#define XREG_MVFR0_A_SIMD_MASK (0xF << MVFR0_A_SIMD_BIT) + +/* FPEXC bits */ +#define XREG_FPEXC_EX (1 << 31) +#define XREG_FPEXC_EN (1 << 30) +#define XREG_FPEXC_DEX (1 << 29) + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* XREG_CORTEXA9_H */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xscugic.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xscugic.h new file mode 100644 index 0000000..5502a20 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xscugic.h @@ -0,0 +1,598 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xscugic.h +* @addtogroup scugic_v4_0 +* @{ +* @details +* +* The generic interrupt controller driver component. +* +* The interrupt controller driver uses the idea of priority for the various +* handlers. Priority is an integer within the range of 1 and 31 inclusive with +* default of 1 being the highest priority interrupt source. The priorities +* of the various sources can be dynamically altered as needed through +* hardware configuration. +* +* The generic interrupt controller supports the following +* features: +* +* - specific individual interrupt enabling/disabling +* - specific individual interrupt acknowledging +* - attaching specific callback function to handle interrupt source +* - assigning desired priority to interrupt source if default is not +* acceptable. +* +* Details about connecting the interrupt handler of the driver are contained +* in the source file specific to interrupt processing, xscugic_intr.c. +* +* This driver is intended to be RTOS and processor independent. It works with +* physical addresses only. Any needs for dynamic memory management, threads +* or thread mutual exclusion, virtual memory, or cache control must be +* satisfied by the layer above this driver. +* +* Interrupt Vector Tables +* +* The device ID of the interrupt controller device is used by the driver as a +* direct index into the configuration data table. The user should populate the +* vector table with handlers and callbacks at run-time using the +* XScuGic_Connect() and XScuGic_Disconnect() functions. +* +* Each vector table entry corresponds to a device that can generate an +* interrupt. Each entry contains an interrupt handler function and an +* argument to be passed to the handler when an interrupt occurs. The +* user must use XScuGic_Connect() when the interrupt handler takes an +* argument other than the base address. +* +* Nested Interrupts Processing +* +* Nested interrupts are not supported by this driver. +* +* NOTE: +* The generic interrupt controller is not a part of the snoop control unit +* as indicated by the prefix "scu" in the name of the driver. +* It is an independent module in APU. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- ---------------------------------------------------------
+* 1.00a drg  01/19/00 First release
+* 1.01a sdm  11/09/11 The XScuGic and XScuGic_Config structures have changed.
+*		      The HandlerTable (of type XScuGic_VectorTableEntry) is
+*		      moved to XScuGic_Config structure from XScuGic structure.
+*
+*		      The "Config" entry in XScuGic structure is made as
+*		      pointer for better efficiency.
+*
+*		      A new file named as xscugic_hw.c is now added. It is
+*		      to implement low level driver routines without using
+*		      any xscugic instance pointer. They are useful when the
+*		      user wants to use xscugic through device id or
+*		      base address. The driver routines provided are explained
+*		      below.
+*		      XScuGic_DeviceInitialize that takes device id as
+*		      argument and initializes the device (without calling
+*		      XScuGic_CfgInitialize).
+*		      XScuGic_DeviceInterruptHandler that takes device id
+*		      as argument and calls appropriate handlers from the
+*		      HandlerTable.
+*		      XScuGic_RegisterHandler that registers a new handler
+*		      by taking xscugic hardware base address as argument.
+*		      LookupConfigByBaseAddress is used to return the
+*		      corresponding config structure from XScuGic_ConfigTable
+*		      based on the scugic base address passed.
+* 1.02a sdm  12/20/11 Removed AckBeforeService from the XScuGic_Config
+*		      structure.
+* 1.03a srt  02/27/13 Moved Offset calculation macros from *.c and *_hw.c to
+*		      *_hw.h
+*		      Added APIs
+*			- XScuGic_SetPriTrigTypeByDistAddr()
+*			- XScuGic_GetPriTrigTypeByDistAddr()
+*		      (CR 702687)
+*			Added support to direct interrupts to the appropriate CPU. Earlier
+*			  interrupts were directed to CPU1 (hard coded). Now depending
+*			  upon the CPU selected by the user (xparameters.h), interrupts
+*			  will be directed to the relevant CPU. This fixes CR 699688.
+* 1.04a hk   05/04/13 Assigned EffectiveAddr to CpuBaseAddress in
+*			  XScuGic_CfgInitialize. Fix for CR#704400 to remove warnings.
+*			  Moved functions XScuGic_SetPriTrigTypeByDistAddr and
+*             XScuGic_GetPriTrigTypeByDistAddr to xscugic_hw.c.
+*			  This is fix for CR#705621.
+* 1.05a hk   06/26/13 Modified tcl to export external interrupts correctly to
+*                     xparameters.h. Fix for CR's 690505, 708928 & 719359.
+* 2.0   adk  12/10/13 Updated as per the New Tcl API's
+* 2.1   adk  25/04/14 Fixed the CR:789373 changes are made in the driver tcl file.
+* 3.00  kvn  02/13/15 Modified code for MISRA-C:2012 compliance.
+* 3.2   asa  02/29/16 Modified DistributorInit function for Zynq AMP case. The
+*			  distributor is left uninitialized for Zynq AMP. It is assumed
+*             that the distributor will be initialized by Linux master. However
+*             for CortexR5 case, the earlier code is left unchanged where the
+*             the interrupt processor target registers in the distributor is
+*             initialized with the corresponding CPU ID on which the application
+*             built over the scugic driver runs.
+*             These changes fix CR#937243.
+*
+* 3.4   asa  04/07/16 Created a new static function DoDistributorInit to simplify
+*            the flow and avoid code duplication. Changes are made for
+*            USE_AMP use case for R5. In a scenario (in R5 split mode) when
+*            one R5 is operating with A53 in open amp config and other
+*            R5 running baremetal app, the existing code
+*            had the potential to stop the whole AMP solution to work (if
+*            for some reason the R5 running the baremetal app tasked to
+*            initialize the Distributor hangs or crashes before initializing).
+*            Changes are made so that the R5 under AMP first checks if
+*            the distributor is enabled or not and if not, it does the
+*            standard Distributor initialization.
+*            This fixes the CR#952962.
+* 3.6   ms   01/23/17 Modified xil_printf statement in main function for all
+*                     examples to ensure that "Successfully ran" and "Failed"
+*                     strings are available in all examples. This is a fix
+*                     for CR-965028.
+*       kvn  02/17/17 Add support for changing GIC CPU master at run time.
+*       kvn  02/28/17 Make the CpuId as static variable and Added new
+*                     XScugiC_GetCpuId to access CpuId.
+*       ms   03/17/17 Added readme.txt file in examples folder for doxygen
+*                     generation.
+* 3.7   ms   04/11/17 Modified tcl file to add suffix U for all macro
+*                     definitions of scugic in xparameters.h
+* 3.8   mus  07/05/17 Updated scugic.tcl to add support for intrrupts connected
+*                     through util_reduced_vector IP(OR gate)
+*       mus  07/05/17 Updated xdefine_zynq_canonical_xpars proc to initialize
+*                     the HandlerTable in XScuGic_ConfigTable to 0, it removes
+*                     the compilation warning in xscugic_g.c. Fix for CR#978736.
+*       mus  07/25/17 Updated xdefine_gic_params proc to export correct canonical
+*                     definitions for pl to ps interrupts.Fix for CR#980534
+* 3.9   mus  02/21/18 Added new API's XScuGic_UnmapAllInterruptsFromCpu and
+*                     XScuGic_InterruptUnmapFromCpu, These API's can be used
+*                     by applications to unmap specific/all interrupts from
+*                     target CPU.
+* 3.10  aru  08/23/18 Resolved MISRA-C:2012 compliance mandatory violations
+* 4.0   mus  11/22/18 Fixed bugs in software interrupt generation through 
+*                      XScuGic_SoftwareIntr API
+*
+* 
+* +******************************************************************************/ + +#ifndef XSCUGIC_H /* prevent circular inclusions */ +#define XSCUGIC_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/***************************** Include Files *********************************/ + +#include "xstatus.h" +#include "xil_io.h" +#include "xscugic_hw.h" +#include "xil_exception.h" + +/************************** Constant Definitions *****************************/ + +#define EFUSE_STATUS_OFFSET 0x10 +#define EFUSE_STATUS_CPU_MASK 0x80 + +#if !defined (ARMR5) && !defined (__aarch64__) && !defined (ARMA53_32) +#define ARMA9 +#endif + +#define XSCUGIC500_DCTLR_ARE_NS_ENABLE 0x20 +#define XSCUGIC500_DCTLR_ARE_S_ENABLE 0x10 +/**************************** Type Definitions *******************************/ + +/* The following data type defines each entry in an interrupt vector table. + * The callback reference is the base address of the interrupting device + * for the low level driver and an instance pointer for the high level driver. + */ +typedef struct +{ + Xil_InterruptHandler Handler; + void *CallBackRef; +} XScuGic_VectorTableEntry; + +/** + * This typedef contains configuration information for the device. + */ +typedef struct +{ + u16 DeviceId; /**< Unique ID of device */ + u32 CpuBaseAddress; /**< CPU Interface Register base address */ + u32 DistBaseAddress; /**< Distributor Register base address */ + XScuGic_VectorTableEntry HandlerTable[XSCUGIC_MAX_NUM_INTR_INPUTS];/**< + Vector table of interrupt handlers */ +} XScuGic_Config; + +/** + * The XScuGic driver instance data. The user is required to allocate a + * variable of this type for every intc device in the system. A pointer + * to a variable of this type is then passed to the driver API functions. + */ +typedef struct +{ + XScuGic_Config *Config; /**< Configuration table entry */ + u32 IsReady; /**< Device is initialized and ready */ + u32 UnhandledInterrupts; /**< Intc Statistics */ +} XScuGic; + +/***************** Macros (Inline Functions) Definitions *********************/ + +/****************************************************************************/ +/** +* +* Write the given CPU Interface register +* +* @param InstancePtr is a pointer to the instance to be worked on. +* @param RegOffset is the register offset to be written +* @param Data is the 32-bit value to write to the register +* +* @return None. +* +* @note +* C-style signature: +* void XScuGic_CPUWriteReg(XScuGic *InstancePtr, u32 RegOffset, u32 Data) +* +*****************************************************************************/ +#define XScuGic_CPUWriteReg(InstancePtr, RegOffset, Data) \ +(XScuGic_WriteReg(((InstancePtr)->Config->CpuBaseAddress), (RegOffset), \ + ((u32)(Data)))) + +/****************************************************************************/ +/** +* +* Read the given CPU Interface register +* +* @param InstancePtr is a pointer to the instance to be worked on. +* @param RegOffset is the register offset to be read +* +* @return The 32-bit value of the register +* +* @note +* C-style signature: +* u32 XScuGic_CPUReadReg(XScuGic *InstancePtr, u32 RegOffset) +* +*****************************************************************************/ +#define XScuGic_CPUReadReg(InstancePtr, RegOffset) \ + (XScuGic_ReadReg(((InstancePtr)->Config->CpuBaseAddress), (RegOffset))) + +/****************************************************************************/ +/** +* +* Write the given Distributor Interface register +* +* @param InstancePtr is a pointer to the instance to be worked on. +* @param RegOffset is the register offset to be written +* @param Data is the 32-bit value to write to the register +* +* @return None. +* +* @note +* C-style signature: +* void XScuGic_DistWriteReg(XScuGic *InstancePtr, u32 RegOffset, u32 Data) +* +*****************************************************************************/ +#define XScuGic_DistWriteReg(InstancePtr, RegOffset, Data) \ +(XScuGic_WriteReg(((InstancePtr)->Config->DistBaseAddress), (RegOffset), \ + ((u32)(Data)))) + +/****************************************************************************/ +/** +* +* Read the given Distributor Interface register +* +* @param InstancePtr is a pointer to the instance to be worked on. +* @param RegOffset is the register offset to be read +* +* @return The 32-bit value of the register +* +* @note +* C-style signature: +* u32 XScuGic_DistReadReg(XScuGic *InstancePtr, u32 RegOffset) +* +*****************************************************************************/ +#define XScuGic_DistReadReg(InstancePtr, RegOffset) \ +(XScuGic_ReadReg(((InstancePtr)->Config->DistBaseAddress), (RegOffset))) + +/****************************************************************************/ +/** +* +* Write the given ReDistributor Interface register +* +* @param InstancePtr is a pointer to the instance to be worked on. +* @param RegOffset is the register offset to be written +* @param Data is the 32-bit value to write to the register +* +* @return None. +* +* @note +* C-style signature: +* void XScuGic_DistWriteReg(XScuGic *InstancePtr, u32 RegOffset, u32 Data) +* +*****************************************************************************/ +#define XScuGic_ReDistWriteReg(InstancePtr, RegOffset, Data) \ +(XScuGic_WriteReg(((InstancePtr)->Config->DistBaseAddress)+ \ + XSCUGIC_RDIST_OFFSET, (RegOffset), ((u32)(Data)))) + +/****************************************************************************/ +/** +* +* Read the given ReDistributor Interface register +* +* @param InstancePtr is a pointer to the instance to be worked on. +* @param RegOffset is the register offset to be read +* +* @return The 32-bit value of the register +* +* @note +* C-style signature: +* u32 XScuGic_DistReadReg(XScuGic *InstancePtr, u32 RegOffset) +* +*****************************************************************************/ +#define XScuGic_ReDistReadReg(InstancePtr, RegOffset) \ +(XScuGic_ReadReg((((InstancePtr)->Config->DistBaseAddress)+ \ +XSCUGIC_RDIST_OFFSET), (RegOffset))) + +/****************************************************************************/ +/** +* +* Write the given ReDistributor SGI PPI Interface register +* +* @param InstancePtr is a pointer to the instance to be worked on. +* @param RegOffset is the register offset to be written +* @param Data is the 32-bit value to write to the register +* +* @return None. +* +* @note +* C-style signature: +* void XScuGic_DistWriteReg(XScuGic *InstancePtr, u32 RegOffset, u32 Data) +* +*****************************************************************************/ +#define XScuGic_ReDistSGIPPIWriteReg(InstancePtr, RegOffset, Data) \ +(XScuGic_WriteReg(((InstancePtr)->Config->DistBaseAddress)+ \ + XSCUGIC_RDIST_SGI_PPI_OFFSET, (RegOffset), ((u32)(Data)))) + +/****************************************************************************/ +/** +* +* Read the given ReDistributor SGI PPI Interface register +* +* @param InstancePtr is a pointer to the instance to be worked on. +* @param RegOffset is the register offset to be read +* +* @return The 32-bit value of the register +* +* @note +* C-style signature: +* u32 XScuGic_DistReadReg(XScuGic *InstancePtr, u32 RegOffset) +* +*****************************************************************************/ +#define XScuGic_ReDistSGIPPIReadReg(InstancePtr, RegOffset) \ +(XScuGic_ReadReg((((InstancePtr)->Config->DistBaseAddress)+ \ + XSCUGIC_RDIST_SGI_PPI_OFFSET), (RegOffset))) + +/****************************************************************************/ +/** +* This function enables system register interface for GIC CPU Interface +* +* @param value to be written +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +#define XScuGic_Enable_SystemReg_CPU_Interface_EL3() mtcp(S3_6_C12_C12_5, 0xF); +#define XScuGic_Enable_SystemReg_CPU_Interface_EL1() mtcp(S3_0_C12_C12_5, 0xF); +/****************************************************************************/ +/** +* This function enables Grou0 interrupts +* +* @param None. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +#define XScuGic_Enable_Group0_Interrupts() mtcp(S3_0_C12_C12_6,0x1); +/****************************************************************************/ +/** +* This function enables Group1 interrupts +* +* @param None. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +#if defined (__aarch64__) +#if EL1_NONSECURE +#define XScuGic_Enable_Group1_Interrupts() \ + mtcp (S3_0_C12_C12_7, 0x1 | mfcp(S3_0_C12_C12_7) ); +#else +#define XScuGic_Enable_Group1_Interrupts() \ + mtcp (S3_6_C12_C12_7, 0x1 | mfcp(S3_6_C12_C12_7) ); +#endif +#endif +/****************************************************************************/ +/** +* This function writes to ICC_SGI0R_EL1 +* +* @param value to be written +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +#define XScuGic_WriteICC_SGI0R_EL1(val) mtcp(S3_0_C12_C11_7,val) + +/****************************************************************************/ +/** +* This function writes to ICC_SGI1R_EL1 +* +* @param value to be written +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +#define XScuGic_WriteICC_SGI1R_EL1(val) mtcp(S3_0_C12_C11_5,val) + +/****************************************************************************/ +/** +* This function reads ICC_SGI1R_EL1 register +* +* @param None +* +* @return Value of ICC_SGI1R_EL1 register +* +* @note None. +* +*****************************************************************************/ +#define XScuGic_ReadICC_SGI1R_EL1() mfcp(S3_0_C12_C11_5) +/****************************************************************************/ +/** +* This function sets interrupt priority filter +* +* @param None. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +#define XScuGic_set_priority_filter(val) __asm__ __volatile__("msr S3_0_C4_C6_0,%0" : : "r" (val)) +/****************************************************************************/ +/** +* This function returns interrupt id of highest priority pending interrupt +* +* @param None. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +#if defined (__aarch64__) +#if EL3 +#define XScuGic_get_IntID() mfcp(S3_0_C12_C8_0) +#else +#define XScuGic_get_IntID() mfcp(S3_0_C12_C12_0) +#endif +#endif +/****************************************************************************/ +/** +* This function acks the interrupt +* +* @param None. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +#if defined (__aarch64__) +#if EL3 +#define XScuGic_ack_Int(val) mtcp(S3_0_C12_C8_1,val) +#else +#define XScuGic_ack_Int(val) mtcp(S3_0_C12_C12_1,val) +#endif +#endif +/****************************************************************************/ +/** +* This macro returns bit position for the specific interrupt's trigger type +* configuration within GICR_ICFGR0/GICR_ICFGR1 register +* +* @param None. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +#define XScuGic_Get_Rdist_Int_Trigger_Index(IntrId) (((Int_Id%16) & 0x1f) << 2) +1 +/************************** Function Prototypes ******************************/ + +/* + * Required functions in xscugic.c + */ + +s32 XScuGic_Connect(XScuGic *InstancePtr, u32 Int_Id, + Xil_InterruptHandler Handler, void *CallBackRef); +void XScuGic_Disconnect(XScuGic *InstancePtr, u32 Int_Id); + +void XScuGic_Enable(XScuGic *InstancePtr, u32 Int_Id); +void XScuGic_Disable(XScuGic *InstancePtr, u32 Int_Id); + +s32 XScuGic_CfgInitialize(XScuGic *InstancePtr, XScuGic_Config *ConfigPtr, + u32 EffectiveAddr); + +s32 XScuGic_SoftwareIntr(XScuGic *InstancePtr, u32 Int_Id, u32 Cpu_Id); + +void XScuGic_GetPriorityTriggerType(XScuGic *InstancePtr, u32 Int_Id, + u8 *Priority, u8 *Trigger); +void XScuGic_SetPriorityTriggerType(XScuGic *InstancePtr, u32 Int_Id, + u8 Priority, u8 Trigger); +void XScuGic_InterruptMaptoCpu(XScuGic *InstancePtr, u8 Cpu_Id, u32 Int_Id); +void XScuGic_InterruptUnmapFromCpu(XScuGic *InstancePtr, u8 Cpu_Id, u32 Int_Id); +void XScuGic_UnmapAllInterruptsFromCpu(XScuGic *InstancePtr, u8 Cpu_Id); +void XScuGic_Stop(XScuGic *InstancePtr); +void XScuGic_SetCpuID(u32 CpuCoreId); +u32 XScuGic_GetCpuID(void); +/* + * Initialization functions in xscugic_sinit.c + */ +XScuGic_Config *XScuGic_LookupConfig(u16 DeviceId); + +/* + * Interrupt functions in xscugic_intr.c + */ +void XScuGic_InterruptHandler(XScuGic *InstancePtr); + +/* + * Self-test functions in xscugic_selftest.c + */ +s32 XScuGic_SelfTest(XScuGic *InstancePtr); + +void XScuGic_EnableSGI_PPI(XScuGic *InstancePtr,u32 ID); +void XScuGic_SetPPI_SGI_Priority(XScuGic *InstancePtr,u32 ID, u32 priority); +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xscugic_hw.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xscugic_hw.h new file mode 100644 index 0000000..60d111f --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xscugic_hw.h @@ -0,0 +1,753 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xscugic_hw.h +* @addtogroup scugic_v4_0 +* @{ +* +* This header file contains identifiers and HW access functions (or +* macros) that can be used to access the device. The user should refer to the +* hardware device specification for more details of the device operation. +* The driver functions/APIs are defined in xscugic.h. +* +* This GIC device has two parts, a distributor and CPU interface(s). Each part +* has separate register definition sections. +* +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------------
+* 1.00a drg  01/19/10 First release
+* 1.01a sdm  11/09/11 "xil_exception.h" added as include.
+*		      Macros XScuGic_EnableIntr and XScuGic_DisableIntr are
+*		      added to enable or disable interrupts based on
+*		      Distributor Register base address. Normally users use
+*		      XScuGic instance and call XScuGic_Enable or
+*		      XScuGic_Disable to enable/disable interrupts. These
+*		      new macros are provided when user does not want to
+*		      use an instance pointer but still wants to enable or
+*		      disable interrupts.
+*		      Function prototypes for functions (present in newly
+*		      added file xscugic_hw.c) are added.
+* 1.03a srt  02/27/13 Moved Offset calculation macros from *_hw.c (CR
+*		      702687).
+* 1.04a hk   05/04/13 Fix for CR#705621. Moved function prototypes
+*		      XScuGic_SetPriTrigTypeByDistAddr and
+*         	      XScuGic_GetPriTrigTypeByDistAddr here from xscugic.h
+* 3.0	pkp  12/09/14 changed XSCUGIC_MAX_NUM_INTR_INPUTS for
+*		      Zynq Ultrascale Mp
+* 3.0   kvn  02/13/14 Modified code for MISRA-C:2012 compliance.
+* 3.2	pkp  11/09/15 Corrected the interrupt processsor target mask value
+*					  for CPU interface 2 i.e. XSCUGIC_SPI_CPU2_MASK
+* 3.9   mus  02/21/18 Added new API's XScuGic_InterruptUnmapFromCpuByDistAddr
+*					  and XScuGic_UnmapAllInterruptsFromCpuByDistAddr, These
+*					  API's can be used by applications to unmap specific/all
+*					  interrupts from target CPU. It fixes CR#992490.
+* 3.10  aru  08/23/18 Resolved MISRA-C:2012 compliance mandatory violations
+*
+* 
+* +******************************************************************************/ + +#ifndef XSCUGIC_HW_H /* prevent circular inclusions */ +#define XSCUGIC_HW_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +#include "xil_types.h" +#include "xil_assert.h" +#include "xil_io.h" +#include "xil_exception.h" +#include "bspconfig.h" + +/************************** Constant Definitions *****************************/ + +/* + * The maximum number of interrupts supported by the hardware. + */ +#ifdef PLATFORM_ZYNQ +#define XSCUGIC_MAX_NUM_INTR_INPUTS 95U /* Maximum number of interrupt defined by Zynq */ +#elif defined (versal) && !defined(ARMR5) +#define XSCUGIC_MAX_NUM_INTR_INPUTS 191U +#else +#define XSCUGIC_MAX_NUM_INTR_INPUTS 195U /* Maximum number of interrupt defined by Zynq Ultrascale Mp */ +#endif + +/* + * First Interrupt Id for SPI interrupts. + */ +#define XSCUGIC_SPI_INT_ID_START 0x20 +/* + * The maximum priority value that can be used in the GIC. + */ +#define XSCUGIC_MAX_INTR_PRIO_VAL 248U +#define XSCUGIC_INTR_PRIO_MASK 0x000000F8U + +/** @name Distributor Interface Register Map + * + * Define the offsets from the base address for all Distributor registers of + * the interrupt controller, some registers may be reserved in the hardware + * device. + * @{ + */ +#define XSCUGIC_DIST_EN_OFFSET 0x00000000U /**< Distributor Enable + Register */ +#define XSCUGIC_IC_TYPE_OFFSET 0x00000004U /**< Interrupt Controller + Type Register */ +#define XSCUGIC_DIST_IDENT_OFFSET 0x00000008U /**< Implementor ID + Register */ +#define XSCUGIC_SECURITY_OFFSET 0x00000080U /**< Interrupt Security + Register */ +#define XSCUGIC_ENABLE_SET_OFFSET 0x00000100U /**< Enable Set + Register */ +#define XSCUGIC_DISABLE_OFFSET 0x00000180U /**< Enable Clear Register */ +#define XSCUGIC_PENDING_SET_OFFSET 0x00000200U /**< Pending Set + Register */ +#define XSCUGIC_PENDING_CLR_OFFSET 0x00000280U /**< Pending Clear + Register */ +#define XSCUGIC_ACTIVE_OFFSET 0x00000300U /**< Active Status Register */ +#define XSCUGIC_PRIORITY_OFFSET 0x00000400U /**< Priority Level Register */ +#define XSCUGIC_SPI_TARGET_OFFSET 0x00000800U /**< SPI Target + Register 0x800-0x8FB */ +#define XSCUGIC_INT_CFG_OFFSET 0x00000C00U /**< Interrupt Configuration + Register 0xC00-0xCFC */ +#define XSCUGIC_PPI_STAT_OFFSET 0x00000D00U /**< PPI Status Register */ +#define XSCUGIC_SPI_STAT_OFFSET 0x00000D04U /**< SPI Status Register + 0xd04-0xd7C */ +#define XSCUGIC_AHB_CONFIG_OFFSET 0x00000D80U /**< AHB Configuration + Register */ +#define XSCUGIC_SFI_TRIG_OFFSET 0x00000F00U /**< Software Triggered + Interrupt Register */ +#define XSCUGIC_PERPHID_OFFSET 0x00000FD0U /**< Peripheral ID Reg */ +#if defined (versal) && !defined(ARMR5) +#define XSCUGIC_PCELLID_OFFSET 0x0000FFF0U /**< Pcell ID Register */ +#else +#define XSCUGIC_PCELLID_OFFSET 0x00000FF0U /**< Pcell ID Register */ +#endif +/* @} */ + +/** @name Distributor Enable Register + * Controls if the distributor response to external interrupt inputs. + * @{ + */ +#if defined (versal) && !defined(ARMR5) +#define XSCUGIC_EN_INT_MASK 0x00000003U /**< Interrupt In Enable */ +#else +#define XSCUGIC_EN_INT_MASK 0x00000001U /**< Interrupt In Enable */ +#endif +/* @} */ + +/** @name Interrupt Controller Type Register + * @{ + */ +#define XSCUGIC_LSPI_MASK 0x0000F800U /**< Number of Lockable + Shared Peripheral + Interrupts*/ +#define XSCUGIC_DOMAIN_MASK 0x00000400U /**< Number os Security domains*/ +#define XSCUGIC_CPU_NUM_MASK 0x000000E0U /**< Number of CPU Interfaces */ +#define XSCUGIC_NUM_INT_MASK 0x0000001FU /**< Number of Interrupt IDs */ +/* @} */ + +/** @name Implementor ID Register + * Implementor and revision information. + * @{ + */ +#define XSCUGIC_REV_MASK 0x00FFF000U /**< Revision Number */ +#define XSCUGIC_IMPL_MASK 0x00000FFFU /**< Implementor */ +/* @} */ + +/** @name Interrupt Security Registers + * Each bit controls the security level of an interrupt, either secure or non + * secure. These registers can only be accessed using secure read and write. + * There are registers for each of the CPU interfaces at offset 0x080. A + * register set for the SPI interrupts is available to all CPU interfaces. + * There are up to 32 of these registers staring at location 0x084. + * @{ + */ +#define XSCUGIC_INT_NS_MASK 0x00000001U /**< Each bit corresponds to an + INT_ID */ +/* @} */ + +/** @name Enable Set Register + * Each bit controls the enabling of an interrupt, a 0 is disabled, a 1 is + * enabled. Writing a 0 has no effect. Use the ENABLE_CLR register to set a + * bit to 0. + * There are registers for each of the CPU interfaces at offset 0x100. With up + * to 8 registers aliased to the same address. A register set for the SPI + * interrupts is available to all CPU interfaces. + * There are up to 32 of these registers staring at location 0x104. + * @{ + */ +#define XSCUGIC_INT_EN_MASK 0x00000001U /**< Each bit corresponds to an + INT_ID */ +/* @} */ + +/** @name Enable Clear Register + * Each bit controls the disabling of an interrupt, a 0 is disabled, a 1 is + * enabled. Writing a 0 has no effect. Writing a 1 disables an interrupt and + * sets the corresponding bit to 0. + * There are registers for each of the CPU interfaces at offset 0x180. With up + * to 8 registers aliased to the same address. + * A register set for the SPI interrupts is available to all CPU interfaces. + * There are up to 32 of these registers staring at location 0x184. + * @{ + */ +#define XSCUGIC_INT_CLR_MASK 0x00000001U /**< Each bit corresponds to an + INT_ID */ +/* @} */ + +/** @name Pending Set Register + * Each bit controls the Pending or Active and Pending state of an interrupt, a + * 0 is not pending, a 1 is pending. Writing a 0 has no effect. Writing a 1 sets + * an interrupt to the pending state. + * There are registers for each of the CPU interfaces at offset 0x200. With up + * to 8 registers aliased to the same address. + * A register set for the SPI interrupts is available to all CPU interfaces. + * There are up to 32 of these registers staring at location 0x204. + * @{ + */ +#define XSCUGIC_PEND_SET_MASK 0x00000001U /**< Each bit corresponds to an + INT_ID */ +/* @} */ + +/** @name Pending Clear Register + * Each bit can clear the Pending or Active and Pending state of an interrupt, a + * 0 is not pending, a 1 is pending. Writing a 0 has no effect. Writing a 1 + * clears the pending state of an interrupt. + * There are registers for each of the CPU interfaces at offset 0x280. With up + * to 8 registers aliased to the same address. + * A register set for the SPI interrupts is available to all CPU interfaces. + * There are up to 32 of these registers staring at location 0x284. + * @{ + */ +#define XSCUGIC_PEND_CLR_MASK 0x00000001U /**< Each bit corresponds to an + INT_ID */ +/* @} */ + +/** @name Active Status Register + * Each bit provides the Active status of an interrupt, a + * 0 is not Active, a 1 is Active. This is a read only register. + * There are registers for each of the CPU interfaces at offset 0x300. With up + * to 8 registers aliased to each address. + * A register set for the SPI interrupts is available to all CPU interfaces. + * There are up to 32 of these registers staring at location 0x380. + * @{ + */ +#define XSCUGIC_ACTIVE_MASK 0x00000001U /**< Each bit corresponds to an + INT_ID */ +/* @} */ + +/** @name Priority Level Register + * Each byte in a Priority Level Register sets the priority level of an + * interrupt. Reading the register provides the priority level of an interrupt. + * There are registers for each of the CPU interfaces at offset 0x400 through + * 0x41C. With up to 8 registers aliased to each address. + * 0 is highest priority, 0xFF is lowest. + * A register set for the SPI interrupts is available to all CPU interfaces. + * There are up to 255 of these registers staring at location 0x420. + * @{ + */ +#define XSCUGIC_PRIORITY_MASK 0x000000FFU /**< Each Byte corresponds to an + INT_ID */ +#define XSCUGIC_PRIORITY_MAX 0x000000FFU /**< Highest value of a priority + actually the lowest priority*/ +/* @} */ + +/** @name SPI Target Register 0x800-0x8FB + * Each byte references a separate SPI and programs which of the up to 8 CPU + * interfaces are sent a Pending interrupt. + * There are registers for each of the CPU interfaces at offset 0x800 through + * 0x81C. With up to 8 registers aliased to each address. + * A register set for the SPI interrupts is available to all CPU interfaces. + * There are up to 255 of these registers staring at location 0x820. + * + * This driver does not support multiple CPU interfaces. These are included + * for complete documentation. + * @{ + */ +#define XSCUGIC_SPI_CPU7_MASK 0x00000080U /**< CPU 7 Mask*/ +#define XSCUGIC_SPI_CPU6_MASK 0x00000040U /**< CPU 6 Mask*/ +#define XSCUGIC_SPI_CPU5_MASK 0x00000020U /**< CPU 5 Mask*/ +#define XSCUGIC_SPI_CPU4_MASK 0x00000010U /**< CPU 4 Mask*/ +#define XSCUGIC_SPI_CPU3_MASK 0x00000008U /**< CPU 3 Mask*/ +#define XSCUGIC_SPI_CPU2_MASK 0x00000004U /**< CPU 2 Mask*/ +#define XSCUGIC_SPI_CPU1_MASK 0x00000002U /**< CPU 1 Mask*/ +#define XSCUGIC_SPI_CPU0_MASK 0x00000001U /**< CPU 0 Mask*/ +/* @} */ + +/** @name Interrupt Configuration Register 0xC00-0xCFC + * The interrupt configuration registers program an SFI to be active HIGH level + * sensitive or rising edge sensitive. + * Each bit pair describes the configuration for an INT_ID. + * SFI Read Only b10 always + * PPI Read Only depending on how the PPIs are configured. + * b01 Active HIGH level sensitive + * b11 Rising edge sensitive + * SPI LSB is read only. + * b01 Active HIGH level sensitive + * b11 Rising edge sensitive/ + * There are registers for each of the CPU interfaces at offset 0xC00 through + * 0xC04. With up to 8 registers aliased to each address. + * A register set for the SPI interrupts is available to all CPU interfaces. + * There are up to 255 of these registers staring at location 0xC08. + * @{ + */ +#define XSCUGIC_INT_CFG_MASK 0x00000003U /**< */ +/* @} */ + +/** @name PPI Status Register + * Enables an external AMBA master to access the status of the PPI inputs. + * A CPU can only read the status of its local PPI signals and cannot read the + * status for other CPUs. + * This register is aliased for each CPU interface. + * @{ + */ +#define XSCUGIC_PPI_C15_MASK 0x00008000U /**< PPI Status */ +#define XSCUGIC_PPI_C14_MASK 0x00004000U /**< PPI Status */ +#define XSCUGIC_PPI_C13_MASK 0x00002000U /**< PPI Status */ +#define XSCUGIC_PPI_C12_MASK 0x00001000U /**< PPI Status */ +#define XSCUGIC_PPI_C11_MASK 0x00000800U /**< PPI Status */ +#define XSCUGIC_PPI_C10_MASK 0x00000400U /**< PPI Status */ +#define XSCUGIC_PPI_C09_MASK 0x00000200U /**< PPI Status */ +#define XSCUGIC_PPI_C08_MASK 0x00000100U /**< PPI Status */ +#define XSCUGIC_PPI_C07_MASK 0x00000080U /**< PPI Status */ +#define XSCUGIC_PPI_C06_MASK 0x00000040U /**< PPI Status */ +#define XSCUGIC_PPI_C05_MASK 0x00000020U /**< PPI Status */ +#define XSCUGIC_PPI_C04_MASK 0x00000010U /**< PPI Status */ +#define XSCUGIC_PPI_C03_MASK 0x00000008U /**< PPI Status */ +#define XSCUGIC_PPI_C02_MASK 0x00000004U /**< PPI Status */ +#define XSCUGIC_PPI_C01_MASK 0x00000002U /**< PPI Status */ +#define XSCUGIC_PPI_C00_MASK 0x00000001U /**< PPI Status */ +/* @} */ + +/** @name SPI Status Register 0xd04-0xd7C + * Enables an external AMBA master to access the status of the SPI inputs. + * There are up to 63 registers if the maximum number of SPI inputs are + * configured. + * @{ + */ +#define XSCUGIC_SPI_N_MASK 0x00000001U /**< Each bit corresponds to an SPI + input */ +/* @} */ + +/** @name AHB Configuration Register + * Provides the status of the CFGBIGEND input signal and allows the endianess + * of the GIC to be set. + * @{ + */ +#define XSCUGIC_AHB_END_MASK 0x00000004U /**< 0-GIC uses little Endian, + 1-GIC uses Big Endian */ +#define XSCUGIC_AHB_ENDOVR_MASK 0x00000002U /**< 0-Uses CFGBIGEND control, + 1-use the AHB_END bit */ +#define XSCUGIC_AHB_TIE_OFF_MASK 0x00000001U /**< State of CFGBIGEND */ + +/* @} */ + +/** @name Software Triggered Interrupt Register + * Controls issueing of software interrupts. + * @{ + */ +#define XSCUGIC_SFI_SELFTRIG_MASK 0x02010000U +#define XSCUGIC_SFI_TRIG_TRGFILT_MASK 0x03000000U /**< Target List filter + b00-Use the target List + b01-All CPUs except requester + b10-To Requester + b11-reserved */ +#define XSCUGIC_SFI_TRIG_CPU_MASK 0x00FF0000U /**< CPU Target list */ +#define XSCUGIC_SFI_TRIG_SATT_MASK 0x00008000U /**< 0= Use a secure interrupt */ +#define XSCUGIC_SFI_TRIG_INTID_MASK 0x0000000FU /**< Set to the INTID + signaled to the CPU*/ +/* @} */ + +/** @name CPU Interface Register Map + * + * Define the offsets from the base address for all CPU registers of the + * interrupt controller, some registers may be reserved in the hardware device. + * @{ + */ +#define XSCUGIC_CONTROL_OFFSET 0x00000000U /**< CPU Interface Control + Register */ +#define XSCUGIC_CPU_PRIOR_OFFSET 0x00000004U /**< Priority Mask Reg */ +#define XSCUGIC_BIN_PT_OFFSET 0x00000008U /**< Binary Point Register */ +#define XSCUGIC_INT_ACK_OFFSET 0x0000000CU /**< Interrupt ACK Reg */ +#define XSCUGIC_EOI_OFFSET 0x00000010U /**< End of Interrupt Reg */ +#define XSCUGIC_RUN_PRIOR_OFFSET 0x00000014U /**< Running Priority Reg */ +#define XSCUGIC_HI_PEND_OFFSET 0x00000018U /**< Highest Pending Interrupt + Register */ +#define XSCUGIC_ALIAS_BIN_PT_OFFSET 0x0000001CU /**< Aliased non-Secure + Binary Point Register */ + +/**< 0x00000020 to 0x00000FBC are reserved and should not be read or written + * to. */ +/* @} */ + + +/** @name Control Register + * CPU Interface Control register definitions + * All bits are defined here although some are not available in the non-secure + * mode. + * @{ + */ +#define XSCUGIC_CNTR_SBPR_MASK 0x00000010U /**< Secure Binary Pointer, + 0=separate registers, + 1=both use bin_pt_s */ +#define XSCUGIC_CNTR_FIQEN_MASK 0x00000008U /**< Use nFIQ_C for secure + interrupts, + 0= use IRQ for both, + 1=Use FIQ for secure, IRQ for non*/ +#define XSCUGIC_CNTR_ACKCTL_MASK 0x00000004U /**< Ack control for secure or non secure */ +#define XSCUGIC_CNTR_EN_NS_MASK 0x00000002U /**< Non Secure enable */ +#define XSCUGIC_CNTR_EN_S_MASK 0x00000001U /**< Secure enable, 0=Disabled, 1=Enabled */ +/* @} */ + +/** @name Priority Mask Register + * Priority Mask register definitions + * The CPU interface does not send interrupt if the level of the interrupt is + * lower than the level of the register. + * @{ + */ +/*#define XSCUGIC_PRIORITY_MASK 0x000000FFU*/ /**< All interrupts */ +/* @} */ + +/** @name Binary Point Register + * Binary Point register definitions + * @{ + */ + +#define XSCUGIC_BIN_PT_MASK 0x00000007U /**< Binary point mask value + Value Secure Non-secure + b000 0xFE 0xFF + b001 0xFC 0xFE + b010 0xF8 0xFC + b011 0xF0 0xF8 + b100 0xE0 0xF0 + b101 0xC0 0xE0 + b110 0x80 0xC0 + b111 0x00 0x80 + */ +/*@}*/ + +/** @name Interrupt Acknowledge Register + * Interrupt Acknowledge register definitions + * Identifies the current Pending interrupt, and the CPU ID for software + * interrupts. + */ +#define XSCUGIC_ACK_INTID_MASK 0x000003FFU /**< Interrupt ID */ +#define XSCUGIC_CPUID_MASK 0x00000C00U /**< CPU ID */ +/* @} */ + +/** @name End of Interrupt Register + * End of Interrupt register definitions + * Allows the CPU to signal the GIC when it completes an interrupt service + * routine. + */ +#define XSCUGIC_EOI_INTID_MASK 0x000003FFU /**< Interrupt ID */ + +/* @} */ + +/** @name Running Priority Register + * Running Priority register definitions + * Identifies the interrupt priority level of the highest priority active + * interrupt. + */ +#define XSCUGIC_RUN_PRIORITY_MASK 0x000000FFU /**< Interrupt Priority */ +/* @} */ + +#if defined (versal) && !defined(ARMR5) +#define XSCUGIC_IROUTER_BASE_OFFSET 0x6000U +#endif +/* + * Highest Pending Interrupt register definitions + * Identifies the interrupt priority of the highest priority pending interupt + */ +#define XSCUGIC_PEND_INTID_MASK 0x000003FFU /**< Pending Interrupt ID */ +/*#define XSCUGIC_CPUID_MASK 0x00000C00U */ /**< CPU ID */ +/* @} */ +#if defined (versal) && !defined(ARMR5) +/** @name ReDistributor Interface Register Map + * + * @{ + */ +#define XSCUGIC_RDIST_OFFSET 0x80000U +#define XSCUGIC_RDIST_BASE_ADDRESS (XPAR_SCUGIC_0_DIST_BASEADDR + XSCUGIC_RDIST_OFFSET) +#define XSCUGIC_RDIST_SGI_PPI_OFFSET 0x90000U +#define XSCUGIC_RDIST_SGI_PPI_BASE_ADDRESS (XPAR_SCUGIC_0_DIST_BASEADDR + XSCUGIC_RDIST_SGI_PPI_OFFSET) +#define XSCUGIC_RDIST_ISENABLE_OFFSET 0x100U +#define XSCUGIC_RDIST_IPRIORITYR_OFFSET 0x400U +#define XSCUGIC_RDIST_IGROUPR_OFFSET 0x80U +#define XSCUGIC_RDIST_GRPMODR_OFFSET 0xD00U +#define XSCUGIC_RDIST_INT_CONFIG_OFFSET 0xC00U +#define XSCUGIC_RDIST_WAKER_OFFSET 0x14U +#define XSCUGIC_SGIR_EL1_INITID_SHIFT 24U + +/* + * GICR_IGROUPR register definitions + */ +#if EL3 +#define XSCUGIC_DEFAULT_SECURITY 0x0U +#else +#define XSCUGIC_DEFAULT_SECURITY 0xFFFFFFFFU +#endif +/* + * GICR_WAKER register definitions + */ +#define XSCUGIC_RDIST_WAKER_LOW_POWER_STATE_MASK 0x7 +#endif +/***************** Macros (Inline Functions) Definitions *********************/ + +/****************************************************************************/ +/** +* +* Read the Interrupt Configuration Register offset for an interrupt id. +* +* @param InterruptID is the interrupt number. +* +* @return The 32-bit value of the offset +* +* @note +* +*****************************************************************************/ +#define XSCUGIC_INT_CFG_OFFSET_CALC(InterruptID) \ + ((u32)XSCUGIC_INT_CFG_OFFSET + (((InterruptID)/16U) * 4U)) + +/****************************************************************************/ +/** +* +* Read the Interrupt Priority Register offset for an interrupt id. +* +* @param InterruptID is the interrupt number. +* +* @return The 32-bit value of the offset +* +* @note +* +*****************************************************************************/ +#define XSCUGIC_PRIORITY_OFFSET_CALC(InterruptID) \ + ((u32)XSCUGIC_PRIORITY_OFFSET + (((InterruptID)/4U) * 4U)) + +/****************************************************************************/ +/** +* +* Read the Interrupt Routing Register offset for an interrupt id. +* +* @param InterruptID is the interrupt number. +* +* @return The 32-bit value of the offset +* +* @note +* +*****************************************************************************/ +#define XSCUGIC_IROUTER_OFFSET_CALC(InterruptID) \ + ((u32)XSCUGIC_IROUTER_BASE_OFFSET + (InterruptID * 8)) + +/****************************************************************************/ +/** +* +* Read the SPI Target Register offset for an interrupt id. +* +* @param InterruptID is the interrupt number. +* +* @return The 32-bit value of the offset +* +* @note +* +*****************************************************************************/ +#define XSCUGIC_SPI_TARGET_OFFSET_CALC(InterruptID) \ + ((u32)XSCUGIC_SPI_TARGET_OFFSET + (((InterruptID)/4U) * 4U)) +/****************************************************************************/ +/** +* +* Read the SPI Target Register offset for an interrupt id. +* +* @param InterruptID is the interrupt number. +* +* @return The 32-bit value of the offset +* +* @note +* +*****************************************************************************/ +#define XSCUGIC_SECURITY_TARGET_OFFSET_CALC(InterruptID) \ + ((u32)XSCUGIC_SECURITY_OFFSET + (((InterruptID)/32U)*4U)) + +/****************************************************************************/ +/** +* +* Read the Re-distributor Interrupt configuration register offset +* +* @param InterruptID is the interrupt number. +* +* @return The 32-bit value of the offset +* +* @note +* +*****************************************************************************/ +#define XSCUGIC_RDIST_INT_CONFIG_OFFSET_CALC(InterruptID) \ + ((u32)XSCUGIC_RDIST_INT_CONFIG_OFFSET + ((InterruptID /16)*4)) + +/****************************************************************************/ +/** +* +* Read the Re-distributor Interrupt Priority register offset +* +* @param InterruptID is the interrupt number. +* +* @return The 32-bit value of the offset +* +* @note +* +*****************************************************************************/ +#define XSCUGIC_RDIST_INT_PRIORITY_OFFSET_CALC(InterruptID) \ + ((u32)XSCUGIC_RDIST_IPRIORITYR_OFFSET + (InterruptID * 4)) +/****************************************************************************/ +/** +* +* Read the Interrupt Clear-Enable Register offset for an interrupt ID +* +* @param Register is the register offset for the clear/enable bank. +* @param InterruptID is the interrupt number. +* +* @return The 32-bit value of the offset +* +* @note +* +*****************************************************************************/ +#define XSCUGIC_EN_DIS_OFFSET_CALC(Register, InterruptID) \ + ((Register) + (((InterruptID)/32U) * 4U)) + +/****************************************************************************/ +/** +* +* Read the given Intc register. +* +* @param BaseAddress is the base address of the device. +* @param RegOffset is the register offset to be read +* +* @return The 32-bit value of the register +* +* @note +* C-style signature: +* u32 XScuGic_ReadReg(u32 BaseAddress, u32 RegOffset) +* +*****************************************************************************/ +#define XScuGic_ReadReg(BaseAddress, RegOffset) \ + (Xil_In32((BaseAddress) + (RegOffset))) + + +/****************************************************************************/ +/** +* +* Write the given Intc register. +* +* @param BaseAddress is the base address of the device. +* @param RegOffset is the register offset to be written +* @param Data is the 32-bit value to write to the register +* +* @return None. +* +* @note +* C-style signature: +* void XScuGic_WriteReg(u32 BaseAddress, u32 RegOffset, u32 Data) +* +*****************************************************************************/ +#define XScuGic_WriteReg(BaseAddress, RegOffset, Data) \ + (Xil_Out32(((BaseAddress) + (RegOffset)), ((u32)(Data)))) + + +/****************************************************************************/ +/** +* +* Enable specific interrupt(s) in the interrupt controller. +* +* @param DistBaseAddress is the Distributor Register base address of the +* device +* @param Int_Id is the ID of the interrupt source and should be in the +* range of 0 to XSCUGIC_MAX_NUM_INTR_INPUTS - 1 +* +* @return None. +* +* @note C-style signature: +* void XScuGic_EnableIntr(u32 DistBaseAddress, u32 Int_Id) +* +*****************************************************************************/ +#define XScuGic_EnableIntr(DistBaseAddress, Int_Id) \ + XScuGic_WriteReg((DistBaseAddress), \ + XSCUGIC_ENABLE_SET_OFFSET + (((Int_Id) / 32U) * 4U), \ + (0x00000001U << ((Int_Id) % 32U))) + +/****************************************************************************/ +/** +* +* Disable specific interrupt(s) in the interrupt controller. +* +* @param DistBaseAddress is the Distributor Register base address of the +* device +* @param Int_Id is the ID of the interrupt source and should be in the +* range of 0 to XSCUGIC_MAX_NUM_INTR_INPUTS - 1 +* +* +* @return None. +* +* @note C-style signature: +* void XScuGic_DisableIntr(u32 DistBaseAddress, u32 Int_Id) +* +*****************************************************************************/ +#define XScuGic_DisableIntr(DistBaseAddress, Int_Id) \ + XScuGic_WriteReg((DistBaseAddress), \ + XSCUGIC_DISABLE_OFFSET + (((Int_Id) / 32U) * 4U), \ + (0x00000001U << ((Int_Id) % 32U))) + + +/************************** Function Prototypes ******************************/ + +void XScuGic_DeviceInterruptHandler(void *DeviceId); +s32 XScuGic_DeviceInitialize(u32 DeviceId); +void XScuGic_RegisterHandler(u32 BaseAddress, s32 InterruptID, + Xil_InterruptHandler Handler, void *CallBackRef); +void XScuGic_SetPriTrigTypeByDistAddr(u32 DistBaseAddress, u32 Int_Id, + u8 Priority, u8 Trigger); +void XScuGic_GetPriTrigTypeByDistAddr(u32 DistBaseAddress, u32 Int_Id, + u8 *Priority, u8 *Trigger); +void XScuGic_InterruptUnmapFromCpuByDistAddr(u32 DistBaseAddress, + u8 Cpu_Id, u32 Int_Id); +void XScuGic_UnmapAllInterruptsFromCpuByDistAddr(u32 DistBaseAddress, + u8 Cpu_Id); +/************************** Variable Definitions *****************************/ +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xscutimer.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xscutimer.h new file mode 100644 index 0000000..5434684 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xscutimer.h @@ -0,0 +1,364 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xscutimer.h +* @addtogroup scutimer_v2_1 +* @{ +* @details +* +* The timer driver supports the Cortex A9 private timer. +* +* The timer driver supports the following features: +* - Normal mode and Auto reload mode +* - Interrupts (Interrupt handler is not provided in this driver. Application +* has to register it's own handler) +* +* Initialization and Configuration +* +* The device driver enables higher layer software (e.g., an application) to +* communicate with the Timer. +* +* XScuTimer_CfgInitialize() API is used to initialize the Timer. The +* user needs to first call the XScuTimer_LookupConfig() API which returns +* the Configuration structure pointer which is passed as a parameter to +* the XScuTimer_CfgInitialize() API. +* +* Interrupts +* +* The Timer hardware supports interrupts. +* +* This driver does not provide a Interrupt Service Routine (ISR) for the device. +* It is the responsibility of the application to provide one if needed. Refer to +* the interrupt example provided with this driver for details on using the +* Timer in interrupt mode. +* +* Virtual Memory +* +* This driver supports Virtual Memory. The RTOS is responsible for calculating +* the correct device base address in Virtual Memory space. +* +* Threads +* +* This driver is not thread safe. Any needs for threads or thread mutual +* exclusion must be satisfied by the layer above this driver. +* +* Asserts +* +* Asserts are used within all Xilinx drivers to enforce constraints on argument +* values. Asserts can be turned off on a system-wide basis by defining, at +* compile time, the NDEBUG identifier. By default, asserts are turned on and it +* is recommended that users leave asserts on during development. +* +* Building the driver +* +* The XScuTimer driver is composed of several source files. This allows the user +* to build and link only those parts of the driver that are necessary. +* +*

+* +* NOTE: +* The timer is not a part of the snoop control unit as indicated by the +* prefix "scu" in the name of the driver. +* It is an independent module in APU. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who Date     Changes
+* ----- --- -------- ---------------------------------------------
+* 1.00a nm  03/10/10 First release
+* 1.02a sg  07/17/12 Included xil_assert.h for CR 667947. This is an issue
+*		     when the xstatus.h in the common driver overwrites
+*		     the xstatus.h of the standalone BSP during the
+*		     libgen.
+* 2.1 	sk  02/26/15 Modified the code for MISRA-C:2012 compliance.
+*       ms  03/17/17 Added readme.txt file in examples folder for doxygen
+*                    generation.
+* 
+* +******************************************************************************/ +#ifndef XSCUTIMER_H /* prevent circular inclusions */ +#define XSCUTIMER_H /* by using protection macros */ + +/***************************** Include Files *********************************/ + +#include "xstatus.h" +#include "xscutimer_hw.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/** + * This typedef contains configuration information for the device. + */ +typedef struct { + u16 DeviceId; /**< Unique ID of device */ + u32 BaseAddr; /**< Base address of the device */ +} XScuTimer_Config; + +/** + * The XScuTimer driver instance data. The user is required to allocate a + * variable of this type for every timer device in the system. + * A pointer to a variable of this type is then passed to the driver API + * functions. + */ +typedef struct { + XScuTimer_Config Config; /**< Hardware Configuration */ + u32 IsReady; /**< Device is initialized and ready */ + u32 IsStarted; /**< Device timer is running */ +} XScuTimer; + +/***************** Macros (Inline Functions) Definitions *********************/ + +/****************************************************************************/ +/** +* +* Check if the timer has expired. +* +* @param InstancePtr is a pointer to the XScuTimer instance. +* +* @return +* - TRUE if the timer has expired. +* - FALSE if the timer has not expired. +* +* @note C-style signature: +* int XScuTimer_IsExpired(XScuTimer *InstancePtr) +* +******************************************************************************/ +#define XScuTimer_IsExpired(InstancePtr) \ + ((XScuTimer_ReadReg((InstancePtr)->Config.BaseAddr, \ + XSCUTIMER_ISR_OFFSET) & \ + XSCUTIMER_ISR_EVENT_FLAG_MASK) == \ + XSCUTIMER_ISR_EVENT_FLAG_MASK) + +/****************************************************************************/ +/** +* +* Re-start the timer. This macro will read the timer load register +* and writes the same value to load register to update the counter register. +* +* @param InstancePtr is a pointer to the XScuTimer instance. +* +* @return None. +* +* @note C-style signature: +* void XScuTimer_RestartTimer(XScuTimer *InstancePtr) +* +******************************************************************************/ +#define XScuTimer_RestartTimer(InstancePtr) \ + XScuTimer_LoadTimer((InstancePtr), \ + XScuTimer_ReadReg((InstancePtr)->Config.BaseAddr, \ + XSCUTIMER_LOAD_OFFSET)) + +/****************************************************************************/ +/** +* +* Write to the timer load register. This will also update the +* timer counter register with the new value. This macro can be used to +* change the time-out value. +* +* @param InstancePtr is a pointer to the XScuTimer instance. +* @param Value is the count to be loaded in to the load register. +* +* @return None. +* +* @note C-style signature: +* void XScuTimer_LoadTimer(XScuTimer *InstancePtr, u32 Value) +* +******************************************************************************/ +#define XScuTimer_LoadTimer(InstancePtr, Value) \ + XScuTimer_WriteReg((InstancePtr)->Config.BaseAddr, \ + XSCUTIMER_LOAD_OFFSET, (Value)) + +/****************************************************************************/ +/** +* +* Returns the current timer counter register value. It can be called at any +* time. +* +* @param InstancePtr is a pointer to the XScuTimer instance. +* +* @return Contents of the timer counter register. +* +* @note C-style signature: + u32 XScuTimer_GetCounterValue(XScuTimer *InstancePtr) +* +******************************************************************************/ +#define XScuTimer_GetCounterValue(InstancePtr) \ + XScuTimer_ReadReg((InstancePtr)->Config.BaseAddr, \ + XSCUTIMER_COUNTER_OFFSET) + +/****************************************************************************/ +/** +* +* Enable auto-reload mode. +* +* @param InstancePtr is a pointer to the XScuTimer instance. +* +* @return None. +* +* @note C-style signature: +* void XScuTimer_EnableAutoReload(XScuTimer *InstancePtr) +* +******************************************************************************/ +#define XScuTimer_EnableAutoReload(InstancePtr) \ + XScuTimer_WriteReg((InstancePtr)->Config.BaseAddr, \ + XSCUTIMER_CONTROL_OFFSET, \ + (XScuTimer_ReadReg((InstancePtr)->Config.BaseAddr, \ + XSCUTIMER_CONTROL_OFFSET) | \ + XSCUTIMER_CONTROL_AUTO_RELOAD_MASK)) + +/****************************************************************************/ +/** +* +* Disable auto-reload mode. +* +* @param InstancePtr is a pointer to the XScuTimer instance. +* +* @return None. +* +* @note C-style signature: +* void XScuTimer_DisableAutoReload(XScuTimer *InstancePtr) +* +******************************************************************************/ +#define XScuTimer_DisableAutoReload(InstancePtr) \ + XScuTimer_WriteReg((InstancePtr)->Config.BaseAddr, \ + XSCUTIMER_CONTROL_OFFSET, \ + (XScuTimer_ReadReg((InstancePtr)->Config.BaseAddr, \ + XSCUTIMER_CONTROL_OFFSET) & \ + ~(XSCUTIMER_CONTROL_AUTO_RELOAD_MASK))) + +/****************************************************************************/ +/** +* +* Enable the Timer interrupt. +* +* @param InstancePtr is a pointer to the XScuTimer instance. +* +* @return None. +* +* @note C-style signature: +* void XScuTimer_EnableInterrupt(XScuTimer *InstancePtr) +* +******************************************************************************/ +#define XScuTimer_EnableInterrupt(InstancePtr) \ + XScuTimer_WriteReg((InstancePtr)->Config.BaseAddr, \ + XSCUTIMER_CONTROL_OFFSET, \ + (XScuTimer_ReadReg((InstancePtr)->Config.BaseAddr, \ + XSCUTIMER_CONTROL_OFFSET) | \ + XSCUTIMER_CONTROL_IRQ_ENABLE_MASK)) + +/****************************************************************************/ +/** +* +* Disable the Timer interrupt. +* +* @param InstancePtr is a pointer to the XScuTimer instance. +* +* @return None. +* +* @note C-style signature: +* void XScuTimer_DisableInterrupt(XScuTimer *InstancePtr) +* +******************************************************************************/ +#define XScuTimer_DisableInterrupt(InstancePtr) \ + XScuTimer_WriteReg((InstancePtr)->Config.BaseAddr, \ + XSCUTIMER_CONTROL_OFFSET, \ + (XScuTimer_ReadReg((InstancePtr)->Config.BaseAddr, \ + XSCUTIMER_CONTROL_OFFSET) & \ + ~(XSCUTIMER_CONTROL_IRQ_ENABLE_MASK))) + +/*****************************************************************************/ +/** +* +* This function reads the interrupt status. +* +* @param InstancePtr is a pointer to the XScuTimer instance. +* +* @return None. +* +* @note C-style signature: +* void XScuTimer_GetInterruptStatus(XScuTimer *InstancePtr) +* +******************************************************************************/ +#define XScuTimer_GetInterruptStatus(InstancePtr) \ + XScuTimer_ReadReg((InstancePtr)->Config.BaseAddr, \ + XSCUTIMER_ISR_OFFSET) + +/*****************************************************************************/ +/** +* +* This function clears the interrupt status. +* +* @param InstancePtr is a pointer to the XScuTimer instance. +* +* @return None. +* +* @note C-style signature: +* void XScuTimer_ClearInterruptStatus(XScuTimer *InstancePtr) +* +******************************************************************************/ +#define XScuTimer_ClearInterruptStatus(InstancePtr) \ + XScuTimer_WriteReg((InstancePtr)->Config.BaseAddr, \ + XSCUTIMER_ISR_OFFSET, XSCUTIMER_ISR_EVENT_FLAG_MASK) + +/************************** Function Prototypes ******************************/ + +/* + * Lookup configuration in xscutimer_sinit.c + */ +XScuTimer_Config *XScuTimer_LookupConfig(u16 DeviceId); + +/* + * Selftest function in xscutimer_selftest.c + */ +s32 XScuTimer_SelfTest(XScuTimer *InstancePtr); + +/* + * Interface functions in xscutimer.c + */ +s32 XScuTimer_CfgInitialize(XScuTimer *InstancePtr, + XScuTimer_Config *ConfigPtr, u32 EffectiveAddress); +void XScuTimer_Start(XScuTimer *InstancePtr); +void XScuTimer_Stop(XScuTimer *InstancePtr); +void XScuTimer_SetPrescaler(XScuTimer *InstancePtr, u8 PrescalerValue); +u8 XScuTimer_GetPrescaler(XScuTimer *InstancePtr); + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xscutimer_hw.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xscutimer_hw.h new file mode 100644 index 0000000..d577784 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xscutimer_hw.h @@ -0,0 +1,283 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xscutimer_hw.h +* @addtogroup scutimer_v2_1 +* @{ +* +* This file contains the hardware interface to the Timer. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who Date     Changes
+* ----- --- -------- ---------------------------------------------
+* 1.00a nm  03/10/10 First release
+* 1.01a sdm 02/02/12 Added low level macros to read/write load, counter, control
+*		     and interrupt registers
+* 1.02a  sg 07/17/12 Included xil_assert.h for CR 667947. This is an issue
+*		     when the xstatus.h in the common driver overwrites
+*		     the xstatus.h of the standalone BSP during the
+*		     libgen.
+* 2.1 	sk  02/26/15 Modified the code for MISRA-C:2012 compliance.
+* 
+* +******************************************************************************/ +#ifndef XSCUTIMER_HW_H /* prevent circular inclusions */ +#define XSCUTIMER_HW_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ +#include "xil_types.h" +#include "xil_io.h" +#include "xil_assert.h" +/************************** Constant Definitions *****************************/ + +/** @name Register Map + * Offsets of registers from the start of the device + * @{ + */ + +#define XSCUTIMER_LOAD_OFFSET 0x00U /**< Timer Load Register */ +#define XSCUTIMER_COUNTER_OFFSET 0x04U /**< Timer Counter Register */ +#define XSCUTIMER_CONTROL_OFFSET 0x08U /**< Timer Control Register */ +#define XSCUTIMER_ISR_OFFSET 0x0CU /**< Timer Interrupt + Status Register */ +/* @} */ + +/** @name Timer Control register + * This register bits control the prescaler, Intr enable, + * auto-reload and timer enable. + * @{ + */ + +#define XSCUTIMER_CONTROL_PRESCALER_MASK 0x0000FF00U /**< Prescaler */ +#define XSCUTIMER_CONTROL_PRESCALER_SHIFT 8U +#define XSCUTIMER_CONTROL_IRQ_ENABLE_MASK 0x00000004U /**< Intr enable */ +#define XSCUTIMER_CONTROL_AUTO_RELOAD_MASK 0x00000002U /**< Auto-reload */ +#define XSCUTIMER_CONTROL_ENABLE_MASK 0x00000001U /**< Timer enable */ +/* @} */ + +/** @name Interrupt Status register + * This register indicates the Timer counter register has reached zero. + * @{ + */ + +#define XSCUTIMER_ISR_EVENT_FLAG_MASK 0x00000001U /**< Event flag */ +/*@}*/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/****************************************************************************/ +/** +* +* Write to the timer load register. This will also update the +* timer counter register with the new value. This macro can be used to +* change the time-out value. +* +* @param BaseAddr is the base address of the scu timer. +* @param Value is the count to be loaded in to the load register. +* +* @return None. +* +* @note C-style signature: +* void XScuTimer_SetLoadReg(u32 BaseAddr, u32 Value) +* +******************************************************************************/ +#define XScuTimer_SetLoadReg(BaseAddr, Value) \ + XScuTimer_WriteReg(BaseAddr, XSCUTIMER_LOAD_OFFSET, (Value)) + +/****************************************************************************/ +/** +* +* Returns the current timer load register value. +* +* @param BaseAddr is the base address of the scu timer. +* +* @return Contents of the timer load register. +* +* @note C-style signature: +* u32 XScuTimer_GetLoadReg(u32 BaseAddr) +* +******************************************************************************/ +#define XScuTimer_GetLoadReg(BaseAddr) \ + XScuTimer_ReadReg(BaseAddr, XSCUTIMER_LOAD_OFFSET) + +/****************************************************************************/ +/** +* +* Write to the timer counter register. +* +* @param BaseAddr is the base address of the scu timer. +* @param Value is the count to be loaded in to the counter register. +* +* @return None. +* +* @note C-style signature: +* void XScuTimer_SetCounterReg(u32 BaseAddr, u32 Value) +* +******************************************************************************/ +#define XScuTimer_SetCounterReg(BaseAddr, Value) \ + XScuTimer_WriteReg(BaseAddr, XSCUTIMER_COUNTER_OFFSET, (Value)) + +/****************************************************************************/ +/** +* +* Returns the current timer counter register value. +* +* @param BaseAddr is the base address of the scu timer. +* +* @return Contents of the timer counter register. +* +* @note C-style signature: + u32 XScuTimer_GetCounterReg(u32 BaseAddr) +* +******************************************************************************/ +#define XScuTimer_GetCounterReg(BaseAddr) \ + XScuTimer_ReadReg(BaseAddr, XSCUTIMER_COUNTER_OFFSET) + +/****************************************************************************/ +/** +* +* Write to the timer load register. This will also update the +* timer counter register with the new value. This macro can be used to +* change the time-out value. +* +* @param BaseAddr is the base address of the scu timer. +* @param Value is the count to be loaded in to the load register. +* +* @return None. +* +* @note C-style signature: +* void XScuTimer_SetControlReg(u32 BaseAddr, u32 Value) +* +******************************************************************************/ +#define XScuTimer_SetControlReg(BaseAddr, Value) \ + XScuTimer_WriteReg(BaseAddr, XSCUTIMER_CONTROL_OFFSET, (Value)) + +/****************************************************************************/ +/** +* +* Returns the current timer load register value. +* +* @param BaseAddr is the base address of the scu timer. +* +* @return Contents of the timer load register. +* +* @note C-style signature: + u32 XScuTimer_GetControlReg(u32 BaseAddr) +* +******************************************************************************/ +#define XScuTimer_GetControlReg(BaseAddr) \ + XScuTimer_ReadReg(BaseAddr, XSCUTIMER_CONTROL_OFFSET) + +/****************************************************************************/ +/** +* +* Write to the timer counter register. +* +* @param BaseAddr is the base address of the scu timer. +* @param Value is the count to be loaded in to the counter register. +* +* @return None. +* +* @note C-style signature: +* void XScuTimer_SetIntrReg(u32 BaseAddr, u32 Value) +* +******************************************************************************/ +#define XScuTimer_SetIntrReg(BaseAddr, Value) \ + XScuTimer_WriteReg(BaseAddr, XSCUTIMER_ISR_OFFSET, (Value)) + +/****************************************************************************/ +/** +* +* Returns the current timer counter register value. +* +* @param BaseAddr is the base address of the scu timer. +* +* @return Contents of the timer counter register. +* +* @note C-style signature: + u32 XScuTimer_GetIntrReg(u32 BaseAddr) +* +******************************************************************************/ +#define XScuTimer_GetIntrReg(BaseAddr) \ + XScuTimer_ReadReg(BaseAddr, XSCUTIMER_ISR_OFFSET) + +/****************************************************************************/ +/** +* +* Read from the given Timer register. +* +* @param BaseAddr is the base address of the device +* @param RegOffset is the register offset to be read +* +* @return The 32-bit value of the register +* +* @note C-style signature: +* u32 XScuTimer_ReadReg(u32 BaseAddr, u32 RegOffset) +* +*****************************************************************************/ +#define XScuTimer_ReadReg(BaseAddr, RegOffset) \ + Xil_In32((BaseAddr) + (RegOffset)) + +/****************************************************************************/ +/** +* +* Write to the given Timer register. +* +* @param BaseAddr is the base address of the device +* @param RegOffset is the register offset to be written +* @param Data is the 32-bit value to write to the register +* +* @return None. +* +* @note C-style signature: +* void XScuTimer_WriteReg(u32 BaseAddr, u32 RegOffset, u32 Data) +* +*****************************************************************************/ +#define XScuTimer_WriteReg(BaseAddr, RegOffset, Data) \ + Xil_Out32((BaseAddr) + (RegOffset), (Data)) + +/************************** Function Prototypes ******************************/ + +/************************** Variable Definitions *****************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xscuwdt.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xscuwdt.h new file mode 100644 index 0000000..551eaf5 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xscuwdt.h @@ -0,0 +1,379 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xscuwdt.h +* @addtogroup scuwdt_v2_1 +* @{ +* @details +* +* The Xilinx SCU watchdog timer driver (XScuWdt) supports the Xilinx SCU private +* watchdog timer hardware. +* +* The XScuWdt driver supports the following features: +* - Watchdog mode +* - Timer mode +* - Auto reload (timer mode only) +* +* The watchdog counter register is a down counter and starts decrementing when +* the watchdog is started. +* In watchdog mode, when the counter reaches 0, the Reset flag is set in the +* Reset status register and the WDRESETREQ pin is asserted, causing a system +* reset. The Reset flag is not reset by normal processor reset and is cleared +* when written with a value of 1. This enables the user to differentiate a +* normal reset and a reset caused by watchdog time-out. The user needs to call +* XScuWdt_RestartWdt() periodically, to avoid the watchdog from being timed-out. +* +* The IsWdtExpired function can be used to check if the watchdog was the cause +* of the last reset. In this situation, call Initialize then call IsWdtExpired. +* If the result is true, watchdog timeout caused the last system reset. The +* application then needs to clear the Reset flag. +* +* In timer mode, when the counter reaches 0, the Event flag is set in the +* Interrupt status register and if interrupts are enabled, interrupt ID 30 is +* set as pending in the interrupt distributor. The IsTimerExpired function +* is used to check if the watchdog counter has decremented to 0 in timer mode. +* If auto-reload mode is enabled, the Counter register is automatically reloaded +* from the Load register. +* +* Initialization and Configuration +* +* The device driver enables higher layer software (e.g., an application) to +* communicate with the Watchdog Timer. +* +* XScuWdt_CfgInitialize() API is used to initialize the Watchdog Timer. The +* user needs to first call the XScuWdt_LookupConfig() API which returns +* the Configuration structure pointer which is passed as a parameter to +* the XScuWdt_CfgInitialize() API. +* +* Interrupts +* +* The SCU Watchdog Timer supports interrupts in Timer mode. +* +* This driver does not provide a Interrupt Service Routine (ISR) for the device. +* It is the responsibility of the application to provide one if needed. Refer to +* the interrupt example provided with this driver for details on using the +* Timer in interrupt mode. +* +* Virtual Memory +* +* This driver supports Virtual Memory. The RTOS is responsible for calculating +* the correct device base address in Virtual Memory space. +* +* Threads +* +* This driver is not thread safe. Any needs for threads or thread mutual +* exclusion must be satisfied by the layer above this driver. +* +* Asserts +* +* Asserts are used within all Xilinx drivers to enforce constraints on argument +* values. Asserts can be turned off on a system-wide basis by defining, at +* compile time, the NDEBUG identifier. By default, asserts are turned on and it +* is recommended that users leave asserts on during development. +* +* Building the driver +* +* The XScuWdt driver is composed of several source files. This allows the user +* to build and link only those parts of the driver that are necessary. +* +*

+* +* NOTE: +* The watchdog timer is not a part of the snoop control unit as indicated +* by the prefix "scu" in the name of the driver. +* It is an independent module in APU. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who Date     Changes
+* ----- --- -------- ---------------------------------------------
+* 1.00a sdm 01/15/10 First release
+* 1.02a  sg 07/17/12 Included xil_assert.h for CR 667947. This is an issue
+*		     when the xstatus.h in the common driver overwrites
+*		     the xstatus.h of the standalone BSP during the
+*		     libgen.
+* 2.1 	sk  02/26/15 Modified the code for MISRA-C:2012 compliance.
+*       ms  03/17/17 Added readme.txt file in examples folder for doxygen
+*                    generation.
+* 
+* +******************************************************************************/ +#ifndef XSCUWDT_H /* prevent circular inclusions */ +#define XSCUWDT_H /* by using protection macros */ + +/***************************** Include Files *********************************/ + +#include "xstatus.h" +#include "xscuwdt_hw.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/** + * This typedef contains configuration information for the device. + */ +typedef struct { + u16 DeviceId; /**< Unique ID of device */ + u32 BaseAddr; /**< Base address of the device */ +} XScuWdt_Config; + +/** + * The XScuWdt driver instance data. The user is required to allocate a + * variable of this type for every watchdog/timer device in the system. + * A pointer to a variable of this type is then passed to the driver API + * functions. + */ +typedef struct { + XScuWdt_Config Config;/**< Hardware Configuration */ + u32 IsReady; /**< Device is initialized and ready */ + u32 IsStarted; /**< Device watchdog timer is running */ +} XScuWdt; + +/***************** Macros (Inline Functions) Definitions *********************/ +/****************************************************************************/ +/** +* +* This function is used to check if the watchdog has timed-out and the last +* reset was caused by the watchdog reset. +* +* @param InstancePtr is a pointer to the XScuWdt instance. +* +* @return +* - TRUE if the watchdog has expired. +* - FALSE if the watchdog has not expired. +* +* @note C-style signature: +* int XScuWdt_IsWdtExpired(XScuWdt *InstancePtr) +* +******************************************************************************/ +#define XScuWdt_IsWdtExpired(InstancePtr) \ + ((XScuWdt_ReadReg((InstancePtr)->Config.BaseAddr, \ + XSCUWDT_RST_STS_OFFSET) & \ + XSCUWDT_RST_STS_RESET_FLAG_MASK) == XSCUWDT_RST_STS_RESET_FLAG_MASK) + +/****************************************************************************/ +/** +* +* This function is used to check if the watchdog counter has reached 0 in timer +* mode. +* +* @param InstancePtr is a pointer to the XScuWdt instance. +* +* @return +* - TRUE if the watchdog has expired. +* - FALSE if the watchdog has not expired. +* +* @note C-style signature: +* int XScuWdt_IsTimerExpired(XScuWdt *InstancePtr) +* +******************************************************************************/ +#define XScuWdt_IsTimerExpired(InstancePtr) \ + ((XScuWdt_ReadReg((InstancePtr)->Config.BaseAddr, \ + XSCUWDT_ISR_OFFSET) & \ + XSCUWDT_ISR_EVENT_FLAG_MASK) == XSCUWDT_ISR_EVENT_FLAG_MASK) + +/****************************************************************************/ +/** +* +* Re-start the watchdog timer. This macro will read the watchdog load register +* and write the same value to load register to update the counter register. +* An application needs to call this function periodically to keep the watchdog +* from asserting the WDRESETREQ reset request output pin. +* +* @param InstancePtr is a pointer to the XScuWdt instance. +* +* @return None. +* +* @note C-style signature: +* void XScuWdt_RestartWdt(XScuWdt *InstancePtr) +* +******************************************************************************/ +#define XScuWdt_RestartWdt(InstancePtr) \ + XScuWdt_LoadWdt((InstancePtr), \ + (XScuWdt_ReadReg((InstancePtr)->Config.BaseAddr, \ + XSCUWDT_LOAD_OFFSET))) + +/****************************************************************************/ +/** +* +* Write to the watchdog timer load register. This will also update the +* watchdog counter register with the new value. This macro can be used to +* change the time-out value. +* +* @param InstancePtr is a pointer to the XScuWdt instance. +* @param Value is the value to be written to the Watchdog Load register. +* +* @return None. +* +* @note C-style signature: +* void XScuWdt_LoadWdt(XScuWdt *InstancePtr, u32 Value) +* +******************************************************************************/ +#define XScuWdt_LoadWdt(InstancePtr, Value) \ + XScuWdt_WriteReg((InstancePtr)->Config.BaseAddr, \ + XSCUWDT_LOAD_OFFSET, (Value)) + +/****************************************************************************/ +/** +* +* Put the watchdog timer in Watchdog mode by setting the WD mode bit of the +* Watchdog control register. +* +* @param InstancePtr is a pointer to the XScuWdt instance. +* +* @return None. +* +* @note C-style signature: +* void XScuWdt_SetWdMode(XScuWdt *InstancePtr) +* +******************************************************************************/ +#define XScuWdt_SetWdMode(InstancePtr) \ + XScuWdt_WriteReg((InstancePtr)->Config.BaseAddr, \ + XSCUWDT_CONTROL_OFFSET, \ + (XScuWdt_ReadReg((InstancePtr)->Config.BaseAddr, \ + XSCUWDT_CONTROL_OFFSET) | \ + (XSCUWDT_CONTROL_WD_MODE_MASK))) + +/****************************************************************************/ +/** +* +* Put the watchdog timer in Timer mode by writing 0x12345678 and 0x87654321 +* successively to the Watchdog Disable Register. +* The software must write 0x12345678 and 0x87654321 successively to the +* Watchdog Disable Register so that the watchdog mode bit in the Watchdog +* Control Register is set to zero. +* +* @param InstancePtr is a pointer to the XScuWdt instance. +* +* @return None. +* +* @note C-style signature: +* void XScuWdt_SetTimerMode(XScuWdt *InstancePtr) +* +******************************************************************************/ +#define XScuWdt_SetTimerMode(InstancePtr) \ +{ \ + XScuWdt_WriteReg((InstancePtr)->Config.BaseAddr, \ + XSCUWDT_DISABLE_OFFSET, \ + XSCUWDT_DISABLE_VALUE1); \ + XScuWdt_WriteReg((InstancePtr)->Config.BaseAddr, \ + XSCUWDT_DISABLE_OFFSET, \ + XSCUWDT_DISABLE_VALUE2); \ +} + +/****************************************************************************/ +/** +* +* Get the contents of the watchdog control register. +* +* @param InstancePtr is a pointer to the XScuWdt instance. +* +* @return Contents of the watchdog control register. +* +* @note C-style signature: + u32 XScuWdt_GetControlReg(XScuWdt *InstancePtr) +* +******************************************************************************/ +#define XScuWdt_GetControlReg(InstancePtr) \ + XScuWdt_ReadReg((InstancePtr)->Config.BaseAddr, \ + XSCUWDT_CONTROL_OFFSET) + +/****************************************************************************/ +/** +* +* Write to the watchdog control register. +* +* @param InstancePtr is a pointer to the XScuWdt instance. +* @param ControlReg is the value to be written to the watchdog control +* register. +* +* @return None. +* +* @note C-style signature: + void XScuWdt_SetControlReg(XScuWdt *InstancePtr, u32 ControlReg) +* +******************************************************************************/ +#define XScuWdt_SetControlReg(InstancePtr, ControlReg) \ + XScuWdt_WriteReg((InstancePtr)->Config.BaseAddr, \ + XSCUWDT_CONTROL_OFFSET, (ControlReg)) + +/****************************************************************************/ +/** +* +* Enable auto-reload mode. +* +* @param InstancePtr is a pointer to the XScuWdt instance. +* +* @return None. +* +* @note C-style signature: +* void XScuWdt_EnableAutoReload(XScuWdt *InstancePtr) +* +******************************************************************************/ +#define XScuWdt_EnableAutoReload(InstancePtr) \ + XScuWdt_SetControlReg((InstancePtr), \ + (XScuWdt_GetControlReg(InstancePtr) | \ + XSCUWDT_CONTROL_AUTO_RELOAD_MASK)) + +/************************** Function Prototypes ******************************/ + +/* + * Lookup configuration in xscuwdt_sinit.c. + */ +XScuWdt_Config *XScuWdt_LookupConfig(u16 DeviceId); + +/* + * Selftest function in xscuwdt_selftest.c + */ +s32 XScuWdt_SelfTest(XScuWdt *InstancePtr); + +/* + * Interface functions in xscuwdt.c + */ +s32 XScuWdt_CfgInitialize(XScuWdt *InstancePtr, + XScuWdt_Config *ConfigPtr, u32 EffectiveAddress); + +void XScuWdt_Start(XScuWdt *InstancePtr); + +void XScuWdt_Stop(XScuWdt *InstancePtr); + + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xscuwdt_hw.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xscuwdt_hw.h new file mode 100644 index 0000000..ad87a05 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xscuwdt_hw.h @@ -0,0 +1,178 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xscuwdt_hw.h +* @addtogroup scuwdt_v2_1 +* @{ +* +* This file contains the hardware interface to the Xilinx SCU private Watch Dog +* Timer (XSCUWDT). +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who Date     Changes
+* ----- --- -------- ---------------------------------------------
+* 1.00a sdm 01/15/10 First release
+* 1.01a bss 02/27/12 Updated the register offsets to start at 0x0 instead
+*                    of 0x20 as the base address obtained from the tools
+*		     starts at 0x20.
+* 1.02a  sg 07/17/12 Included xil_assert.h for CR 667947. This is an issue
+*		     when the xstatus.h in the common driver overwrites
+*		     the xstatus.h of the standalone BSP during the
+*		     libgen.
+* 2.1 	sk  02/26/15 Modified the code for MISRA-C:2012 compliance.
+* 
+* +******************************************************************************/ +#ifndef XSCUWDT_HW_H /* prevent circular inclusions */ +#define XSCUWDT_HW_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +#include "xil_types.h" +#include "xil_io.h" +#include "xil_assert.h" +/************************** Constant Definitions *****************************/ + +/** @name Register Map + * Offsets of registers from the start of the device. The WDT registers start at + * an offset 0x20 + * @{ + */ + +#define XSCUWDT_LOAD_OFFSET 0x00U /**< Watchdog Load Register */ +#define XSCUWDT_COUNTER_OFFSET 0x04U /**< Watchdog Counter Register */ +#define XSCUWDT_CONTROL_OFFSET 0x08U /**< Watchdog Control Register */ +#define XSCUWDT_ISR_OFFSET 0x0CU /**< Watchdog Interrupt Status Register */ +#define XSCUWDT_RST_STS_OFFSET 0x10U /**< Watchdog Reset Status Register */ +#define XSCUWDT_DISABLE_OFFSET 0x14U /**< Watchdog Disable Register */ +/* @} */ + +/** @name Watchdog Control register + * This register bits control the prescaler, WD/Timer mode, Intr enable, + * auto-reload, watchdog enable. + * @{ + */ + +#define XSCUWDT_CONTROL_PRESCALER_MASK 0x0000FF00U /**< Prescaler */ +#define XSCUWDT_CONTROL_PRESCALER_SHIFT 8U +#define XSCUWDT_CONTROL_WD_MODE_MASK 0x00000008U /**< Watchdog/Timer mode */ +#define XSCUWDT_CONTROL_IT_ENABLE_MASK 0x00000004U /**< Intr enable (in + timer mode) */ +#define XSCUWDT_CONTROL_AUTO_RELOAD_MASK 0x00000002U /**< Auto-reload (in + timer mode) */ +#define XSCUWDT_CONTROL_WD_ENABLE_MASK 0x00000001U /**< Watchdog enable */ +/* @} */ + +/** @name Interrupt Status register + * This register indicates the Counter register has reached zero in Counter + * mode. + * @{ + */ + +#define XSCUWDT_ISR_EVENT_FLAG_MASK 0x00000001U /**< Event flag */ +/*@}*/ + +/** @name Reset Status register + * This register indicates the Counter register has reached zero in Watchdog + * mode and a reset request is sent. + * @{ + */ + +#define XSCUWDT_RST_STS_RESET_FLAG_MASK 0x00000001U /**< Time out occured */ +/*@}*/ + +/** @name Disable register + * This register is used to switch from watchdog mode to timer mode. + * The software must write 0x12345678 and 0x87654321 successively to the + * Watchdog Disable Register so that the watchdog mode bit in the Watchdog + * Control Register is set to zero. + * @{ + */ +#define XSCUWDT_DISABLE_VALUE1 0x12345678U /**< Watchdog mode disable + value 1 */ +#define XSCUWDT_DISABLE_VALUE2 0x87654321U /**< Watchdog mode disable + value 2 */ +/*@}*/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/****************************************************************************/ +/** +* +* Read the given register. +* +* @param BaseAddr is the base address of the device +* @param RegOffset is the register offset to be read +* +* @return The 32-bit value of the register +* +* @note C-style signature: +* u32 XScuWdt_ReadReg(u32 BaseAddr, u32 RegOffset) +* +*****************************************************************************/ +#define XScuWdt_ReadReg(BaseAddr, RegOffset) \ + Xil_In32((BaseAddr) + ((u32)RegOffset)) + +/****************************************************************************/ +/** +* +* Write the given register. +* +* @param BaseAddr is the base address of the device +* @param RegOffset is the register offset to be written +* @param Data is the 32-bit value to write to the register +* +* @return None. +* +* @note C-style signature: +* void XScuWdt_WriteReg(u32 BaseAddr, u32 RegOffset, u32 Data) +* +*****************************************************************************/ +#define XScuWdt_WriteReg(BaseAddr, RegOffset, Data) \ + Xil_Out32((BaseAddr) + ((u32)RegOffset), ((u32)Data)) + +/************************** Function Prototypes ******************************/ + +/************************** Variable Definitions *****************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xstatus.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xstatus.h new file mode 100644 index 0000000..1a212bf --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xstatus.h @@ -0,0 +1,533 @@ +/****************************************************************************** +* +* Copyright (C) 2002 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xstatus.h +* +* @addtogroup common_status_codes Xilinx® software status codes +* +* The xstatus.h file contains the Xilinx® software status codes.These codes are +* used throughout the Xilinx device drivers. +* +* @{ +******************************************************************************/ + +#ifndef XSTATUS_H /* prevent circular inclusions */ +#define XSTATUS_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +#include "xil_types.h" +#include "xil_assert.h" + +/************************** Constant Definitions *****************************/ + +/*********************** Common statuses 0 - 500 *****************************/ +/** +@name Common Status Codes for All Device Drivers +@{ +*/ +#define XST_SUCCESS 0L +#define XST_FAILURE 1L +#define XST_DEVICE_NOT_FOUND 2L +#define XST_DEVICE_BLOCK_NOT_FOUND 3L +#define XST_INVALID_VERSION 4L +#define XST_DEVICE_IS_STARTED 5L +#define XST_DEVICE_IS_STOPPED 6L +#define XST_FIFO_ERROR 7L /*!< An error occurred during an + operation with a FIFO such as + an underrun or overrun, this + error requires the device to + be reset */ +#define XST_RESET_ERROR 8L /*!< An error occurred which requires + the device to be reset */ +#define XST_DMA_ERROR 9L /*!< A DMA error occurred, this error + typically requires the device + using the DMA to be reset */ +#define XST_NOT_POLLED 10L /*!< The device is not configured for + polled mode operation */ +#define XST_FIFO_NO_ROOM 11L /*!< A FIFO did not have room to put + the specified data into */ +#define XST_BUFFER_TOO_SMALL 12L /*!< The buffer is not large enough + to hold the expected data */ +#define XST_NO_DATA 13L /*!< There was no data available */ +#define XST_REGISTER_ERROR 14L /*!< A register did not contain the + expected value */ +#define XST_INVALID_PARAM 15L /*!< An invalid parameter was passed + into the function */ +#define XST_NOT_SGDMA 16L /*!< The device is not configured for + scatter-gather DMA operation */ +#define XST_LOOPBACK_ERROR 17L /*!< A loopback test failed */ +#define XST_NO_CALLBACK 18L /*!< A callback has not yet been + registered */ +#define XST_NO_FEATURE 19L /*!< Device is not configured with + the requested feature */ +#define XST_NOT_INTERRUPT 20L /*!< Device is not configured for + interrupt mode operation */ +#define XST_DEVICE_BUSY 21L /*!< Device is busy */ +#define XST_ERROR_COUNT_MAX 22L /*!< The error counters of a device + have maxed out */ +#define XST_IS_STARTED 23L /*!< Used when part of device is + already started i.e. + sub channel */ +#define XST_IS_STOPPED 24L /*!< Used when part of device is + already stopped i.e. + sub channel */ +#define XST_DATA_LOST 26L /*!< Driver defined error */ +#define XST_RECV_ERROR 27L /*!< Generic receive error */ +#define XST_SEND_ERROR 28L /*!< Generic transmit error */ +#define XST_NOT_ENABLED 29L /*!< A requested service is not + available because it has not + been enabled */ +#define XST_NO_ACCESS 30L /* Generic access error */ +/** @} */ +/***************** Utility Component statuses 401 - 500 *********************/ +/** +@name Utility Component Status Codes 401 - 500 +@{ +*/ +#define XST_MEMTEST_FAILED 401L /*!< Memory test failed */ + +/** @} */ +/***************** Common Components statuses 501 - 1000 *********************/ +/** +@name Packet Fifo Status Codes 501 - 510 +@{ +*/ +/********************* Packet Fifo statuses 501 - 510 ************************/ + +#define XST_PFIFO_LACK_OF_DATA 501L /*!< Not enough data in FIFO */ +#define XST_PFIFO_NO_ROOM 502L /*!< Not enough room in FIFO */ +#define XST_PFIFO_BAD_REG_VALUE 503L /*!< Self test, a register value + was invalid after reset */ +#define XST_PFIFO_ERROR 504L /*!< Generic packet FIFO error */ +#define XST_PFIFO_DEADLOCK 505L /*!< Packet FIFO is reporting + * empty and full simultaneously + */ +/** @} */ +/** +@name DMA Status Codes 511 - 530 +@{ +*/ +/************************** DMA statuses 511 - 530 ***************************/ + +#define XST_DMA_TRANSFER_ERROR 511L /*!< Self test, DMA transfer + failed */ +#define XST_DMA_RESET_REGISTER_ERROR 512L /*!< Self test, a register value + was invalid after reset */ +#define XST_DMA_SG_LIST_EMPTY 513L /*!< Scatter gather list contains + no buffer descriptors ready + to be processed */ +#define XST_DMA_SG_IS_STARTED 514L /*!< Scatter gather not stopped */ +#define XST_DMA_SG_IS_STOPPED 515L /*!< Scatter gather not running */ +#define XST_DMA_SG_LIST_FULL 517L /*!< All the buffer desciptors of + the scatter gather list are + being used */ +#define XST_DMA_SG_BD_LOCKED 518L /*!< The scatter gather buffer + descriptor which is to be + copied over in the scatter + list is locked */ +#define XST_DMA_SG_NOTHING_TO_COMMIT 519L /*!< No buffer descriptors have been + put into the scatter gather + list to be commited */ +#define XST_DMA_SG_COUNT_EXCEEDED 521L /*!< The packet count threshold + specified was larger than the + total # of buffer descriptors + in the scatter gather list */ +#define XST_DMA_SG_LIST_EXISTS 522L /*!< The scatter gather list has + already been created */ +#define XST_DMA_SG_NO_LIST 523L /*!< No scatter gather list has + been created */ +#define XST_DMA_SG_BD_NOT_COMMITTED 524L /*!< The buffer descriptor which was + being started was not committed + to the list */ +#define XST_DMA_SG_NO_DATA 525L /*!< The buffer descriptor to start + has already been used by the + hardware so it can't be reused + */ +#define XST_DMA_SG_LIST_ERROR 526L /*!< General purpose list access + error */ +#define XST_DMA_BD_ERROR 527L /*!< General buffer descriptor + error */ +/** @} */ +/** +@name IPIF Status Codes Codes 531 - 550 +@{ +*/ +/************************** IPIF statuses 531 - 550 ***************************/ + +#define XST_IPIF_REG_WIDTH_ERROR 531L /*!< An invalid register width + was passed into the function */ +#define XST_IPIF_RESET_REGISTER_ERROR 532L /*!< The value of a register at + reset was not valid */ +#define XST_IPIF_DEVICE_STATUS_ERROR 533L /*!< A write to the device interrupt + status register did not read + back correctly */ +#define XST_IPIF_DEVICE_ACK_ERROR 534L /*!< The device interrupt status + register did not reset when + acked */ +#define XST_IPIF_DEVICE_ENABLE_ERROR 535L /*!< The device interrupt enable + register was not updated when + other registers changed */ +#define XST_IPIF_IP_STATUS_ERROR 536L /*!< A write to the IP interrupt + status register did not read + back correctly */ +#define XST_IPIF_IP_ACK_ERROR 537L /*!< The IP interrupt status register + did not reset when acked */ +#define XST_IPIF_IP_ENABLE_ERROR 538L /*!< IP interrupt enable register was + not updated correctly when other + registers changed */ +#define XST_IPIF_DEVICE_PENDING_ERROR 539L /*!< The device interrupt pending + register did not indicate the + expected value */ +#define XST_IPIF_DEVICE_ID_ERROR 540L /*!< The device interrupt ID register + did not indicate the expected + value */ +#define XST_IPIF_ERROR 541L /*!< Generic ipif error */ +/** @} */ + +/****************** Device specific statuses 1001 - 4095 *********************/ +/** +@name Ethernet Status Codes 1001 - 1050 +@{ +*/ +/********************* Ethernet statuses 1001 - 1050 *************************/ + +#define XST_EMAC_MEMORY_SIZE_ERROR 1001L /*!< Memory space is not big enough + * to hold the minimum number of + * buffers or descriptors */ +#define XST_EMAC_MEMORY_ALLOC_ERROR 1002L /*!< Memory allocation failed */ +#define XST_EMAC_MII_READ_ERROR 1003L /*!< MII read error */ +#define XST_EMAC_MII_BUSY 1004L /*!< An MII operation is in progress */ +#define XST_EMAC_OUT_OF_BUFFERS 1005L /*!< Driver is out of buffers */ +#define XST_EMAC_PARSE_ERROR 1006L /*!< Invalid driver init string */ +#define XST_EMAC_COLLISION_ERROR 1007L /*!< Excess deferral or late + * collision on polled send */ +/** @} */ +/** +@name UART Status Codes 1051 - 1075 +@{ +*/ +/*********************** UART statuses 1051 - 1075 ***************************/ +#define XST_UART + +#define XST_UART_INIT_ERROR 1051L +#define XST_UART_START_ERROR 1052L +#define XST_UART_CONFIG_ERROR 1053L +#define XST_UART_TEST_FAIL 1054L +#define XST_UART_BAUD_ERROR 1055L +#define XST_UART_BAUD_RANGE 1056L + +/** @} */ +/** +@name IIC Status Codes 1076 - 1100 +@{ +*/ +/************************ IIC statuses 1076 - 1100 ***************************/ + +#define XST_IIC_SELFTEST_FAILED 1076 /*!< self test failed */ +#define XST_IIC_BUS_BUSY 1077 /*!< bus found busy */ +#define XST_IIC_GENERAL_CALL_ADDRESS 1078 /*!< mastersend attempted with */ + /* general call address */ +#define XST_IIC_STAND_REG_RESET_ERROR 1079 /*!< A non parameterizable reg */ + /* value after reset not valid */ +#define XST_IIC_TX_FIFO_REG_RESET_ERROR 1080 /*!< Tx fifo included in design */ + /* value after reset not valid */ +#define XST_IIC_RX_FIFO_REG_RESET_ERROR 1081 /*!< Rx fifo included in design */ + /* value after reset not valid */ +#define XST_IIC_TBA_REG_RESET_ERROR 1082 /*!< 10 bit addr incl in design */ + /* value after reset not valid */ +#define XST_IIC_CR_READBACK_ERROR 1083 /*!< Read of the control register */ + /* didn't return value written */ +#define XST_IIC_DTR_READBACK_ERROR 1084 /*!< Read of the data Tx reg */ + /* didn't return value written */ +#define XST_IIC_DRR_READBACK_ERROR 1085 /*!< Read of the data Receive reg */ + /* didn't return value written */ +#define XST_IIC_ADR_READBACK_ERROR 1086 /*!< Read of the data Tx reg */ + /* didn't return value written */ +#define XST_IIC_TBA_READBACK_ERROR 1087 /*!< Read of the 10 bit addr reg */ + /* didn't return written value */ +#define XST_IIC_NOT_SLAVE 1088 /*!< The device isn't a slave */ +#define XST_IIC_ARB_LOST 1089 /*!< Arbitration lost for master */ +/** @} */ +/** +@name ATMC Status Codes 1101 - 1125 +@{ +*/ +/*********************** ATMC statuses 1101 - 1125 ***************************/ + +#define XST_ATMC_ERROR_COUNT_MAX 1101L /*!< the error counters in the ATM + controller hit the max value + which requires the statistics + to be cleared */ +/** @} */ +/** +@name Flash Status Codes 1126 - 1150 +@{ +*/ +/*********************** Flash statuses 1126 - 1150 **************************/ + +#define XST_FLASH_BUSY 1126L /*!< Flash is erasing or programming + */ +#define XST_FLASH_READY 1127L /*!< Flash is ready for commands */ +#define XST_FLASH_ERROR 1128L /*!< Flash had detected an internal + error. Use XFlash_DeviceControl + to retrieve device specific codes + */ +#define XST_FLASH_ERASE_SUSPENDED 1129L /*!< Flash is in suspended erase state + */ +#define XST_FLASH_WRITE_SUSPENDED 1130L /*!< Flash is in suspended write state + */ +#define XST_FLASH_PART_NOT_SUPPORTED 1131L /*!< Flash type not supported by + driver */ +#define XST_FLASH_NOT_SUPPORTED 1132L /*!< Operation not supported */ +#define XST_FLASH_TOO_MANY_REGIONS 1133L /*!< Too many erase regions */ +#define XST_FLASH_TIMEOUT_ERROR 1134L /*!< Programming or erase operation + aborted due to a timeout */ +#define XST_FLASH_ADDRESS_ERROR 1135L /*!< Accessed flash outside its + addressible range */ +#define XST_FLASH_ALIGNMENT_ERROR 1136L /*!< Write alignment error */ +#define XST_FLASH_BLOCKING_CALL_ERROR 1137L /*!< Couldn't return immediately from + write/erase function with + XFL_NON_BLOCKING_WRITE/ERASE + option cleared */ +#define XST_FLASH_CFI_QUERY_ERROR 1138L /*!< Failed to query the device */ +/** @} */ +/** +@name SPI Status Codes 1151 - 1175 +@{ +*/ +/*********************** SPI statuses 1151 - 1175 ****************************/ + +#define XST_SPI_MODE_FAULT 1151 /*!< master was selected as slave */ +#define XST_SPI_TRANSFER_DONE 1152 /*!< data transfer is complete */ +#define XST_SPI_TRANSMIT_UNDERRUN 1153 /*!< slave underruns transmit register */ +#define XST_SPI_RECEIVE_OVERRUN 1154 /*!< device overruns receive register */ +#define XST_SPI_NO_SLAVE 1155 /*!< no slave has been selected yet */ +#define XST_SPI_TOO_MANY_SLAVES 1156 /*!< more than one slave is being + * selected */ +#define XST_SPI_NOT_MASTER 1157 /*!< operation is valid only as master */ +#define XST_SPI_SLAVE_ONLY 1158 /*!< device is configured as slave-only + */ +#define XST_SPI_SLAVE_MODE_FAULT 1159 /*!< slave was selected while disabled */ +#define XST_SPI_SLAVE_MODE 1160 /*!< device has been addressed as slave */ +#define XST_SPI_RECEIVE_NOT_EMPTY 1161 /*!< device received data in slave mode */ + +#define XST_SPI_COMMAND_ERROR 1162 /*!< unrecognised command - qspi only */ +#define XST_SPI_POLL_DONE 1163 /*!< controller completed polling the + device for status */ +/** @} */ +/** +@name OPB Arbiter Status Codes 1176 - 1200 +@{ +*/ +/********************** OPB Arbiter statuses 1176 - 1200 *********************/ + +#define XST_OPBARB_INVALID_PRIORITY 1176 /*!< the priority registers have either + * one master assigned to two or more + * priorities, or one master not + * assigned to any priority + */ +#define XST_OPBARB_NOT_SUSPENDED 1177 /*!< an attempt was made to modify the + * priority levels without first + * suspending the use of priority + * levels + */ +#define XST_OPBARB_PARK_NOT_ENABLED 1178 /*!< bus parking by id was enabled but + * bus parking was not enabled + */ +#define XST_OPBARB_NOT_FIXED_PRIORITY 1179 /*!< the arbiter must be in fixed + * priority mode to allow the + * priorities to be changed + */ +/** @} */ +/** +@name INTC Status Codes 1201 - 1225 +@{ +*/ +/************************ Intc statuses 1201 - 1225 **************************/ + +#define XST_INTC_FAIL_SELFTEST 1201 /*!< self test failed */ +#define XST_INTC_CONNECT_ERROR 1202 /*!< interrupt already in use */ +/** @} */ +/** +@name TmrCtr Status Codes 1226 - 1250 +@{ +*/ +/********************** TmrCtr statuses 1226 - 1250 **************************/ + +#define XST_TMRCTR_TIMER_FAILED 1226 /*!< self test failed */ +/** @} */ +/** +@name WdtTb Status Codes 1251 - 1275 +@{ +*/ +/********************** WdtTb statuses 1251 - 1275 ***************************/ + +#define XST_WDTTB_TIMER_FAILED 1251L +/** @} */ +/** +@name PlbArb status Codes 1276 - 1300 +@{ +*/ +/********************** PlbArb statuses 1276 - 1300 **************************/ + +#define XST_PLBARB_FAIL_SELFTEST 1276L +/** @} */ +/** +@name Plb2Opb Status Codes 1301 - 1325 +@{ +*/ +/********************** Plb2Opb statuses 1301 - 1325 *************************/ + +#define XST_PLB2OPB_FAIL_SELFTEST 1301L +/** @} */ +/** +@name Opb2Plb Status 1326 - 1350 +@{ +*/ +/********************** Opb2Plb statuses 1326 - 1350 *************************/ + +#define XST_OPB2PLB_FAIL_SELFTEST 1326L +/** @} */ +/** +@name SysAce Status Codes 1351 - 1360 +@{ +*/ +/********************** SysAce statuses 1351 - 1360 **************************/ + +#define XST_SYSACE_NO_LOCK 1351L /*!< No MPU lock has been granted */ +/** @} */ +/** +@name PCI Bridge Status Codes 1361 - 1375 +@{ +*/ +/********************** PCI Bridge statuses 1361 - 1375 **********************/ + +#define XST_PCI_INVALID_ADDRESS 1361L +/** @} */ +/** +@name FlexRay Constants 1400 - 1409 +@{ +*/ +/********************** FlexRay constants 1400 - 1409 *************************/ + +#define XST_FR_TX_ERROR 1400 +#define XST_FR_TX_BUSY 1401 +#define XST_FR_BUF_LOCKED 1402 +#define XST_FR_NO_BUF 1403 +/** @} */ +/** +@name USB constants 1410 - 1420 +@{ +*/ +/****************** USB constants 1410 - 1420 *******************************/ + +#define XST_USB_ALREADY_CONFIGURED 1410 +#define XST_USB_BUF_ALIGN_ERROR 1411 +#define XST_USB_NO_DESC_AVAILABLE 1412 +#define XST_USB_BUF_TOO_BIG 1413 +#define XST_USB_NO_BUF 1414 +/** @} */ +/** +@name HWICAP constants 1421 - 1429 +@{ +*/ +/****************** HWICAP constants 1421 - 1429 *****************************/ + +#define XST_HWICAP_WRITE_DONE 1421 + +/** @} */ +/** +@name AXI VDMA constants 1430 - 1440 +@{ +*/ +/****************** AXI VDMA constants 1430 - 1440 *****************************/ + +#define XST_VDMA_MISMATCH_ERROR 1430 +/** @} */ +/** +@name NAND Flash Status Codes 1441 - 1459 +@{ +*/ +/*********************** NAND Flash statuses 1441 - 1459 *********************/ + +#define XST_NAND_BUSY 1441L /*!< Flash is erasing or + * programming + */ +#define XST_NAND_READY 1442L /*!< Flash is ready for commands + */ +#define XST_NAND_ERROR 1443L /*!< Flash had detected an + * internal error. + */ +#define XST_NAND_PART_NOT_SUPPORTED 1444L /*!< Flash type not supported by + * driver + */ +#define XST_NAND_OPT_NOT_SUPPORTED 1445L /*!< Operation not supported + */ +#define XST_NAND_TIMEOUT_ERROR 1446L /*!< Programming or erase + * operation aborted due to a + * timeout + */ +#define XST_NAND_ADDRESS_ERROR 1447L /*!< Accessed flash outside its + * addressible range + */ +#define XST_NAND_ALIGNMENT_ERROR 1448L /*!< Write alignment error + */ +#define XST_NAND_PARAM_PAGE_ERROR 1449L /*!< Failed to read parameter + * page of the device + */ +#define XST_NAND_CACHE_ERROR 1450L /*!< Flash page buffer error + */ + +#define XST_NAND_WRITE_PROTECTED 1451L /*!< Flash is write protected + */ +/** @} */ + +/**************************** Type Definitions *******************************/ + +typedef s32 XStatus; + +/***************** Macros (Inline Functions) Definitions *********************/ + + +/************************** Function Prototypes ******************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** +* @} End of "addtogroup common_status_codes". +*/ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xtime_l.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xtime_l.h new file mode 100644 index 0000000..12004e1 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xtime_l.h @@ -0,0 +1,104 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* @file xtime_l.h +* @addtogroup a9_time_apis Cortex A9 Time Functions +* +* xtime_l.h provides access to the 64-bit Global Counter in the PMU. This +* counter increases by one at every two processor cycles. These functions can +* be used to get/set time in the global timer. +* +* @{ +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date     Changes
+* ----- ------ -------- ---------------------------------------------------
+* 1.00a rp/sdm 11/03/09 Initial release.
+* 3.06a sgd    05/15/12 Upadted get/set time functions to make use Global Timer
+* 3.06a asa    06/17/12 Reverted back the changes to make use Global Timer.
+* 3.07a sgd    07/05/12 Upadted get/set time functions to make use Global Timer
+* 6.6   srm    10/23/17 Updated the macros to support user configurable sleep
+*						implementation
+* 6.8   aru  09/06/18 Removed compilation warnings for ARMCC toolchain.
+* 
+* +******************************************************************************/ + +#ifndef XTIME_H /* prevent circular inclusions */ +#define XTIME_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +#include "xil_types.h" +#include "xparameters.h" + +/***************** Macros (Inline Functions) Definitions *********************/ + +/**************************** Type Definitions *******************************/ + +typedef u64 XTime; + +/************************** Constant Definitions *****************************/ +#define GLOBAL_TMR_BASEADDR XPAR_GLOBAL_TMR_BASEADDR +#define GTIMER_COUNTER_LOWER_OFFSET 0x00U +#define GTIMER_COUNTER_UPPER_OFFSET 0x04U +#define GTIMER_CONTROL_OFFSET 0x08U + +#if defined (SLEEP_TIMER_BASEADDR) +#define COUNTS_PER_SECOND (SLEEP_TIMER_FREQUENCY) +#else +/* Global Timer is always clocked at half of the CPU frequency */ +#define COUNTS_PER_SECOND (XPAR_CPU_CORTEXA9_CORE_CLOCK_FREQ_HZ /2) +#endif + +#if defined (XSLEEP_TIMER_IS_DEFAULT_TIMER) +#ifdef __GNUC__ +#pragma message ("For the sleep routines, Global timer is being used") +#endif +#endif +/************************** Variable Definitions *****************************/ + +/************************** Function Prototypes ******************************/ + +void XTime_SetTime(XTime Xtime_Global); +void XTime_GetTime(XTime *Xtime_Global); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* XTIME_H */ +/** +* @} End of "addtogroup a9_time_apis". +*/ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xuartps.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xuartps.h new file mode 100644 index 0000000..c6c2a0a --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xuartps.h @@ -0,0 +1,517 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xuartps.h +* @addtogroup uartps_v3_5 +* @{ +* @details +* +* This driver supports the following features: +* +* - Dynamic data format (baud rate, data bits, stop bits, parity) +* - Polled mode +* - Interrupt driven mode +* - Transmit and receive FIFOs (32 byte FIFO depth) +* - Access to the external modem control lines +* +* Initialization & Configuration +* +* The XUartPs_Config structure is used by the driver to configure itself. +* Fields inside this structure are properties of XUartPs based on its hardware +* build. +* +* To support multiple runtime loading and initialization strategies employed +* by various operating systems, the driver instance can be initialized in the +* following way: +* +* - XUartPs_CfgInitialize(InstancePtr, CfgPtr, EffectiveAddr) - Uses a +* configuration structure provided by the caller. If running in a system +* with address translation, the parameter EffectiveAddr should be the +* virtual address. +* +* Baud Rate +* +* The UART has an internal baud rate generator, which furnishes the baud rate +* clock for both the receiver and the transmitter. Ther input clock frequency +* can be either the master clock or the master clock divided by 8, configured +* through the mode register. +* +* Accompanied with the baud rate divider register, the baud rate is determined +* by: +*
+*	baud_rate = input_clock / (bgen * (bdiv + 1)
+* 
+* where bgen is the value of the baud rate generator, and bdiv is the value of +* baud rate divider. +* +* Interrupts +* +* The FIFOs are not flushed when the driver is initialized, but a function is +* provided to allow the user to reset the FIFOs if desired. +* +* The driver defaults to no interrupts at initialization such that interrupts +* must be enabled if desired. An interrupt is generated for one of the +* following conditions. +* +* - A change in the modem signals +* - Data in the receive FIFO for a configuable time without receiver activity +* - A parity error +* - A framing error +* - An overrun error +* - Transmit FIFO is full +* - Transmit FIFO is empty +* - Receive FIFO is full +* - Receive FIFO is empty +* - Data in the receive FIFO equal to the receive threshold +* +* The application can control which interrupts are enabled using the +* XUartPs_SetInterruptMask() function. +* +* In order to use interrupts, it is necessary for the user to connect the +* driver interrupt handler, XUartPs_InterruptHandler(), to the interrupt +* system of the application. A separate handler should be provided by the +* application to communicate with the interrupt system, and conduct +* application specific interrupt handling. An application registers its own +* handler through the XUartPs_SetHandler() function. +* +* Data Transfer +* +* The functions, XUartPs_Send() and XUartPs_Recv(), are provided in the +* driver to allow data to be sent and received. They can be used in either +* polled or interrupt mode. +* +* @note +* +* The default configuration for the UART after initialization is: +* +* - 9,600 bps or XPAR_DFT_BAUDRATE if defined +* - 8 data bits +* - 1 stop bit +* - no parity +* - FIFO's are enabled with a receive threshold of 8 bytes +* - The RX timeout is enabled with a timeout of 1 (4 char times) +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date	Changes
+* ----- ------ -------- ----------------------------------------------
+* 1.00a	drg/jz 01/12/10 First Release
+* 1.00a sdm    09/27/11 Fixed compiler warnings and also a bug
+*		        in XUartPs_SetFlowDelay where the value was not
+*			being written to the register.
+* 1.01a sdm    12/20/11 Removed the InputClockHz parameter from the XUartPs
+*			instance structure and the driver is updated to use
+*			InputClockHz parameter from the XUartPs_Config config
+*			structure.
+*			Added a parameter to XUartPs_Config structure which
+*			specifies whether the user has selected Modem pins
+*			to be connected to MIO or FMIO.
+*			Added the tcl file to generate the xparameters.h
+* 1.02a sg     05/16/12	Changed XUARTPS_RXWM_MASK to 0x3F for CR 652540 fix.
+* 1.03a sg     07/16/12 Updated XUARTPS_FORMAT_7_BITS and XUARTPS_FORMAT_6_BITS
+*			with the correct values for CR 666724
+* 			Added defines for XUARTPS_IXR_TOVR,  XUARTPS_IXR_TNFUL
+*			and XUARTPS_IXR_TTRIG.
+*			Modified the name of these defines
+*			XUARTPS_MEDEMSR_DCDX to XUARTPS_MODEMSR_DDCD
+*			XUARTPS_MEDEMSR_RIX to XUARTPS_MODEMSR_TERI
+*			XUARTPS_MEDEMSR_DSRX to XUARTPS_MODEMSR_DDSR
+*			XUARTPS_MEDEMSR_CTSX to XUARTPS_MODEMSR_DCTS
+* 1.05a hk     08/22/13 Added API for uart reset and related
+*			constant definitions.
+* 2.0   hk      03/07/14 Version number revised.
+* 2.1   hk     04/16/14 Change XUARTPS_MAX_RATE to 921600. CR# 780625.
+* 2.2   hk     06/23/14 SW reset of RX and TX should be done when changing
+*                       baud rate. CR# 804281.
+* 3.0   vm     12/09/14 Modified source code according to misrac guideline.
+*			Support for Zynq Ultrascale Mp added.
+* 3.1	kvn    04/10/15 Modified code for latest RTL changes. Also added
+*						platform variable in driver instance structure.
+* 3.1   adk   14/03/16  Include interrupt examples in the peripheral test when
+*			uart is connected to a valid interrupt controller CR#946803.
+* 3.2   rk     07/20/16 Modified the logic for transmission break bit set
+* 3.4   ms     01/23/17 Added xil_printf statement in main function for all
+*                       examples to ensure that "Successfully ran" and "Failed"
+*                       strings are available in all examples. This is a fix
+*                       for CR-965028.
+*       ms     03/17/17 Added readme.txt file in examples folder for doxygen
+*                       generation.
+* 3.6   ms     02/16/18 Updates the flow control mode offset value in modem
+*                       control register.
+* 3.7   aru    08/17/18 Resolved MISRA-C:2012 compliance mandatory violations.
+*
+* 
+* +*****************************************************************************/ + +#ifndef XUARTPS_H /* prevent circular inclusions */ +#define XUARTPS_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files ********************************/ + +#include "xil_types.h" +#include "xil_assert.h" +#include "xstatus.h" +#include "xuartps_hw.h" +#include "xplatform_info.h" + +/************************** Constant Definitions ****************************/ + +/* + * The following constants indicate the max and min baud rates and these + * numbers are based only on the testing that has been done. The hardware + * is capable of other baud rates. + */ +#define XUARTPS_MAX_RATE 921600U +#define XUARTPS_MIN_RATE 110U + +#define XUARTPS_DFT_BAUDRATE 115200U /* Default baud rate */ + +/** @name Configuration options + * @{ + */ +/** + * These constants specify the options that may be set or retrieved + * with the driver, each is a unique bit mask such that multiple options + * may be specified. These constants indicate the available options + * in active state. + * + */ + +#define XUARTPS_OPTION_SET_BREAK 0x0080U /**< Starts break transmission */ +#define XUARTPS_OPTION_STOP_BREAK 0x0040U /**< Stops break transmission */ +#define XUARTPS_OPTION_RESET_TMOUT 0x0020U /**< Reset the receive timeout */ +#define XUARTPS_OPTION_RESET_TX 0x0010U /**< Reset the transmitter */ +#define XUARTPS_OPTION_RESET_RX 0x0008U /**< Reset the receiver */ +#define XUARTPS_OPTION_ASSERT_RTS 0x0004U /**< Assert the RTS bit */ +#define XUARTPS_OPTION_ASSERT_DTR 0x0002U /**< Assert the DTR bit */ +#define XUARTPS_OPTION_SET_FCM 0x0001U /**< Turn on flow control mode */ +/*@}*/ + + +/** @name Channel Operational Mode + * + * The UART can operate in one of four modes: Normal, Local Loopback, Remote + * Loopback, or automatic echo. + * + * @{ + */ + +#define XUARTPS_OPER_MODE_NORMAL (u8)0x00U /**< Normal Mode */ +#define XUARTPS_OPER_MODE_AUTO_ECHO (u8)0x01U /**< Auto Echo Mode */ +#define XUARTPS_OPER_MODE_LOCAL_LOOP (u8)0x02U /**< Local Loopback Mode */ +#define XUARTPS_OPER_MODE_REMOTE_LOOP (u8)0x03U /**< Remote Loopback Mode */ + +/* @} */ + +/** @name Data format values + * + * These constants specify the data format that the driver supports. + * The data format includes the number of data bits, the number of stop + * bits and parity. + * + * @{ + */ +#define XUARTPS_FORMAT_8_BITS 0U /**< 8 data bits */ +#define XUARTPS_FORMAT_7_BITS 2U /**< 7 data bits */ +#define XUARTPS_FORMAT_6_BITS 3U /**< 6 data bits */ + +#define XUARTPS_FORMAT_NO_PARITY 4U /**< No parity */ +#define XUARTPS_FORMAT_MARK_PARITY 3U /**< Mark parity */ +#define XUARTPS_FORMAT_SPACE_PARITY 2U /**< parity */ +#define XUARTPS_FORMAT_ODD_PARITY 1U /**< Odd parity */ +#define XUARTPS_FORMAT_EVEN_PARITY 0U /**< Even parity */ + +#define XUARTPS_FORMAT_2_STOP_BIT 2U /**< 2 stop bits */ +#define XUARTPS_FORMAT_1_5_STOP_BIT 1U /**< 1.5 stop bits */ +#define XUARTPS_FORMAT_1_STOP_BIT 0U /**< 1 stop bit */ +/*@}*/ + +/** @name Callback events + * + * These constants specify the handler events that an application can handle + * using its specific handler function. Note that these constants are not bit + * mask, so only one event can be passed to an application at a time. + * + * @{ + */ +#define XUARTPS_EVENT_RECV_DATA 1U /**< Data receiving done */ +#define XUARTPS_EVENT_RECV_TOUT 2U /**< A receive timeout occurred */ +#define XUARTPS_EVENT_SENT_DATA 3U /**< Data transmission done */ +#define XUARTPS_EVENT_RECV_ERROR 4U /**< A receive error detected */ +#define XUARTPS_EVENT_MODEM 5U /**< Modem status changed */ +#define XUARTPS_EVENT_PARE_FRAME_BRKE 6U /**< A receive parity, frame, break + * error detected */ +#define XUARTPS_EVENT_RECV_ORERR 7U /**< A receive overrun error detected */ +/*@}*/ + + +/**************************** Type Definitions ******************************/ + +/** + * This typedef contains configuration information for the device. + */ +typedef struct { + u16 DeviceId; /**< Unique ID of device */ + u32 BaseAddress; /**< Base address of device (IPIF) */ + u32 InputClockHz;/**< Input clock frequency */ + s32 ModemPinsConnected; /** Specifies whether modem pins are connected + * to MIO or FMIO */ +} XUartPs_Config; + +/* Keep track of state information about a data buffer in the interrupt mode. */ +typedef struct { + u8 *NextBytePtr; + u32 RequestedBytes; + u32 RemainingBytes; +} XUartPsBuffer; + +/** + * Keep track of data format setting of a device. + */ +typedef struct { + u32 BaudRate; /**< In bps, ie 1200 */ + u32 DataBits; /**< Number of data bits */ + u32 Parity; /**< Parity */ + u8 StopBits; /**< Number of stop bits */ +} XUartPsFormat; + +/******************************************************************************/ +/** + * This data type defines a handler that an application defines to communicate + * with interrupt system to retrieve state information about an application. + * + * @param CallBackRef is a callback reference passed in by the upper layer + * when setting the handler, and is passed back to the upper layer + * when the handler is called. It is used to find the device driver + * instance. + * @param Event contains one of the event constants indicating events that + * have occurred. + * @param EventData contains the number of bytes sent or received at the + * time of the call for send and receive events and contains the + * modem status for modem events. + * + ******************************************************************************/ +typedef void (*XUartPs_Handler) (void *CallBackRef, u32 Event, + u32 EventData); + +/** + * The XUartPs driver instance data structure. A pointer to an instance data + * structure is passed around by functions to refer to a specific driver + * instance. + */ +typedef struct { + XUartPs_Config Config; /* Configuration data structure */ + u32 InputClockHz; /* Input clock frequency */ + u32 IsReady; /* Device is initialized and ready */ + u32 BaudRate; /* Current baud rate */ + + XUartPsBuffer SendBuffer; + XUartPsBuffer ReceiveBuffer; + + XUartPs_Handler Handler; + void *CallBackRef; /* Callback reference for event handler */ + u32 Platform; + u8 is_rxbs_error; +} XUartPs; + + +/***************** Macros (Inline Functions) Definitions ********************/ + +/****************************************************************************/ +/** +* Get the UART Channel Status Register. +* +* @param InstancePtr is a pointer to the XUartPs instance. +* +* @return The value read from the register. +* +* @note C-Style signature: +* u16 XUartPs_GetChannelStatus(XUartPs *InstancePtr) +* +******************************************************************************/ +#define XUartPs_GetChannelStatus(InstancePtr) \ + Xil_In32(((InstancePtr)->Config.BaseAddress) + (u32)XUARTPS_SR_OFFSET) + +/****************************************************************************/ +/** +* Get the UART Mode Control Register. +* +* @param InstancePtr is a pointer to the XUartPs instance. +* +* @return The value read from the register. +* +* @note C-Style signature: +* u32 XUartPs_GetControl(XUartPs *InstancePtr) +* +******************************************************************************/ +#define XUartPs_GetModeControl(InstancePtr) \ + Xil_In32(((InstancePtr)->Config.BaseAddress) + (u32)XUARTPS_CR_OFFSET) + +/****************************************************************************/ +/** +* Set the UART Mode Control Register. +* +* @param InstancePtr is a pointer to the XUartPs instance. +* @param RegisterValue is the value to be written to the register. +* +* @return None. +* +* @note C-Style signature: +* void XUartPs_SetModeControl(XUartPs *InstancePtr, u16 RegisterValue) +* +******************************************************************************/ +#define XUartPs_SetModeControl(InstancePtr, RegisterValue) \ + Xil_Out32(((InstancePtr)->Config.BaseAddress) + (u32)XUARTPS_CR_OFFSET, \ + (u32)(RegisterValue)) + +/****************************************************************************/ +/** +* Enable the transmitter and receiver of the UART. +* +* @param InstancePtr is a pointer to the XUartPs instance. +* +* @return None. +* +* @note C-Style signature: +* void XUartPs_EnableUart(XUartPs *InstancePtr) +* +******************************************************************************/ +#define XUartPs_EnableUart(InstancePtr) \ + Xil_Out32(((InstancePtr)->Config.BaseAddress + (u32)XUARTPS_CR_OFFSET), \ + ((Xil_In32((InstancePtr)->Config.BaseAddress + (u32)XUARTPS_CR_OFFSET) & \ + (u32)(~XUARTPS_CR_EN_DIS_MASK)) | ((u32)XUARTPS_CR_RX_EN | (u32)XUARTPS_CR_TX_EN))) + +/****************************************************************************/ +/** +* Disable the transmitter and receiver of the UART. +* +* @param InstancePtr is a pointer to the XUartPs instance. +* +* @return None. +* +* @note C-Style signature: +* void XUartPs_DisableUart(XUartPs *InstancePtr) +* +******************************************************************************/ +#define XUartPs_DisableUart(InstancePtr) \ + Xil_Out32(((InstancePtr)->Config.BaseAddress + (u32)XUARTPS_CR_OFFSET), \ + (((Xil_In32((InstancePtr)->Config.BaseAddress + (u32)XUARTPS_CR_OFFSET)) & \ + (u32)(~XUARTPS_CR_EN_DIS_MASK)) | ((u32)XUARTPS_CR_RX_DIS | (u32)XUARTPS_CR_TX_DIS))) + +/****************************************************************************/ +/** +* Determine if the transmitter FIFO is empty. +* +* @param InstancePtr is a pointer to the XUartPs instance. +* +* @return +* - TRUE if a byte can be sent +* - FALSE if the Transmitter Fifo is not empty +* +* @note C-Style signature: +* u32 XUartPs_IsTransmitEmpty(XUartPs InstancePtr) +* +******************************************************************************/ +#define XUartPs_IsTransmitEmpty(InstancePtr) \ + ((Xil_In32(((InstancePtr)->Config.BaseAddress) + (u32)XUARTPS_SR_OFFSET) & \ + (u32)XUARTPS_SR_TXEMPTY) == (u32)XUARTPS_SR_TXEMPTY) + + +/************************** Function Prototypes *****************************/ + +/* Static lookup function implemented in xuartps_sinit.c */ +XUartPs_Config *XUartPs_LookupConfig(u16 DeviceId); + +/* Interface functions implemented in xuartps.c */ +s32 XUartPs_CfgInitialize(XUartPs *InstancePtr, + XUartPs_Config * Config, u32 EffectiveAddr); + +u32 XUartPs_Send(XUartPs *InstancePtr,u8 *BufferPtr, + u32 NumBytes); + +u32 XUartPs_Recv(XUartPs *InstancePtr,u8 *BufferPtr, + u32 NumBytes); + +s32 XUartPs_SetBaudRate(XUartPs *InstancePtr, u32 BaudRate); + +/* Options functions in xuartps_options.c */ +void XUartPs_SetOptions(XUartPs *InstancePtr, u16 Options); + +u16 XUartPs_GetOptions(XUartPs *InstancePtr); + +void XUartPs_SetFifoThreshold(XUartPs *InstancePtr, u8 TriggerLevel); + +u8 XUartPs_GetFifoThreshold(XUartPs *InstancePtr); + +u16 XUartPs_GetModemStatus(XUartPs *InstancePtr); + +u32 XUartPs_IsSending(XUartPs *InstancePtr); + +u8 XUartPs_GetOperMode(XUartPs *InstancePtr); + +void XUartPs_SetOperMode(XUartPs *InstancePtr, u8 OperationMode); + +u8 XUartPs_GetFlowDelay(XUartPs *InstancePtr); + +void XUartPs_SetFlowDelay(XUartPs *InstancePtr, u8 FlowDelayValue); + +u8 XUartPs_GetRecvTimeout(XUartPs *InstancePtr); + +void XUartPs_SetRecvTimeout(XUartPs *InstancePtr, u8 RecvTimeout); + +s32 XUartPs_SetDataFormat(XUartPs *InstancePtr, XUartPsFormat * FormatPtr); + +void XUartPs_GetDataFormat(XUartPs *InstancePtr, XUartPsFormat * FormatPtr); + +/* interrupt functions in xuartps_intr.c */ +u32 XUartPs_GetInterruptMask(XUartPs *InstancePtr); + +void XUartPs_SetInterruptMask(XUartPs *InstancePtr, u32 Mask); + +void XUartPs_InterruptHandler(XUartPs *InstancePtr); + +void XUartPs_SetHandler(XUartPs *InstancePtr, XUartPs_Handler FuncPtr, + void *CallBackRef); + +/* self-test functions in xuartps_selftest.c */ +s32 XUartPs_SelfTest(XUartPs *InstancePtr); + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/include/xuartps_hw.h b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xuartps_hw.h new file mode 100644 index 0000000..8c46ecf --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/include/xuartps_hw.h @@ -0,0 +1,447 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2017 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xuartps_hw.h +* @addtogroup uartps_v3_5 +* @{ +* +* This header file contains the hardware interface of an XUartPs device. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date	Changes
+* ----- ------ -------- ----------------------------------------------
+* 1.00	drg/jz 01/12/10 First Release
+* 1.03a sg     09/04/12 Added defines for XUARTPS_IXR_TOVR,  XUARTPS_IXR_TNFUL
+*			and XUARTPS_IXR_TTRIG.
+*			Modified the names of these defines
+*			XUARTPS_MEDEMSR_DCDX to XUARTPS_MODEMSR_DDCD
+*			XUARTPS_MEDEMSR_RIX to XUARTPS_MODEMSR_TERI
+*			XUARTPS_MEDEMSR_DSRX to XUARTPS_MODEMSR_DDSR
+*			XUARTPS_MEDEMSR_CTSX to XUARTPS_MODEMSR_DCTS
+* 1.05a hk     08/22/13 Added prototype for uart reset and related
+*			constant definitions.
+* 3.00  kvn    02/13/15 Modified code for MISRA-C:2012 compliance.
+* 3.1	kvn    04/10/15 Modified code for latest RTL changes.
+* 3.6   ms     02/16/18 Updates flow control mode offset value in
+*			modem control register.
+*
+* 
+* +******************************************************************************/ +#ifndef XUARTPS_HW_H /* prevent circular inclusions */ +#define XUARTPS_HW_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +#include "xil_types.h" +#include "xil_assert.h" +#include "xil_io.h" + +/************************** Constant Definitions *****************************/ + +/** @name Register Map + * + * Register offsets for the UART. + * @{ + */ +#define XUARTPS_CR_OFFSET 0x0000U /**< Control Register [8:0] */ +#define XUARTPS_MR_OFFSET 0x0004U /**< Mode Register [9:0] */ +#define XUARTPS_IER_OFFSET 0x0008U /**< Interrupt Enable [12:0] */ +#define XUARTPS_IDR_OFFSET 0x000CU /**< Interrupt Disable [12:0] */ +#define XUARTPS_IMR_OFFSET 0x0010U /**< Interrupt Mask [12:0] */ +#define XUARTPS_ISR_OFFSET 0x0014U /**< Interrupt Status [12:0]*/ +#define XUARTPS_BAUDGEN_OFFSET 0x0018U /**< Baud Rate Generator [15:0] */ +#define XUARTPS_RXTOUT_OFFSET 0x001CU /**< RX Timeout [7:0] */ +#define XUARTPS_RXWM_OFFSET 0x0020U /**< RX FIFO Trigger Level [5:0] */ +#define XUARTPS_MODEMCR_OFFSET 0x0024U /**< Modem Control [5:0] */ +#define XUARTPS_MODEMSR_OFFSET 0x0028U /**< Modem Status [8:0] */ +#define XUARTPS_SR_OFFSET 0x002CU /**< Channel Status [14:0] */ +#define XUARTPS_FIFO_OFFSET 0x0030U /**< FIFO [7:0] */ +#define XUARTPS_BAUDDIV_OFFSET 0x0034U /**< Baud Rate Divider [7:0] */ +#define XUARTPS_FLOWDEL_OFFSET 0x0038U /**< Flow Delay [5:0] */ +#define XUARTPS_TXWM_OFFSET 0x0044U /**< TX FIFO Trigger Level [5:0] */ +#define XUARTPS_RXBS_OFFSET 0x0048U /**< RX FIFO Byte Status [11:0] */ +/* @} */ + +/** @name Control Register + * + * The Control register (CR) controls the major functions of the device. + * + * Control Register Bit Definition + */ + +#define XUARTPS_CR_STOPBRK 0x00000100U /**< Stop transmission of break */ +#define XUARTPS_CR_STARTBRK 0x00000080U /**< Set break */ +#define XUARTPS_CR_TORST 0x00000040U /**< RX timeout counter restart */ +#define XUARTPS_CR_TX_DIS 0x00000020U /**< TX disabled. */ +#define XUARTPS_CR_TX_EN 0x00000010U /**< TX enabled */ +#define XUARTPS_CR_RX_DIS 0x00000008U /**< RX disabled. */ +#define XUARTPS_CR_RX_EN 0x00000004U /**< RX enabled */ +#define XUARTPS_CR_EN_DIS_MASK 0x0000003CU /**< Enable/disable Mask */ +#define XUARTPS_CR_TXRST 0x00000002U /**< TX logic reset */ +#define XUARTPS_CR_RXRST 0x00000001U /**< RX logic reset */ +/* @}*/ + + +/** @name Mode Register + * + * The mode register (MR) defines the mode of transfer as well as the data + * format. If this register is modified during transmission or reception, + * data validity cannot be guaranteed. + * + * Mode Register Bit Definition + * @{ + */ +#define XUARTPS_MR_CCLK 0x00000400U /**< Input clock selection */ +#define XUARTPS_MR_CHMODE_R_LOOP 0x00000300U /**< Remote loopback mode */ +#define XUARTPS_MR_CHMODE_L_LOOP 0x00000200U /**< Local loopback mode */ +#define XUARTPS_MR_CHMODE_ECHO 0x00000100U /**< Auto echo mode */ +#define XUARTPS_MR_CHMODE_NORM 0x00000000U /**< Normal mode */ +#define XUARTPS_MR_CHMODE_SHIFT 8U /**< Mode shift */ +#define XUARTPS_MR_CHMODE_MASK 0x00000300U /**< Mode mask */ +#define XUARTPS_MR_STOPMODE_2_BIT 0x00000080U /**< 2 stop bits */ +#define XUARTPS_MR_STOPMODE_1_5_BIT 0x00000040U /**< 1.5 stop bits */ +#define XUARTPS_MR_STOPMODE_1_BIT 0x00000000U /**< 1 stop bit */ +#define XUARTPS_MR_STOPMODE_SHIFT 6U /**< Stop bits shift */ +#define XUARTPS_MR_STOPMODE_MASK 0x000000A0U /**< Stop bits mask */ +#define XUARTPS_MR_PARITY_NONE 0x00000020U /**< No parity mode */ +#define XUARTPS_MR_PARITY_MARK 0x00000018U /**< Mark parity mode */ +#define XUARTPS_MR_PARITY_SPACE 0x00000010U /**< Space parity mode */ +#define XUARTPS_MR_PARITY_ODD 0x00000008U /**< Odd parity mode */ +#define XUARTPS_MR_PARITY_EVEN 0x00000000U /**< Even parity mode */ +#define XUARTPS_MR_PARITY_SHIFT 3U /**< Parity setting shift */ +#define XUARTPS_MR_PARITY_MASK 0x00000038U /**< Parity mask */ +#define XUARTPS_MR_CHARLEN_6_BIT 0x00000006U /**< 6 bits data */ +#define XUARTPS_MR_CHARLEN_7_BIT 0x00000004U /**< 7 bits data */ +#define XUARTPS_MR_CHARLEN_8_BIT 0x00000000U /**< 8 bits data */ +#define XUARTPS_MR_CHARLEN_SHIFT 1U /**< Data Length shift */ +#define XUARTPS_MR_CHARLEN_MASK 0x00000006U /**< Data length mask */ +#define XUARTPS_MR_CLKSEL 0x00000001U /**< Input clock selection */ +/* @} */ + + +/** @name Interrupt Registers + * + * Interrupt control logic uses the interrupt enable register (IER) and the + * interrupt disable register (IDR) to set the value of the bits in the + * interrupt mask register (IMR). The IMR determines whether to pass an + * interrupt to the interrupt status register (ISR). + * Writing a 1 to IER Enbables an interrupt, writing a 1 to IDR disables an + * interrupt. IMR and ISR are read only, and IER and IDR are write only. + * Reading either IER or IDR returns 0x00. + * + * All four registers have the same bit definitions. + * + * @{ + */ +#define XUARTPS_IXR_RBRK 0x00002000U /**< Rx FIFO break detect interrupt */ +#define XUARTPS_IXR_TOVR 0x00001000U /**< Tx FIFO Overflow interrupt */ +#define XUARTPS_IXR_TNFUL 0x00000800U /**< Tx FIFO Nearly Full interrupt */ +#define XUARTPS_IXR_TTRIG 0x00000400U /**< Tx Trig interrupt */ +#define XUARTPS_IXR_DMS 0x00000200U /**< Modem status change interrupt */ +#define XUARTPS_IXR_TOUT 0x00000100U /**< Timeout error interrupt */ +#define XUARTPS_IXR_PARITY 0x00000080U /**< Parity error interrupt */ +#define XUARTPS_IXR_FRAMING 0x00000040U /**< Framing error interrupt */ +#define XUARTPS_IXR_OVER 0x00000020U /**< Overrun error interrupt */ +#define XUARTPS_IXR_TXFULL 0x00000010U /**< TX FIFO full interrupt. */ +#define XUARTPS_IXR_TXEMPTY 0x00000008U /**< TX FIFO empty interrupt. */ +#define XUARTPS_IXR_RXFULL 0x00000004U /**< RX FIFO full interrupt. */ +#define XUARTPS_IXR_RXEMPTY 0x00000002U /**< RX FIFO empty interrupt. */ +#define XUARTPS_IXR_RXOVR 0x00000001U /**< RX FIFO trigger interrupt. */ +#define XUARTPS_IXR_MASK 0x00003FFFU /**< Valid bit mask */ +/* @} */ + + +/** @name Baud Rate Generator Register + * + * The baud rate generator control register (BRGR) is a 16 bit register that + * controls the receiver bit sample clock and baud rate. + * Valid values are 1 - 65535. + * + * Bit Sample Rate = CCLK / BRGR, where the CCLK is selected by the MR_CCLK bit + * in the MR register. + * @{ + */ +#define XUARTPS_BAUDGEN_DISABLE 0x00000000U /**< Disable clock */ +#define XUARTPS_BAUDGEN_MASK 0x0000FFFFU /**< Valid bits mask */ +#define XUARTPS_BAUDGEN_RESET_VAL 0x0000028BU /**< Reset value */ + +/** @name Baud Divisor Rate register + * + * The baud rate divider register (BDIV) controls how much the bit sample + * rate is divided by. It sets the baud rate. + * Valid values are 0x04 to 0xFF. Writing a value less than 4 will be ignored. + * + * Baud rate = CCLK / ((BAUDDIV + 1) x BRGR), where the CCLK is selected by + * the MR_CCLK bit in the MR register. + * @{ + */ +#define XUARTPS_BAUDDIV_MASK 0x000000FFU /**< 8 bit baud divider mask */ +#define XUARTPS_BAUDDIV_RESET_VAL 0x0000000FU /**< Reset value */ +/* @} */ + + +/** @name Receiver Timeout Register + * + * Use the receiver timeout register (RTR) to detect an idle condition on + * the receiver data line. + * + * @{ + */ +#define XUARTPS_RXTOUT_DISABLE 0x00000000U /**< Disable time out */ +#define XUARTPS_RXTOUT_MASK 0x000000FFU /**< Valid bits mask */ + +/** @name Receiver FIFO Trigger Level Register + * + * Use the Receiver FIFO Trigger Level Register (RTRIG) to set the value at + * which the RX FIFO triggers an interrupt event. + * @{ + */ + +#define XUARTPS_RXWM_DISABLE 0x00000000U /**< Disable RX trigger interrupt */ +#define XUARTPS_RXWM_MASK 0x0000003FU /**< Valid bits mask */ +#define XUARTPS_RXWM_RESET_VAL 0x00000020U /**< Reset value */ +/* @} */ + +/** @name Transmit FIFO Trigger Level Register + * + * Use the Transmit FIFO Trigger Level Register (TTRIG) to set the value at + * which the TX FIFO triggers an interrupt event. + * @{ + */ + +#define XUARTPS_TXWM_MASK 0x0000003FU /**< Valid bits mask */ +#define XUARTPS_TXWM_RESET_VAL 0x00000020U /**< Reset value */ +/* @} */ + +/** @name Modem Control Register + * + * This register (MODEMCR) controls the interface with the modem or data set, + * or a peripheral device emulating a modem. + * + * @{ + */ +#define XUARTPS_MODEMCR_FCM 0x00000020U /**< Flow control mode */ +#define XUARTPS_MODEMCR_RTS 0x00000002U /**< Request to send */ +#define XUARTPS_MODEMCR_DTR 0x00000001U /**< Data terminal ready */ +/* @} */ + +/** @name Modem Status Register + * + * This register (MODEMSR) indicates the current state of the control lines + * from a modem, or another peripheral device, to the CPU. In addition, four + * bits of the modem status register provide change information. These bits + * are set to a logic 1 whenever a control input from the modem changes state. + * + * Note: Whenever the DCTS, DDSR, TERI, or DDCD bit is set to logic 1, a modem + * status interrupt is generated and this is reflected in the modem status + * register. + * + * @{ + */ +#define XUARTPS_MODEMSR_FCMS 0x00000100U /**< Flow control mode (FCMS) */ +#define XUARTPS_MODEMSR_DCD 0x00000080U /**< Complement of DCD input */ +#define XUARTPS_MODEMSR_RI 0x00000040U /**< Complement of RI input */ +#define XUARTPS_MODEMSR_DSR 0x00000020U /**< Complement of DSR input */ +#define XUARTPS_MODEMSR_CTS 0x00000010U /**< Complement of CTS input */ +#define XUARTPS_MODEMSR_DDCD 0x00000008U /**< Delta DCD indicator */ +#define XUARTPS_MODEMSR_TERI 0x00000004U /**< Trailing Edge Ring Indicator */ +#define XUARTPS_MODEMSR_DDSR 0x00000002U /**< Change of DSR */ +#define XUARTPS_MODEMSR_DCTS 0x00000001U /**< Change of CTS */ +/* @} */ + +/** @name Channel Status Register + * + * The channel status register (CSR) is provided to enable the control logic + * to monitor the status of bits in the channel interrupt status register, + * even if these are masked out by the interrupt mask register. + * + * @{ + */ +#define XUARTPS_SR_TNFUL 0x00004000U /**< TX FIFO Nearly Full Status */ +#define XUARTPS_SR_TTRIG 0x00002000U /**< TX FIFO Trigger Status */ +#define XUARTPS_SR_FLOWDEL 0x00001000U /**< RX FIFO fill over flow delay */ +#define XUARTPS_SR_TACTIVE 0x00000800U /**< TX active */ +#define XUARTPS_SR_RACTIVE 0x00000400U /**< RX active */ +#define XUARTPS_SR_TXFULL 0x00000010U /**< TX FIFO full */ +#define XUARTPS_SR_TXEMPTY 0x00000008U /**< TX FIFO empty */ +#define XUARTPS_SR_RXFULL 0x00000004U /**< RX FIFO full */ +#define XUARTPS_SR_RXEMPTY 0x00000002U /**< RX FIFO empty */ +#define XUARTPS_SR_RXOVR 0x00000001U /**< RX FIFO fill over trigger */ +/* @} */ + +/** @name Flow Delay Register + * + * Operation of the flow delay register (FLOWDEL) is very similar to the + * receive FIFO trigger register. An internal trigger signal activates when the + * FIFO is filled to the level set by this register. This trigger will not + * cause an interrupt, although it can be read through the channel status + * register. In hardware flow control mode, RTS is deactivated when the trigger + * becomes active. RTS only resets when the FIFO level is four less than the + * level of the flow delay trigger and the flow delay trigger is not activated. + * A value less than 4 disables the flow delay. + * @{ + */ +#define XUARTPS_FLOWDEL_MASK XUARTPS_RXWM_MASK /**< Valid bit mask */ +/* @} */ + +/** @name Receiver FIFO Byte Status Register + * + * The Receiver FIFO Status register is used to have a continuous + * monitoring of the raw unmasked byte status information. The register + * contains frame, parity and break status information for the top + * four bytes in the RX FIFO. + * + * Receiver FIFO Byte Status Register Bit Definition + * @{ + */ +#define XUARTPS_RXBS_BYTE3_BRKE 0x00000800U /**< Byte3 Break Error */ +#define XUARTPS_RXBS_BYTE3_FRME 0x00000400U /**< Byte3 Frame Error */ +#define XUARTPS_RXBS_BYTE3_PARE 0x00000200U /**< Byte3 Parity Error */ +#define XUARTPS_RXBS_BYTE2_BRKE 0x00000100U /**< Byte2 Break Error */ +#define XUARTPS_RXBS_BYTE2_FRME 0x00000080U /**< Byte2 Frame Error */ +#define XUARTPS_RXBS_BYTE2_PARE 0x00000040U /**< Byte2 Parity Error */ +#define XUARTPS_RXBS_BYTE1_BRKE 0x00000020U /**< Byte1 Break Error */ +#define XUARTPS_RXBS_BYTE1_FRME 0x00000010U /**< Byte1 Frame Error */ +#define XUARTPS_RXBS_BYTE1_PARE 0x00000008U /**< Byte1 Parity Error */ +#define XUARTPS_RXBS_BYTE0_BRKE 0x00000004U /**< Byte0 Break Error */ +#define XUARTPS_RXBS_BYTE0_FRME 0x00000002U /**< Byte0 Frame Error */ +#define XUARTPS_RXBS_BYTE0_PARE 0x00000001U /**< Byte0 Parity Error */ +#define XUARTPS_RXBS_MASK 0x00000007U /**< 3 bit RX byte status mask */ +/* @} */ + + +/* + * Defines for backwards compatabilty, will be removed + * in the next version of the driver + */ +#define XUARTPS_MEDEMSR_DCDX XUARTPS_MODEMSR_DDCD +#define XUARTPS_MEDEMSR_RIX XUARTPS_MODEMSR_TERI +#define XUARTPS_MEDEMSR_DSRX XUARTPS_MODEMSR_DDSR +#define XUARTPS_MEDEMSR_CTSX XUARTPS_MODEMSR_DCTS + + + +/**************************** Type Definitions *******************************/ + + +/***************** Macros (Inline Functions) Definitions *********************/ + +/****************************************************************************/ +/** +* Read a UART register. +* +* @param BaseAddress contains the base address of the device. +* @param RegOffset contains the offset from the base address of the +* device. +* +* @return The value read from the register. +* +* @note C-Style signature: +* u32 XUartPs_ReadReg(u32 BaseAddress, int RegOffset) +* +******************************************************************************/ +#define XUartPs_ReadReg(BaseAddress, RegOffset) \ + Xil_In32((BaseAddress) + (u32)(RegOffset)) + +/***************************************************************************/ +/** +* Write a UART register. +* +* @param BaseAddress contains the base address of the device. +* @param RegOffset contains the offset from the base address of the +* device. +* @param RegisterValue is the value to be written to the register. +* +* @return None. +* +* @note C-Style signature: +* void XUartPs_WriteReg(u32 BaseAddress, int RegOffset, +* u16 RegisterValue) +* +******************************************************************************/ +#define XUartPs_WriteReg(BaseAddress, RegOffset, RegisterValue) \ + Xil_Out32((BaseAddress) + (u32)(RegOffset), (u32)(RegisterValue)) + +/****************************************************************************/ +/** +* Determine if there is receive data in the receiver and/or FIFO. +* +* @param BaseAddress contains the base address of the device. +* +* @return TRUE if there is receive data, FALSE otherwise. +* +* @note C-Style signature: +* u32 XUartPs_IsReceiveData(u32 BaseAddress) +* +******************************************************************************/ +#define XUartPs_IsReceiveData(BaseAddress) \ + !((Xil_In32((BaseAddress) + XUARTPS_SR_OFFSET) & \ + (u32)XUARTPS_SR_RXEMPTY) == (u32)XUARTPS_SR_RXEMPTY) + +/****************************************************************************/ +/** +* Determine if a byte of data can be sent with the transmitter. +* +* @param BaseAddress contains the base address of the device. +* +* @return TRUE if the TX FIFO is full, FALSE if a byte can be put in the +* FIFO. +* +* @note C-Style signature: +* u32 XUartPs_IsTransmitFull(u32 BaseAddress) +* +******************************************************************************/ +#define XUartPs_IsTransmitFull(BaseAddress) \ + ((Xil_In32((BaseAddress) + XUARTPS_SR_OFFSET) & \ + (u32)XUARTPS_SR_TXFULL) == (u32)XUARTPS_SR_TXFULL) + +/************************** Function Prototypes ******************************/ + +void XUartPs_SendByte(u32 BaseAddress, u8 Data); + +u8 XUartPs_RecvByte(u32 BaseAddress); + +void XUartPs_ResetHw(u32 BaseAddress); + +/************************** Variable Definitions *****************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/Makefile b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/Makefile new file mode 100644 index 0000000..dce15aa --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/Makefile @@ -0,0 +1,28 @@ +COMPILER= +ARCHIVER= +CP=cp +COMPILER_FLAGS= +EXTRA_COMPILER_FLAGS= +LIB=libxil.a + +RELEASEDIR=../../../lib +INCLUDEDIR=../../../include +INCLUDES=-I./. -I${INCLUDEDIR} + +INCLUDEFILES=*.h + +LIBSOURCES=*.c +OUTS = *.o +OBJECTS = $(addsuffix .o, $(basename $(wildcard *.c))) + +libs: + echo "Compiling bram" + $(COMPILER) $(COMPILER_FLAGS) $(EXTRA_COMPILER_FLAGS) $(INCLUDES) $(LIBSOURCES) + $(ARCHIVER) -r ${RELEASEDIR}/${LIB} $(OBJECTS) + make clean + +include: + ${CP} ${INCLUDEFILES} ${INCLUDEDIR} + +clean: + rm -rf ${OBJECTS} diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram.c new file mode 100644 index 0000000..0976b82 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram.c @@ -0,0 +1,145 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ + +/** +* @file xbram.c +* @addtogroup bram_v4_2 +* @{ +* +* The implementation of the XBram driver's basic functionality. +* See xbram.h for more information about the driver. +* +* @note +* +* None +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a sa   05/11/10 First release
+* 3.01a sa   13/01/12 Added CorrectableFailingDataRegs and
+*                     UncorrectableFailingDataRegs in
+*					  XBram_CfgInitialize API.
+* 4.1   sk   11/10/15 Used UINTPTR instead of u32 for Baseaddress CR# 867425.
+*                     Changed the prototype of XBram_CfgInitialize API.
+*
+* +*****************************************************************************/ + +/***************************** Include Files ********************************/ + +#include "xbram.h" +#include "xstatus.h" + +/************************** Constant Definitions ****************************/ + +/**************************** Type Definitions ******************************/ + +/***************** Macros (Inline Functions) Definitions ********************/ + +/************************** Variable Definitions ****************************/ + + +/************************** Function Prototypes *****************************/ + + +/****************************************************************************/ +/** +* Initialize the XBram instance provided by the caller based on the given +* configuration data. +* +* Nothing is done except to initialize the InstancePtr. +* +* @param InstancePtr is a pointer to an XBram instance. +* The memory the pointer references must be pre-allocated by +* the caller. Further calls to manipulate the driver through +* the XBram API must be made with this pointer. +* @param Config is a reference to a structure containing information +* about a specific BRAM device. This function +* initializes an InstancePtr object for a specific device +* specified by the contents of Config. This function can +* initialize multiple instance objects with the use of multiple +* calls giving different Config information on each call. +* @param EffectiveAddr is the device base address in the virtual memory +* address space. The caller is responsible for keeping the +* address mapping from EffectiveAddr to the device physical base +* address unchanged once this function is invoked. Unexpected +* errors may occur if the address mapping changes after this +* function is called. If address translation is not used, use +* Config->BaseAddress for this parameters, passing the physical +* address instead. +* +* @return +* - XST_SUCCESS Initialization was successful. +* +* @note None. +* +*****************************************************************************/ +int XBram_CfgInitialize(XBram *InstancePtr, + XBram_Config *Config, + UINTPTR EffectiveAddr) +{ + /* + * Assert arguments + */ + Xil_AssertNonvoid(InstancePtr != NULL); + + /* + * Set some default values. + */ + InstancePtr->Config.CtrlBaseAddress = EffectiveAddr; + InstancePtr->Config.MemBaseAddress = Config->MemBaseAddress; + InstancePtr->Config.MemHighAddress = Config->MemHighAddress; + InstancePtr->Config.DataWidth = Config->DataWidth; + InstancePtr->Config.EccPresent = Config->EccPresent; + InstancePtr->Config.FaultInjectionPresent = + Config->FaultInjectionPresent; + InstancePtr->Config.CorrectableFailingRegisters = + Config->CorrectableFailingRegisters; + InstancePtr->Config.CorrectableFailingDataRegs = + Config->CorrectableFailingDataRegs; + InstancePtr->Config.UncorrectableFailingRegisters = + Config->UncorrectableFailingRegisters; + InstancePtr->Config.UncorrectableFailingDataRegs = + Config->UncorrectableFailingDataRegs; + InstancePtr->Config.EccStatusInterruptPresent = + Config->EccStatusInterruptPresent; + InstancePtr->Config.CorrectableCounterBits = + Config->CorrectableCounterBits; + InstancePtr->Config.WriteAccess = Config->WriteAccess; + + /* + * Indicate the instance is now ready to use, initialized without error + */ + InstancePtr->IsReady = XIL_COMPONENT_IS_READY; + return (XST_SUCCESS); +} + +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram.h new file mode 100644 index 0000000..246df6d --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram.h @@ -0,0 +1,223 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2019 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* @file xbram.h +* @addtogroup bram_v4_2 +* @{ +* @details +* +* If ECC is not enabled, this driver exists only to allow the tools to +* create a memory test application and to populate xparameters.h with memory +* range constants. In this case there is no source code. +* +* If ECC is enabled, this file contains the software API definition of the +* Xilinx BRAM Interface Controller (XBram) device driver. +* +* The Xilinx BRAM controller is a soft IP core designed for Xilinx +* FPGAs and contains the following general features: +* - LMB v2.0 bus interfaces with byte enable support +* - Used in conjunction with bram_block peripheral to provide fast BRAM +* memory solution for MicroBlaze ILMB and DLMB ports +* - Supports byte, half-word, and word transfers +* - Supports optional BRAM error correction and detection. +* +* The driver provides interrupt management functions. Implementation of +* interrupt handlers is left to the user. Refer to the provided interrupt +* example in the examples directory for details. +* +* This driver is intended to be RTOS and processor independent. Any needs for +* dynamic memory management, threads or thread mutual exclusion, virtual +* memory, or cache control must be satisfied by the layer above this driver. +* +* Initialization & Configuration +* +* The XBram_Config structure is used by the driver to configure +* itself. This configuration structure is typically created by the tool-chain +* based on HW build properties. +* +* To support multiple runtime loading and initialization strategies employed +* by various operating systems, the driver instance can be initialized as +* follows: +* +* - XBram_CfgInitialize(InstancePtr, CfgPtr, EffectiveAddr) - +* Uses a configuration structure provided by the caller. If running in a +* system with address translation, the provided virtual memory base address +* replaces the physical address present in the configuration structure. +* +* @note +* +* This API utilizes 32 bit I/O to the BRAM registers. With less +* than 32 bits, the unused bits from registers are read as zero and written as +* don't cares. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 3.00a sa  05/11/10 Added ECC support
+* 3.01a sa  01/13/12  Changed Selftest API from
+*		      XBram_SelfTest(XBram *InstancePtr) to
+*		      XBram_SelfTest(XBram *InstancePtr, u8 IntMask) and
+*		      fixed a problem with interrupt generation for CR 639274
+*		      Modified Selftest example to return XST_SUCCESS when
+*		      ECC is not enabled and return XST_FAILURE when ECC is
+*		      enabled and Control Base Address is zero (CR 636581)
+*		      Modified Selftest to use correct CorrectableCounterBits
+*		      for CR 635655
+*		      Updated to check CorrectableFailingDataRegs in the case
+*		      of LMB BRAM.
+* 		      Added CorrectableFailingDataRegs and
+*		      UncorrectableFailingDataRegs to the config structure to
+*		      distinguish between AXI BRAM and LMB BRAM.
+*		      These registers are not present in the current version of
+*		      the AXI BRAM Controller.
+* 3.02a sa 04/16/12   Added test of byte and halfword read-modify-write
+* 3.02a sa 04/16/12   Modified driver tcl to sort the address parameters
+*  	       	      to support both xps and vivado designs.
+* 3.02a adk 24/4/13   Modified the tcl file to avoid warnings
+*	       	      when ecc is disabled cr:705002.
+* 3.03a bss 05/22/13  Added Xil_DCacheFlushRange in xbram_selftest.c to
+*		      flush the Cache after writing to BRAM in InjectErrors
+*		      API(CR #719011)
+* 4.0   adk  19/12/13 Updated as per the New Tcl API's
+* 4.1   sk   11/10/15 Used UINTPTR instead of u32 for Baseaddress CR# 867425.
+*                     Changed the prototype of XBram_CfgInitialize API.
+*       ms  01/23/17 Modified xil_printf statement in main function for all
+*                    examples to ensure that "Successfully ran" and "Failed"
+*                    strings are available in all examples. This is a fix
+*                    for CR-965028.
+*       ms  03/17/17 Added readme.txt file in examples folder for doxygen
+*                    generation.
+* 4.2   ms  04/18/17 Modified tcl file to add suffix U for all macro
+*                    definitions of bram in xparameters.h
+*       ms  08/07/17 Fixed compilation warnings in xbram_sinit.c
+* 4.3   aru 03/23/19 Used UINTPTR instead of u32 for MemBaseAddress and
+*                    MemHighAddress.
+* 
+*****************************************************************************/ +#ifndef XBRAM_H /* prevent circular inclusions */ +#define XBRAM_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files ********************************/ + +#include "xil_types.h" +#include "xil_assert.h" +#include "xstatus.h" +#include "xbram_hw.h" + +/************************** Constant Definitions ****************************/ + + +/**************************** Type Definitions ******************************/ + +/** + * This typedef contains configuration information for the device. + */ +typedef struct { + u16 DeviceId; /**< Unique ID of device */ + u32 DataWidth; /**< BRAM data width */ + int EccPresent; /**< Is ECC supported in H/W */ + int FaultInjectionPresent; /**< Is Fault Injection + * supported in H/W */ + int CorrectableFailingRegisters; /**< Is Correctable Failing Registers + * supported in H/W */ + int CorrectableFailingDataRegs; /**< Is Correctable Failing Data + * Registers supported in H/W */ + int UncorrectableFailingRegisters; /**< Is Un-correctable Failing + * Registers supported in H/W */ + int UncorrectableFailingDataRegs; /**< Is Un-correctable Failing Data + * Registers supported in H/W */ + int EccStatusInterruptPresent; /**< Are ECC status and interrupts + * supported in H/W */ + int CorrectableCounterBits; /**< Number of bits in the + * Correctable Error Counter */ + int EccOnOffRegister; /**< Is ECC on/off register supported + * in h/w */ + int EccOnOffResetValue; /**< Reset value of the ECC on/off + * register in h/w */ + int WriteAccess; /**< Is write access enabled in + * h/w */ + UINTPTR MemBaseAddress; /**< Device memory base address */ + UINTPTR MemHighAddress; /**< Device memory high address */ + UINTPTR CtrlBaseAddress; /**< Device register base address.*/ + UINTPTR CtrlHighAddress; /**< Device register base address.*/ +} XBram_Config; + +/** + * The XBram driver instance data. The user is required to + * allocate a variable of this type for every BRAM device in the + * system. A pointer to a variable of this type is then passed to the driver + * API functions. + */ +typedef struct { + XBram_Config Config; /* BRAM config structure */ + u32 IsReady; /* Device is initialized and ready */ +} XBram; + +/***************** Macros (Inline Functions) Definitions ********************/ + + +/************************** Function Prototypes *****************************/ + +/* + * Functions in xbram_sinit.c + */ +XBram_Config *XBram_LookupConfig(u16 DeviceId); + +/* + * Functions implemented in xbram.c + */ +int XBram_CfgInitialize(XBram *InstancePtr, XBram_Config *Config, + UINTPTR EffectiveAddr); + +/* + * Functions implemented in xbram_selftest.c + */ +int XBram_SelfTest(XBram *InstancePtr, u8 IntMask); + +/* + * Functions implemented in xbram_intr.c + */ +void XBram_InterruptEnable(XBram *InstancePtr, u32 Mask); +void XBram_InterruptDisable(XBram *InstancePtr, u32 Mask); +void XBram_InterruptClear(XBram *InstancePtr, u32 Mask); +u32 XBram_InterruptGetEnabled(XBram *InstancePtr); +u32 XBram_InterruptGetStatus(XBram *InstancePtr); + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram_g.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram_g.c new file mode 100644 index 0000000..df2bd77 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram_g.c @@ -0,0 +1,104 @@ + +/******************************************************************* +* +* CAUTION: This file is automatically generated by HSI. +* Version: 2019.1.3 +* DO NOT EDIT. +* +* Copyright (C) 2010-2023 Xilinx, Inc. All Rights Reserved.* +*Permission is hereby granted, free of charge, to any person obtaining a copy +*of this software and associated documentation files (the Software), to deal +*in the Software without restriction, including without limitation the rights +*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +*copies of the Software, and to permit persons to whom the Software is +*furnished to do so, subject to the following conditions: +* +*The above copyright notice and this permission notice shall be included in +*all copies or substantial portions of the Software. +* +*THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +*XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +*OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*Except as contained in this notice, the name of the Xilinx shall not be used +*in advertising or otherwise to promote the sale, use or other dealings in +*this Software without prior written authorization from Xilinx. +* + +* +* Description: Driver configuration +* +*******************************************************************/ + +#include "xparameters.h" +#include "xbram.h" + +/* +* The configuration table for devices +*/ + +XBram_Config XBram_ConfigTable[] = +{ + { + XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_AXI_BRAM_CTRL_DEVICE_ID, + XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_AXI_BRAM_CTRL_DATA_WIDTH, + XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_AXI_BRAM_CTRL_ECC, + XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_AXI_BRAM_CTRL_FAULT_INJECT, + XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_AXI_BRAM_CTRL_CE_FAILING_REGISTERS, + 0, + XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_AXI_BRAM_CTRL_UE_FAILING_REGISTERS, + 0, + XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_AXI_BRAM_CTRL_ECC_STATUS_REGISTERS, + XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_AXI_BRAM_CTRL_CE_COUNTER_WIDTH, + XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_AXI_BRAM_CTRL_ECC_ONOFF_REGISTER, + XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_AXI_BRAM_CTRL_ECC_ONOFF_RESET_VALUE, + XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_AXI_BRAM_CTRL_WRITE_ACCESS, + XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_AXI_BRAM_CTRL_S_AXI_BASEADDR, + XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_AXI_BRAM_CTRL_S_AXI_HIGHADDR, + XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_AXI_BRAM_CTRL_S_AXI_CTRL_BASEADDR, + XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_AXI_BRAM_CTRL_S_AXI_CTRL_HIGHADDR + }, + { + XPAR_PHY_DATA_INTERFACE_PHY_RX_BUFF_AXI_BRAM_CTRL_DEVICE_ID, + XPAR_PHY_DATA_INTERFACE_PHY_RX_BUFF_AXI_BRAM_CTRL_DATA_WIDTH, + XPAR_PHY_DATA_INTERFACE_PHY_RX_BUFF_AXI_BRAM_CTRL_ECC, + XPAR_PHY_DATA_INTERFACE_PHY_RX_BUFF_AXI_BRAM_CTRL_FAULT_INJECT, + XPAR_PHY_DATA_INTERFACE_PHY_RX_BUFF_AXI_BRAM_CTRL_CE_FAILING_REGISTERS, + 0, + XPAR_PHY_DATA_INTERFACE_PHY_RX_BUFF_AXI_BRAM_CTRL_UE_FAILING_REGISTERS, + 0, + XPAR_PHY_DATA_INTERFACE_PHY_RX_BUFF_AXI_BRAM_CTRL_ECC_STATUS_REGISTERS, + XPAR_PHY_DATA_INTERFACE_PHY_RX_BUFF_AXI_BRAM_CTRL_CE_COUNTER_WIDTH, + XPAR_PHY_DATA_INTERFACE_PHY_RX_BUFF_AXI_BRAM_CTRL_ECC_ONOFF_REGISTER, + XPAR_PHY_DATA_INTERFACE_PHY_RX_BUFF_AXI_BRAM_CTRL_ECC_ONOFF_RESET_VALUE, + XPAR_PHY_DATA_INTERFACE_PHY_RX_BUFF_AXI_BRAM_CTRL_WRITE_ACCESS, + XPAR_PHY_DATA_INTERFACE_PHY_RX_BUFF_AXI_BRAM_CTRL_S_AXI_BASEADDR, + XPAR_PHY_DATA_INTERFACE_PHY_RX_BUFF_AXI_BRAM_CTRL_S_AXI_HIGHADDR, + XPAR_PHY_DATA_INTERFACE_PHY_RX_BUFF_AXI_BRAM_CTRL_S_AXI_CTRL_BASEADDR, + XPAR_PHY_DATA_INTERFACE_PHY_RX_BUFF_AXI_BRAM_CTRL_S_AXI_CTRL_HIGHADDR + }, + { + XPAR_PHY_DATA_INTERFACE_PHY_TX_BUFF_AXI_BRAM_CTRL_DEVICE_ID, + XPAR_PHY_DATA_INTERFACE_PHY_TX_BUFF_AXI_BRAM_CTRL_DATA_WIDTH, + XPAR_PHY_DATA_INTERFACE_PHY_TX_BUFF_AXI_BRAM_CTRL_ECC, + XPAR_PHY_DATA_INTERFACE_PHY_TX_BUFF_AXI_BRAM_CTRL_FAULT_INJECT, + XPAR_PHY_DATA_INTERFACE_PHY_TX_BUFF_AXI_BRAM_CTRL_CE_FAILING_REGISTERS, + 0, + XPAR_PHY_DATA_INTERFACE_PHY_TX_BUFF_AXI_BRAM_CTRL_UE_FAILING_REGISTERS, + 0, + XPAR_PHY_DATA_INTERFACE_PHY_TX_BUFF_AXI_BRAM_CTRL_ECC_STATUS_REGISTERS, + XPAR_PHY_DATA_INTERFACE_PHY_TX_BUFF_AXI_BRAM_CTRL_CE_COUNTER_WIDTH, + XPAR_PHY_DATA_INTERFACE_PHY_TX_BUFF_AXI_BRAM_CTRL_ECC_ONOFF_REGISTER, + XPAR_PHY_DATA_INTERFACE_PHY_TX_BUFF_AXI_BRAM_CTRL_ECC_ONOFF_RESET_VALUE, + XPAR_PHY_DATA_INTERFACE_PHY_TX_BUFF_AXI_BRAM_CTRL_WRITE_ACCESS, + XPAR_PHY_DATA_INTERFACE_PHY_TX_BUFF_AXI_BRAM_CTRL_S_AXI_BASEADDR, + XPAR_PHY_DATA_INTERFACE_PHY_TX_BUFF_AXI_BRAM_CTRL_S_AXI_HIGHADDR, + XPAR_PHY_DATA_INTERFACE_PHY_TX_BUFF_AXI_BRAM_CTRL_S_AXI_CTRL_BASEADDR, + XPAR_PHY_DATA_INTERFACE_PHY_TX_BUFF_AXI_BRAM_CTRL_S_AXI_CTRL_HIGHADDR + } +}; + + diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram_hw.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram_hw.h new file mode 100644 index 0000000..55a2505 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram_hw.h @@ -0,0 +1,405 @@ +/****************************************************************************** +* +* Copyright (C) 2011 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xbram_hw.h +* @addtogroup bram_v4_2 +* @{ +* +* This header file contains identifiers and driver functions (or +* macros) that can be used to access the device. The user should refer to the +* hardware device specification for more details of the device operation. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a sa   24/11/10 First release
+* 
+* +******************************************************************************/ +#ifndef XBRAM_HW_H /* prevent circular inclusions */ +#define XBRAM_HW_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +#include "xil_types.h" +#include "xil_assert.h" +#include "xil_io.h" + +/************************** Constant Definitions *****************************/ + +/** @name Registers + * + * Register offsets for this device. + * @{ + */ + +#define XBRAM_ECC_STATUS_OFFSET 0x0 /**< ECC status Register */ +#define XBRAM_ECC_EN_IRQ_OFFSET 0x4 /**< ECC interrupt enable Register */ +#define XBRAM_ECC_ON_OFF_OFFSET 0x8 /**< ECC on/off register */ +#define XBRAM_CE_CNT_OFFSET 0xC /**< Correctable error counter Register */ + +#define XBRAM_CE_FFD_0_OFFSET 0x100 /**< Correctable error first failing + * data Register, 31-0 */ +#define XBRAM_CE_FFD_1_OFFSET 0x104 /**< Correctable error first failing + * data Register, 63-32 */ +#define XBRAM_CE_FFD_2_OFFSET 0x108 /**< Correctable error first failing + * data Register, 95-64 */ +#define XBRAM_CE_FFD_3_OFFSET 0x10C /**< Correctable error first failing + * data Register, 127-96 */ +#define XBRAM_CE_FFD_4_OFFSET 0x110 /**< Correctable error first failing + * data Register, 159-128 */ +#define XBRAM_CE_FFD_5_OFFSET 0x114 /**< Correctable error first failing + * data Register, 191-160 */ +#define XBRAM_CE_FFD_6_OFFSET 0x118 /**< Correctable error first failing + * data Register, 223-192 */ +#define XBRAM_CE_FFD_7_OFFSET 0x11C /**< Correctable error first failing + * data Register, 255-224 */ +#define XBRAM_CE_FFD_8_OFFSET 0x120 /**< Correctable error first failing + * data Register, 287-256 */ +#define XBRAM_CE_FFD_9_OFFSET 0x124 /**< Correctable error first failing + * data Register, 319-288 */ +#define XBRAM_CE_FFD_10_OFFSET 0x128 /**< Correctable error first failing + * data Register, 351-320 */ +#define XBRAM_CE_FFD_11_OFFSET 0x12C /**< Correctable error first failing + * data Register, 383-352 */ +#define XBRAM_CE_FFD_12_OFFSET 0x130 /**< Correctable error first failing + * data Register, 415-384 */ +#define XBRAM_CE_FFD_13_OFFSET 0x134 /**< Correctable error first failing + * data Register, 447-416 */ +#define XBRAM_CE_FFD_14_OFFSET 0x138 /**< Correctable error first failing + * data Register, 479-448 */ +#define XBRAM_CE_FFD_15_OFFSET 0x13C /**< Correctable error first failing + * data Register, 511-480 */ +#define XBRAM_CE_FFD_16_OFFSET 0x140 /**< Correctable error first failing + * data Register, 543-512 */ +#define XBRAM_CE_FFD_17_OFFSET 0x144 /**< Correctable error first failing + * data Register, 575-544 */ +#define XBRAM_CE_FFD_18_OFFSET 0x148 /**< Correctable error first failing + * data Register, 607-576 */ +#define XBRAM_CE_FFD_19_OFFSET 0x14C /**< Correctable error first failing + * data Register, 639-608 */ +#define XBRAM_CE_FFD_20_OFFSET 0x150 /**< Correctable error first failing + * data Register, 671-640 */ +#define XBRAM_CE_FFD_21_OFFSET 0x154 /**< Correctable error first failing + * data Register, 703-672 */ +#define XBRAM_CE_FFD_22_OFFSET 0x158 /**< Correctable error first failing + * data Register, 735-704 */ +#define XBRAM_CE_FFD_23_OFFSET 0x15C /**< Correctable error first failing + * data Register, 767-736 */ +#define XBRAM_CE_FFD_24_OFFSET 0x160 /**< Correctable error first failing + * data Register, 799-768 */ +#define XBRAM_CE_FFD_25_OFFSET 0x164 /**< Correctable error first failing + * data Register, 831-800 */ +#define XBRAM_CE_FFD_26_OFFSET 0x168 /**< Correctable error first failing + * data Register, 863-832 */ +#define XBRAM_CE_FFD_27_OFFSET 0x16C /**< Correctable error first failing + * data Register, 895-864 */ +#define XBRAM_CE_FFD_28_OFFSET 0x170 /**< Correctable error first failing + * data Register, 927-896 */ +#define XBRAM_CE_FFD_29_OFFSET 0x174 /**< Correctable error first failing + * data Register, 959-928 */ +#define XBRAM_CE_FFD_30_OFFSET 0x178 /**< Correctable error first failing + * data Register, 991-960 */ +#define XBRAM_CE_FFD_31_OFFSET 0x17C /**< Correctable error first failing + * data Register, 1023-992 */ + +#define XBRAM_CE_FFE_0_OFFSET 0x180 /**< Correctable error first failing + * ECC Register, 31-0 */ +#define XBRAM_CE_FFE_1_OFFSET 0x184 /**< Correctable error first failing + * ECC Register, 63-32 */ +#define XBRAM_CE_FFE_2_OFFSET 0x188 /**< Correctable error first failing + * ECC Register, 95-64 */ +#define XBRAM_CE_FFE_3_OFFSET 0x18C /**< Correctable error first failing + * ECC Register, 127-96 */ +#define XBRAM_CE_FFE_4_OFFSET 0x190 /**< Correctable error first failing + * ECC Register, 159-128 */ +#define XBRAM_CE_FFE_5_OFFSET 0x194 /**< Correctable error first failing + * ECC Register, 191-160 */ +#define XBRAM_CE_FFE_6_OFFSET 0x198 /**< Correctable error first failing + * ECC Register, 223-192 */ +#define XBRAM_CE_FFE_7_OFFSET 0x19C /**< Correctable error first failing + * ECC Register, 255-224 */ + +#define XBRAM_CE_FFA_0_OFFSET 0x1C0 /**< Correctable error first failing + * address Register 31-0 */ +#define XBRAM_CE_FFA_1_OFFSET 0x1C4 /**< Correctable error first failing + * address Register 63-32 */ + +#define XBRAM_UE_FFD_0_OFFSET 0x200 /**< Uncorrectable error first failing + * data Register, 31-0 */ +#define XBRAM_UE_FFD_1_OFFSET 0x204 /**< Uncorrectable error first failing + * data Register, 63-32 */ +#define XBRAM_UE_FFD_2_OFFSET 0x208 /**< Uncorrectable error first failing + * data Register, 95-64 */ +#define XBRAM_UE_FFD_3_OFFSET 0x20C /**< Uncorrectable error first failing + * data Register, 127-96 */ +#define XBRAM_UE_FFD_4_OFFSET 0x210 /**< Uncorrectable error first failing + * data Register, 159-128 */ +#define XBRAM_UE_FFD_5_OFFSET 0x214 /**< Uncorrectable error first failing + * data Register, 191-160 */ +#define XBRAM_UE_FFD_6_OFFSET 0x218 /**< Uncorrectable error first failing + * data Register, 223-192 */ +#define XBRAM_UE_FFD_7_OFFSET 0x21C /**< Uncorrectable error first failing + * data Register, 255-224 */ +#define XBRAM_UE_FFD_8_OFFSET 0x220 /**< Uncorrectable error first failing + * data Register, 287-256 */ +#define XBRAM_UE_FFD_9_OFFSET 0x224 /**< Uncorrectable error first failing + * data Register, 319-288 */ +#define XBRAM_UE_FFD_10_OFFSET 0x228 /**< Uncorrectable error first failing + * data Register, 351-320 */ +#define XBRAM_UE_FFD_11_OFFSET 0x22C /**< Uncorrectable error first failing + * data Register, 383-352 */ +#define XBRAM_UE_FFD_12_OFFSET 0x230 /**< Uncorrectable error first failing + * data Register, 415-384 */ +#define XBRAM_UE_FFD_13_OFFSET 0x234 /**< Uncorrectable error first failing + * data Register, 447-416 */ +#define XBRAM_UE_FFD_14_OFFSET 0x238 /**< Uncorrectable error first failing + * data Register, 479-448 */ +#define XBRAM_UE_FFD_15_OFFSET 0x23C /**< Uncorrectable error first failing + * data Register, 511-480 */ +#define XBRAM_UE_FFD_16_OFFSET 0x240 /**< Uncorrectable error first failing + * data Register, 543-512 */ +#define XBRAM_UE_FFD_17_OFFSET 0x244 /**< Uncorrectable error first failing + * data Register, 575-544 */ +#define XBRAM_UE_FFD_18_OFFSET 0x248 /**< Uncorrectable error first failing + * data Register, 607-576 */ +#define XBRAM_UE_FFD_19_OFFSET 0x24C /**< Uncorrectable error first failing + * data Register, 639-608 */ +#define XBRAM_UE_FFD_20_OFFSET 0x250 /**< Uncorrectable error first failing + * data Register, 671-640 */ +#define XBRAM_UE_FFD_21_OFFSET 0x254 /**< Uncorrectable error first failing + * data Register, 703-672 */ +#define XBRAM_UE_FFD_22_OFFSET 0x258 /**< Uncorrectable error first failing + * data Register, 735-704 */ +#define XBRAM_UE_FFD_23_OFFSET 0x25C /**< Uncorrectable error first failing + * data Register, 767-736 */ +#define XBRAM_UE_FFD_24_OFFSET 0x260 /**< Uncorrectable error first failing + * data Register, 799-768 */ +#define XBRAM_UE_FFD_25_OFFSET 0x264 /**< Uncorrectable error first failing + * data Register, 831-800 */ +#define XBRAM_UE_FFD_26_OFFSET 0x268 /**< Uncorrectable error first failing + * data Register, 863-832 */ +#define XBRAM_UE_FFD_27_OFFSET 0x26C /**< Uncorrectable error first failing + * data Register, 895-864 */ +#define XBRAM_UE_FFD_28_OFFSET 0x270 /**< Uncorrectable error first failing + * data Register, 927-896 */ +#define XBRAM_UE_FFD_29_OFFSET 0x274 /**< Uncorrectable error first failing + * data Register, 959-928 */ +#define XBRAM_UE_FFD_30_OFFSET 0x278 /**< Uncorrectable error first failing + * data Register, 991-960 */ +#define XBRAM_UE_FFD_31_OFFSET 0x27C /**< Uncorrectable error first failing + * data Register, 1023-992 */ + +#define XBRAM_UE_FFE_0_OFFSET 0x280 /**< Uncorrectable error first failing + * ECC Register, 31-0 */ +#define XBRAM_UE_FFE_1_OFFSET 0x284 /**< Uncorrectable error first failing + * ECC Register, 63-32 */ +#define XBRAM_UE_FFE_2_OFFSET 0x288 /**< Uncorrectable error first failing + * ECC Register, 95-64 */ +#define XBRAM_UE_FFE_3_OFFSET 0x28C /**< Uncorrectable error first failing + * ECC Register, 127-96 */ +#define XBRAM_UE_FFE_4_OFFSET 0x290 /**< Uncorrectable error first failing + * ECC Register, 159-128 */ +#define XBRAM_UE_FFE_5_OFFSET 0x294 /**< Uncorrectable error first failing + * ECC Register, 191-160 */ +#define XBRAM_UE_FFE_6_OFFSET 0x298 /**< Uncorrectable error first failing + * ECC Register, 223-192 */ +#define XBRAM_UE_FFE_7_OFFSET 0x29C /**< Uncorrectable error first failing + * ECC Register, 255-224 */ + +#define XBRAM_UE_FFA_0_OFFSET 0x2C0 /**< Uncorrectable error first failing + * address Register 31-0 */ +#define XBRAM_UE_FFA_1_OFFSET 0x2C4 /**< Uncorrectable error first failing + * address Register 63-32 */ + +#define XBRAM_FI_D_0_OFFSET 0x300 /**< Fault injection Data Register, + * 31-0 */ +#define XBRAM_FI_D_1_OFFSET 0x304 /**< Fault injection Data Register, + * 63-32 */ +#define XBRAM_FI_D_2_OFFSET 0x308 /**< Fault injection Data Register, + * 95-64 */ +#define XBRAM_FI_D_3_OFFSET 0x30C /**< Fault injection Data Register, + * 127-96 */ +#define XBRAM_FI_D_4_OFFSET 0x310 /**< Fault injection Data Register, + * 159-128 */ +#define XBRAM_FI_D_5_OFFSET 0x314 /**< Fault injection Data Register, + * 191-160 */ +#define XBRAM_FI_D_6_OFFSET 0x318 /**< Fault injection Data Register, + * 223-192 */ +#define XBRAM_FI_D_7_OFFSET 0x31C /**< Fault injection Data Register, + * 255-224 */ +#define XBRAM_FI_D_8_OFFSET 0x320 /**< Fault injection Data Register, + * 287-256 */ +#define XBRAM_FI_D_9_OFFSET 0x324 /**< Fault injection Data Register, + * 319-288 */ +#define XBRAM_FI_D_10_OFFSET 0x328 /**< Fault injection Data Register, + * 351-320 */ +#define XBRAM_FI_D_11_OFFSET 0x32C /**< Fault injection Data Register, + * 383-352 */ +#define XBRAM_FI_D_12_OFFSET 0x330 /**< Fault injection Data Register, + * 415-384 */ +#define XBRAM_FI_D_13_OFFSET 0x334 /**< Fault injection Data Register, + * 447-416 */ +#define XBRAM_FI_D_14_OFFSET 0x338 /**< Fault injection Data Register, + * 479-448 */ +#define XBRAM_FI_D_15_OFFSET 0x33C /**< Fault injection Data Register, + * 511-480 */ +#define XBRAM_FI_D_16_OFFSET 0x340 /**< Fault injection Data Register, + * 543-512 */ +#define XBRAM_FI_D_17_OFFSET 0x344 /**< Fault injection Data Register, + * 575-544 */ +#define XBRAM_FI_D_18_OFFSET 0x348 /**< Fault injection Data Register, + * 607-576 */ +#define XBRAM_FI_D_19_OFFSET 0x34C /**< Fault injection Data Register, + * 639-608 */ +#define XBRAM_FI_D_20_OFFSET 0x350 /**< Fault injection Data Register, + * 671-640 */ +#define XBRAM_FI_D_21_OFFSET 0x354 /**< Fault injection Data Register, + * 703-672 */ +#define XBRAM_FI_D_22_OFFSET 0x358 /**< Fault injection Data Register, + * 735-704 */ +#define XBRAM_FI_D_23_OFFSET 0x35C /**< Fault injection Data Register, + * 767-736 */ +#define XBRAM_FI_D_24_OFFSET 0x360 /**< Fault injection Data Register, + * 799-768 */ +#define XBRAM_FI_D_25_OFFSET 0x364 /**< Fault injection Data Register, + * 831-800 */ +#define XBRAM_FI_D_26_OFFSET 0x368 /**< Fault injection Data Register, + * 863-832 */ +#define XBRAM_FI_D_27_OFFSET 0x36C /**< Fault injection Data Register, + * 895-864 */ +#define XBRAM_FI_D_28_OFFSET 0x370 /**< Fault injection Data Register, + * 927-896 */ +#define XBRAM_FI_D_29_OFFSET 0x374 /**< Fault injection Data Register, + * 959-928 */ +#define XBRAM_FI_D_30_OFFSET 0x378 /**< Fault injection Data Register, + * 991-960 */ +#define XBRAM_FI_D_31_OFFSET 0x37C /**< Fault injection Data Register, + * 1023-992 */ + +#define XBRAM_FI_ECC_0_OFFSET 0x380 /**< Fault injection ECC Register, + * 31-0 */ +#define XBRAM_FI_ECC_1_OFFSET 0x384 /**< Fault injection ECC Register, + * 63-32 */ +#define XBRAM_FI_ECC_2_OFFSET 0x388 /**< Fault injection ECC Register, + * 95-64 */ +#define XBRAM_FI_ECC_3_OFFSET 0x38C /**< Fault injection ECC Register, + * 127-96 */ +#define XBRAM_FI_ECC_4_OFFSET 0x390 /**< Fault injection ECC Register, + * 159-128 */ +#define XBRAM_FI_ECC_5_OFFSET 0x394 /**< Fault injection ECC Register, + * 191-160 */ +#define XBRAM_FI_ECC_6_OFFSET 0x398 /**< Fault injection ECC Register, + * 223-192 */ +#define XBRAM_FI_ECC_7_OFFSET 0x39C /**< Fault injection ECC Register, + * 255-224 */ + + +/* @} */ + +/** @name Interrupt Status and Enable Register bitmaps and masks + * + * Bit definitions for the ECC status register and ECC interrupt enable register. + * @{ + */ +#define XBRAM_IR_CE_MASK 0x2 /**< Mask for the correctable error */ +#define XBRAM_IR_UE_MASK 0x1 /**< Mask for the uncorrectable error */ +#define XBRAM_IR_ALL_MASK 0x3 /**< Mask of all bits */ +/*@}*/ + + +/**************************** Type Definitions *******************************/ + + +/***************** Macros (Inline Functions) Definitions *********************/ + +#define XBram_In32 Xil_In32 +#define XBram_Out32 Xil_Out32 + +#define XBram_In16 Xil_In16 +#define XBram_Out16 Xil_Out16 + +#define XBram_In8 Xil_In8 +#define XBram_Out8 Xil_Out8 + + +/****************************************************************************/ +/** +* +* Write a value to a BRAM register. A 32 bit write is performed. +* +* @param BaseAddress is the base address of the BRAM device register. +* @param RegOffset is the register offset from the base to write to. +* @param Data is the data written to the register. +* +* @return None. +* +* @note C-style signature: +* void XBram_WriteReg(u32 BaseAddress, u32 RegOffset, u32 Data) +* +****************************************************************************/ +#define XBram_WriteReg(BaseAddress, RegOffset, Data) \ + XBram_Out32((BaseAddress) + (RegOffset), (u32)(Data)) + +/****************************************************************************/ +/** +* +* Read a value from a BRAM register. A 32 bit read is performed. +* +* @param BaseAddress is the base address of the BRAM device registers. +* @param RegOffset is the register offset from the base to read from. +* +* @return Data read from the register. +* +* @note C-style signature: +* u32 XBram_ReadReg(u32 BaseAddress, u32 RegOffset) +* +****************************************************************************/ +#define XBram_ReadReg(BaseAddress, RegOffset) \ + XBram_In32((BaseAddress) + (RegOffset)) + +/************************** Function Prototypes ******************************/ + +/************************** Variable Definitions *****************************/ + + + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram_intr.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram_intr.c new file mode 100644 index 0000000..50644aa --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram_intr.c @@ -0,0 +1,234 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ + +/*****************************************************************************/ +/** +* @file xbram_intr.c +* @addtogroup bram_v4_2 +* @{ +* +* Implements BRAM interrupt processing functions for the +* XBram driver. See xbram.h for more information +* about the driver. +* +* The functions in this file require the hardware device to be built with +* interrupt capabilities. The functions will assert if called using hardware +* that does not have interrupt capabilities. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a sa   05/11/10 Initial release
+* 
+* +*****************************************************************************/ + +/***************************** Include Files ********************************/ +#include "xbram.h" + + +/************************** Constant Definitions ****************************/ + +/**************************** Type Definitions ******************************/ + +/***************** Macros (Inline Functions) Definitions ********************/ + +/************************** Variable Definitions ****************************/ + +/************************** Function Prototypes *****************************/ + + +/****************************************************************************/ +/** +* Enable interrupts. This function will assert if the hardware device has not +* been built with interrupt capabilities. +* +* @param InstancePtr is the BRAM instance to operate on. +* @param Mask is the mask to enable. Bit positions of 1 are enabled. +* This mask is formed by OR'ing bits from XBRAM_IR* +* bits which are contained in xbram_hw.h. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XBram_InterruptEnable(XBram *InstancePtr, u32 Mask) +{ + u32 Register; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid(InstancePtr->Config.CtrlBaseAddress != 0); + + /* + * Read the interrupt enable register and only enable the specified + * interrupts without disabling or enabling any others. + */ + Register = XBram_ReadReg(InstancePtr->Config.CtrlBaseAddress, + XBRAM_ECC_EN_IRQ_OFFSET); + XBram_WriteReg(InstancePtr->Config.CtrlBaseAddress, + XBRAM_ECC_EN_IRQ_OFFSET, + Register | Mask); +} + + +/****************************************************************************/ +/** +* Disable interrupts. This function allows each specific interrupt to be +* disabled. This function will assert if the hardware device has not been +* built with interrupt capabilities. +* +* @param InstancePtr is the BRAM instance to operate on. +* @param Mask is the mask to disable. Bits set to 1 are disabled. This +* mask is formed by OR'ing bits from XBRAM_IR* bits +* which are contained in xbram_hw.h. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XBram_InterruptDisable(XBram *InstancePtr, u32 Mask) +{ + u32 Register; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid(InstancePtr->Config.CtrlBaseAddress != 0); + + /* + * Read the interrupt enable register and only disable the specified + * interrupts without enabling or disabling any others. + */ + Register = XBram_ReadReg(InstancePtr->Config.CtrlBaseAddress, + XBRAM_ECC_EN_IRQ_OFFSET); + XBram_WriteReg(InstancePtr->Config.CtrlBaseAddress, + XBRAM_ECC_EN_IRQ_OFFSET, + Register & (~Mask)); +} + +/****************************************************************************/ +/** +* Clear pending interrupts with the provided mask. This function should be +* called after the software has serviced the interrupts that are pending. +* This function will assert if the hardware device has not been built with +* interrupt capabilities. +* +* @param InstancePtr is the BRAM instance to operate on. +* @param Mask is the mask to clear pending interrupts for. Bit positions +* of 1 are cleared. This mask is formed by OR'ing bits from +* XBRAM_IR* bits which are contained in +* xbram_hw.h. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XBram_InterruptClear(XBram *InstancePtr, u32 Mask) +{ + u32 Register; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid(InstancePtr->Config.CtrlBaseAddress != 0); + + /* + * Read the interrupt status register and only clear the interrupts + * that are specified without affecting any others. Since the register + * is a toggle on write, make sure any bits to be written are already + * set. + */ + Register = XBram_ReadReg(InstancePtr->Config.CtrlBaseAddress, + XBRAM_ECC_STATUS_OFFSET); + XBram_WriteReg(InstancePtr->Config.CtrlBaseAddress, + XBRAM_ECC_STATUS_OFFSET, + Register & Mask); + + +} + + +/****************************************************************************/ +/** +* Returns the interrupt enable mask. This function will assert if the +* hardware device has not been built with interrupt capabilities. +* +* @param InstancePtr is the BRAM instance to operate on. +* +* @return A mask of bits made from XBRAM_IR* bits which +* are contained in xbram_hw.h. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +u32 XBram_InterruptGetEnabled(XBram * InstancePtr) +{ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid(InstancePtr->Config.CtrlBaseAddress != 0); + + return XBram_ReadReg(InstancePtr->Config.CtrlBaseAddress, + XBRAM_ECC_EN_IRQ_OFFSET); +} + + +/****************************************************************************/ +/** +* Returns the status of interrupt signals. Any bit in the mask set to 1 +* indicates that the channel associated with the bit has asserted an interrupt +* condition. This function will assert if the hardware device has not been +* built with interrupt capabilities. +* +* @param InstancePtr is the BRAM instance to operate on. +* +* @return A pointer to a mask of bits made from XBRAM_IR* +* bits which are contained in xbram_hw.h. +* +* @note +* +* The interrupt status indicates the status of the device irregardless if +* the interrupts from the devices have been enabled or not through +* XBram_InterruptEnable(). +* +*****************************************************************************/ +u32 XBram_InterruptGetStatus(XBram * InstancePtr) +{ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid(InstancePtr->Config.CtrlBaseAddress != 0); + + return XBram_ReadReg(InstancePtr->Config.CtrlBaseAddress, + XBRAM_ECC_EN_IRQ_OFFSET); +} +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram_selftest.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram_selftest.c new file mode 100644 index 0000000..e57e09c --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram_selftest.c @@ -0,0 +1,557 @@ +/****************************************************************************** +* +* Copyright (C) 2011 - 2019 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* @file xbram_selftest.c +* @addtogroup bram_v4_2 +* @{ +* +* The implementation of the XBram driver's self test function. This SelfTest +* is only applicable if ECC is enabled. +* If ECC is not enabled then this function will return XST_SUCCESS. +* See xbram.h for more information about the driver. +* Temp change +* +* @note +* +* None +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a sa   11/24/10 First release
+* 3.01a sa   01/13/12  Changed Selftest API from
+*		       XBram_SelfTest(XBram *InstancePtr) to
+*		       XBram_SelfTest(XBram *InstancePtr, u8 IntMask) and
+*		       fixed a problem with interrupt generation for CR 639274
+*		       Modified Selftest example to return XST_SUCCESS when
+*		       ECC is not enabled and return XST_FAILURE when ECC is
+*		       enabled and Control Base Address is zero (CR 636581)
+*		       Modified Selftest to use correct CorrectableCounterBits
+*		       for CR 635655
+*		       Updated to check CorrectableFailingDataRegs in the case
+*		       of LMB BRAM.
+* 3.02a sa  04/16/12   Added test of byte and halfword read-modify-write
+* 3.03a bss 05/22/13   Added Xil_DCacheFlushRange in InjectErrors API to
+*		       flush the Cache after writing to BRAM (CR #719011)
+* 4.3   aru 04/09/19   Used UINTPTR instead of u32 for Addr in XBram_SelfTest()
+*
+* 
+*****************************************************************************/ + +/***************************** Include Files ********************************/ +#include "xbram.h" +#include "xil_cache.h" +/************************** Constant Definitions ****************************/ +#define TOTAL_BITS 39 + +/**************************** Type Definitions ******************************/ + +/***************** Macros (Inline Functions) Definitions ********************/ +#define RD(reg) XBram_ReadReg(InstancePtr->Config.CtrlBaseAddress, \ + XBRAM_ ## reg) +#define WR(reg, data) XBram_WriteReg(InstancePtr->Config.CtrlBaseAddress, \ + XBRAM_ ## reg, data) + +#define CHECK(reg, data, result) if (result!=XST_SUCCESS || RD(reg)!=data) \ + result = XST_FAILURE; + +/************************** Variable Definitions ****************************/ +static u32 PrngResult; + +/************************** Function Prototypes *****************************/ +static inline u32 PrngData(u32 *PrngResult); + +static inline u32 CalculateEcc(u32 Data); + +static void InjectErrors(XBram * InstancePtr, UINTPTR Addr, + int Index1, int Index2, int Width, + u32 *ActualData, u32 *ActualEcc); + + +/*****************************************************************************/ +/** +* Generate a pseudo random number. +* +* @param The PrngResult is the previous random number in the pseudo +* random sequence, also knwon as the seed. It is modified to +* the calculated pseudo random number by the function. +* +* @return The generated pseudo random number +* +* @note None. +* +******************************************************************************/ +static inline u32 PrngData(u32 *PrngResult) +{ + *PrngResult = *PrngResult * 0x77D15E25 + 0x3617C161; + return *PrngResult; +} + + +/*****************************************************************************/ +/** +* Calculate ECC from Data. +* +* @param The Data Value +* +* @return The calculated ECC +* +* @note None. +* +******************************************************************************/ +static inline u32 CalculateEcc(u32 Data) +{ + unsigned char c[7], d[32]; + u32 Result = 0; + int Index; + + for (Index = 0; Index < 32; Index++) { + d[31 - Index] = Data & 1; + Data = Data >> 1; + } + + c[0] = d[0] ^ d[1] ^ d[3] ^ d[4] ^ d[6] ^ d[8] ^ d[10] ^ d[11] ^ + d[13] ^ d[15] ^ d[17] ^ d[19] ^ d[21] ^ d[23] ^ d[25] ^ d[26] ^ + d[28] ^ d[30]; + + c[1] = d[0] ^ d[2] ^ d[3] ^ d[5] ^ d[6] ^ d[9] ^ d[10] ^ d[12] ^ + d[13] ^ d[16] ^ d[17] ^ d[20] ^ d[21] ^ d[24] ^ d[25] ^ d[27] ^ + d[28] ^ d[31]; + + c[2] = d[1] ^ d[2] ^ d[3] ^ d[7] ^ d[8] ^ d[9] ^ d[10] ^ d[14] ^ + d[15] ^ d[16] ^ d[17] ^ d[22] ^ d[23] ^ d[24] ^ d[25] ^ d[29] ^ + d[30] ^ d[31]; + + c[3] = d[4] ^ d[5] ^ d[6] ^ d[7] ^ d[8] ^ d[9] ^ d[10] ^ d[18] ^ + d[19] ^ d[20] ^ d[21] ^ d[22] ^ d[23] ^ d[24] ^ d[25]; + + c[4] = d[11] ^ d[12] ^ d[13] ^ d[14] ^ d[15] ^ d[16] ^ d[17] ^ d[18] ^ + d[19] ^ d[20] ^ d[21] ^ d[22] ^ d[23] ^ d[24] ^ d[25]; + + c[5] = d[26] ^ d[27] ^ d[28] ^ d[29] ^ d[30] ^ d[31]; + + c[6] = d[0] ^ d[1] ^ d[2] ^ d[3] ^ d[4] ^ d[5] ^ d[6] ^ d[7] ^ + d[8] ^ d[9] ^ d[10] ^ d[11] ^ d[12] ^ d[13] ^ d[14] ^ d[15] ^ + d[16] ^ d[17] ^ d[18] ^ d[19] ^ d[20] ^ d[21] ^ d[22] ^ d[23] ^ + d[24] ^ d[25] ^ d[26] ^ d[27] ^ d[28] ^ d[29] ^ d[30] ^ d[31] ^ + c[5] ^ c[4] ^ c[3] ^ c[2] ^ c[1] ^ c[0]; + + for (Index = 0; Index < 7; Index++) { + Result = Result << 1; + Result |= c[Index] & 1; + } + + return Result; +} + +/*****************************************************************************/ +/** +* Get the expected actual data read in case of uncorrectable errors. +* +* @param The injected data value including errors (if any) +* @param The syndrome (calculated ecc ^ actual ecc read) +* +* @return The actual data value read +* +* @note None. +* +******************************************************************************/ +static inline u32 UncorrectableData(u32 Data, u8 Syndrome) +{ + switch (Syndrome) { + case 0x03: return Data ^ 0x00000034; + case 0x05: return Data ^ 0x001a2000; + case 0x09: return Data ^ 0x0d000000; + case 0x0d: return Data ^ 0x00001a00; + + case 0x11: return Data ^ 0x60000000; + case 0x13: return Data ^ 0x00000003; + case 0x15: return Data ^ 0x00018000; + case 0x19: return Data ^ 0x00c00000; + case 0x1d: return Data ^ 0x00000180; + + case 0x21: return Data ^ 0x80000000; + case 0x23: return Data ^ 0x00000008; + case 0x25: return Data ^ 0x00040000; + case 0x29: return Data ^ 0x02000000; + case 0x2d: return Data ^ 0x00000400; + + case 0x31: return Data ^ 0x10000000; + case 0x35: return Data ^ 0x00004000; + case 0x39: return Data ^ 0x00200000; + case 0x3d: return Data ^ 0x00000040; + } + return Data; +} + +/*****************************************************************************/ +/** +* Inject errors using the hardware fault injection functionality, and write +* random data and read it back using the indicated location. +* +* @param InstancePtr is a pointer to the XBram instance to +* be worked on. +* @param The Addr is the indicated memory location to use +* @param The Index1 is the bit location of the first injected error +* @param The Index2 is the bit location of the second injected error +* @param The Width is the data byte width +* @param The ActualData is filled in with expected data for checking +* @param The ActualEcc is filled in with expected ECC for checking +* +* @return None +* +* @note None. +* +******************************************************************************/ +static void InjectErrors(XBram * InstancePtr, UINTPTR Addr, + int Index1, int Index2, int Width, + u32 *ActualData, u32 *ActualEcc) +{ + u32 InjectedData = 0; + u32 InjectedEcc = 0; + u32 RandomData = PrngData(&PrngResult); + + if (Index1 < 32) { + InjectedData = 1 << Index1; + } else { + InjectedEcc = 1 << (Index1 - 32); + } + + if (Index2 < 32) { + InjectedData |= (1 << Index2); + } else { + InjectedEcc |= 1 << (Index2 - 32); + } + + WR(FI_D_0_OFFSET, InjectedData); + WR(FI_ECC_0_OFFSET, InjectedEcc); + + XBram_Out32(Addr, RandomData); + Xil_DCacheFlushRange(Addr, 4); + switch (Width) { + case 1: /* Byte - Write to do Read-Modify-Write */ + XBram_Out8(Addr, PrngData(&PrngResult) & 0xFF); + break; + case 2: /* Halfword - Write to do Read-Modify-Write */ + XBram_Out16(Addr, PrngData(&PrngResult) & 0xFFFF); + break; + case 4: /* Word - Read */ + (void) XBram_In32(Addr); + break; + } + *ActualData = InjectedData ^ RandomData; + *ActualEcc = InjectedEcc ^ CalculateEcc(RandomData); +} + + +/*****************************************************************************/ +/** +* Run a self-test on the driver/device. Unless fault injection is implemented +* in hardware, this function only does a minimal test in which available +* registers (if any) are written and read. +* +* With fault injection, all possible single-bit and double-bit errors are +* injected, and checked to the extent possible, given the implemented hardware. +* +* @param InstancePtr is a pointer to the XBram instance. +* @param IntMask is the interrupt mask to use. When testing +* with interrupts, this should be set to allow interrupt +* generation, otherwise it should be 0. +* +* @return +* - XST_SUCCESS if fault injection/detection is working properly OR +* if ECC is Not Enabled in the HW. +* - XST_FAILURE if the injected fault is not correctly detected or +* the Control Base Address is Zero when ECC is enabled. +* . +* +* If the BRAM device is not present in the +* hardware a bus error could be generated. Other indicators of a +* bus error, such as registers in bridges or buses, may be +* necessary to determine if this function caused a bus error. +* +* @note None. +* +******************************************************************************/ +int XBram_SelfTest(XBram *InstancePtr, u8 IntMask) +{ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + + + if (InstancePtr->Config.EccPresent == 0) { + return (XST_SUCCESS); + } + + if (InstancePtr->Config.CtrlBaseAddress == 0) { + return (XST_SUCCESS); + } + + /* + * Only 32-bit data width is supported as of yet. 64-bit and 128-bit + * widths will be supported in future. + */ + if (InstancePtr->Config.DataWidth != 32) + return (XST_SUCCESS); + + /* + * Read from the implemented readable registers in the hardware device. + */ + if (InstancePtr->Config.CorrectableFailingRegisters) { + (void) RD(CE_FFA_0_OFFSET); + } + if (InstancePtr->Config.CorrectableFailingDataRegs) { + (void) RD(CE_FFD_0_OFFSET); + (void) RD(CE_FFE_0_OFFSET); + } + if (InstancePtr->Config.UncorrectableFailingRegisters) { + (void) RD(UE_FFA_0_OFFSET); + } + if (InstancePtr->Config.UncorrectableFailingDataRegs) { + (void) RD(UE_FFD_0_OFFSET); + (void) RD(UE_FFE_0_OFFSET); + } + + /* + * Write and read the implemented read/write registers in the hardware + * device. + */ + if (InstancePtr->Config.EccStatusInterruptPresent) { + WR(ECC_EN_IRQ_OFFSET, 0); + if (RD(ECC_EN_IRQ_OFFSET) != 0) { + return (XST_FAILURE); + } + } + + if (InstancePtr->Config.CorrectableCounterBits > 0) { + u32 Value; + + /* Calculate counter max value */ + if (InstancePtr->Config.CorrectableCounterBits == 32) { + Value = 0xFFFFFFFF; + } else { + Value = (1 << + InstancePtr->Config.CorrectableCounterBits) - 1; + } + + WR(CE_CNT_OFFSET, Value); + if (RD(CE_CNT_OFFSET) != Value) { + return (XST_FAILURE); + } + + WR(CE_CNT_OFFSET, 0); + if (RD(CE_CNT_OFFSET) != 0) { + return (XST_FAILURE); + } + } + + /* + * If fault injection is implemented, inject all possible single-bit + * and double-bit errors, and check all observable effects. + */ + if (InstancePtr->Config.FaultInjectionPresent && + InstancePtr->Config.WriteAccess != 0) { + + const UINTPTR Addr[2] = {InstancePtr->Config.MemBaseAddress & + (UINTPTR)0xfffffffffffffffc, + InstancePtr->Config.MemHighAddress & + (UINTPTR)0xfffffffffffffffc}; + u32 SavedWords[2]; + u32 ActualData; + u32 ActualEcc; + u32 CounterValue = 0; + u32 CounterMax; + int WordIndex = 0; + int Result = XST_SUCCESS; + int Index1; + int Index2; + int Width; + + PrngResult = 42; /* Random seed */ + + /* Save two words in BRAM used for test */ + SavedWords[0] = XBram_In32(Addr[0]); + SavedWords[1] = XBram_In32(Addr[1]); + + for (Width = 1; Width <= 4; Width <<= 1) { + /* Calculate counter max value */ + if (InstancePtr->Config.CorrectableCounterBits == 32) { + CounterMax = 0xFFFFFFFF; + } else { + CounterMax =(1 << + InstancePtr->Config.CorrectableCounterBits) - 1; + } + + /* Inject and check all single bit errors */ + for (Index1 = 0; Index1 < TOTAL_BITS; Index1++) { + /* Save counter value */ + if (InstancePtr->Config.CorrectableCounterBits > 0) { + CounterValue = RD(CE_CNT_OFFSET); + } + + /* Inject single bit error */ + InjectErrors(InstancePtr, Addr[WordIndex], Index1, + Index1, Width, &ActualData, &ActualEcc); + + /* Check that CE is set */ + if (InstancePtr->Config.EccStatusInterruptPresent) { + CHECK(ECC_STATUS_OFFSET, + XBRAM_IR_CE_MASK, Result); + } + + /* Check that address, data, ECC are correct */ + if (InstancePtr->Config.CorrectableFailingRegisters) { + CHECK(CE_FFA_0_OFFSET, Addr[WordIndex], Result); + } + /* Checks are only for LMB BRAM */ + if (InstancePtr->Config.CorrectableFailingDataRegs) { + CHECK(CE_FFD_0_OFFSET, ActualData, Result); + CHECK(CE_FFE_0_OFFSET, ActualEcc, Result); + } + + /* Check that counter has incremented */ + if (InstancePtr->Config.CorrectableCounterBits > 0 && + CounterValue < CounterMax) { + CHECK(CE_CNT_OFFSET, + CounterValue + 1, Result); + } + + /* Restore correct data in the used word */ + XBram_Out32(Addr[WordIndex], SavedWords[WordIndex]); + + /* Allow interrupts to occur */ + /* Clear status register */ + if (InstancePtr->Config.EccStatusInterruptPresent) { + WR(ECC_EN_IRQ_OFFSET, IntMask); + WR(ECC_STATUS_OFFSET, XBRAM_IR_ALL_MASK); + WR(ECC_EN_IRQ_OFFSET, 0); + } + + /* Switch to the other word */ + WordIndex = WordIndex ^ 1; + + if (Result != XST_SUCCESS) break; + + } + + if (Result != XST_SUCCESS) { + return XST_FAILURE; + } + + for (Index1 = 0; Index1 < TOTAL_BITS; Index1++) { + for (Index2 = 0; Index2 < TOTAL_BITS; Index2++) { + if (Index1 != Index2) { + /* Inject double bit error */ + InjectErrors(InstancePtr, + Addr[WordIndex], + Index1, Index2, Width, + &ActualData, + &ActualEcc); + + /* Check that UE is set */ + if (InstancePtr->Config. + EccStatusInterruptPresent) { + CHECK(ECC_STATUS_OFFSET, + XBRAM_IR_UE_MASK, + Result); + } + + /* Check that address, data, ECC are correct */ + if (InstancePtr->Config. + UncorrectableFailingRegisters) { + CHECK(UE_FFA_0_OFFSET, Addr[WordIndex], + Result); + CHECK(UE_FFD_0_OFFSET, + ActualData, Result); + CHECK(UE_FFE_0_OFFSET, ActualEcc, + Result); + } + + /* Restore correct data in the used word */ + XBram_Out32(Addr[WordIndex], + SavedWords[WordIndex]); + + /* Allow interrupts to occur */ + /* Clear status register */ + if (InstancePtr->Config. + EccStatusInterruptPresent) { + WR(ECC_EN_IRQ_OFFSET, IntMask); + WR(ECC_STATUS_OFFSET, + XBRAM_IR_ALL_MASK); + WR(ECC_EN_IRQ_OFFSET, 0); + } + + /* Switch to the other word */ + WordIndex = WordIndex ^ 1; + } + if (Result != XST_SUCCESS) break; + } + if (Result != XST_SUCCESS) break; + } + + /* Check saturation of correctable error counter */ + if (InstancePtr->Config.CorrectableCounterBits > 0 && + Result == XST_SUCCESS) { + + WR(CE_CNT_OFFSET, CounterMax); + + InjectErrors(InstancePtr, Addr[WordIndex], 0, 0, + 4, &ActualData, &ActualEcc); + + CHECK(CE_CNT_OFFSET, CounterMax, Result); + } + + /* Restore the two words used for test */ + XBram_Out32(Addr[0], SavedWords[0]); + XBram_Out32(Addr[1], SavedWords[1]); + + /* Clear the Status Register. */ + if (InstancePtr->Config.EccStatusInterruptPresent) { + WR(ECC_STATUS_OFFSET, XBRAM_IR_ALL_MASK); + } + + /* Set Correctable Counter to zero */ + if (InstancePtr->Config.CorrectableCounterBits > 0) { + WR(CE_CNT_OFFSET, 0); + } + + if (Result != XST_SUCCESS) break; + + } /* Width loop */ + + return (Result); + } + + return (XST_SUCCESS); +} + +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram_sinit.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram_sinit.c new file mode 100644 index 0000000..adc560e --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram_sinit.c @@ -0,0 +1,101 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2017 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* @file xbram_sinit.c +* @addtogroup bram_v4_2 +* @{ +* +* The implementation of the XBram driver's static initialzation +* functionality. +* +* @note +* +* None +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 2.01a jvb  10/13/05 First release
+* 2.11a mta  03/21/07 Updated to new coding style
+* 4.2   ms   08/07/17 Fixed compilation warnings.
+* 
+* +*****************************************************************************/ + +/***************************** Include Files ********************************/ + +#include "xstatus.h" +#include "xparameters.h" +#include "xbram.h" + +/************************** Constant Definitions ****************************/ + +/**************************** Type Definitions ******************************/ + +/***************** Macros (Inline Functions) Definitions ********************/ + +/************************** Variable Definitions ****************************/ +extern XBram_Config XBram_ConfigTable[]; + +/************************** Function Prototypes *****************************/ + + +/*****************************************************************************/ +/** +* Lookup the device configuration based on the unique device ID. The table +* ConfigTable contains the configuration info for each device in the system. +* +* @param DeviceId is the device identifier to lookup. +* +* @return +* - A pointer of data type XBram_Config which +* points to the device configuration if DeviceID is found. +* - NULL if DeviceID is not found. +* +* @note None. +* +******************************************************************************/ +XBram_Config *XBram_LookupConfig(u16 DeviceId) +{ + XBram_Config *CfgPtr = NULL; + + u32 Index; + + for (Index = 0U; Index < XPAR_XBRAM_NUM_INSTANCES; Index++) { + if (XBram_ConfigTable[Index].DeviceId == DeviceId) { + CfgPtr = &XBram_ConfigTable[Index]; + break; + } + } + + return CfgPtr; +} +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/coresightps_dcc_v1_5/src/Makefile b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/coresightps_dcc_v1_5/src/Makefile new file mode 100644 index 0000000..007162d --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/coresightps_dcc_v1_5/src/Makefile @@ -0,0 +1,40 @@ +COMPILER= +ARCHIVER= +CP=cp +COMPILER_FLAGS= +EXTRA_COMPILER_FLAGS= +LIB=libxil.a + +CC_FLAGS = $(COMPILER_FLAGS) +ECC_FLAGS = $(EXTRA_COMPILER_FLAGS) + +RELEASEDIR=../../../lib +INCLUDEDIR=../../../include +INCLUDES=-I./. -I${INCLUDEDIR} + +OUTS = *.o + +LIBSOURCES:=*.c +INCLUDEFILES:=*.h + +OBJECTS = $(addsuffix .o, $(basename $(wildcard *.c))) + +libs: banner coresightps_dcc_comp_libs clean + +%.o: %.c + ${COMPILER} $(CC_FLAGS) $(ECC_FLAGS) $(INCLUDES) -o $@ $< + +banner: + echo "Compiling coresightps_dcc" + +coresightps_dcc_comp_libs: ${OBJECTS} + $(ARCHIVER) -r ${RELEASEDIR}/${LIB} ${OBJECTS} + +.PHONY: include +include: coresightps_dcc_includes + +coresightps_dcc_includes: + ${CP} ${INCLUDEFILES} ${INCLUDEDIR} + +clean: + rm -rf ${OBJECTS} diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/coresightps_dcc_v1_5/src/xcoresightpsdcc.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/coresightps_dcc_v1_5/src/xcoresightpsdcc.c new file mode 100644 index 0000000..235eb8e --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/coresightps_dcc_v1_5/src/xcoresightpsdcc.c @@ -0,0 +1,186 @@ +/****************************************************************************** +* +* Copyright (C) 2015-2019 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xcoresightpsdcc.c +* @addtogroup coresightps_dcc_v1_5 +* @{ +* +* Functions in this file are the minimum required functions for the +* XCoreSightPs driver. +* +* @note None. +* +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date		Changes
+* ----- -----  -------- -----------------------------------------------
+* 1.00  kvn    02/14/15 First release
+* 1.1   kvn    06/12/15 Add support for Zynq Ultrascale+ MP.
+*       kvn    08/18/15 Modified Makefile according to compiler changes.
+* 1.2   kvn    10/09/15 Add support for IAR Compiler.
+* 1.3   asa    07/01/16 Made changes to ensure that the file does not compile
+*                       for MB BSPs. Instead it throws up a warning. This
+*                       fixes the CR#953056.
+* 1.5   sne    01/19/19 Fixed MISRA-C Violations CR#1025101.
+*
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ +#ifdef __MICROBLAZE__ +#warning "The driver is supported only for ARM architecture" +#else + +#include "xil_types.h" +#include "xpseudo_asm.h" +#include "xcoresightpsdcc.h" + +#ifdef __ICCARM__ +#define INLINE +#else +#define INLINE __inline +#endif + +/* DCC Status Bits */ +#define XCORESIGHTPS_DCC_STATUS_RX (1 << 30) +#define XCORESIGHTPS_DCC_STATUS_TX (1 << 29) + +static INLINE u32 XCoresightPs_DccGetStatus(void); + +/****************************************************************************/ +/** +* +* This functions sends a single byte using the DCC. It is blocking in that it +* waits for the transmitter to become non-full before it writes the byte to +* the transmit register. +* +* @param BaseAddress is a dummy parameter to match the function proto +* of functions for other stdio devices. +* @param Data is the byte of data to send +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XCoresightPs_DccSendByte(u32 BaseAddress, u8 Data) +{ + (void) BaseAddress; + while (XCoresightPs_DccGetStatus() & XCORESIGHTPS_DCC_STATUS_TX) + {dsb();} +#ifdef __aarch64__ + asm volatile ("msr dbgdtrtx_el0, %0" : : "r" (Data)); +#elif defined (__GNUC__) || defined (__ICCARM__) + asm volatile("mcr p14, 0, %0, c0, c5, 0" + : : "r" (Data)); +#else + { + volatile register u32 Reg __asm("cp14:0:c0:c5:0"); + Reg = Data; + } +#endif + isb(); + +} + +/****************************************************************************/ +/** +* +* This functions receives a single byte using the DCC. It is blocking in that +* it waits for the receiver to become non-empty before it reads from the +* receive register. +* +* @param BaseAddress is a dummy parameter to match the function proto +* of functions for other stdio devices. +* +* @return The byte of data received. +* +* @note None. +* +******************************************************************************/ +u8 XCoresightPs_DccRecvByte(u32 BaseAddress) +{ + u8 Data = 0U; + (void) BaseAddress; + + while (!(XCoresightPs_DccGetStatus() & XCORESIGHTPS_DCC_STATUS_RX)) + {dsb();} + +#ifdef __aarch64__ + asm volatile ("mrs %0, dbgdtrrx_el0" : "=r" (Data)); +#elif defined (__GNUC__) || defined (__ICCARM__) + asm volatile("mrc p14, 0, %0, c0, c5, 0" + : "=r" (Data)); +#else + { + volatile register u32 Reg __asm("cp14:0:c0:c5:0"); + Data = Reg; + } +#endif + isb(); + + return Data; +} + + +/****************************************************************************/ +/**INLINE +* +* This functions read the status register of the DCC. +* +* @param BaseAddress is the base address of the device +* +* @return The contents of the Status Register. +* +* @note None. +* +******************************************************************************/ +static INLINE u32 XCoresightPs_DccGetStatus(void) +{ + u32 Status = 0U; + +#ifdef __aarch64__ + asm volatile ("mrs %0, mdccsr_el0" : "=r" (Status)); +#elif defined (__GNUC__) || defined (__ICCARM__) + asm volatile("mrc p14, 0, %0, c0, c1, 0" + : "=r" (Status) : : "cc"); +#else + { + volatile register u32 Reg __asm("cp14:0:c0:c1:0"); + Status = Reg; + } +#endif + return Status; +#endif +} +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/coresightps_dcc_v1_5/src/xcoresightpsdcc.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/coresightps_dcc_v1_5/src/xcoresightpsdcc.h new file mode 100644 index 0000000..79bde0b --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/coresightps_dcc_v1_5/src/xcoresightpsdcc.h @@ -0,0 +1,74 @@ +/****************************************************************************** +* +* Copyright (C) 2015 - 2019 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xcoresightpsdcc.h +* @addtogroup coresightps_dcc_v1_5 +* @{ +* @details +* +* CoreSight driver component. +* +* The coresight is a part of debug communication channel (DCC) group. Jtag UART +* for ARM uses DCC. Each ARM core has its own DCC, so one need to select an +* ARM target in XSDB console before running the jtag terminal command. Using the +* coresight driver component, the output stream can be directed to a log file. +* +* @note None. +* +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date		Changes
+* ----- -----  -------- -----------------------------------------------
+* 1.00  kvn    02/14/15 First release
+* 1.1   kvn    06/12/15 Add support for Zynq Ultrascale+ MP.
+*       kvn    08/18/15 Modified Makefile according to compiler changes.
+* 1.3   asa    07/01/16 Made changes to ensure that the file does not compile
+*                       for MB BSPs. Instead it throws up a warning. This
+*                       fixes the CR#953056.
+* 1.5   sne    01/19/19 Fixed MISRA-C Violations CR#1025101.
+*
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ +#ifndef XCORESIGHTPSDCC_H /* prevent circular inclusions */ +#define XCORESIGHTPSDCC_H /* by using protection macros */ +#ifndef __MICROBLAZE__ +#include + +void XCoresightPs_DccSendByte(u32 BaseAddress, u8 Data); + +u8 XCoresightPs_DccRecvByte(u32 BaseAddress); +#endif +#endif +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/cpu_cortexa9_v2_7/src/Makefile b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/cpu_cortexa9_v2_7/src/Makefile new file mode 100644 index 0000000..7ea505c --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/cpu_cortexa9_v2_7/src/Makefile @@ -0,0 +1,25 @@ +COMPILER= +ARCHIVER= +CP=cp +COMPILER_FLAGS= +EXTRA_COMPILER_FLAGS= +LIB=libxil.a + +RELEASEDIR=../../../lib +INCLUDEDIR=../../../include +INCLUDES=-I${INCLUDEDIR} + +OUTS = *.o +OBJECTS = $(addsuffix .o, $(basename $(wildcard *.c))) +LIBSOURCES=*.c +INCLUDEFILES=*.h + +libs: + echo "Compiling cpu_cortexa9" + +.PHONY: include +include: + ${CP} $(INCLUDEFILES) $(INCLUDEDIR) + +clean: + rm -rf ${OBJECTS} diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/cpu_cortexa9_v2_7/src/xcpu_cortexa9.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/cpu_cortexa9_v2_7/src/xcpu_cortexa9.h new file mode 100644 index 0000000..e4a5e28 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/cpu_cortexa9_v2_7/src/xcpu_cortexa9.h @@ -0,0 +1,47 @@ +/****************************************************************************** +* +* Copyright (C) 2011 - 2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xcpu_cortexa9.h +* @addtogroup cpu_cortexa9_v2_7 +* @{ +* @details +* +* dummy file +* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ---- -------- --------------------------------------------------------- +* 2.5 ms 04/18/17 Modified tcl file to add suffix U for XPAR_CPU_ID +* parameter of cpu_cortexa9 in xparameters.h +# 2.7 mus 07/03/18 Updated tcl to not to add default flags forcefully into +# extra compiler flags. Now, user can remove default flags +# from extra compiler flags. It fixes CR#998768. +******************************************************************************/ +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/ddrps_v1_0/src/Makefile b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/ddrps_v1_0/src/Makefile new file mode 100644 index 0000000..7b191dd --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/ddrps_v1_0/src/Makefile @@ -0,0 +1,40 @@ +COMPILER= +ARCHIVER= +CP=cp +COMPILER_FLAGS= +EXTRA_COMPILER_FLAGS= +LIB=libxil.a + +CC_FLAGS = $(COMPILER_FLAGS) +ECC_FLAGS = $(EXTRA_COMPILER_FLAGS) + +RELEASEDIR=../../../lib +INCLUDEDIR=../../../include +INCLUDES=-I./. -I${INCLUDEDIR} + +OUTS = *.o + +LIBSOURCES:=*.c +INCLUDEFILES:=*.h + +OBJECTS = $(addsuffix .o, $(basename $(wildcard *.c))) + +libs: banner xddrps_libs clean + +%.o: %.c + ${COMPILER} $(CC_FLAGS) $(ECC_FLAGS) $(INCLUDES) -o $@ $< + +banner: + echo "Compiling ddrps" + +xddrps_libs: ${OBJECTS} + $(ARCHIVER) -r ${RELEASEDIR}/${LIB} ${OBJECTS} + +.PHONY: include +include: xddrps_includes + +xddrps_includes: + ${CP} ${INCLUDEFILES} ${INCLUDEDIR} + +clean: + rm -rf ${OBJECTS} diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/ddrps_v1_0/src/xddrps.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/ddrps_v1_0/src/xddrps.h new file mode 100644 index 0000000..b4d1f56 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/ddrps_v1_0/src/xddrps.h @@ -0,0 +1,62 @@ +/******************************************************************************* + * + * Copyright (C) 2015 Xilinx, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of the Xilinx shall not be used + * in advertising or otherwise to promote the sale, use or other dealings in + * this Software without prior written authorization from Xilinx. + * +*******************************************************************************/ +/******************************************************************************/ +/** + * + * @file xddrps.h + * @addtogroup ddrps_v1_0 + * @{ + * @details + * + * The Xilinx DdrPs driver. This driver supports the Xilinx ddrps + * IP core. + * + * @note None. + * + *
+ * MODIFICATION HISTORY:
+ *
+ * Ver   Who  Date     Changes
+ * ----- ---- -------- -----------------------------------------------
+ * 1.0	 nsk  08/06/15 First Release
+ * 1.0	 nsk  08/20/15 Updated define_addr_params in ddrps.tcl
+ *		       to support PBD Designs (CR #876857)
+ *
+ * 
+ * +*******************************************************************************/ + +#ifndef XDDRPS_H_ +/* Prevent circular inclusions by using protection macros. */ +#define XDDRPS_H_ + +/******************************* Include Files ********************************/ + + +#endif /* XDDRPS_H_ */ +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/Makefile b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/Makefile new file mode 100644 index 0000000..25ff740 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/Makefile @@ -0,0 +1,40 @@ +COMPILER= +ARCHIVER= +CP=cp +COMPILER_FLAGS= +EXTRA_COMPILER_FLAGS= +LIB=libxil.a + +CC_FLAGS = $(COMPILER_FLAGS) +ECC_FLAGS = $(EXTRA_COMPILER_FLAGS) + +RELEASEDIR=../../../lib +INCLUDEDIR=../../../include +INCLUDES=-I./. -I${INCLUDEDIR} + +OUTS = *.o + +LIBSOURCES:=*.c +INCLUDEFILES:=*.h + +OBJECTS = $(addsuffix .o, $(basename $(wildcard *.c))) + +libs: banner xdevcfg_libs clean + +%.o: %.c + ${COMPILER} $(CC_FLAGS) $(ECC_FLAGS) $(INCLUDES) -o $@ $< + +banner: + echo "Compiling devcfg" + +xdevcfg_libs: ${OBJECTS} + $(ARCHIVER) -r ${RELEASEDIR}/${LIB} ${OBJECTS} + +.PHONY: include +include: xdevcfg_includes + +xdevcfg_includes: + ${CP} ${INCLUDEFILES} ${INCLUDEDIR} + +clean: + rm -rf ${OBJECTS} diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg.c new file mode 100644 index 0000000..74e1d59 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg.c @@ -0,0 +1,941 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xdevcfg.c +* @addtogroup devcfg_v3_5 +* @{ +* +* This file contains the implementation of the interface functions for XDcfg +* driver. Refer to the header file xdevcfg.h for more detailed information. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who Date     Changes
+* ----- --- -------- ---------------------------------------------
+* 1.00a hvm 02/07/11 First release
+* 2.00a nm  05/31/12 Updated the driver for CR 660835 so that input length for
+*		     source/destination to the XDcfg_InitiateDma, XDcfg_Transfer
+*		     APIs is words (32 bit) and not bytes.
+* 		     Updated the notes for XDcfg_InitiateDma/XDcfg_Transfer APIs
+*		     to add information that 2 LSBs of the Source/Destination
+*		     address when equal to 2�b01 indicate the last DMA command
+*		     of an overall transfer.
+*		     Updated the XDcfg_Transfer function to use the
+*		     Destination Address passed to this API for secure transfers
+*		     instead of using 0xFFFFFFFF for CR 662197. This issue was
+*		     resulting in the failure of secure transfers of
+*		     non-bitstream images.
+* 2.01a nm  08/27/12 Updated the XDcfg_Transfer API to clear the
+*		     QUARTER_PCAP_RATE_EN bit in the control register for
+*		     non secure writes for CR 675543.
+* 2.02a nm  01/31/13 Fixed CR# 679335.
+* 		     Added Setting and Clearing the internal PCAP loopback.
+*		     Removed code for enabling/disabling AES engine as BootROM
+*		     locks down this setting.
+*		     Fixed CR# 681976.
+*		     Skip Checking the PCFG_INIT in case of non-secure DMA
+*		     loopback.
+*		     Fixed CR# 699558.
+*		     XDcfg_Transfer fails to transfer data in loopback mode.
+* 2.03a nm  04/19/13 Fixed CR# 703728.
+*		     Updated the register definitions as per the latest TRM
+*		     version UG585 (v1.4) November 16, 2012.
+* 3.0   kpc 21/02/14 Implemented new function XDcfg_ClearControlRegister
+* 3.2   sb  08/25/14 Fixed XDcfg_PcapReadback() function
+*		     updated driver code with != instead of ==,
+*		     while checking for Interrupt Status with DMA and
+*		     PCAP Done Mask
+*		     ((XDcfg_ReadReg(InstancePtr->Config.BaseAddr,
+*			XDCFG_INT_STS_OFFSET) &
+*			XDCFG_IXR_D_P_DONE_MASK) !=
+*			XDCFG_IXR_D_P_DONE_MASK);
+*
+*
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xdevcfg.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/************************** Variable Definitions *****************************/ + +/****************************************************************************/ +/** +* +* Initialize the Device Config Interface driver. This function +* must be called before other functions of the driver are called. +* +* @param InstancePtr is a pointer to the XDcfg instance. +* @param ConfigPtr is the config structure. +* @param EffectiveAddress is the base address for the device. It could be +* a virtual address if address translation is supported in the +* system, otherwise it is the physical address. +* +* @return +* - XST_SUCCESS if initialization was successful. +* - XST_DEVICE_IS_STARTED if the device has already been started. +* +* @note The very first APB access to the Device Configuration Interface +* block needs to be a write to the UNLOCK register with the value +* of 0x757BDF0D. This step is to be done once after reset, any +* other APB access has to come after this. The APB access is +* considered illegal if the step is not done or if it is done +* incorrectly. Furthermore, if any of efuse_sec_cfg[5:0] is high, +* the following additional actions would be carried out. +* In other words, if all bits are low, the following steps are not +* done. +* 1. AES is disabled +* 2. All APB writes disabled +* 3. SoC debug fully enabled +* +******************************************************************************/ +int XDcfg_CfgInitialize(XDcfg *InstancePtr, + XDcfg_Config *ConfigPtr, u32 EffectiveAddress) +{ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(ConfigPtr != NULL); + + /* + * If the device is started, disallow the initialize and return a + * status indicating it is started. This allows the user to stop the + * device and reinitialize, but prevents a user from inadvertently + * initializing. + */ + if (InstancePtr->IsStarted == XIL_COMPONENT_IS_STARTED) { + return XST_DEVICE_IS_STARTED; + } + + /* + * Copy configuration into instance. + */ + InstancePtr->Config.DeviceId = ConfigPtr->DeviceId; + + /* + * Save the base address pointer such that the registers of the block + * can be accessed and indicate it has not been started yet. + */ + InstancePtr->Config.BaseAddr = EffectiveAddress; + InstancePtr->IsStarted = 0; + + + /* Unlock the Device Configuration Interface */ + XDcfg_Unlock(InstancePtr); + + /* + * Indicate the instance is ready to use, successfully initialized. + */ + InstancePtr->IsReady = XIL_COMPONENT_IS_READY; + + return XST_SUCCESS; +} + +/****************************************************************************/ +/** +* +* The functions enables the PCAP interface by setting the PCAP mode bit in the +* control register. +* +* @param InstancePtr is a pointer to the XDcfg instance. +* +* @return None. +* +* @note Enable FPGA programming from PCAP interface. Enabling this bit +* disables all the external interfaces from programming of FPGA +* except for ICAP. The user needs to ensure that the FPGA is +* programmed through either PCAP or ICAP. +* +*****************************************************************************/ +void XDcfg_EnablePCAP(XDcfg *InstancePtr) +{ + u32 CtrlReg; + /* + * Assert the arguments. + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + + CtrlReg = XDcfg_ReadReg(InstancePtr->Config.BaseAddr, + XDCFG_CTRL_OFFSET); + + XDcfg_WriteReg(InstancePtr->Config.BaseAddr, XDCFG_CTRL_OFFSET, + (CtrlReg | XDCFG_CTRL_PCAP_MODE_MASK)); + +} + +/****************************************************************************/ +/** +* +* The functions disables the PCAP interface by clearing the PCAP mode bit in +* the control register. +* +* @param InstancePtr is a pointer to the XDcfg instance. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XDcfg_DisablePCAP(XDcfg *InstancePtr) +{ + u32 CtrlReg; + /* + * Assert the arguments. + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + + CtrlReg = XDcfg_ReadReg(InstancePtr->Config.BaseAddr, + XDCFG_CTRL_OFFSET); + + XDcfg_WriteReg(InstancePtr->Config.BaseAddr, XDCFG_CTRL_OFFSET, + (CtrlReg & ( ~XDCFG_CTRL_PCAP_MODE_MASK))); + +} + +/****************************************************************************/ +/** +* +* The function sets the contents of the Control Register. +* +* @param InstancePtr is a pointer to the XDcfg instance. +* @param Mask is the 32 bit mask data to be written to the Register. +* The mask definitions are defined in the xdevcfg_hw.h file. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XDcfg_SetControlRegister(XDcfg *InstancePtr, u32 Mask) +{ + u32 CtrlReg; + /* + * Assert the arguments. + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + + CtrlReg = XDcfg_ReadReg(InstancePtr->Config.BaseAddr, + XDCFG_CTRL_OFFSET); + + XDcfg_WriteReg(InstancePtr->Config.BaseAddr, XDCFG_CTRL_OFFSET, + (CtrlReg | Mask)); + +} + +/****************************************************************************/ +/** +* +* The function Clears the specified bit positions of the Control Register. +* +* @param InstancePtr is a pointer to the XDcfg instance. +* @param Mask is the 32 bit value which holds the bit positions to be cleared. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XDcfg_ClearControlRegister(XDcfg *InstancePtr, u32 Mask) +{ + u32 CtrlReg; + /* + * Assert the arguments. + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + + CtrlReg = XDcfg_ReadReg(InstancePtr->Config.BaseAddr, + XDCFG_CTRL_OFFSET); + + XDcfg_WriteReg(InstancePtr->Config.BaseAddr, XDCFG_CTRL_OFFSET, + (CtrlReg & ~Mask)); + +} + +/****************************************************************************/ +/** +* +* The function reads the contents of the Control Register. +* +* @param InstancePtr is a pointer to the XDcfg instance. +* +* @return A 32-bit value representing the contents of the Control +* Register. +* Use the XDCFG_CTRL_*_MASK constants defined in xdevcfg_hw.h to +* interpret the returned value. +* +* @note None. +* +*****************************************************************************/ +u32 XDcfg_GetControlRegister(XDcfg *InstancePtr) +{ + /* + * Assert the arguments. + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the Control Register and return the value. + */ + return XDcfg_ReadReg(InstancePtr->Config.BaseAddr, XDCFG_CTRL_OFFSET); +} + +/****************************************************************************/ +/** +* +* The function sets the contents of the Lock Register. These bits +* can only be set to a 1. They will be cleared after a Power On Reset. +* +* @param InstancePtr is a pointer to the XDcfg instance. +* @param Data is the 32 bit data to be written to the Register. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XDcfg_SetLockRegister(XDcfg *InstancePtr, u32 Data) +{ + /* + * Assert the arguments. + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + XDcfg_WriteReg(InstancePtr->Config.BaseAddr, XDCFG_LOCK_OFFSET, Data); + +} + +/****************************************************************************/ +/** +* +* The function reads the contents of the Lock Register. +* +* @param InstancePtr is a pointer to the XDcfg instance. +* +* @return A 32-bit value representing the contents of the Lock +* Register. +* Use the XDCFG_CR_*_MASK constants defined in xdevcfg_hw.h to +* interpret the returned value. +* +* @note None. +* +*****************************************************************************/ +u32 XDcfg_GetLockRegister(XDcfg *InstancePtr) +{ + /* + * Assert the arguments. + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the Lock Register and return the value. + */ + return XDcfg_ReadReg(InstancePtr->Config.BaseAddr, XDCFG_LOCK_OFFSET); +} + +/****************************************************************************/ +/** +* +* The function sets the contents of the Configuration Register with the +* given value. +* +* @param InstancePtr is a pointer to the XDcfg instance. +* @param Data is the 32 bit data to be written to the Register. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XDcfg_SetConfigRegister(XDcfg *InstancePtr, u32 Data) +{ + /* + * Assert the arguments. + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + XDcfg_WriteReg(InstancePtr->Config.BaseAddr, XDCFG_CFG_OFFSET, Data); + +} + +/****************************************************************************/ +/** +* +* The function reads the contents of the Configuration Register with the +* given value. +* +* @param InstancePtr is a pointer to the XDcfg instance. +* +* @return A 32-bit value representing the contents of the Config +* Register. +* Use the XDCFG_CFG_*_MASK constants defined in xdevcfg_hw.h to +* interpret the returned value. +* +* @note None. +* +*****************************************************************************/ +u32 XDcfg_GetConfigRegister(XDcfg *InstancePtr) +{ + /* + * Assert the arguments. + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + return XDcfg_ReadReg(InstancePtr->Config.BaseAddr, XDCFG_CFG_OFFSET); + +} + +/****************************************************************************/ +/** +* +* The function sets the contents of the Status Register. +* +* @param InstancePtr is a pointer to the XDcfg instance. +* @param Data is the 32 bit data to be written to the Register. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XDcfg_SetStatusRegister(XDcfg *InstancePtr, u32 Data) +{ + /* + * Assert the arguments. + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + XDcfg_WriteReg(InstancePtr->Config.BaseAddr, XDCFG_STATUS_OFFSET, Data); + +} + +/****************************************************************************/ +/** +* +* The function reads the contents of the Status Register. +* +* @param InstancePtr is a pointer to the XDcfg instance. +* +* @return A 32-bit value representing the contents of the Status +* Register. +* Use the XDCFG_STATUS_*_MASK constants defined in +* xdevcfg_hw.h to interpret the returned value. +* +* @note None. +* +*****************************************************************************/ +u32 XDcfg_GetStatusRegister(XDcfg *InstancePtr) +{ + /* + * Assert the arguments. + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the Status Register and return the value. + */ + return XDcfg_ReadReg(InstancePtr->Config.BaseAddr, XDCFG_STATUS_OFFSET); +} + +/****************************************************************************/ +/** +* +* The function sets the contents of the ROM Shadow Control Register. +* +* @param InstancePtr is a pointer to the XDcfg instance. +* @param Data is the 32 bit data to be written to the Register. +* +* @return None. +* +* @note This register is can only be written and is used to control the +* RAM shadow of 32 bit 4K page ROM pages in user mode +* +*****************************************************************************/ +void XDcfg_SetRomShadowRegister(XDcfg *InstancePtr, u32 Data) +{ + /* + * Assert the arguments. + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + XDcfg_WriteReg(InstancePtr->Config.BaseAddr, XDCFG_ROM_SHADOW_OFFSET, + Data); + +} + +/****************************************************************************/ +/** +* +* The function reads the contents of the Software ID Register. +* +* @param InstancePtr is a pointer to the XDcfg instance. +* +* @return 32 Bit boot software ID. +* +* @note This register is locked for write once the system enters +* usermode. Hence API for reading the register only is provided. +* +*****************************************************************************/ +u32 XDcfg_GetSoftwareIdRegister(XDcfg *InstancePtr) +{ + /* + * Assert the arguments. + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the Software ID Register and return the value. + */ + return XDcfg_ReadReg(InstancePtr->Config.BaseAddr, XDCFG_SW_ID_OFFSET); +} + +/****************************************************************************/ +/** +* +* The function sets the bit mask for the feature in Miscellaneous Control +* Register. +* +* @param InstancePtr is a pointer to the XDcfg instance. +* @param Mask is the bit-mask of the feature to be set. +* +* @return None. +* +* @note None +* +*****************************************************************************/ +void XDcfg_SetMiscControlRegister(XDcfg *InstancePtr, u32 Mask) +{ + u32 RegData; + + /* + * Assert the arguments. + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + + RegData = XDcfg_ReadReg(InstancePtr->Config.BaseAddr, + XDCFG_MCTRL_OFFSET); + + XDcfg_WriteReg(InstancePtr->Config.BaseAddr, XDCFG_MCTRL_OFFSET, + (RegData | Mask)); +} + +/****************************************************************************/ +/** +* +* The function reads the contents of the Miscellaneous Control Register. +* +* @param InstancePtr is a pointer to the XDcfg instance. +* +* @return 32 Bit boot software ID. +* +* @note This register is locked for write once the system enters +* usermode. Hence API to reading the register only is provided. +* +*****************************************************************************/ +u32 XDcfg_GetMiscControlRegister(XDcfg *InstancePtr) +{ + /* + * Assert the arguments. + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the Miscellaneous Control Register and return the value. + */ + return XDcfg_ReadReg(InstancePtr->Config.BaseAddr, XDCFG_MCTRL_OFFSET); +} + +/******************************************************************************/ +/** +* +* This function checks if DMA command queue is full. +* +* @param InstancePtr is a pointer to the XDcfg instance. +* +* @return XST_SUCCESS is the DMA is busy +* XST_FAILURE if the DMA is idle +* +* @note The DMA queue has a depth of two. +* +****************************************************************************/ +u32 XDcfg_IsDmaBusy(XDcfg *InstancePtr) +{ + + u32 RegData; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* Read the PCAP status register for DMA status */ + RegData = XDcfg_ReadReg(InstancePtr->Config.BaseAddr, + XDCFG_STATUS_OFFSET); + + if ((RegData & XDCFG_STATUS_DMA_CMD_Q_F_MASK) == + XDCFG_STATUS_DMA_CMD_Q_F_MASK){ + return XST_SUCCESS; + } + + return XST_FAILURE; +} + +/******************************************************************************/ +/** +* +* This function initiates the DMA transfer. +* +* @param InstancePtr is a pointer to the XDcfg instance. +* @param SourcePtr contains a pointer to the source memory where the data +* is to be transferred from. +* @param SrcWordLength is the number of words (32 bit) to be transferred +* for the source transfer. +* @param DestPtr contains a pointer to the destination memory +* where the data is to be transferred to. +* @param DestWordLength is the number of words (32 bit) to be transferred +* for the Destination transfer. +* +* @return None. +* +* @note It is the responsibility of the caller function to ensure that +* correct values are passed to this function. +* +* The 2 LSBs of the SourcePtr (Source)/ DestPtr (Destination) +* address when equal to 2�b01 indicates the last DMA command of +* an overall transfer. +* +****************************************************************************/ +void XDcfg_InitiateDma(XDcfg *InstancePtr, u32 SourcePtr, u32 DestPtr, + u32 SrcWordLength, u32 DestWordLength) +{ + + XDcfg_WriteReg(InstancePtr->Config.BaseAddr, + XDCFG_DMA_SRC_ADDR_OFFSET, + SourcePtr); + + XDcfg_WriteReg(InstancePtr->Config.BaseAddr, + XDCFG_DMA_DEST_ADDR_OFFSET, + DestPtr); + + XDcfg_WriteReg(InstancePtr->Config.BaseAddr, + XDCFG_DMA_SRC_LEN_OFFSET, + SrcWordLength); + + XDcfg_WriteReg(InstancePtr->Config.BaseAddr, + XDCFG_DMA_DEST_LEN_OFFSET, + DestWordLength); +} + +/******************************************************************************/ +/** +* +* This function Implements the DMA Read Command. This command is used to +* transfer the image data from FPGA to the external memory. +* +* @param InstancePtr is a pointer to the XDcfg instance. +* @param SourcePtr contains a pointer to the source memory where the data +* is to be transferred from. +* @param SrcWordLength is the number of words (32 bit) to be transferred +* for the source transfer. +* @param DestPtr contains a pointer to the destination memory +* where the data is to be transferred to. +* @param DestWordLength is the number of words (32 bit) to be transferred +* for the Destination transfer. +* +* @return - XST_INVALID_PARAM if source address/length is invalid. +* - XST_SUCCESS if DMA transfer initiated properly. +* +* @note None. +* +****************************************************************************/ +static u32 XDcfg_PcapReadback(XDcfg *InstancePtr, u32 SourcePtr, + u32 SrcWordLength, u32 DestPtr, + u32 DestWordLength) +{ + u32 IntrReg; + + /* + * Send READ Frame command to FPGA + */ + XDcfg_InitiateDma(InstancePtr, SourcePtr, XDCFG_DMA_INVALID_ADDRESS, + SrcWordLength, 0); + + /* + * Store the enabled interrupts to enable before the actual read + * transfer is initiated and Disable all the interrupts temporarily. + */ + IntrReg = XDcfg_IntrGetEnabled(InstancePtr); + XDcfg_IntrDisable(InstancePtr, XDCFG_IXR_ALL_MASK); + + /* + * Wait till you get the DMA done for the read command sent + */ + while ((XDcfg_ReadReg(InstancePtr->Config.BaseAddr, + XDCFG_INT_STS_OFFSET) & + XDCFG_IXR_D_P_DONE_MASK) != + XDCFG_IXR_D_P_DONE_MASK); + /* + * Enable the previously stored Interrupts . + */ + XDcfg_IntrEnable(InstancePtr, IntrReg); + + /* + * Initiate the DMA write command. + */ + XDcfg_InitiateDma(InstancePtr, XDCFG_DMA_INVALID_ADDRESS, (u32)DestPtr, + 0, DestWordLength); + + return XST_SUCCESS; +} + + +/****************************************************************************/ +/** +* +* This function starts the DMA transfer. This function only starts the +* operation and returns before the operation may be completed. +* If the interrupt is enabled, an interrupt will be generated when the +* operation is completed, otherwise it is necessary to poll the Status register +* to determine when it is completed. It is the responsibility of the caller to +* determine when the operation is completed by handling the generated interrupt +* or polling the Status Register. +* +* @param InstancePtr is a pointer to the XDcfg instance. +* @param SourcePtr contains a pointer to the source memory where the data +* is to be transferred from. +* @param SrcWordLength is the number of words (32 bit) to be transferred +* for the source transfer. +* @param DestPtr contains a pointer to the destination memory +* where the data is to be transferred to. +* @param DestWordLength is the number of words (32 bit) to be transferred +* for the Destination transfer. +* @param TransferType contains the type of PCAP transfer being requested. +* The definitions can be found in the xdevcfg.h file. +* @return +* - XST_SUCCESS.if DMA transfer initiated successfully +* - XST_DEVICE_BUSY if DMA is busy +* - XST_INVALID_PARAM if invalid Source / Destination address +* is sent or an invalid Source / Destination length is +* sent +* +* @note It is the responsibility of the caller to ensure that the cache +* is flushed and invalidated both before the DMA operation is +* started and after the DMA operation completes if the memory +* pointed to is cached. The caller must also ensure that the +* pointers contain physical address rather than a virtual address +* if address translation is being used. +* +* The 2 LSBs of the SourcePtr (Source)/ DestPtr (Destination) +* address when equal to 2�b01 indicates the last DMA command of +* an overall transfer. +* +*****************************************************************************/ +u32 XDcfg_Transfer(XDcfg *InstancePtr, + void *SourcePtr, u32 SrcWordLength, + void *DestPtr, u32 DestWordLength, + u32 TransferType) +{ + + u32 CtrlReg; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + + if (XDcfg_IsDmaBusy(InstancePtr) == XST_SUCCESS) { + return XST_DEVICE_BUSY; + } + + /* + * Check whether the fabric is in initialized state + */ + if ((XDcfg_ReadReg(InstancePtr->Config.BaseAddr, XDCFG_STATUS_OFFSET) + & XDCFG_STATUS_PCFG_INIT_MASK) == 0) { + /* + * We don't need to check PCFG_INIT to be high for + * non-encrypted loopback transfers. + */ + if (TransferType != XDCFG_CONCURRENT_NONSEC_READ_WRITE) { + return XST_FAILURE; + } + } + + if ((TransferType == XDCFG_SECURE_PCAP_WRITE) || + (TransferType == XDCFG_NON_SECURE_PCAP_WRITE)) { + + /* Check for valid source pointer and length */ + if ((!SourcePtr) || (SrcWordLength == 0)) { + return XST_INVALID_PARAM; + } + + /* Clear internal PCAP loopback */ + CtrlReg = XDcfg_ReadReg(InstancePtr->Config.BaseAddr, + XDCFG_MCTRL_OFFSET); + XDcfg_WriteReg(InstancePtr->Config.BaseAddr, + XDCFG_MCTRL_OFFSET, (CtrlReg & + ~(XDCFG_MCTRL_PCAP_LPBK_MASK))); + + if (TransferType == XDCFG_NON_SECURE_PCAP_WRITE) { + /* + * Clear QUARTER_PCAP_RATE_EN bit + * so that the PCAP data is transmitted every clock + */ + CtrlReg = XDcfg_ReadReg(InstancePtr->Config.BaseAddr, + XDCFG_CTRL_OFFSET); + + XDcfg_WriteReg(InstancePtr->Config.BaseAddr, + XDCFG_CTRL_OFFSET, (CtrlReg & + ~XDCFG_CTRL_PCAP_RATE_EN_MASK)); + + } + if (TransferType == XDCFG_SECURE_PCAP_WRITE) { + /* + * AES engine handles only 8 bit data every clock cycle. + * Hence, Encrypted PCAP data which is 32 bit data can + * only be sent in every 4 clock cycles. Set the control + * register QUARTER_PCAP_RATE_EN bit to achieve this + * operation. + */ + XDcfg_SetControlRegister(InstancePtr, + XDCFG_CTRL_PCAP_RATE_EN_MASK); + } + + XDcfg_InitiateDma(InstancePtr, (u32)SourcePtr, + (u32)DestPtr, SrcWordLength, DestWordLength); + + } + + if (TransferType == XDCFG_PCAP_READBACK) { + + if ((!DestPtr) || (DestWordLength == 0)) { + + return XST_INVALID_PARAM; + } + + /* Clear internal PCAP loopback */ + CtrlReg = XDcfg_ReadReg(InstancePtr->Config.BaseAddr, + XDCFG_MCTRL_OFFSET); + XDcfg_WriteReg(InstancePtr->Config.BaseAddr, + XDCFG_MCTRL_OFFSET, (CtrlReg & + ~(XDCFG_MCTRL_PCAP_LPBK_MASK))); + + /* + * For PCAP readback of FPGA configuration register or memory, + * the read command is first sent (written) to the FPGA fabric + * which responds by returning the required read data. Read data + * from the FPGA is captured if pcap_radata_v is active.A DMA + * read transfer is required to obtain the readback command, + * which is then sent to the FPGA, followed by a DMA write + * transfer to support this mode of operation. + */ + return XDcfg_PcapReadback(InstancePtr, + (u32)SourcePtr, SrcWordLength, + (u32)DestPtr, DestWordLength); + } + + + if ((TransferType == XDCFG_CONCURRENT_SECURE_READ_WRITE) || + (TransferType == XDCFG_CONCURRENT_NONSEC_READ_WRITE)) { + + if ((!SourcePtr) || (SrcWordLength == 0) || + (!DestPtr) || (DestWordLength == 0)) { + return XST_INVALID_PARAM; + } + + if (TransferType == XDCFG_CONCURRENT_NONSEC_READ_WRITE) { + /* Enable internal PCAP loopback */ + CtrlReg = XDcfg_ReadReg(InstancePtr->Config.BaseAddr, + XDCFG_MCTRL_OFFSET); + XDcfg_WriteReg(InstancePtr->Config.BaseAddr, + XDCFG_MCTRL_OFFSET, (CtrlReg | + XDCFG_MCTRL_PCAP_LPBK_MASK)); + + /* + * Clear QUARTER_PCAP_RATE_EN bit + * so that the PCAP data is transmitted every clock + */ + CtrlReg = XDcfg_ReadReg(InstancePtr->Config.BaseAddr, + XDCFG_CTRL_OFFSET); + + XDcfg_WriteReg(InstancePtr->Config.BaseAddr, + XDCFG_CTRL_OFFSET, (CtrlReg & + ~XDCFG_CTRL_PCAP_RATE_EN_MASK)); + + } + if (TransferType == XDCFG_CONCURRENT_SECURE_READ_WRITE) { + /* Clear internal PCAP loopback */ + CtrlReg = XDcfg_ReadReg(InstancePtr->Config.BaseAddr, + XDCFG_MCTRL_OFFSET); + XDcfg_WriteReg(InstancePtr->Config.BaseAddr, + XDCFG_MCTRL_OFFSET, (CtrlReg & + ~(XDCFG_MCTRL_PCAP_LPBK_MASK))); + + /* + * Set the QUARTER_PCAP_RATE_EN bit + * so that the PCAP data is transmitted every 4 clock + * cycles, this is required for encrypted data. + */ + XDcfg_SetControlRegister(InstancePtr, + XDCFG_CTRL_PCAP_RATE_EN_MASK); + } + + XDcfg_InitiateDma(InstancePtr, (u32)SourcePtr, + (u32)DestPtr, SrcWordLength, DestWordLength); + } + + return XST_SUCCESS; +} +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg.h new file mode 100644 index 0000000..6586370 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg.h @@ -0,0 +1,399 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2017 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xdevcfg.h +* @addtogroup devcfg_v3_5 +* @{ +* @details +* +* The is the main header file for the Device Configuration Interface of the Zynq +* device. The device configuration interface has three main functionality. +* 1. AXI-PCAP +* 2. Security Policy +* 3. XADC +* This current version of the driver supports only the AXI-PCAP and Security +* Policy blocks. There is a separate driver for XADC. +* +* AXI-PCAP is used for download/upload an encrypted or decrypted bitstream. +* DMA embedded in the AXI PCAP provides the master interface to +* the Device configuration block for any DMA transfers. The data transfer can +* take place between the Tx/RxFIFOs of AXI-PCAP and memory (on chip +* RAM/DDR/peripheral memory). +* +* The current driver only supports the downloading the FPGA bitstream and +* readback of the decrypted image (sort of loopback). +* The driver does not know what information needs to be written to the FPGA to +* readback FPGA configuration register or memory data. The application above the +* driver should take care of creating the data that needs to be downloaded to +* the FPGA so that the bitstream can be readback. +* This driver also does not support the reading of the internal registers of the +* PCAP. The driver has no knowledge of the PCAP internals. +* +* Initialization and Configuration +* +* The device driver enables higher layer software (e.g., an application) to +* communicate with the Device Configuration device. +* +* XDcfg_CfgInitialize() API is used to initialize the Device Configuration +* Interface. The user needs to first call the XDcfg_LookupConfig() API which +* returns the Configuration structure pointer which is passed as a parameter to +* the XDcfg_CfgInitialize() API. +* +* Interrupts +* The Driver implements an interrupt handler to support the interrupts provided +* by this interface. +* +* Threads +* +* This driver is not thread safe. Any needs for threads or thread mutual +* exclusion must be satisfied by the layer above this driver. +* +* Asserts +* +* Asserts are used within all Xilinx drivers to enforce constraints on argument +* values. Asserts can be turned off on a system-wide basis by defining, at +* compile time, the NDEBUG identifier. By default, asserts are turned on and it +* is recommended that users leave asserts on during development. +* +* Building the driver +* +* The XDcfg driver is composed of several source files. This allows the user +* to build and link only those parts of the driver that are necessary. +* +*

+* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who Date     Changes
+* ----- --- -------- ---------------------------------------------
+* 1.00a hvm 02/07/11 First release
+* 2.00a nm  05/31/12 Updated the driver for CR 660835 so that input length for
+*		     source/destination to the XDcfg_InitiateDma, XDcfg_Transfer
+*		     APIs is words (32 bit) and not bytes.
+* 		     Updated the notes for XDcfg_InitiateDma/XDcfg_Transfer APIs
+*		     to add information that 2 LSBs of the Source/Destination
+*		     address when equal to 2�b01 indicate the last DMA command
+*		     of an overall transfer.
+*		     Destination Address passed to this API for secure transfers
+*		     instead of using 0xFFFFFFFF for CR 662197. This issue was
+*		     resulting in the failure of secure transfers of
+*		     non-bitstream images.
+* 2.01a nm  07/07/12 Updated the XDcfg_IntrClear function to directly
+*		     set the mask instead of oring it with the
+*		     value read from the interrupt status register
+* 		     Added defines for the PS Version bits,
+*	             removed the FIFO Flush bits from the
+*		     Miscellaneous Control Reg.
+*		     Added XDcfg_GetPsVersion, XDcfg_SelectIcapInterface
+*		     and XDcfg_SelectPcapInterface APIs for CR 643295
+*		     The user has to call the XDcfg_SelectIcapInterface API
+*		     for the PL reconfiguration using AXI HwIcap.
+*		     Updated the XDcfg_Transfer API to clear the
+*		     QUARTER_PCAP_RATE_EN bit in the control register for
+*		     non secure writes for CR 675543.
+* 2.02a nm  01/31/13 Fixed CR# 679335.
+* 		     Added Setting and Clearing the internal PCAP loopback.
+*		     Removed code for enabling/disabling AES engine as BootROM
+*		     locks down this setting.
+*		     Fixed CR# 681976.
+*		     Skip Checking the PCFG_INIT in case of non-secure DMA
+*		     loopback.
+*		     Fixed CR# 699558.
+*		     XDcfg_Transfer fails to transfer data in loopback mode.
+*		     Fixed CR# 701348.
+*                    Peripheral test fails with  Running
+* 		     DcfgSelfTestExample() in SECURE bootmode.
+* 2.03a nm  04/19/13 Fixed CR# 703728.
+*		     Updated the register definitions as per the latest TRM
+*		     version UG585 (v1.4) November 16, 2012.
+* 3.0   adk 10/12/13 Updated as per the New Tcl API's
+* 3.0   kpc 21/02/14 Added function prototype for XDcfg_ClearControlRegister
+* 3.2   sb  08/25/14 Fixed XDcfg_PcapReadback() function
+*		     updated driver code with != instead of ==,
+*		     while checking for Interrupt Status with DMA and
+*		     PCAP Done Mask
+*		     ((XDcfg_ReadReg(InstancePtr->Config.BaseAddr,
+*			XDCFG_INT_STS_OFFSET) &
+*			XDCFG_IXR_D_P_DONE_MASK) !=
+*			XDCFG_IXR_D_P_DONE_MASK);
+*		     A new example has been added to read back the
+*		     configuration registers from the PL region.
+*		     xdevcfg_reg_readback_example.c
+* 3.3   sk  04/06/15 Modified XDcfg_ReadMultiBootConfig Macro CR# 851335.
+*       ms  03/17/17 Added readme.txt file in examples folder for doxygen
+*                    generation.
+*       ms  04/10/17 Modified filename tag in interrupt and polled examples
+*                    to include them in doxygen examples.
+* 3.5   ms  04/18/17 Modified tcl file to add suffix U for all macros
+*                    definitions of devcfg in xparameters.h
+*       ms  08/07/17 Fixed compilation warnings in xdevcfg_sinit.c
+* 
+* +******************************************************************************/ +#ifndef XDCFG_H /* prevent circular inclusions */ +#define XDCFG_H /* by using protection macros */ + +/***************************** Include Files *********************************/ + +#include "xdevcfg_hw.h" +#include "xstatus.h" +#include "xil_assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/************************** Constant Definitions *****************************/ + +/* Types of PCAP transfers */ + +#define XDCFG_NON_SECURE_PCAP_WRITE 1 +#define XDCFG_SECURE_PCAP_WRITE 2 +#define XDCFG_PCAP_READBACK 3 +#define XDCFG_CONCURRENT_SECURE_READ_WRITE 4 +#define XDCFG_CONCURRENT_NONSEC_READ_WRITE 5 + + +/**************************** Type Definitions *******************************/ +/** +* The handler data type allows the user to define a callback function to +* respond to interrupt events in the system. This function is executed +* in interrupt context, so amount of processing should be minimized. +* +* @param CallBackRef is the callback reference passed in by the upper +* layer when setting the callback functions, and passed back to +* the upper layer when the callback is invoked. Its type is +* unimportant to the driver component, so it is a void pointer. +* @param Status is the Interrupt status of the XDcfg device. +*/ +typedef void (*XDcfg_IntrHandler) (void *CallBackRef, u32 Status); + +/** + * This typedef contains configuration information for the device. + */ +typedef struct { + u16 DeviceId; /**< Unique ID of device */ + u32 BaseAddr; /**< Base address of the device */ +} XDcfg_Config; + +/** + * The XDcfg driver instance data. + */ +typedef struct { + XDcfg_Config Config; /**< Hardware Configuration */ + u32 IsReady; /**< Device is initialized and ready */ + u32 IsStarted; /**< Device Configuration Interface + * is running + */ + XDcfg_IntrHandler StatusHandler; /* Event handler function */ + void *CallBackRef; /* Callback reference for event handler */ +} XDcfg; + +/****************************************************************************/ +/** +* +* Unlock the Device Config Interface block. +* +* @param InstancePtr is a pointer to the instance of XDcfg driver. +* +* @return None. +* +* @note C-style signature: +* void XDcfg_Unlock(XDcfg* InstancePtr) +* +*****************************************************************************/ +#define XDcfg_Unlock(InstancePtr) \ + XDcfg_WriteReg((InstancePtr)->Config.BaseAddr, \ + XDCFG_UNLOCK_OFFSET, XDCFG_UNLOCK_DATA) + + + +/****************************************************************************/ +/** +* +* Get the version number of the PS from the Miscellaneous Control Register. +* +* @param InstancePtr is a pointer to the instance of XDcfg driver. +* +* @return Version of the PS. +* +* @note C-style signature: +* void XDcfg_GetPsVersion(XDcfg* InstancePtr) +* +*****************************************************************************/ +#define XDcfg_GetPsVersion(InstancePtr) \ + ((XDcfg_ReadReg((InstancePtr)->Config.BaseAddr, \ + XDCFG_MCTRL_OFFSET)) & \ + XDCFG_MCTRL_PCAP_PS_VERSION_MASK) >> \ + XDCFG_MCTRL_PCAP_PS_VERSION_SHIFT + + + +/****************************************************************************/ +/** +* +* Read the multiboot config register value. +* +* @param InstancePtr is a pointer to the instance of XDcfg driver. +* +* @return None. +* +* @note C-style signature: +* u32 XDcfg_ReadMultiBootConfig(XDcfg* InstancePtr) +* +*****************************************************************************/ +#define XDcfg_ReadMultiBootConfig(InstancePtr) \ + XDcfg_ReadReg((InstancePtr)->Config.BaseAddr, \ + XDCFG_MULTIBOOT_ADDR_OFFSET) + + +/****************************************************************************/ +/** +* +* Selects ICAP interface for reconfiguration after the initial configuration +* of the PL. +* +* @param InstancePtr is a pointer to the instance of XDcfg driver. +* +* @return None. +* +* @note C-style signature: +* void XDcfg_SelectIcapInterface(XDcfg* InstancePtr) +* +*****************************************************************************/ +#define XDcfg_SelectIcapInterface(InstancePtr) \ + XDcfg_WriteReg((InstancePtr)->Config.BaseAddr, XDCFG_CTRL_OFFSET, \ + ((XDcfg_ReadReg((InstancePtr)->Config.BaseAddr, XDCFG_CTRL_OFFSET)) \ + & ( ~XDCFG_CTRL_PCAP_PR_MASK))) + +/****************************************************************************/ +/** +* +* Selects PCAP interface for reconfiguration after the initial configuration +* of the PL. +* +* @param InstancePtr is a pointer to the instance of XDcfg driver. +* +* @return None. +* +* @note C-style signature: +* void XDcfg_SelectPcapInterface(XDcfg* InstancePtr) +* +*****************************************************************************/ +#define XDcfg_SelectPcapInterface(InstancePtr) \ + XDcfg_WriteReg((InstancePtr)->Config.BaseAddr, XDCFG_CTRL_OFFSET, \ + ((XDcfg_ReadReg((InstancePtr)->Config.BaseAddr, XDCFG_CTRL_OFFSET)) \ + | XDCFG_CTRL_PCAP_PR_MASK)) + + + +/************************** Function Prototypes ******************************/ + +/* + * Lookup configuration in xdevcfg_sinit.c. + */ +XDcfg_Config *XDcfg_LookupConfig(u16 DeviceId); + +/* + * Selftest function in xdevcfg_selftest.c + */ +int XDcfg_SelfTest(XDcfg *InstancePtr); + +/* + * Interface functions in xdevcfg.c + */ +int XDcfg_CfgInitialize(XDcfg *InstancePtr, + XDcfg_Config *ConfigPtr, u32 EffectiveAddress); + +void XDcfg_EnablePCAP(XDcfg *InstancePtr); + +void XDcfg_DisablePCAP(XDcfg *InstancePtr); + +void XDcfg_SetControlRegister(XDcfg *InstancePtr, u32 Mask); + +void XDcfg_ClearControlRegister(XDcfg *InstancePtr, u32 Mask); + +u32 XDcfg_GetControlRegister(XDcfg *InstancePtr); + +void XDcfg_SetLockRegister(XDcfg *InstancePtr, u32 Data); + +u32 XDcfg_GetLockRegister(XDcfg *InstancePtr); + +void XDcfg_SetConfigRegister(XDcfg *InstancePtr, u32 Data); + +u32 XDcfg_GetConfigRegister(XDcfg *InstancePtr); + +void XDcfg_SetStatusRegister(XDcfg *InstancePtr, u32 Data); + +u32 XDcfg_GetStatusRegister(XDcfg *InstancePtr); + +void XDcfg_SetRomShadowRegister(XDcfg *InstancePtr, u32 Data); + +u32 XDcfg_GetSoftwareIdRegister(XDcfg *InstancePtr); + +void XDcfg_SetMiscControlRegister(XDcfg *InstancePtr, u32 Mask); + +u32 XDcfg_GetMiscControlRegister(XDcfg *InstancePtr); + +u32 XDcfg_IsDmaBusy(XDcfg *InstancePtr); + +void XDcfg_InitiateDma(XDcfg *InstancePtr, u32 SourcePtr, u32 DestPtr, + u32 SrcWordLength, u32 DestWordLength); + +u32 XDcfg_Transfer(XDcfg *InstancePtr, + void *SourcePtr, u32 SrcWordLength, + void *DestPtr, u32 DestWordLength, + u32 TransferType); + +/* + * Interrupt related function prototypes implemented in xdevcfg_intr.c + */ +void XDcfg_IntrEnable(XDcfg *InstancePtr, u32 Mask); + +void XDcfg_IntrDisable(XDcfg *InstancePtr, u32 Mask); + +u32 XDcfg_IntrGetEnabled(XDcfg *InstancePtr); + +u32 XDcfg_IntrGetStatus(XDcfg *InstancePtr); + +void XDcfg_IntrClear(XDcfg *InstancePtr, u32 Mask); + +void XDcfg_InterruptHandler(XDcfg *InstancePtr); + +void XDcfg_SetHandler(XDcfg *InstancePtr, void *CallBackFunc, + void *CallBackRef); + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg_g.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg_g.c new file mode 100644 index 0000000..62b8d43 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg_g.c @@ -0,0 +1,51 @@ + +/******************************************************************* +* +* CAUTION: This file is automatically generated by HSI. +* Version: 2019.1.3 +* DO NOT EDIT. +* +* Copyright (C) 2010-2023 Xilinx, Inc. All Rights Reserved.* +*Permission is hereby granted, free of charge, to any person obtaining a copy +*of this software and associated documentation files (the Software), to deal +*in the Software without restriction, including without limitation the rights +*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +*copies of the Software, and to permit persons to whom the Software is +*furnished to do so, subject to the following conditions: +* +*The above copyright notice and this permission notice shall be included in +*all copies or substantial portions of the Software. +* +*THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +*XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +*OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*Except as contained in this notice, the name of the Xilinx shall not be used +*in advertising or otherwise to promote the sale, use or other dealings in +*this Software without prior written authorization from Xilinx. +* + +* +* Description: Driver configuration +* +*******************************************************************/ + +#include "xparameters.h" +#include "xdevcfg.h" + +/* +* The configuration table for devices +*/ + +XDcfg_Config XDcfg_ConfigTable[] = +{ + { + XPAR_PS7_DEV_CFG_0_DEVICE_ID, + XPAR_PS7_DEV_CFG_0_BASEADDR + } +}; + + diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg_hw.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg_hw.c new file mode 100644 index 0000000..8a1379a --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg_hw.c @@ -0,0 +1,109 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xdevcfg_hw.c +* @addtogroup devcfg_v3_5 +* @{ +* +* This file contains the implementation of the interface reset functionality +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who Date     Changes
+* ----- --- -------- ---------------------------------------------
+* 2.04a kpc 10/07/13 First release
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xdevcfg_hw.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/************************** Variable Definitions *****************************/ + +/*****************************************************************************/ +/** +* This function perform the reset sequence to the given devcfg interface by +* configuring the appropriate control bits in the devcfg specifc registers +* the devcfg reset squence involves the following steps +* Disable all the interuupts +* Clear the status +* Update relevant config registers with reset values +* Disbale the looopback mode and pcap rate enable +* +* @param BaseAddress of the interface +* +* @return N/A +* +* @note +* This function will not modify the slcr registers that are relavant for +* devcfg controller +******************************************************************************/ +void XDcfg_ResetHw(u32 BaseAddr) +{ + u32 Regval = 0; + + /* Mask the interrupts */ + XDcfg_WriteReg(BaseAddr, XDCFG_INT_MASK_OFFSET, + XDCFG_IXR_ALL_MASK); + /* Clear the interuupt status */ + Regval = XDcfg_ReadReg(BaseAddr, XDCFG_INT_STS_OFFSET); + XDcfg_WriteReg(BaseAddr, XDCFG_INT_STS_OFFSET, Regval); + /* Clear the source address register */ + XDcfg_WriteReg(BaseAddr, XDCFG_DMA_SRC_ADDR_OFFSET, 0x0); + /* Clear the destination address register */ + XDcfg_WriteReg(BaseAddr, XDCFG_DMA_DEST_ADDR_OFFSET, 0x0); + /* Clear the source length register */ + XDcfg_WriteReg(BaseAddr, XDCFG_DMA_SRC_LEN_OFFSET, 0x0); + /* Clear the destination length register */ + XDcfg_WriteReg(BaseAddr, XDCFG_DMA_DEST_LEN_OFFSET, 0x0); + /* Clear the loopback enable bit */ + Regval = XDcfg_ReadReg(BaseAddr, XDCFG_MCTRL_OFFSET); + Regval = Regval & ~XDCFG_MCTRL_PCAP_LPBK_MASK; + XDcfg_WriteReg(BaseAddr, XDCFG_MCTRL_OFFSET, Regval); + /*Reset the configuration register to reset value */ + XDcfg_WriteReg(BaseAddr, XDCFG_CFG_OFFSET, + XDCFG_CONFIG_RESET_VALUE); + /*Disable the PCAP rate enable bit */ + Regval = XDcfg_ReadReg(BaseAddr, XDCFG_CTRL_OFFSET); + Regval = Regval & ~XDCFG_CTRL_PCAP_RATE_EN_MASK; + XDcfg_WriteReg(BaseAddr, XDCFG_CTRL_OFFSET, Regval); + +} +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg_hw.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg_hw.h new file mode 100644 index 0000000..80b6678 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg_hw.h @@ -0,0 +1,391 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xdevcfg_hw.h +* @addtogroup devcfg_v3_3 +* @{ +* +* This file contains the hardware interface to the Device Config Interface. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who Date     Changes
+* ----- --- -------- ---------------------------------------------
+* 1.00a hvm 02/07/11 First release
+* 2.01a nm  08/01/12 Added defines for the PS Version bits,
+*	             removed the FIFO Flush bits from the
+*		     Miscellaneous Control Reg
+* 2.03a nm  04/19/13 Fixed CR# 703728.
+*		     Updated the register definitions as per the latest TRM
+*		     version UG585 (v1.4) November 16, 2012.
+* 2.04a	kpc	10/07/13 Added function prototype.
+* 3.00a	kpc	25/02/14 Corrected the XDCFG_BASE_ADDRESS macro value.
+* 
+* +******************************************************************************/ +#ifndef XDCFG_HW_H /* prevent circular inclusions */ +#define XDCFG_HW_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +#include "xil_types.h" +#include "xil_io.h" + +/************************** Constant Definitions *****************************/ + +/** @name Register Map + * Offsets of registers from the start of the device + * @{ + */ + +#define XDCFG_CTRL_OFFSET 0x00 /**< Control Register */ +#define XDCFG_LOCK_OFFSET 0x04 /**< Lock Register */ +#define XDCFG_CFG_OFFSET 0x08 /**< Configuration Register */ +#define XDCFG_INT_STS_OFFSET 0x0C /**< Interrupt Status Register */ +#define XDCFG_INT_MASK_OFFSET 0x10 /**< Interrupt Mask Register */ +#define XDCFG_STATUS_OFFSET 0x14 /**< Status Register */ +#define XDCFG_DMA_SRC_ADDR_OFFSET 0x18 /**< DMA Source Address Register */ +#define XDCFG_DMA_DEST_ADDR_OFFSET 0x1C /**< DMA Destination Address Reg */ +#define XDCFG_DMA_SRC_LEN_OFFSET 0x20 /**< DMA Source Transfer Length */ +#define XDCFG_DMA_DEST_LEN_OFFSET 0x24 /**< DMA Destination Transfer */ +#define XDCFG_ROM_SHADOW_OFFSET 0x28 /**< DMA ROM Shadow Register */ +#define XDCFG_MULTIBOOT_ADDR_OFFSET 0x2C /**< Multi BootAddress Pointer */ +#define XDCFG_SW_ID_OFFSET 0x30 /**< Software ID Register */ +#define XDCFG_UNLOCK_OFFSET 0x34 /**< Unlock Register */ +#define XDCFG_MCTRL_OFFSET 0x80 /**< Miscellaneous Control Reg */ + +/* @} */ + +/** @name Control Register Bit definitions + * @{ + */ + +#define XDCFG_CTRL_FORCE_RST_MASK 0x80000000 /**< Force into + * Secure Reset + */ +#define XDCFG_CTRL_PCFG_PROG_B_MASK 0x40000000 /**< Program signal to + * Reset FPGA + */ +#define XDCFG_CTRL_PCFG_POR_CNT_4K_MASK 0x20000000 /**< Control PL POR timer */ +#define XDCFG_CTRL_PCAP_PR_MASK 0x08000000 /**< Enable PCAP for PR */ +#define XDCFG_CTRL_PCAP_MODE_MASK 0x04000000 /**< Enable PCAP */ +#define XDCFG_CTRL_PCAP_RATE_EN_MASK 0x02000000 /**< Enable PCAP send data + * to FPGA every 4 PCAP + * cycles + */ +#define XDCFG_CTRL_MULTIBOOT_EN_MASK 0x01000000 /**< Multiboot Enable */ +#define XDCFG_CTRL_JTAG_CHAIN_DIS_MASK 0x00800000 /**< JTAG Chain Disable */ +#define XDCFG_CTRL_USER_MODE_MASK 0x00008000 /**< User Mode Mask */ +#define XDCFG_CTRL_PCFG_AES_FUSE_MASK 0x00001000 /**< AES key source */ +#define XDCFG_CTRL_PCFG_AES_EN_MASK 0x00000E00 /**< AES Enable Mask */ +#define XDCFG_CTRL_SEU_EN_MASK 0x00000100 /**< SEU Enable Mask */ +#define XDCFG_CTRL_SEC_EN_MASK 0x00000080 /**< Secure/Non Secure + * Status mask + */ +#define XDCFG_CTRL_SPNIDEN_MASK 0x00000040 /**< Secure Non Invasive + * Debug Enable + */ +#define XDCFG_CTRL_SPIDEN_MASK 0x00000020 /**< Secure Invasive + * Debug Enable + */ +#define XDCFG_CTRL_NIDEN_MASK 0x00000010 /**< Non-Invasive Debug + * Enable + */ +#define XDCFG_CTRL_DBGEN_MASK 0x00000008 /**< Invasive Debug + * Enable + */ +#define XDCFG_CTRL_DAP_EN_MASK 0x00000007 /**< DAP Enable Mask */ + +/* @} */ + +/** @name Lock register bit definitions + * @{ + */ + +#define XDCFG_LOCK_AES_EFUSE_MASK 0x00000010 /**< Lock AES Efuse bit */ +#define XDCFG_LOCK_AES_EN_MASK 0x00000008 /**< Lock AES_EN update */ +#define XDCFG_LOCK_SEU_MASK 0x00000004 /**< Lock SEU_En update */ +#define XDCFG_LOCK_SEC_MASK 0x00000002 /**< Lock SEC_EN and + * USER_MODE + */ +#define XDCFG_LOCK_DBG_MASK 0x00000001 /**< This bit locks + * security config + * including: DAP_En, + * DBGEN,, + * NIDEN, SPNIEN + */ +/*@}*/ + + + +/** @name Config Register Bit definitions + * @{ + */ +#define XDCFG_CFG_RFIFO_TH_MASK 0x00000C00 /**< Read FIFO + * Threshold Mask + */ +#define XDCFG_CFG_WFIFO_TH_MASK 0x00000300 /**< Write FIFO Threshold + * Mask + */ +#define XDCFG_CFG_RCLK_EDGE_MASK 0x00000080 /**< Read data active + * clock edge + */ +#define XDCFG_CFG_WCLK_EDGE_MASK 0x00000040 /**< Write data active + * clock edge + */ +#define XDCFG_CFG_DISABLE_SRC_INC_MASK 0x00000020 /**< Disable Source address + * increment mask + */ +#define XDCFG_CFG_DISABLE_DST_INC_MASK 0x00000010 /**< Disable Destination + * address increment + * mask + */ +/* @} */ + + +/** @name Interrupt Status/Mask Register Bit definitions + * @{ + */ +#define XDCFG_IXR_PSS_GTS_USR_B_MASK 0x80000000 /**< Tri-state IO during + * HIZ + */ +#define XDCFG_IXR_PSS_FST_CFG_B_MASK 0x40000000 /**< First configuration + * done + */ +#define XDCFG_IXR_PSS_GPWRDWN_B_MASK 0x20000000 /**< Global power down */ +#define XDCFG_IXR_PSS_GTS_CFG_B_MASK 0x10000000 /**< Tri-state IO during + * configuration + */ +#define XDCFG_IXR_PSS_CFG_RESET_B_MASK 0x08000000 /**< PL configuration + * reset + */ +#define XDCFG_IXR_AXI_WTO_MASK 0x00800000 /**< AXI Write Address + * or Data or response + * timeout + */ +#define XDCFG_IXR_AXI_WERR_MASK 0x00400000 /**< AXI Write response + * error + */ +#define XDCFG_IXR_AXI_RTO_MASK 0x00200000 /**< AXI Read Address or + * response timeout + */ +#define XDCFG_IXR_AXI_RERR_MASK 0x00100000 /**< AXI Read response + * error + */ +#define XDCFG_IXR_RX_FIFO_OV_MASK 0x00040000 /**< Rx FIFO Overflow */ +#define XDCFG_IXR_WR_FIFO_LVL_MASK 0x00020000 /**< Tx FIFO less than + * threshold */ +#define XDCFG_IXR_RD_FIFO_LVL_MASK 0x00010000 /**< Rx FIFO greater than + * threshold */ +#define XDCFG_IXR_DMA_CMD_ERR_MASK 0x00008000 /**< Illegal DMA command */ +#define XDCFG_IXR_DMA_Q_OV_MASK 0x00004000 /**< DMA command queue + * overflow + */ +#define XDCFG_IXR_DMA_DONE_MASK 0x00002000 /**< DMA Command Done */ +#define XDCFG_IXR_D_P_DONE_MASK 0x00001000 /**< DMA and PCAP + * transfers Done + */ +#define XDCFG_IXR_P2D_LEN_ERR_MASK 0x00000800 /**< PCAP to DMA transfer + * length error + */ +#define XDCFG_IXR_PCFG_HMAC_ERR_MASK 0x00000040 /**< HMAC error mask */ +#define XDCFG_IXR_PCFG_SEU_ERR_MASK 0x00000020 /**< SEU Error mask */ +#define XDCFG_IXR_PCFG_POR_B_MASK 0x00000010 /**< FPGA POR mask */ +#define XDCFG_IXR_PCFG_CFG_RST_MASK 0x00000008 /**< FPGA Reset mask */ +#define XDCFG_IXR_PCFG_DONE_MASK 0x00000004 /**< Done Signal Mask */ +#define XDCFG_IXR_PCFG_INIT_PE_MASK 0x00000002 /**< Detect Positive edge + * of Init Signal + */ +#define XDCFG_IXR_PCFG_INIT_NE_MASK 0x00000001 /**< Detect Negative edge + * of Init Signal + */ +#define XDCFG_IXR_ERROR_FLAGS_MASK (XDCFG_IXR_AXI_WTO_MASK | \ + XDCFG_IXR_AXI_WERR_MASK | \ + XDCFG_IXR_AXI_RTO_MASK | \ + XDCFG_IXR_AXI_RERR_MASK | \ + XDCFG_IXR_RX_FIFO_OV_MASK | \ + XDCFG_IXR_DMA_CMD_ERR_MASK |\ + XDCFG_IXR_DMA_Q_OV_MASK | \ + XDCFG_IXR_P2D_LEN_ERR_MASK |\ + XDCFG_IXR_PCFG_HMAC_ERR_MASK) + + +#define XDCFG_IXR_ALL_MASK 0x00F7F8EF + + + +/* @} */ + + +/** @name Status Register Bit definitions + * @{ + */ +#define XDCFG_STATUS_DMA_CMD_Q_F_MASK 0x80000000 /**< DMA command + * Queue full + */ +#define XDCFG_STATUS_DMA_CMD_Q_E_MASK 0x40000000 /**< DMA command + * Queue empty + */ +#define XDCFG_STATUS_DMA_DONE_CNT_MASK 0x30000000 /**< Number of + * completed DMA + * transfers + */ +#define XDCFG_STATUS_RX_FIFO_LVL_MASK 0x01F000000 /**< Rx FIFO level */ +#define XDCFG_STATUS_TX_FIFO_LVL_MASK 0x0007F000 /**< Tx FIFO level */ + +#define XDCFG_STATUS_PSS_GTS_USR_B 0x00000800 /**< Tri-state IO + * during HIZ + */ +#define XDCFG_STATUS_PSS_FST_CFG_B 0x00000400 /**< First PL config + * done + */ +#define XDCFG_STATUS_PSS_GPWRDWN_B 0x00000200 /**< Global power down */ +#define XDCFG_STATUS_PSS_GTS_CFG_B 0x00000100 /**< Tri-state IO during + * config + */ +#define XDCFG_STATUS_SECURE_RST_MASK 0x00000080 /**< Secure Reset + * POR Status + */ +#define XDCFG_STATUS_ILLEGAL_APB_ACCESS_MASK 0x00000040 /**< Illegal APB + * access + */ +#define XDCFG_STATUS_PSS_CFG_RESET_B 0x00000020 /**< PL config + * reset status + */ +#define XDCFG_STATUS_PCFG_INIT_MASK 0x00000010 /**< FPGA Init + * Status + */ +#define XDCFG_STATUS_EFUSE_BBRAM_KEY_DISABLE_MASK 0x00000008 + /**< BBRAM key + * disable + */ +#define XDCFG_STATUS_EFUSE_SEC_EN_MASK 0x00000004 /**< Efuse Security + * Enable Status + */ +#define XDCFG_STATUS_EFUSE_JTAG_DIS_MASK 0x00000002 /**< EFuse JTAG + * Disable + * status + */ +/* @} */ + + +/** @name DMA Source/Destination Transfer Length Register Bit definitions + * @{ + */ +#define XDCFG_DMA_LEN_MASK 0x7FFFFFF /**< Length Mask */ +/*@}*/ + + + + +/** @name Miscellaneous Control Register Bit definitions + * @{ + */ +#define XDCFG_MCTRL_PCAP_PS_VERSION_MASK 0xF0000000 /**< PS Version Mask */ +#define XDCFG_MCTRL_PCAP_PS_VERSION_SHIFT 28 /**< PS Version Shift */ +#define XDCFG_MCTRL_PCAP_LPBK_MASK 0x00000010 /**< PCAP loopback mask */ +/* @} */ + +/** @name FIFO Threshold Bit definitions + * @{ + */ + +#define XDCFG_CFG_FIFO_QUARTER 0x0 /**< Quarter empty */ +#define XDCFG_CFG_FIFO_HALF 0x1 /**< Half empty */ +#define XDCFG_CFG_FIFO_3QUARTER 0x2 /**< 3/4 empty */ +#define XDCFG_CFG_FIFO_EMPTY 0x4 /**< Empty */ +/* @}*/ + + +/* Miscellaneous constant values */ +#define XDCFG_DMA_INVALID_ADDRESS 0xFFFFFFFF /**< Invalid DMA address */ +#define XDCFG_UNLOCK_DATA 0x757BDF0D /**< First APB access data*/ +#define XDCFG_BASE_ADDRESS 0xF8007000 /**< Device Config base + * address + */ +#define XDCFG_CONFIG_RESET_VALUE 0x508 /**< Config reg reset value */ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/****************************************************************************/ +/** +* +* Read the given register. +* +* @param BaseAddr is the base address of the device +* @param RegOffset is the register offset to be read +* +* @return The 32-bit value of the register +* +* @note C-style signature: +* u32 XDcfg_ReadReg(u32 BaseAddr, u32 RegOffset) +* +*****************************************************************************/ +#define XDcfg_ReadReg(BaseAddr, RegOffset) \ + Xil_In32((BaseAddr) + (RegOffset)) + +/****************************************************************************/ +/** +* +* Write to the given register. +* +* @param BaseAddr is the base address of the device +* @param RegOffset is the register offset to be written +* @param Data is the 32-bit value to write to the register +* +* @return None. +* +* @note C-style signature: +* void XDcfg_WriteReg(u32 BaseAddr, u32 RegOffset, u32 Data) +* +*****************************************************************************/ +#define XDcfg_WriteReg(BaseAddr, RegOffset, Data) \ + Xil_Out32((BaseAddr) + (RegOffset), (Data)) + +/************************** Function Prototypes ******************************/ +/* + * Perform reset operation to the devcfg interface + */ +void XDcfg_ResetHw(u32 BaseAddr); +/************************** Variable Definitions *****************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg_intr.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg_intr.c new file mode 100644 index 0000000..f0e5044 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg_intr.c @@ -0,0 +1,306 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xdevcfg_intr.c +* @addtogroup devcfg_v3_5 +* @{ +* +* Contains the implementation of interrupt related functions of the XDcfg +* driver. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who Date     Changes
+* ----- --- -------- ---------------------------------------------
+* 1.00a hvm 02/07/11 First release
+* 2.01a nm  07/07/12 Updated the XDcfg_IntrClear function to directly
+*		     set the mask instead of oring it with the
+*		     value read from the interrupt status register
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xdevcfg.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/************************** Variable Definitions *****************************/ + +/****************************************************************************/ +/** +* +* This function enables the specified interrupts in the device. +* +* @param InstancePtr is a pointer to the XDcfg instance. +* @param Mask is the bit-mask of the interrupts to be enabled. +* Bit positions of 1 will be enabled. Bit positions of 0 will +* keep the previous setting. This mask is formed by OR'ing +* XDCFG_INT_* bits defined in xdevcfg_hw.h. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XDcfg_IntrEnable(XDcfg *InstancePtr, u32 Mask) +{ + u32 RegValue; + + /* + * Assert the arguments. + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Enable the specified interrupts in the Interrupt Mask Register. + */ + RegValue = XDcfg_ReadReg(InstancePtr->Config.BaseAddr, + XDCFG_INT_MASK_OFFSET); + RegValue &= ~(Mask & XDCFG_IXR_ALL_MASK); + XDcfg_WriteReg(InstancePtr->Config.BaseAddr, + XDCFG_INT_MASK_OFFSET, + RegValue); +} + + +/****************************************************************************/ +/** +* +* This function disables the specified interrupts in the device. +* +* @param InstancePtr is a pointer to the XDcfg instance. +* @param Mask is the bit-mask of the interrupts to be disabled. +* Bit positions of 1 will be disabled. Bit positions of 0 will +* keep the previous setting. This mask is formed by OR'ing +* XDCFG_INT_* bits defined in xdevcfg_hw.h. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XDcfg_IntrDisable(XDcfg *InstancePtr, u32 Mask) +{ + u32 RegValue; + + /* + * Assert the arguments. + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Disable the specified interrupts in the Interrupt Mask Register. + */ + RegValue = XDcfg_ReadReg(InstancePtr->Config.BaseAddr, + XDCFG_INT_MASK_OFFSET); + RegValue |= (Mask & XDCFG_IXR_ALL_MASK); + XDcfg_WriteReg(InstancePtr->Config.BaseAddr, + XDCFG_INT_MASK_OFFSET, + RegValue); +} +/****************************************************************************/ +/** +* +* This function returns the enabled interrupts read from the Interrupt Mask +* Register. Use the XDCFG_INT_* constants defined in xdevcfg_hw.h +* to interpret the returned value. +* +* @param InstancePtr is a pointer to the XDcfg instance. +* +* @return A 32-bit value representing the contents of the IMR. +* +* @note None. +* +*****************************************************************************/ +u32 XDcfg_IntrGetEnabled(XDcfg *InstancePtr) +{ + /* + * Assert the arguments. + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Return the value read from the Interrupt Mask Register. + */ + return (~ XDcfg_ReadReg(InstancePtr->Config.BaseAddr, + XDCFG_INT_MASK_OFFSET)); +} + +/****************************************************************************/ +/** +* +* This function returns the interrupt status read from Interrupt Status +* Register. Use the XDCFG_INT_* constants defined in xdevcfg_hw.h +* to interpret the returned value. +* +* @param InstancePtr is a pointer to the XDcfg instance. +* +* @return A 32-bit value representing the contents of the Interrupt +* Status register. +* +* @note None. +* +*****************************************************************************/ +u32 XDcfg_IntrGetStatus(XDcfg *InstancePtr) +{ + /* + * Assert the arguments. + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Return the value read from the Interrupt Status register. + */ + return XDcfg_ReadReg(InstancePtr->Config.BaseAddr, + XDCFG_INT_STS_OFFSET); +} + +/****************************************************************************/ +/** +* +* This function clears the specified interrupts in the Interrupt Status +* Register. +* +* @param InstancePtr is a pointer to the XDcfg instance. +* @param Mask is the bit-mask of the interrupts to be cleared. +* Bit positions of 1 will be cleared. Bit positions of 0 will not +* change the previous interrupt status. This mask is formed by +* OR'ing XDCFG_INT_* bits which are defined in xdevcfg_hw.h. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XDcfg_IntrClear(XDcfg *InstancePtr, u32 Mask) +{ + /* + * Assert the arguments. + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + XDcfg_WriteReg(InstancePtr->Config.BaseAddr, + XDCFG_INT_STS_OFFSET, + Mask); + +} + +/*****************************************************************************/ +/** +* The interrupt handler for the Device Config Interface. +* +* Events are signaled to upper layer for proper handling. +* +* +* @param InstancePtr is a pointer to the XDcfg instance. +* +* @return None. +* +* @note None. +* +****************************************************************************/ +void XDcfg_InterruptHandler(XDcfg *InstancePtr) +{ + u32 IntrStatusReg; + + /* + * Assert validates the input arguments. + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the Interrupt status register. + */ + IntrStatusReg = XDcfg_ReadReg(InstancePtr->Config.BaseAddr, + XDCFG_INT_STS_OFFSET); + + /* + * Write the status back to clear the interrupts so that no + * subsequent interrupts are missed while processing this interrupt. + * This also does the DMA acknowledgment automatically. + */ + XDcfg_WriteReg(InstancePtr->Config.BaseAddr, + XDCFG_INT_STS_OFFSET, IntrStatusReg); + + /* + * Signal application that there are events to handle. + */ + InstancePtr->StatusHandler(InstancePtr->CallBackRef, + IntrStatusReg); + +} + +/****************************************************************************/ +/** +* +* This function sets the handler that will be called when an event (interrupt) +* occurs that needs application's attention. +* +* @param InstancePtr is a pointer to the XDcfg instance +* @param CallBackFunc is the address of the callback function. +* @param CallBackRef is a user data item that will be passed to the +* callback function when it is invoked. +* +* @return None. +* +* @note None. +* +* +*****************************************************************************/ +void XDcfg_SetHandler(XDcfg *InstancePtr, void *CallBackFunc, + void *CallBackRef) +{ + /* + * Asserts validate the input arguments + * CallBackRef not checked, no way to know what is valid + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(CallBackFunc != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + InstancePtr->StatusHandler = (XDcfg_IntrHandler) CallBackFunc; + InstancePtr->CallBackRef = CallBackRef; +} +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg_selftest.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg_selftest.c new file mode 100644 index 0000000..e8fc663 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg_selftest.c @@ -0,0 +1,110 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xdevcfg_selftest.c +* @addtogroup devcfg_v3_5 +* @{ +* +* Contains diagnostic self-test functions for the XDcfg driver. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who Date     Changes
+* ----- --- -------- ---------------------------------------------
+* 1.00a hvm 02/07/11 First release
+* 2.02a nm  02/27/13 Fixed CR# 701348.
+*                    Peripheral test fails with  Running
+* 		     DcfgSelfTestExample() in SECURE bootmode.
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xdevcfg.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/************************** Variable Definitions *****************************/ + +/****************************************************************************/ +/** +* +* Run a self-test on the Device Configuration Interface. This test does a +* control register write and reads back the same value. +* +* @param InstancePtr is a pointer to the XDcfg instance. +* +* @return +* - XST_SUCCESS if self-test was successful. +* - XST_FAILURE if fails. +* +* @note None. +* +******************************************************************************/ +int XDcfg_SelfTest(XDcfg *InstancePtr) +{ + u32 OldCfgReg; + u32 CfgReg; + int Status = XST_SUCCESS; + + /* + * Assert to ensure the inputs are valid and the instance has been + * initialized. + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + OldCfgReg = XDcfg_GetControlRegister(InstancePtr); + + XDcfg_SetControlRegister(InstancePtr, XDCFG_CTRL_NIDEN_MASK); + + CfgReg = XDcfg_GetControlRegister(InstancePtr); + + if ((CfgReg & XDCFG_CTRL_NIDEN_MASK) != XDCFG_CTRL_NIDEN_MASK) { + + Status = XST_FAILURE; + } + + /* + * Restore the original values of the register + */ + XDcfg_SetControlRegister(InstancePtr, OldCfgReg); + + return Status; +} +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg_sinit.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg_sinit.c new file mode 100644 index 0000000..838db3a --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg_sinit.c @@ -0,0 +1,90 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2017 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xdevcfg_sinit.c +* @addtogroup devcfg_v3_5 +* @{ +* +* This file contains method for static initialization (compile-time) of the +* driver. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who Date     Changes
+* ----- --- -------- ---------------------------------------------
+* 1.00a hvm 02/07/11 First release
+* 3.5   ms  08/07/17 Fixed compilation warnings.
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xdevcfg.h" +#include "xparameters.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/*****************************************************************************/ +/** +* Lookup the device configuration based on the unique device ID. The table +* contains the configuration info for each device in the system. +* +* @param DeviceId is the unique device ID of the device being looked up. +* +* @return A pointer to the configuration table entry corresponding to the +* given device ID, or NULL if no match is found. +* +* @note None. +* +******************************************************************************/ +XDcfg_Config *XDcfg_LookupConfig(u16 DeviceId) +{ + extern XDcfg_Config XDcfg_ConfigTable[]; + XDcfg_Config *CfgPtr = NULL; + u32 Index; + + for (Index = 0U; Index < XPAR_XDCFG_NUM_INSTANCES; Index++) { + if (XDcfg_ConfigTable[Index].DeviceId == DeviceId) { + CfgPtr = &XDcfg_ConfigTable[Index]; + break; + } + } + + return (CfgPtr); +} +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/Makefile b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/Makefile new file mode 100644 index 0000000..d1240c5 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/Makefile @@ -0,0 +1,41 @@ +COMPILER= +ARCHIVER= +CP=cp +COMPILER_FLAGS= +EXTRA_COMPILER_FLAGS= +LIB=libxil.a + +CC_FLAGS = $(COMPILER_FLAGS) +ECC_FLAGS = $(EXTRA_COMPILER_FLAGS) + +RELEASEDIR=../../../lib +INCLUDEDIR=../../../include +INCLUDES=-I./. -I${INCLUDEDIR} + +OUTS = *.o + +LIBSOURCES:=*.c +INCLUDEFILES:=*.h + +OBJECTS = $(addsuffix .o, $(basename $(wildcard *.c))) + +libs: banner xdmaps_libs clean + +%.o: %.c + ${COMPILER} $(CC_FLAGS) $(ECC_FLAGS) $(INCLUDES) -o $@ $< + +banner: + echo "Compiling dmaps" + +xdmaps_libs: ${OBJECTS} + $(ARCHIVER) -r ${RELEASEDIR}/${LIB} ${OBJECTS} + +.PHONY: include +include: xdmaps_includes + +xdmaps_includes: + ${CP} ${INCLUDEFILES} ${INCLUDEDIR} + +clean: + rm -rf ${OBJECTS} + diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps.c new file mode 100644 index 0000000..b30a66f --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps.c @@ -0,0 +1,1978 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xdmaps.c +* @addtogroup dmaps_v2_4 +* @{ +* +* This file contains the implementation of the interface functions for XDmaPs +* driver. Refer to the header file xdmaps.h for more detailed information. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  	Date     Changes
+* ----- ------ -------- ----------------------------------------------
+* 1.00	hbm    08/19/2010 First Release
+* 1.00  nm     05/25/2011 Updated for minor doxygen corrections
+* 1.02a sg     05/16/2012 Made changes for doxygen and moved some function
+*			  header from the xdmaps.h file to xdmaps.c file
+*			  Other cleanup for coding guidelines and CR 657109
+*			  and CR 657898
+* 1.03a sg     07/16/2012 changed inline to __inline for CR665681
+* 1.04a nm     10/22/2012 Fixed CR# 681671.
+* 1.05a nm     04/15/2013 Fixed CR# 704396. Removed warnings when compiled
+*			  with -Wall and -Wextra option in bsp.
+*	       05/01/2013 Fixed CR# 700189. Changed XDmaPs_BuildDmaProg()
+*			  function description.
+*			  Fixed CR# 704396. Removed unused variables
+*			  UseM2MByte & MemBurstLen from XDmaPs_BuildDmaProg()
+*			  function.
+* 1.07a asa    11/02/13. Made changes to fix compilation issues for iarcc.
+*			   Removed the PDBG prints. By default they were always
+*			   defined out and never used. The PDBG is non-standard for
+*			   Xilinx drivers and no other driver does something similar.
+*			   Since there is no easy way to fix compilation issues with
+*			   the IARCC compiler around PDBG, it is better to remove it.
+*			   Users can always use xil_printfs if they want to debug.
+* 2.01 kpc    08/23/14   Fixed the IAR compiler reported errors
+* 2.2  mus    12/08/16   Remove definition of INLINE macro to avoid re-definition,
+*                         since it is being defined in xil_io.h
+* 2.3 kpc     14/10/16   Fixed the compiler error when optimization O0 is used.
+* 
+* +*****************************************************************************/ + +/***************************** Include Files ********************************/ + +#include + +#include "xstatus.h" +#include "xdmaps.h" +#include "xil_io.h" +#include "xil_cache.h" + +#include "xil_printf.h" + + +/************************** Constant Definitions ****************************/ + +/* The following constant defines the amount of error that is allowed for + * a specified baud rate. This error is the difference between the actual + * baud rate that will be generated using the specified clock and the + * desired baud rate. + */ + +/**************************** Type Definitions ******************************/ + +/***************** Macros (Inline Functions) Definitions ********************/ + + +/************************** Function Prototypes *****************************/ +static int XDmaPs_Exec_DMAKILL(u32 BaseAddr, + unsigned int Channel, + unsigned int Thread); + +static void XDmaPs_BufPool_Free(XDmaPs_ProgBuf *Pool, void *Buf); + +static int XDmaPs_Exec_DMAGO(u32 BaseAddr, unsigned int Channel, u32 DmaProg); + +static void XDmaPs_DoneISR_n(XDmaPs *InstPtr, unsigned Channel); +static void *XDmaPs_BufPool_Allocate(XDmaPs_ProgBuf *Pool); +static int XDmaPs_BuildDmaProg(unsigned Channel, XDmaPs_Cmd *Cmd, + unsigned CacheLength); + +static void XDmaPs_Print_DmaProgBuf(char *Buf, int Length); + + + +/************************** Variable Definitions ****************************/ + +/****************************************************************************/ +/** +* +* Initializes a specific XDmaPs instance such that it is ready to be used. +* The data format of the device is setup for 8 data bits, 1 stop bit, and no +* parity by default. The baud rate is set to a default value specified by +* Config->DefaultBaudRate if set, otherwise it is set to 19.2K baud. The +* receive FIFO threshold is set for 8 bytes. The default operating mode of the +* driver is polled mode. +* +* @param InstPtr is a pointer to the XDmaPs instance. +* @param Config is a reference to a structure containing information +* about a specific XDmaPs driver. +* @param EffectiveAddr is the device base address in the virtual memory +* address space. The caller is responsible for keeping the +* address mapping from EffectiveAddr to the device physical base +* address unchanged once this function is invoked. Unexpected +* errors may occur if the address mapping changes after this +* function is called. If address translation is not used, pass in +* the physical address instead. +* +* @return +* +* - XST_SUCCESS on initialization completion +* +* @note None. +* +*****************************************************************************/ +int XDmaPs_CfgInitialize(XDmaPs *InstPtr, + XDmaPs_Config *Config, + u32 EffectiveAddr) +{ + int Status = XST_SUCCESS; + unsigned int CacheLength = 0; + u32 CfgReg; + unsigned Channel; + XDmaPs_ChannelData *ChanData; + + /* + * Assert validates the input arguments + */ + Xil_AssertNonvoid(InstPtr != NULL); + Xil_AssertNonvoid(Config != NULL); + + /* + * Setup the driver instance using passed in parameters + */ + InstPtr->Config.DeviceId = Config->DeviceId; + InstPtr->Config.BaseAddress = EffectiveAddr; + + CfgReg = XDmaPs_ReadReg(EffectiveAddr, XDMAPS_CR1_OFFSET); + CacheLength = CfgReg & XDMAPS_CR1_I_CACHE_LEN_MASK; + if (CacheLength < 2 || CacheLength > 5) + CacheLength = 0; + else + CacheLength = 1 << CacheLength; + + InstPtr->CacheLength = CacheLength; + + memset(InstPtr->Chans, 0, + sizeof(XDmaPs_ChannelData[XDMAPS_CHANNELS_PER_DEV])); + + for (Channel = 0; Channel < XDMAPS_CHANNELS_PER_DEV; Channel++) { + ChanData = InstPtr->Chans + Channel; + ChanData->ChanId = Channel; + ChanData->DevId = Config->DeviceId; + } + + InstPtr->IsReady = 1; + + return Status; +} + +/****************************************************************************/ +/** +* +* Reset the DMA Manager. +* +* @param InstPtr is the DMA instance. +* +* @return 0 on success, -1 on time out +* +* @note None. +* +*****************************************************************************/ +int XDmaPs_ResetManager(XDmaPs *InstPtr) +{ + int Status; + Status = XDmaPs_Exec_DMAKILL(InstPtr->Config.BaseAddress, + 0, 0); + + return Status; +} + +/****************************************************************************/ +/** +* +* Reset the specified DMA Channel. +* +* @param InstPtr is the DMA instance. +* @param Channel is the channel to be reset. +* +* @return 0 on success, -1 on time out +* +* @note None. +* +*****************************************************************************/ +int XDmaPs_ResetChannel(XDmaPs *InstPtr, unsigned int Channel) +{ + int Status; + Status = XDmaPs_Exec_DMAKILL(InstPtr->Config.BaseAddress, + Channel, 1); + + return Status; + +} + +/*****************************************************************************/ +/** +* +* Driver fault interrupt service routine +* This is the one that connects the GIC +* +* @param InstPtr is the DMA instance. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XDmaPs_FaultISR(XDmaPs *InstPtr) +{ + + void *DmaProgBuf; + u32 Fsm; /* Fault status DMA manager register value */ + u32 Fsc; /* Fault status DMA channel register value */ + u32 FaultType; /* Fault type DMA manager register value */ + + u32 BaseAddr = InstPtr->Config.BaseAddress; + + u32 Pc; /* DMA Pc or channel Pc */ + XDmaPs_ChannelData *ChanData; + + unsigned Chan; + unsigned DevId; + + XDmaPs_Cmd *DmaCmd; + + Fsm = XDmaPs_ReadReg(BaseAddr, XDMAPS_FSM_OFFSET) & 0x01; + Fsc = XDmaPs_ReadReg(BaseAddr, XDMAPS_FSC_OFFSET) & 0xFF; + + + DevId = InstPtr->Config.DeviceId; + + if (Fsm) { + /* + * if DMA manager is fault + */ + FaultType = XDmaPs_ReadReg(BaseAddr, XDMAPS_FTM_OFFSET); + Pc = XDmaPs_ReadReg(BaseAddr, XDMAPS_DPC_OFFSET); + + xil_printf("PL330 device %d fault with type: %x at Pc %x\n", + DevId, + FaultType, Pc); + + /* kill the DMA manager thread */ + /* Should we disable interrupt?*/ + XDmaPs_Exec_DMAKILL(BaseAddr, 0, 0); + } + + /* + * check which channel faults and kill the channel thread + */ + for (Chan = 0; + Chan < XDMAPS_CHANNELS_PER_DEV; + Chan++) { + if (Fsc & (0x01 << Chan)) { + FaultType = + XDmaPs_ReadReg(BaseAddr, + XDmaPs_FTCn_OFFSET(Chan)); + Pc = XDmaPs_ReadReg(BaseAddr, + XDmaPs_CPCn_OFFSET(Chan)); + + /* kill the channel thread */ + /* Should we disable interrupt? */ + XDmaPs_Exec_DMAKILL(BaseAddr, Chan, 1); + + /* + * get the fault type and fault Pc and invoke the + * fault callback. + */ + ChanData = InstPtr->Chans + Chan; + + DmaCmd = ChanData->DmaCmdToHw; + + /* Should we check DmaCmd is not null */ + DmaCmd->DmaStatus = -1; + DmaCmd->ChanFaultType = FaultType; + DmaCmd->ChanFaultPCAddr = Pc; + ChanData->DmaCmdFromHw = DmaCmd; + ChanData->DmaCmdToHw = NULL; + + if (!ChanData->HoldDmaProg) { + DmaProgBuf = (void *)DmaCmd->GeneratedDmaProg; + if (DmaProgBuf) + XDmaPs_BufPool_Free(ChanData->ProgBufPool, + DmaProgBuf); + DmaCmd->GeneratedDmaProg = NULL; + } + + if (InstPtr->FaultHandler) + InstPtr->FaultHandler(Chan, + DmaCmd, + InstPtr->FaultRef); + + } + } + +} + +/*****************************************************************************/ +/** +* +* Set the done handler for a channel. +* +* @param InstPtr is the DMA instance. +* @param Channel is the channel number. +* @param DoneHandler is the done interrupt handler. +* @param CallbackRef is the callback reference data. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +int XDmaPs_SetDoneHandler(XDmaPs *InstPtr, + unsigned Channel, + XDmaPsDoneHandler DoneHandler, + void *CallbackRef) +{ + XDmaPs_ChannelData *ChanData; + + Xil_AssertNonvoid(InstPtr != NULL); + + if (Channel >= XDMAPS_CHANNELS_PER_DEV) + return XST_FAILURE; + + + ChanData = InstPtr->Chans + Channel; + + ChanData->DoneHandler = DoneHandler; + ChanData->DoneRef = CallbackRef; + + return 0; +} + +/*****************************************************************************/ +/** +* +* Set the fault handler for a channel. +* +* @param InstPtr is the DMA instance. +* @param FaultHandler is the fault interrupt handler. +* @param CallbackRef is the callback reference data. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +int XDmaPs_SetFaultHandler(XDmaPs *InstPtr, + XDmaPsFaultHandler FaultHandler, + void *CallbackRef) +{ + Xil_AssertNonvoid(InstPtr != NULL); + + InstPtr->FaultHandler = FaultHandler; + InstPtr->FaultRef = CallbackRef; + + return XST_SUCCESS; +} + + + +/****************************************************************************/ +/** +* Construction function for DMAEND instruction. This function fills the program +* buffer with the constructed instruction. +* +* @param DmaProg the DMA program buffer, it's the starting address for +* the instruction being constructed +* +* @return The number of bytes for this instruction which is 1. +* +* @note None. +* +*****************************************************************************/ +static INLINE int XDmaPs_Instr_DMAEND(char *DmaProg) +{ + /* + * DMAEND encoding: + * 7 6 5 4 3 2 1 0 + * 0 0 0 0 0 0 0 0 + */ + *DmaProg = 0x0; + + return 1; +} + +static INLINE void XDmaPs_Memcpy4(char *Dst, char *Src) +{ + *Dst = *Src; + *(Dst + 1) = *(Src + 1); + *(Dst + 2) = *(Src + 2); + *(Dst + 3) = *(Src + 3); +} + +/****************************************************************************/ +/** +* +* Construction function for DMAGO instruction. This function fills the program +* buffer with the constructed instruction. +* +* @param DmaProg is the DMA program buffer, it's the starting address +* for the instruction being constructed +* @param Cn is the Channel number, 0 - 7 +* @param Imm is 32-bit immediate number written to the Channel Program +* Counter. +* @param Ns is Non-secure flag. If Ns is 1, the DMA channel operates in +* the Non-secure state. If Ns is 0, the execution depends on the +* security state of the DMA manager: +* DMA manager is in the Secure state, DMA channel operates in the +* Secure state. +* DMA manager is in the Non-secure state, DMAC aborts. +* +* @return The number of bytes for this instruction which is 6. +* +* @note None +* +*****************************************************************************/ +static INLINE int XDmaPs_Instr_DMAGO(char *DmaProg, unsigned int Cn, + u32 Imm, unsigned int Ns) +{ + /* + * DMAGO encoding: + * 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 + * 0 0 0 0 0 |cn[2:0]| 1 0 1 0 0 0 ns 0 + * + * 47 ... 16 + * imm[32:0] + */ + *DmaProg = 0xA0 | ((Ns << 1) & 0x02); + + *(DmaProg + 1) = (u8)(Cn & 0x07); + + // *((u32 *)(DmaProg + 2)) = Imm; + XDmaPs_Memcpy4(DmaProg + 2, (char *)&Imm); + + /* success */ + return 6; +} + +/****************************************************************************/ +/** +* +* Construction function for DMALD instruction. This function fills the program +* buffer with the constructed instruction. +* +* @param DmaProg the DMA program buffer, it's the starting address for the +* instruction being constructed +* +* @return The number of bytes for this instruction which is 1. +* +* @note None. +* +*****************************************************************************/ +static INLINE int XDmaPs_Instr_DMALD(char *DmaProg) +{ + /* + * DMALD encoding + * 7 6 5 4 3 2 1 0 + * 0 0 0 0 0 1 bs x + * + * Note: this driver doesn't support conditional load or store, + * so the bs bit is 0 and x bit is 0. + */ + *DmaProg = 0x04; + return 1; +} + +/****************************************************************************/ +/** +* +* Construction function for DMALP instruction. This function fills the program +* buffer with the constructed instruction. +* +* @param DmaProg is the DMA program buffer, it's the starting address +* for the instruction being constructed +* @param Lc is the Loop counter register, can either be 0 or 1. +* @param LoopIterations: the number of interations, LoopInterations - 1 +* will be encoded in the DMALP instruction. +* +* @return The number of bytes for this instruction which is 2. +* +* @note None. +* +*****************************************************************************/ +static INLINE int XDmaPs_Instr_DMALP(char *DmaProg, unsigned Lc, + unsigned LoopIterations) +{ + /* + * DMALP encoding + * 15 ... 8 7 6 5 4 3 2 1 0 + * | iter[7:0] |0 0 1 0 0 0 lc 0 + */ + *DmaProg = (u8)(0x20 | ((Lc & 1) << 1)); + *(DmaProg + 1) = (u8)(LoopIterations - 1); + return 2; +} + +/****************************************************************************/ +/** +* +* Construction function for DMALPEND instruction. This function fills the +* program buffer with the constructed instruction. +* +* @param DmaProg is the DMA program buffer, it's the starting address +* for the instruction being constructed +* @param BodyStart is the starting address of the loop body. It is used +* to calculate the bytes of backward jump. +* @param Lc is the Loop counter register, can either be 0 or 1. +* +* @return The number of bytes for this instruction which is 2. +* +* @note None. +* +*****************************************************************************/ +static INLINE int XDmaPs_Instr_DMALPEND(char *DmaProg, char *BodyStart, unsigned Lc) +{ + /* + * DMALPEND encoding + * 15 ... 8 7 6 5 4 3 2 1 0 + * | backward_jump[7:0] |0 0 1 nf 1 lc bs x + * + * lc: loop counter + * nf is for loop forever. The driver does not support loop forever, + * so nf is 1. + * The driver does not support conditional LPEND, so bs is 0, x is 0. + */ + *DmaProg = 0x38 | ((Lc & 1) << 2); + *(DmaProg + 1) = (u8)(DmaProg - BodyStart); + + return 2; +} + +/* + * Register number for the DMAMOV instruction + */ +#define XDMAPS_MOV_SAR 0x0 +#define XDMAPS_MOV_CCR 0x1 +#define XDMAPS_MOV_DAR 0x2 + +/****************************************************************************/ +/** +* +* Construction function for DMAMOV instruction. This function fills the +* program buffer with the constructed instruction. +* +* @param DmaProg is the DMA program buffer, it's the starting address +* for the instruction being constructed +* @param Rd is the register id, 0 for SAR, 1 for CCR, and 2 for DAR +* @param Imm is the 32-bit immediate number +* +* @return The number of bytes for this instruction which is 6. +* +* @note None. +* +*****************************************************************************/ +static INLINE int XDmaPs_Instr_DMAMOV(char *DmaProg, unsigned Rd, u32 Imm) +{ + /* + * DMAMOV encoding + * 15 4 3 2 1 10 ... 8 7 6 5 4 3 2 1 0 + * 0 0 0 0 0 |rd[2:0]|1 0 1 1 1 1 0 0 + * + * 47 ... 16 + * imm[32:0] + * + * rd: b000 for SAR, b001 CCR, b010 DAR + */ + *DmaProg = 0xBC; + *(DmaProg + 1) = Rd & 0x7; + // *((u32 *)(DmaProg + 2)) = Imm; + XDmaPs_Memcpy4(DmaProg + 2, (char *)&Imm); + + return 6; +} + +/****************************************************************************/ +/** +* +* Construction function for DMANOP instruction. This function fills the +* program buffer with the constructed instruction. +* +* @param DmaProg is the DMA program buffer, it's the starting address +* for the instruction being constructed +* @return The number of bytes for this instruction which is 1. +* +* @note None. +* +*****************************************************************************/ +static INLINE int XDmaPs_Instr_DMANOP(char *DmaProg) +{ + /* + * DMANOP encoding + * 7 6 5 4 3 2 1 0 + * 0 0 0 1 1 0 0 0 + */ + *DmaProg = 0x18; + return 1; +} + +/****************************************************************************/ +/** +* +* Construction function for DMARMB instruction. This function fills the +* program buffer with the constructed instruction. +* +* @param DmaProg is the DMA program buffer, it's the starting address +* for the instruction being constructed +* +* @return The number of bytes for this instruction which is 1. +* +* @note None. +* +*****************************************************************************/ +int XDmaPs_Instr_DMARMB(char *DmaProg) +{ + /* + * DMARMB encoding + * 7 6 5 4 3 2 1 0 + * 0 0 0 1 0 0 1 0 + */ + *DmaProg = 0x12; + return 1; +} + +/****************************************************************************/ +/** +* +* Construction function for DMASEV instruction. This function fills the +* program buffer with the constructed instruction. +* +* @param DmaProg is the DMA program buffer, it's the starting address +* for the instruction being constructed +* @param EventNumber is the Event number to signal. +* +* @return The number of bytes for this instruction which is 2. +* +* @note None. +* +*****************************************************************************/ +static INLINE int XDmaPs_Instr_DMASEV(char *DmaProg, unsigned int EventNumber) +{ + /* + * DMASEV encoding + * 15 4 3 2 1 10 9 8 7 6 5 4 3 2 1 0 + * |event[4:0]| 0 0 0 0 0 1 1 0 1 0 0 + */ + *DmaProg = 0x34; + *(DmaProg + 1) = (u8)(EventNumber << 3); + + return 2; +} + + +/****************************************************************************/ +/** +* +* Construction function for DMAST instruction. This function fills the +* program buffer with the constructed instruction. +* +* @param DmaProg is the DMA program buffer, it's the starting address +* for the instruction being constructed +* +* @return The number of bytes for this instruction which is 1. +* +* @note None. +* +*****************************************************************************/ +static INLINE int XDmaPs_Instr_DMAST(char *DmaProg) +{ + /* + * DMAST encoding + * 7 6 5 4 3 2 1 0 + * 0 0 0 0 1 0 bs x + * + * Note: this driver doesn't support conditional load or store, + * so the bs bit is 0 and x bit is 0. + */ + *DmaProg = 0x08; + return 1; +} + + +/****************************************************************************/ +/** +* +* Construction function for DMAWMB instruction. This function fills the +* program buffer with the constructed instruction. +* +* @param DmaProg is the DMA program buffer, it's the starting address +* for the instruction being constructed +* +* @return The number of bytes for this instruction which is 1. +* +* @note None. +* +*****************************************************************************/ +int XDmaPs_Instr_DMAWMB(char *DmaProg) +{ + /* + * DMAWMB encoding + * 7 6 5 4 3 2 1 0 + * 0 0 0 1 0 0 1 0 + */ + *DmaProg = 0x13; + return 1; +} + +/****************************************************************************/ +/** +* +* Conversion function from the endian swap size to the bit encoding of the CCR +* +* @param EndianSwapSize is the endian swap size, in terms of bits, it +* could be 8, 16, 32, 64, or 128(We are using DMA assembly syntax) +* +* @return The endian swap size bit encoding for the CCR. +* +* @note None. +* +*****************************************************************************/ +static INLINE unsigned XDmaPs_ToEndianSwapSizeBits(unsigned int EndianSwapSize) +{ + switch (EndianSwapSize) { + case 0: + case 8: + return 0; + case 16: + return 1; + case 32: + return 2; + case 64: + return 3; + case 128: + return 4; + default: + return 0; + } + +} + +/****************************************************************************/ +/** +* +* Conversion function from the burst size to the bit encoding of the CCR +* +* @param BurstSize is the burst size. It's the data width. +* In terms of bytes, it could be 1, 2, 4, 8, 16, 32, 64, or 128. +* It must be no larger than the bus width. +* (We are using DMA assembly syntax.) +* +* @note None. +* +*****************************************************************************/ +static INLINE unsigned XDmaPs_ToBurstSizeBits(unsigned BurstSize) +{ + switch (BurstSize) { + case 1: + return 0; + case 2: + return 1; + case 4: + return 2; + case 8: + return 3; + case 16: + return 4; + case 32: + return 5; + case 64: + return 6; + case 128: + return 7; + default: + return 0; + } +} + + +/****************************************************************************/ +/** +* +* Conversion function from PL330 bus transfer descriptors to CCR value. All the +* values passed to the functions are in terms of assembly languages, not in +* terms of the register bit encoding. +* +* @param ChanCtrl is the Instance of XDmaPs_ChanCtrl. +* +* @return The 32-bit CCR value. +* +* @note None. +* +*****************************************************************************/ +u32 XDmaPs_ToCCRValue(XDmaPs_ChanCtrl *ChanCtrl) +{ + /* + * Channel Control Register encoding + * [31:28] - endian_swap_size + * [27:25] - dst_cache_ctrl + * [24:22] - dst_prot_ctrl + * [21:18] - dst_burst_len + * [17:15] - dst_burst_size + * [14] - dst_inc + * [13:11] - src_cache_ctrl + * [10:8] - src_prot_ctrl + * [7:4] - src_burst_len + * [3:1] - src_burst_size + * [0] - src_inc + */ + + unsigned es = + XDmaPs_ToEndianSwapSizeBits(ChanCtrl->EndianSwapSize); + + unsigned dst_burst_size = + XDmaPs_ToBurstSizeBits(ChanCtrl->DstBurstSize); + unsigned dst_burst_len = (ChanCtrl->DstBurstLen - 1) & 0x0F; + unsigned dst_cache_ctrl = (ChanCtrl->DstCacheCtrl & 0x03) + | ((ChanCtrl->DstCacheCtrl & 0x08) >> 1); + unsigned dst_prot_ctrl = ChanCtrl->DstProtCtrl & 0x07; + unsigned dst_inc_bit = ChanCtrl->DstInc & 1; + + unsigned src_burst_size = + XDmaPs_ToBurstSizeBits(ChanCtrl->SrcBurstSize); + unsigned src_burst_len = (ChanCtrl->SrcBurstLen - 1) & 0x0F; + unsigned src_cache_ctrl = (ChanCtrl->SrcCacheCtrl & 0x03) + | ((ChanCtrl->SrcCacheCtrl & 0x08) >> 1); + unsigned src_prot_ctrl = ChanCtrl->SrcProtCtrl & 0x07; + unsigned src_inc_bit = ChanCtrl->SrcInc & 1; + + u32 ccr_value = (es << 28) + | (dst_cache_ctrl << 25) + | (dst_prot_ctrl << 22) + | (dst_burst_len << 18) + | (dst_burst_size << 15) + | (dst_inc_bit << 14) + | (src_cache_ctrl << 11) + | (src_prot_ctrl << 8) + | (src_burst_len << 4) + | (src_burst_size << 1) + | (src_inc_bit); + + return ccr_value; +} + +/****************************************************************************/ +/** +* Construct a loop with only DMALD and DMAST as the body using loop counter 0. +* The function also makes sure the loop body and the lpend is in the same +* cache line. +* +* @param DmaProgStart is the very start address of the DMA program. +* This is used to calculate whether the loop is in a cache line. +* @param CacheLength is the icache line length, in terms of bytes. +* If it's zero, the performance enhancement feature will be +* turned off. +* @param DmaProgLoopStart The starting address of the loop (DMALP). +* @param LoopCount The inner loop count. Loop count - 1 will be used to +* initialize the loop counter. +* +* @return The number of bytes the loop has. +* +* @note None. +* +*****************************************************************************/ +int XDmaPs_ConstructSingleLoop(char *DmaProgStart, + int CacheLength, + char *DmaProgLoopStart, + int LoopCount) +{ + int CacheStartOffset; + int CacheEndOffset; + int NumNops; + char *DmaProgBuf = DmaProgLoopStart; + + DmaProgBuf += XDmaPs_Instr_DMALP(DmaProgBuf, 0, LoopCount); + + if (CacheLength > 0) { + /* + * the CacheLength > 0 switch is ued to turn on/off nop + * insertion + */ + CacheStartOffset = DmaProgBuf - DmaProgStart; + CacheEndOffset = CacheStartOffset + 3; + + /* + * check whether the body and lpend fit in one cache line + */ + if (CacheStartOffset / CacheLength + != CacheEndOffset / CacheLength) { + /* insert the nops */ + NumNops = CacheLength + - CacheStartOffset % CacheLength; + while (NumNops--) { + DmaProgBuf += + XDmaPs_Instr_DMANOP(DmaProgBuf); + } + } + } + + DmaProgBuf += XDmaPs_Instr_DMALD(DmaProgBuf); + DmaProgBuf += XDmaPs_Instr_DMAST(DmaProgBuf); + DmaProgBuf += XDmaPs_Instr_DMALPEND(DmaProgBuf, + DmaProgBuf - 2, 0); + + return DmaProgBuf - DmaProgLoopStart; +} + +/****************************************************************************/ +/** +* Construct a nested loop with only DMALD and DMAST in the inner loop body. +* It uses loop counter 1 for the outer loop and loop counter 0 for the +* inner loop. +* +* @param DmaProgStart is the very start address of the DMA program. +* This is used to calculate whether the loop is in a cache line. +* @param CacheLength is the icache line length, in terms of bytes. +* If it's zero, the performance enhancement feature will be +* turned off. +* @param DmaProgLoopStart The starting address of the loop (DMALP). +* @param LoopCountOuter The outer loop count. Loop count - 1 will be +* used to initialize the loop counter. +* @param LoopCountInner The inner loop count. Loop count - 1 will be +* used to initialize the loop counter. +* +* @return The number byes the nested loop program has. +* +* @note None. +* +*****************************************************************************/ +int XDmaPs_ConstructNestedLoop(char *DmaProgStart, + int CacheLength, + char *DmaProgLoopStart, + unsigned int LoopCountOuter, + unsigned int LoopCountInner) +{ + int CacheStartOffset; + int CacheEndOffset; + int NumNops; + char *InnerLoopStart; + char *DmaProgBuf = DmaProgLoopStart; + + DmaProgBuf += XDmaPs_Instr_DMALP(DmaProgBuf, 1, LoopCountOuter); + InnerLoopStart = DmaProgBuf; + + if (CacheLength > 0) { + /* + * the CacheLength > 0 switch is ued to turn on/off nop + * insertion + */ + if (CacheLength < 8) { + /* + * if the cache line is too small to fit both loops + * just align the inner loop + */ + DmaProgBuf += + XDmaPs_ConstructSingleLoop(DmaProgStart, + CacheLength, + DmaProgBuf, + LoopCountInner); + /* outer loop end */ + DmaProgBuf += + XDmaPs_Instr_DMALPEND(DmaProgBuf, + InnerLoopStart, + 1); + + /* + * the nested loop is constructed for + * smaller cache line + */ + return DmaProgBuf - DmaProgLoopStart; + } + + /* + * Now let's handle the case where a cache line can + * fit the nested loops. + */ + CacheStartOffset = DmaProgBuf - DmaProgStart; + CacheEndOffset = CacheStartOffset + 7; + + /* + * check whether the body and lpend fit in one cache line + */ + if (CacheStartOffset / CacheLength + != CacheEndOffset / CacheLength) { + /* insert the nops */ + NumNops = CacheLength + - CacheStartOffset % CacheLength; + while (NumNops--) { + DmaProgBuf += + XDmaPs_Instr_DMANOP(DmaProgBuf); + } + } + } + + /* insert the inner DMALP */ + DmaProgBuf += XDmaPs_Instr_DMALP(DmaProgBuf, 0, LoopCountInner); + + /* DMALD and DMAST instructions */ + DmaProgBuf += XDmaPs_Instr_DMALD(DmaProgBuf); + DmaProgBuf += XDmaPs_Instr_DMAST(DmaProgBuf); + + /* inner DMALPEND */ + DmaProgBuf += XDmaPs_Instr_DMALPEND(DmaProgBuf, + DmaProgBuf - 2, 0); + /* outer DMALPEND */ + DmaProgBuf += XDmaPs_Instr_DMALPEND(DmaProgBuf, + InnerLoopStart, 1); + + /* return the number of bytes */ + return DmaProgBuf - DmaProgLoopStart; +} + +/* + * [31:28] endian_swap_size b0000 + * [27:25] dst_cache_ctrl b000 + * [24:22] dst_prot_ctrl b000 + * [21:18] dst_burst_len b0000 + * [17:15] dst_burst_size b000 + * [14] dst_inc b0 + * [27:25] src_cache_ctrl b000 + * [24:22] src_prot_ctrl b000 + * [21:18] src_burst_len b0000 + * [17:15] src_burst_size b000 + * [14] src_inc b0 + */ +#define XDMAPS_CCR_SINGLE_BYTE (0x0) +#define XDMAPS_CCR_M2M_SINGLE_BYTE ((0x1 << 14) | 0x1) + + +/****************************************************************************/ +/** +* +* Construct the DMA program based on the descriptions of the DMA transfer. +* The function handles memory to memory DMA transfers. +* It also handles unalgined head and small amount of residue tail. +* +* @param Channel DMA channel number +* @param Cmd is the DMA command. +* @param CacheLength is the icache line length, in terms of bytes. +* If it's zero, the performance enhancement feature will be +* turned off. +* +* @returns The number of bytes for the program. +* +* @note None. +* +*****************************************************************************/ +static int XDmaPs_BuildDmaProg(unsigned Channel, XDmaPs_Cmd *Cmd, + unsigned CacheLength) +{ + /* + * unpack arguments + */ + char *DmaProgBuf = (char *)Cmd->GeneratedDmaProg; + unsigned DevChan = Channel; + unsigned long DmaLength = Cmd->BD.Length; + u32 SrcAddr = Cmd->BD.SrcAddr; + + unsigned SrcInc = Cmd->ChanCtrl.SrcInc; + u32 DstAddr = Cmd->BD.DstAddr; + unsigned DstInc = Cmd->ChanCtrl.DstInc; + + char *DmaProgStart = DmaProgBuf; + + unsigned int BurstBytes; + unsigned int LoopCount; + unsigned int LoopCount1 = 0; + unsigned int LoopResidue = 0; + unsigned int TailBytes; + unsigned int TailWords; + int DmaProgBytes; + u32 CCRValue; + unsigned int Unaligned; + unsigned int UnalignedCount; + unsigned int MemBurstSize = 1; + u32 MemAddr = 0; + unsigned int Index; + unsigned int SrcUnaligned = 0; + unsigned int DstUnaligned = 0; + + XDmaPs_ChanCtrl *ChanCtrl; + XDmaPs_ChanCtrl WordChanCtrl; + static XDmaPs_ChanCtrl Mem2MemByteCC; + + Mem2MemByteCC.EndianSwapSize = 0; + Mem2MemByteCC.DstCacheCtrl = 0; + Mem2MemByteCC.DstProtCtrl = 0; + Mem2MemByteCC.DstBurstLen = 1; + Mem2MemByteCC.DstBurstSize = 1; + Mem2MemByteCC.DstInc = 1; + Mem2MemByteCC.SrcCacheCtrl = 0; + Mem2MemByteCC.SrcProtCtrl = 0; + Mem2MemByteCC.SrcBurstLen = 1; + Mem2MemByteCC.SrcBurstSize = 1; + Mem2MemByteCC.SrcInc = 1; + + ChanCtrl = &Cmd->ChanCtrl; + + /* insert DMAMOV for SAR and DAR */ + DmaProgBuf += XDmaPs_Instr_DMAMOV(DmaProgBuf, + XDMAPS_MOV_SAR, + SrcAddr); + DmaProgBuf += XDmaPs_Instr_DMAMOV(DmaProgBuf, + XDMAPS_MOV_DAR, + DstAddr); + + + if (ChanCtrl->SrcInc) + SrcUnaligned = SrcAddr % ChanCtrl->SrcBurstSize; + + if (ChanCtrl->DstInc) + DstUnaligned = DstAddr % ChanCtrl->DstBurstSize; + + if ((SrcUnaligned && DstInc) || (DstUnaligned && SrcInc)) { + ChanCtrl = &Mem2MemByteCC; + } + + if (ChanCtrl->SrcInc) { + MemBurstSize = ChanCtrl->SrcBurstSize; + MemAddr = SrcAddr; + + } else if (ChanCtrl->DstInc) { + MemBurstSize = ChanCtrl->DstBurstSize; + MemAddr = DstAddr; + } + + /* check whether the head is aligned or not */ + Unaligned = MemAddr % MemBurstSize; + + if (Unaligned) { + /* if head is unaligned, transfer head in bytes */ + UnalignedCount = MemBurstSize - Unaligned; + CCRValue = XDMAPS_CCR_SINGLE_BYTE + | (SrcInc & 1) + | ((DstInc & 1) << 14); + + DmaProgBuf += XDmaPs_Instr_DMAMOV(DmaProgBuf, + XDMAPS_MOV_CCR, + CCRValue); + + for (Index = 0; Index < UnalignedCount; Index++) { + DmaProgBuf += XDmaPs_Instr_DMALD(DmaProgBuf); + DmaProgBuf += XDmaPs_Instr_DMAST(DmaProgBuf); + } + + DmaLength -= UnalignedCount; + } + + /* now the burst transfer part */ + CCRValue = XDmaPs_ToCCRValue(ChanCtrl); + DmaProgBuf += XDmaPs_Instr_DMAMOV(DmaProgBuf, + XDMAPS_MOV_CCR, + CCRValue); + + BurstBytes = ChanCtrl->SrcBurstSize * ChanCtrl->SrcBurstLen; + + LoopCount = DmaLength / BurstBytes; + TailBytes = DmaLength % BurstBytes; + + /* + * the loop count register is 8-bit wide, so if we need + * a larger loop, we need to have nested loops + */ + if (LoopCount > 256) { + LoopCount1 = LoopCount / 256; + if (LoopCount1 > 256) { + xil_printf("DMA operation cannot fit in a 2-level " + "loop for channel %d, please reduce the " + "DMA length or increase the burst size or " + "length", + Channel); + return 0; + } + LoopResidue = LoopCount % 256; + + if (LoopCount1 > 1) + DmaProgBuf += + XDmaPs_ConstructNestedLoop(DmaProgStart, + CacheLength, + DmaProgBuf, + LoopCount1, + 256); + else + DmaProgBuf += + XDmaPs_ConstructSingleLoop(DmaProgStart, + CacheLength, + DmaProgBuf, + 256); + + /* there will be some that cannot be covered by + * nested loops + */ + LoopCount = LoopResidue; + } + + if (LoopCount > 0) { + DmaProgBuf += XDmaPs_ConstructSingleLoop(DmaProgStart, + CacheLength, + DmaProgBuf, + LoopCount); + } + + if (TailBytes) { + /* handle the tail */ + TailWords = TailBytes / MemBurstSize; + TailBytes = TailBytes % MemBurstSize; + + if (TailWords) { + WordChanCtrl = *ChanCtrl; + /* + * if we can transfer the tail in words, we will + * transfer words as much as possible + */ + WordChanCtrl.SrcBurstSize = MemBurstSize; + WordChanCtrl.SrcBurstLen = 1; + WordChanCtrl.DstBurstSize = MemBurstSize; + WordChanCtrl.DstBurstLen = 1; + + + /* + * the burst length is 1 + */ + CCRValue = XDmaPs_ToCCRValue(&WordChanCtrl); + + DmaProgBuf += + XDmaPs_Instr_DMAMOV(DmaProgBuf, + XDMAPS_MOV_CCR, + CCRValue); + DmaProgBuf += + XDmaPs_ConstructSingleLoop(DmaProgStart, + CacheLength, + DmaProgBuf, + TailWords); + + } + + if (TailBytes) { + /* + * for the rest, we'll tranfer in bytes + */ + /* + * So far just to be safe, the tail bytes + * are transfered in a loop. We can optimize a little + * to perform a burst. + */ + CCRValue = XDMAPS_CCR_SINGLE_BYTE + | (SrcInc & 1) + | ((DstInc & 1) << 14); + + DmaProgBuf += + XDmaPs_Instr_DMAMOV(DmaProgBuf, + XDMAPS_MOV_CCR, + CCRValue); + + DmaProgBuf += + XDmaPs_ConstructSingleLoop(DmaProgStart, + CacheLength, + DmaProgBuf, + TailBytes); + + } + } + + DmaProgBuf += XDmaPs_Instr_DMASEV(DmaProgBuf, DevChan); + DmaProgBuf += XDmaPs_Instr_DMAEND(DmaProgBuf); + + DmaProgBytes = DmaProgBuf - DmaProgStart; + + Xil_DCacheFlushRange((u32)DmaProgStart, DmaProgBytes); + + return DmaProgBytes; + +} + + +/****************************************************************************/ +/** +* +* Generate a DMA program based for the DMA command, the buffer will be pointed +* by the GeneratedDmaProg field of the command. +* +* @param InstPtr is then DMA instance. +* @param Channel is the DMA channel number. +* @param Cmd is the DMA command. +* +* @return - XST_SUCCESS on success. +* - XST_FAILURE if it fails +* +* @note None. +* +*****************************************************************************/ +int XDmaPs_GenDmaProg(XDmaPs *InstPtr, unsigned int Channel, XDmaPs_Cmd *Cmd) +{ + void *Buf; + int ProgLen; + XDmaPs_ChannelData *ChanData; + XDmaPs_ChanCtrl *ChanCtrl; + + Xil_AssertNonvoid(InstPtr != NULL); + Xil_AssertNonvoid(Cmd != NULL); + + + if (Channel > XDMAPS_CHANNELS_PER_DEV) + return XST_FAILURE; + + ChanData = InstPtr->Chans + Channel; + ChanCtrl = &Cmd->ChanCtrl; + + if (ChanCtrl->SrcBurstSize * ChanCtrl->SrcBurstLen + != ChanCtrl->DstBurstSize * ChanCtrl->DstBurstLen) { + return XST_FAILURE; + } + + + /* + * unaligned fixed address is not supported + */ + if (!ChanCtrl->SrcInc && Cmd->BD.SrcAddr % ChanCtrl->SrcBurstSize) { + return XST_FAILURE; + } + + if (!ChanCtrl->DstInc && Cmd->BD.DstAddr % ChanCtrl->DstBurstSize) { + return XST_FAILURE; + } + + Buf = XDmaPs_BufPool_Allocate(ChanData->ProgBufPool); + if (Buf == NULL) { + return XST_FAILURE; + } + + Cmd->GeneratedDmaProg = Buf; + ProgLen = XDmaPs_BuildDmaProg(Channel, Cmd, + InstPtr->CacheLength); + Cmd->GeneratedDmaProgLength = ProgLen; + + +#ifdef XDMAPS_DEBUG + XDmaPs_Print_DmaProg(Cmd); +#endif + + if (ProgLen <= 0) { + /* something wrong, release the buffer */ + XDmaPs_BufPool_Free(ChanData->ProgBufPool, Buf); + Cmd->GeneratedDmaProgLength = 0; + Cmd->GeneratedDmaProg = NULL; + return XST_FAILURE; + } + + return XST_SUCCESS; +} + + +/****************************************************************************/ +/** + * Free the DMA program buffer that is pointed by the GeneratedDmaProg field + * of the command. + * + * @param InstPtr is then DMA instance. + * @param Channel is the DMA channel number. + * @param Cmd is the DMA command. + * + * @return XST_SUCCESS on success. + * XST_FAILURE if there is any error. + * + * @note None. + * + ****************************************************************************/ +int XDmaPs_FreeDmaProg(XDmaPs *InstPtr, unsigned int Channel, XDmaPs_Cmd *Cmd) +{ + + void *Buf; + XDmaPs_ChannelData *ChanData; + + Xil_AssertNonvoid(InstPtr != NULL); + Xil_AssertNonvoid(Cmd != NULL); + + if (Channel > XDMAPS_CHANNELS_PER_DEV) + return XST_FAILURE; + + Buf = (void *)Cmd->GeneratedDmaProg; + ChanData = InstPtr->Chans + Channel; + + if (Buf) { + XDmaPs_BufPool_Free(ChanData->ProgBufPool, Buf); + Cmd->GeneratedDmaProg = 0; + Cmd->GeneratedDmaProgLength = 0; + } + + return XST_SUCCESS; +} + + +/****************************************************************************/ +/** +* +* Start a DMA command. The command can only be invoked when the channel +* is idle. The driver takes the command, generates DMA program if needed, +* then pass the program to DMAC to execute. +* +* @param InstPtr is then DMA instance. +* @param Channel is the DMA channel number. +* @param Cmd is the DMA command. +* @param HoldDmaProg is tag indicating whether the driver can release +* the allocated DMA buffer or not. If a user wants to examine the +* generated DMA program, the flag should be set to 1. After the +* DMA program is finished, a user needs to explicity free the +* buffer. +* +* @return +* - XST_SUCCESS on success +* - XST_DEVICE_BUSY if DMA is busy +* - XST_FAILURE on other failures +* +* @note None. +* +****************************************************************************/ +int XDmaPs_Start(XDmaPs *InstPtr, unsigned int Channel, + XDmaPs_Cmd *Cmd, + int HoldDmaProg) +{ + int Status; + u32 DmaProg = 0; + u32 Inten; + + Xil_AssertNonvoid(InstPtr != NULL); + Xil_AssertNonvoid(Cmd != NULL); + + + Cmd->DmaStatus = XST_FAILURE; + + if (XDmaPs_IsActive(InstPtr, Channel)) + return XST_DEVICE_BUSY; + + if (!Cmd->UserDmaProg && !Cmd->GeneratedDmaProg) { + Status = XDmaPs_GenDmaProg(InstPtr, Channel, Cmd); + if (Status) + return XST_FAILURE; + } + + InstPtr->Chans[Channel].HoldDmaProg = HoldDmaProg; + + if (Cmd->UserDmaProg) + DmaProg = (u32)Cmd->UserDmaProg; + else if (Cmd->GeneratedDmaProg) + DmaProg = (u32)Cmd->GeneratedDmaProg; + + if (DmaProg) { + /* enable the interrupt */ + Inten = XDmaPs_ReadReg(InstPtr->Config.BaseAddress, + XDMAPS_INTEN_OFFSET); + Inten |= 0x01 << Channel; /* set the correpsonding bit */ + XDmaPs_WriteReg(InstPtr->Config.BaseAddress, + XDMAPS_INTEN_OFFSET, + Inten); + Inten = XDmaPs_ReadReg(InstPtr->Config.BaseAddress, + XDMAPS_INTEN_OFFSET); + + InstPtr->Chans[Channel].DmaCmdToHw = Cmd; + + if (Cmd->ChanCtrl.SrcInc) { + Xil_DCacheFlushRange(Cmd->BD.SrcAddr, Cmd->BD.Length); + } + if (Cmd->ChanCtrl.DstInc) { + Xil_DCacheInvalidateRange(Cmd->BD.DstAddr, + Cmd->BD.Length); + } + + Status = XDmaPs_Exec_DMAGO(InstPtr->Config.BaseAddress, + Channel, DmaProg); + } + else { + InstPtr->Chans[Channel].DmaCmdToHw = NULL; + Status = XST_FAILURE; + } + + return Status; +} + +/****************************************************************************/ +/** +* +* Checks whether the DMA channel is active or idle. +* +* @param InstPtr is the DMA instance. +* @param Channel is the DMA channel number. +* +* @return 0: if the channel is idle +* 1: otherwise +* +* @note None. +* +*****************************************************************************/ +int XDmaPs_IsActive(XDmaPs *InstPtr, unsigned int Channel) +{ + Xil_AssertNonvoid(InstPtr != NULL); + + /* Need to assert Channel is in range */ + if (Channel > XDMAPS_CHANNELS_PER_DEV) + return 0; + + return InstPtr->Chans[Channel].DmaCmdToHw != NULL; +} + + + +/****************************************************************************/ +/** +* +* Allocate a buffer of the DMA program buffer from the pool. +* +* @param Pool the DMA program pool. +* +* @return The allocated buffer, NULL if there is any error. +* +* @note None. +* +*****************************************************************************/ +static void *XDmaPs_BufPool_Allocate(XDmaPs_ProgBuf *Pool) +{ + int Index; + + Xil_AssertNonvoid(Pool != NULL); + + for (Index = 0; Index < XDMAPS_MAX_CHAN_BUFS; Index++) { + if (!Pool[Index].Allocated) { + Pool[Index].Allocated = 1; + return Pool[Index].Buf; + } + } + + return NULL; + +} + +/*****************************************************************************/ +/** +* +* Driver done interrupt service routine for channel 0. We need this done ISR +* mainly because the driver needs to release the DMA program buffer. +* This is the one that connects the GIC +* +* @param InstPtr is the DMA instance. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XDmaPs_DoneISR_0(XDmaPs *InstPtr) +{ + XDmaPs_DoneISR_n(InstPtr, 0); +} + +/*****************************************************************************/ +/** +* +* Driver done interrupt service routine for channel 1. We need this done ISR +* mainly because the driver needs to release the DMA program buffer. +* This is the one that connects the GIC +* +* @param InstPtr is the DMA instance. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XDmaPs_DoneISR_1(XDmaPs *InstPtr) +{ + XDmaPs_DoneISR_n(InstPtr, 1); +} + +/*****************************************************************************/ +/** +* +* Driver done interrupt service routine for channel 2. We need this done ISR +* mainly because the driver needs to release the DMA program buffer. +* This is the one that connects the GIC +* +* @param InstPtr is the DMA instance. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XDmaPs_DoneISR_2(XDmaPs *InstPtr) +{ + XDmaPs_DoneISR_n(InstPtr, 2); +} + +/*****************************************************************************/ +/** +* +* Driver done interrupt service routine for channel 3. We need this done ISR +* mainly because the driver needs to release the DMA program buffer. +* This is the one that connects the GIC +* +* @param InstPtr is the DMA instance. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XDmaPs_DoneISR_3(XDmaPs *InstPtr) +{ + XDmaPs_DoneISR_n(InstPtr, 3); +} + +/*****************************************************************************/ +/** +* +* Driver done interrupt service routine for channel 4. We need this done ISR +* mainly because the driver needs to release the DMA program buffer. +* This is the one that connects the GIC +* +* @param InstPtr is the DMA instance. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XDmaPs_DoneISR_4(XDmaPs *InstPtr) +{ + XDmaPs_DoneISR_n(InstPtr, 4); +} + +/*****************************************************************************/ +/** +* +* Driver done interrupt service routine for channel 5. We need this done ISR +* mainly because the driver needs to release the DMA program buffer. +* This is the one that connects the GIC +* +* @param InstPtr is the DMA instance. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XDmaPs_DoneISR_5(XDmaPs *InstPtr) +{ + XDmaPs_DoneISR_n(InstPtr, 5); +} + +/*****************************************************************************/ +/** +* +* Driver done interrupt service routine for channel 6. We need this done ISR +* mainly because the driver needs to release the DMA program buffer. +* This is the one that connects the GIC +* +* @param InstPtr is the DMA instance. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XDmaPs_DoneISR_6(XDmaPs *InstPtr) +{ + XDmaPs_DoneISR_n(InstPtr, 6); +} + +/*****************************************************************************/ +/** +* +* Driver done interrupt service routine for channel 7. We need this done ISR +* mainly because the driver needs to release the DMA program buffer. +* This is the one that connects the GIC +* +* @param InstPtr is the DMA instance. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XDmaPs_DoneISR_7(XDmaPs *InstPtr) +{ + XDmaPs_DoneISR_n(InstPtr, 7); +} + +#ifndef XDMAPS_MAX_WAIT +#define XDMAPS_MAX_WAIT 4000 +#endif + +/****************************************************************************/ +/** +* Use the debug registers to kill the DMA thread. +* +* @param BaseAddr is DMA device base address. +* @param Channel is the DMA channel number. +* @param Thread is Debug thread encoding. +* 0: DMA manager thread, 1: DMA channel. +* +* @return 0 on success, -1 on time out +* +* @note None. +* +*****************************************************************************/ +static int XDmaPs_Exec_DMAKILL(u32 BaseAddr, + unsigned int Channel, + unsigned int Thread) +{ + u32 DbgInst0; + int WaitCount; + + DbgInst0 = XDmaPs_DBGINST0(0, 0x01, Channel, Thread); + + /* wait while debug status is busy */ + WaitCount = 0; + while ((XDmaPs_ReadReg(BaseAddr, XDMAPS_DBGSTATUS_OFFSET) + & XDMAPS_DBGSTATUS_BUSY) + && (WaitCount < XDMAPS_MAX_WAIT)) + WaitCount++; + + if (WaitCount >= XDMAPS_MAX_WAIT) { + /* wait time out */ + xil_printf("PL330 device at %x debug status busy time out\n", + BaseAddr); + + return -1; + } + + /* write debug instruction 0 */ + XDmaPs_WriteReg(BaseAddr, XDMAPS_DBGINST0_OFFSET, DbgInst0); + + XDmaPs_WriteReg(BaseAddr, XDMAPS_DBGINST1_OFFSET, 0); + + + /* run the command in DbgInst0 and DbgInst1 */ + XDmaPs_WriteReg(BaseAddr, XDMAPS_DBGCMD_OFFSET, 0); + + return 0; +} + +/****************************************************************************/ +/** +* +* +* Free a buffer of the DMA program buffer. +* @param Pool the DMA program pool. +* @param Buf the DMA program buffer to be release. +* +* @return None +* +* @note None. +* +*****************************************************************************/ +static void XDmaPs_BufPool_Free(XDmaPs_ProgBuf *Pool, void *Buf) +{ + int Index; + Xil_AssertVoid(Pool != NULL); + + for (Index = 0; Index < XDMAPS_MAX_CHAN_BUFS; Index++) { + if (Pool[Index].Buf == Buf) { + if (Pool[Index].Allocated) { + Pool[Index].Allocated = 0; + } + } + } +} + +/*****************************************************************************/ +/** +* XDmaPs_Exec_DMAGO - Execute the DMAGO to start a channel. +* +* @param BaseAddr PL330 device base address +* @param Channel Channel number for the device +* @param DmaProg DMA program starting address, this should be DMA address +* +* @return 0 on success, -1 on time out +* +* @note None. +* +****************************************************************************/ +static int XDmaPs_Exec_DMAGO(u32 BaseAddr, unsigned int Channel, u32 DmaProg) +{ + char DmaGoProg[8]; + u32 DbgInst0; + u32 DbgInst1; + + int WaitCount; + + XDmaPs_Instr_DMAGO(DmaGoProg, Channel, DmaProg, 0); + + DbgInst0 = XDmaPs_DBGINST0(*(DmaGoProg + 1), *DmaGoProg, 0, 0); + DbgInst1 = (u32)DmaProg; + + /* wait while debug status is busy */ + WaitCount = 0; + while ((XDmaPs_ReadReg(BaseAddr, XDMAPS_DBGSTATUS_OFFSET) + & XDMAPS_DBGSTATUS_BUSY) + && (WaitCount < XDMAPS_MAX_WAIT)) { + + WaitCount++; + } + + if (WaitCount >= XDMAPS_MAX_WAIT) { + xil_printf("PL330 device at %x debug status busy time out\r\n", + BaseAddr); + return -1; + } + + /* write debug instruction 0 */ + XDmaPs_WriteReg(BaseAddr, XDMAPS_DBGINST0_OFFSET, DbgInst0); + /* write debug instruction 1 */ + XDmaPs_WriteReg(BaseAddr, XDMAPS_DBGINST1_OFFSET, DbgInst1); + + + /* wait while the DMA Manager is busy */ + WaitCount = 0; + while ((XDmaPs_ReadReg(BaseAddr, + XDMAPS_DS_OFFSET) & XDMAPS_DS_DMA_STATUS) + != XDMAPS_DS_DMA_STATUS_STOPPED + && WaitCount <= XDMAPS_MAX_WAIT) { + WaitCount++; + } + + if (WaitCount >= XDMAPS_MAX_WAIT) { + xil_printf("PL330 device at %x debug status busy time out\r\n", + BaseAddr); + return -1; + } + + /* run the command in DbgInst0 and DbgInst1 */ + XDmaPs_WriteReg(BaseAddr, XDMAPS_DBGCMD_OFFSET, 0); + + return 0; +} + + +/****************************************************************************/ +/** +* +* It's the generic Done ISR. +* @param InstPtr is the DMA instance. +* @param Channel is the DMA channel numer. +* +* @return None.* +* +* @note None. +* +*****************************************************************************/ +static void XDmaPs_DoneISR_n(XDmaPs *InstPtr, unsigned Channel) +{ + + void *DmaProgBuf; + XDmaPs_ChannelData *ChanData; + XDmaPs_Cmd *DmaCmd; + //u32 Value; + + ChanData = InstPtr->Chans + Channel; + + /*Value = XDmaPs_ReadReg(InstPtr->Config.BaseAddress, + XDMAPS_INTSTATUS_OFFSET);*/ + + /* clear the interrupt status */ + XDmaPs_WriteReg(InstPtr->Config.BaseAddress, + XDMAPS_INTCLR_OFFSET, + 1 << ChanData->ChanId); + + /*Value = XDmaPs_ReadReg(InstPtr->Config.BaseAddress, + XDMAPS_INTSTATUS_OFFSET);*/ + + + DmaCmd = ChanData->DmaCmdToHw; + if (DmaCmd) { + if (!ChanData->HoldDmaProg) { + DmaProgBuf = (void *)DmaCmd->GeneratedDmaProg; + if (DmaProgBuf) + XDmaPs_BufPool_Free(ChanData->ProgBufPool, + DmaProgBuf); + DmaCmd->GeneratedDmaProg = NULL; + } + + DmaCmd->DmaStatus = 0; + ChanData->DmaCmdToHw = NULL; + ChanData->DmaCmdFromHw = DmaCmd; + + if (ChanData->DoneHandler) + ChanData->DoneHandler(Channel, DmaCmd, + ChanData->DoneRef); + } + +} + + +/****************************************************************************/ +/** +* Prints the content of the buffer in bytes +* @param Buf is the buffer. +* @param Length is the length of the DMA program. +* +* @return None. +* +* @note None. +****************************************************************************/ +static void XDmaPs_Print_DmaProgBuf(char *Buf, int Length) +{ + int Index; + for (Index = 0; Index < Length; Index++) + xil_printf("[%x] %x\r\n", Index, Buf[Index]); + +} +/****************************************************************************/ +/** +* Print the Dma Prog Contents. +* +* @param Cmd is the command buffer. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ + void XDmaPs_Print_DmaProg(XDmaPs_Cmd *Cmd) +{ + if (Cmd->GeneratedDmaProg && Cmd->GeneratedDmaProgLength) { + xil_printf("Generated DMA program (%d):\r\n", + Cmd->GeneratedDmaProgLength); + XDmaPs_Print_DmaProgBuf((char *)Cmd->GeneratedDmaProg, + Cmd->GeneratedDmaProgLength); + } + + if (Cmd->UserDmaProg && Cmd->UserDmaProgLength) { + xil_printf("User defined DMA program (%d):\r\n", + Cmd->UserDmaProgLength); + XDmaPs_Print_DmaProgBuf((char *)Cmd->UserDmaProg, + Cmd->UserDmaProgLength); + } +} + + +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps.h new file mode 100644 index 0000000..73e2b1e --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps.h @@ -0,0 +1,349 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xdmaps.h +* @addtogroup dmaps_v2_4 +* @{ +* @details +* +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  	Date     Changes
+* ----- ------ -------- ----------------------------------------------
+* 1.00	hbm    08/19/10 First Release
+* 1.01a nm     12/20/12 Added definition XDMAPS_CHANNELS_PER_DEV which specifies
+*		        the maximum number of channels.
+*		        Replaced the usage of XPAR_XDMAPS_CHANNELS_PER_DEV
+*                       with XDMAPS_CHANNELS_PER_DEV defined in xdmaps_hw.h.
+*			Added the tcl file to automatically generate the
+*			xparameters.h
+* 1.02a sg     05/16/12 Made changes for doxygen and moved some function
+*			header from the xdmaps.h file to xdmaps.c file
+*			Other cleanup for coding guidelines and CR 657109
+*			and CR 657898
+*			The xdmaps_example_no_intr.c example is removed
+*			as it is using interrupts  and is similar to
+*			the interrupt example - CR 652477
+* 1.03a sg     07/16/2012 changed inline to __inline for CR665681
+* 1.04a nm     10/22/2012 Fixed CR# 681671.
+* 1.05a nm     04/15/2013 Fixed CR# 704396. Removed warnings when compiled
+*			  with -Wall and -Wextra option in bsp.
+*	       05/01/2013 Fixed CR# 700189. Changed XDmaPs_BuildDmaProg()
+*			  function description.
+*			  Fixed CR# 704396. Removed unused variables
+*			  UseM2MByte & MemBurstLen from XDmaPs_BuildDmaProg()
+*			  function.
+* 1.07a asa    11/02/13. Made changes to fix compilation issues for iarcc.
+*			   Removed the PDBG prints. By default they were always
+*			   defined out and never used. The PDBG is non-standard for
+*			   Xilinx drivers and no other driver does something similar.
+*			   Since there is no easy way to fix compilation issues with
+*			   the IARCC compiler around PDBG, it is better to remove it.
+*			   Users can always use xil_printfs if they want to debug.
+* 2.0   adk    10/12/13  Updated as per the New Tcl API's
+* 2.01  kpc    08/23/14  Fixed the IAR compiler reported errors
+* 2.2   mus    08/12/16  Declared all inline functions in xdmaps.c as extern, to avoid
+*                        linker error for IAR compiler
+* 2.3   ms     01/23/17 Modified xil_printf statement in main function for all
+*                       examples to ensure that "Successfully ran" and "Failed"
+*                       strings are available in all examples. This is a fix
+*                       for CR-965028.
+*       ms     03/17/17 Added readme.txt file in examples folder for doxygen
+*                       generation.
+* 2.4   adk    13/08/18 Fixed armcc compiler warnings in the driver CR-1008310.
+* 
+* +*****************************************************************************/ + +#ifndef XDMAPS_H /* prevent circular inclusions */ +#define XDMAPS_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files ********************************/ + +#include "xparameters.h" +#include "xil_types.h" +#include "xil_assert.h" +#include "xstatus.h" + +#include "xdmaps_hw.h" + +/************************** Constant Definitions ****************************/ + +/**************************** Type Definitions ******************************/ + +/** + * This typedef contains configuration information for the device. + */ +typedef struct { + u16 DeviceId; /**< Unique ID of device */ + u32 BaseAddress; /**< Base address of device (IPIF) */ +} XDmaPs_Config; + + +/** DMA channle control structure. It's for AXI bus transaction. + * This struct will be translated into a 32-bit channel control register value. + */ +typedef struct { + unsigned int EndianSwapSize; /**< Endian swap size. */ + unsigned int DstCacheCtrl; /**< Destination cache control */ + unsigned int DstProtCtrl; /**< Destination protection control */ + unsigned int DstBurstLen; /**< Destination burst length */ + unsigned int DstBurstSize; /**< Destination burst size */ + unsigned int DstInc; /**< Destination incrementing or fixed + * address */ + unsigned int SrcCacheCtrl; /**< Source cache control */ + unsigned int SrcProtCtrl; /**< Source protection control */ + unsigned int SrcBurstLen; /**< Source burst length */ + unsigned int SrcBurstSize; /**< Source burst size */ + unsigned int SrcInc; /**< Source incrementing or fixed + * address */ +} XDmaPs_ChanCtrl; + +/** DMA block descriptor stucture. + */ +typedef struct { + u32 SrcAddr; /**< Source starting address */ + u32 DstAddr; /**< Destination starting address */ + unsigned int Length; /**< Number of bytes for the block */ +} XDmaPs_BD; + +/** + * A DMA command consisits of a channel control struct, a block descriptor, + * a user defined program, a pointer pointing to generated DMA program, and + * execution result. + * + */ +typedef struct { + XDmaPs_ChanCtrl ChanCtrl; /**< Channel Control Struct */ + XDmaPs_BD BD; /**< Together with SgLength field, + * it's a scatter-gather list. + */ + void *UserDmaProg; /**< If user wants the driver to + * execute their own DMA program, + * this field points to the DMA + * program. + */ + int UserDmaProgLength; /**< The length of user defined + * DMA program. + */ + + void *GeneratedDmaProg; /**< The DMA program genreated + * by the driver. This field will be + * set if a user invokes the DMA + * program generation function. Or + * the DMA command is finished and + * a user informs the driver not to + * release the program buffer. + * This field has two purposes, one + * is to ask the driver to generate + * a DMA program while the DMAC is + * performaning DMA transactions. The + * other purpose is to debug the + * driver. + */ + int GeneratedDmaProgLength; /**< The length of the DMA program + * generated by the driver + */ + int DmaStatus; /**< 0 on success, otherwise error code + */ + u32 ChanFaultType; /**< Channel fault type in case of fault + */ + u32 ChanFaultPCAddr; /**< Channel fault PC address + */ +} XDmaPs_Cmd; + +/** + * It's the done handler a user can set for a channel + */ +typedef void (*XDmaPsDoneHandler) (unsigned int Channel, + XDmaPs_Cmd *DmaCmd, + void *CallbackRef); + +/** + * It's the fault handler a user can set for a channel + */ +typedef void (*XDmaPsFaultHandler) (unsigned int Channel, + XDmaPs_Cmd *DmaCmd, + void *CallbackRef); + +#define XDMAPS_MAX_CHAN_BUFS 2 +#define XDMAPS_CHAN_BUF_LEN 128 + +/** + * The XDmaPs_ProgBuf is the struct for a DMA program buffer. + */ +typedef struct { + char Buf[XDMAPS_CHAN_BUF_LEN]; /**< The actual buffer the holds the + * content */ + unsigned Len; /**< The actual length of the DMA + * program in bytes. */ + int Allocated; /**< A tag indicating whether the + * buffer is allocated or not */ +} XDmaPs_ProgBuf; + +/** + * The XDmaPs_ChannelData is a struct to book keep individual channel of + * the DMAC. + */ +typedef struct { + unsigned DevId; /**< Device id indicating which DMAC */ + unsigned ChanId; /**< Channel number of the DMAC */ + XDmaPs_ProgBuf ProgBufPool[XDMAPS_MAX_CHAN_BUFS]; /**< A pool of + program buffers*/ + XDmaPsDoneHandler DoneHandler; /**< Done interrupt handler */ + void *DoneRef; /**< Done interrupt callback data */ + XDmaPs_Cmd *DmaCmdToHw; /**< DMA command being executed */ + XDmaPs_Cmd *DmaCmdFromHw; /**< DMA command that is finished. + * This field is for debugging purpose + */ + int HoldDmaProg; /**< A tag indicating whether to hold the + * DMA program after the DMA is done. + */ + +} XDmaPs_ChannelData; + +/** + * The XDmaPs driver instance data structure. A pointer to an instance data + * structure is passed around by functions to refer to a specific driver + * instance. + */ +typedef struct { + XDmaPs_Config Config; /**< Configuration data structure */ + int IsReady; /**< Device is Ready */ + int CacheLength; /**< icache length */ + XDmaPsFaultHandler FaultHandler; /**< fault interrupt handler */ + void *FaultRef; /**< fault call back data */ + XDmaPs_ChannelData Chans[XDMAPS_CHANNELS_PER_DEV]; + /**< + * channel data + */ +} XDmaPs; + +/* + * Functions implemented in xdmaps.c + */ +int XDmaPs_CfgInitialize(XDmaPs *InstPtr, + XDmaPs_Config *Config, + u32 EffectiveAddr); + +int XDmaPs_Start(XDmaPs *InstPtr, unsigned int Channel, + XDmaPs_Cmd *Cmd, + int HoldDmaProg); + +int XDmaPs_IsActive(XDmaPs *InstPtr, unsigned int Channel); +int XDmaPs_GenDmaProg(XDmaPs *InstPtr, unsigned int Channel, + XDmaPs_Cmd *Cmd); +int XDmaPs_FreeDmaProg(XDmaPs *InstPtr, unsigned int Channel, + XDmaPs_Cmd *Cmd); +void XDmaPs_Print_DmaProg(XDmaPs_Cmd *Cmd); + + +int XDmaPs_ResetManager(XDmaPs *InstPtr); +int XDmaPs_ResetChannel(XDmaPs *InstPtr, unsigned int Channel); + + +int XDmaPs_SetDoneHandler(XDmaPs *InstPtr, + unsigned Channel, + XDmaPsDoneHandler DoneHandler, + void *CallbackRef); + +int XDmaPs_SetFaultHandler(XDmaPs *InstPtr, + XDmaPsFaultHandler FaultHandler, + void *CallbackRef); + +void XDmaPs_Print_DmaProg(XDmaPs_Cmd *Cmd); +int XDmaPs_Instr_DMARMB(char *DmaProg); +int XDmaPs_Instr_DMAWMB(char *DmaProg); + +/** + * To avoid linking error,Declare all inline functions as extern for + * IAR compiler + */ +#ifdef __ICCARM__ +extern INLINE int XDmaPs_Instr_DMAEND(char *DmaProg); +extern INLINE void XDmaPs_Memcpy4(char *Dst, char *Src); +extern INLINE int XDmaPs_Instr_DMAGO(char *DmaProg, unsigned int Cn, + u32 Imm, unsigned int Ns); +extern INLINE int XDmaPs_Instr_DMALD(char *DmaProg); +extern INLINE int XDmaPs_Instr_DMALP(char *DmaProg, unsigned Lc, + unsigned LoopIterations); +extern INLINE int XDmaPs_Instr_DMALPEND(char *DmaProg, char *BodyStart, unsigned Lc); +extern INLINE int XDmaPs_Instr_DMAMOV(char *DmaProg, unsigned Rd, u32 Imm); +extern INLINE int XDmaPs_Instr_DMANOP(char *DmaProg); +extern INLINE int XDmaPs_Instr_DMASEV(char *DmaProg, unsigned int EventNumber); +extern INLINE int XDmaPs_Instr_DMAST(char *DmaProg); +extern INLINE unsigned XDmaPs_ToEndianSwapSizeBits(unsigned int EndianSwapSize); +extern INLINE unsigned XDmaPs_ToBurstSizeBits(unsigned BurstSize); +#endif + +/** + * Driver done interrupt service routines for the channels. + * We need this done ISR mainly because the driver needs to release the + * DMA program buffer. This is the one that connects the GIC + */ +void XDmaPs_DoneISR_0(XDmaPs *InstPtr); +void XDmaPs_DoneISR_1(XDmaPs *InstPtr); +void XDmaPs_DoneISR_2(XDmaPs *InstPtr); +void XDmaPs_DoneISR_3(XDmaPs *InstPtr); +void XDmaPs_DoneISR_4(XDmaPs *InstPtr); +void XDmaPs_DoneISR_5(XDmaPs *InstPtr); +void XDmaPs_DoneISR_6(XDmaPs *InstPtr); +void XDmaPs_DoneISR_7(XDmaPs *InstPtr); + +/** + * Driver fault interrupt service routine + */ +void XDmaPs_FaultISR(XDmaPs *InstPtr); + + +/* + * Static loopup function implemented in xdmaps_sinit.c + */ +XDmaPs_Config *XDmaPs_LookupConfig(u16 DeviceId); + + +/* + * self-test functions in xdmaps_selftest.c + */ +int XDmaPs_SelfTest(XDmaPs *InstPtr); + + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps_g.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps_g.c new file mode 100644 index 0000000..d9275e8 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps_g.c @@ -0,0 +1,55 @@ + +/******************************************************************* +* +* CAUTION: This file is automatically generated by HSI. +* Version: 2019.1.3 +* DO NOT EDIT. +* +* Copyright (C) 2010-2023 Xilinx, Inc. All Rights Reserved.* +*Permission is hereby granted, free of charge, to any person obtaining a copy +*of this software and associated documentation files (the Software), to deal +*in the Software without restriction, including without limitation the rights +*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +*copies of the Software, and to permit persons to whom the Software is +*furnished to do so, subject to the following conditions: +* +*The above copyright notice and this permission notice shall be included in +*all copies or substantial portions of the Software. +* +*THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +*XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +*OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*Except as contained in this notice, the name of the Xilinx shall not be used +*in advertising or otherwise to promote the sale, use or other dealings in +*this Software without prior written authorization from Xilinx. +* + +* +* Description: Driver configuration +* +*******************************************************************/ + +#include "xparameters.h" +#include "xdmaps.h" + +/* +* The configuration table for devices +*/ + +XDmaPs_Config XDmaPs_ConfigTable[XPAR_XDMAPS_NUM_INSTANCES] = +{ + { + XPAR_PS7_DMA_NS_DEVICE_ID, + XPAR_PS7_DMA_NS_BASEADDR + }, + { + XPAR_PS7_DMA_S_DEVICE_ID, + XPAR_PS7_DMA_S_BASEADDR + } +}; + + diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps_hw.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps_hw.c new file mode 100644 index 0000000..5fbe4ca --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps_hw.c @@ -0,0 +1,112 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xdmaps_hw.c +* @addtogroup dmaps_v2_4 +* @{ +* +* This file contains the implementation of the interface reset functionality +* for XDmaPs driver. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  	Date     Changes
+* ----- ------ -------- ----------------------------------------------
+* 1.06a kpc 10/07/13 First release
+* 
+* +*****************************************************************************/ + +/***************************** Include Files ********************************/ +#include "xdmaps_hw.h" + +/************************** Constant Definitions ****************************/ + +/**************************** Type Definitions ******************************/ + +/***************** Macros (Inline Functions) Definitions ********************/ +#ifndef XDMAPS_MAX_WAIT +#define XDMAPS_MAX_WAIT 4000 +#endif +/************************** Function Prototypes *****************************/ + +/************************** Variable Definitions ****************************/ + +/*****************************************************************************/ +/** +* This function perform the reset sequence to the given dmaps interface by +* configuring the appropriate control bits in the dmaps specifc registers +* the dmaps reset squence involves the following steps +* Disable all the interuupts +* Clear the pending interrupts +* Kill all the active channel threads +* Kill the manager thread +* +* @param BaseAddress of the interface +* +* @return N/A +* +* @note +* This function will not modify the slcr registers that are relavant for +* dmaps controller +******************************************************************************/ +void XDmaPs_ResetHw(u32 BaseAddress) +{ + u32 DbgInst; + u32 WaitCount = 0; + u32 ChanIndex; + + /* Disable all the interrupts */ + XDmaPs_WriteReg(BaseAddress, XDMAPS_INTEN_OFFSET, 0x00); + /* Clear the interrupts */ + XDmaPs_WriteReg(BaseAddress, XDMAPS_INTCLR_OFFSET, XDMAPS_INTCLR_ALL_MASK); + /* Kill the dma channel threads */ + for (ChanIndex=0; ChanIndex < XDMAPS_CHANNELS_PER_DEV; ChanIndex++) { + while ((XDmaPs_ReadReg(BaseAddress, XDMAPS_DBGSTATUS_OFFSET) + & XDMAPS_DBGSTATUS_BUSY) + && (WaitCount < XDMAPS_MAX_WAIT)) + WaitCount++; + + DbgInst = XDmaPs_DBGINST0(0, 0x01, ChanIndex, 1); + XDmaPs_WriteReg(BaseAddress, XDMAPS_DBGINST0_OFFSET, DbgInst); + XDmaPs_WriteReg(BaseAddress, XDMAPS_DBGINST1_OFFSET, 0x0); + XDmaPs_WriteReg(BaseAddress, XDMAPS_DBGCMD_OFFSET, 0x0); + } + /* Kill the manager thread */ + DbgInst = XDmaPs_DBGINST0(0, 0x01, 0, 0); + XDmaPs_WriteReg(BaseAddress, XDMAPS_DBGINST0_OFFSET, DbgInst); + XDmaPs_WriteReg(BaseAddress, XDMAPS_DBGINST1_OFFSET, 0x0); + XDmaPs_WriteReg(BaseAddress, XDMAPS_DBGCMD_OFFSET, 0x0); +} + + + +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps_hw.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps_hw.h new file mode 100644 index 0000000..42dfe69 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps_hw.h @@ -0,0 +1,289 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xdmaps_hw.h +* @addtogroup dmaps_v2_4 +* @{ +* +* This header file contains the hardware interface of an XDmaPs device. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who   Date     Changes
+* ----- ----  -------- ----------------------------------------------
+* 1.00a	hbm   08/18/10 First Release
+* 1.01a nm    12/20/12 Added definition XDMAPS_CHANNELS_PER_DEV which specifies
+*		       the maximum number of channels.
+*		       Replaced the usage of XPAR_XDMAPS_CHANNELS_PER_DEV
+*                      with XDMAPS_CHANNELS_PER_DEV defined in xdmaps_hw.h
+* 1.02a sg    05/16/12 Made changes for doxygen
+* 1.06a kpc   07/10/13 Added function prototype
+* 
+* +******************************************************************************/ + +#ifndef XDMAPS_HW_H /* prevent circular inclusions */ +#define XDMAPS_HW_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +#include "xil_types.h" +#include "xil_assert.h" +#include "xil_io.h" + +/************************** Constant Definitions *****************************/ + +/** @name Register Map + * + * Register offsets for the DMAC. + * @{ + */ + +#define XDMAPS_DS_OFFSET 0x000 /* DMA Status Register */ +#define XDMAPS_DPC_OFFSET 0x004 /* DMA Program Counter Rregister */ +#define XDMAPS_INTEN_OFFSET 0X020 /* DMA Interrupt Enable Register */ +#define XDMAPS_ES_OFFSET 0x024 /* DMA Event Status Register */ +#define XDMAPS_INTSTATUS_OFFSET 0x028 /* DMA Interrupt Status Register + */ +#define XDMAPS_INTCLR_OFFSET 0x02c /* DMA Interrupt Clear Register */ +#define XDMAPS_FSM_OFFSET 0x030 /* DMA Fault Status DMA Manager + * Register + */ +#define XDMAPS_FSC_OFFSET 0x034 /* DMA Fault Status DMA Chanel Register + */ +#define XDMAPS_FTM_OFFSET 0x038 /* DMA Fault Type DMA Manager Register */ + +#define XDMAPS_FTC0_OFFSET 0x040 /* DMA Fault Type for DMA Channel 0 */ +/* + * The offset for the rest of the FTC registers is calculated as + * FTC0 + dev_chan_num * 4 + */ +#define XDmaPs_FTCn_OFFSET(ch) (XDMAPS_FTC0_OFFSET + (ch) * 4) + +#define XDMAPS_CS0_OFFSET 0x100 /* Channel Status for DMA Channel 0 */ +/* + * The offset for the rest of the CS registers is calculated as + * CS0 + * dev_chan_num * 0x08 + */ +#define XDmaPs_CSn_OFFSET(ch) (XDMAPS_CS0_OFFSET + (ch) * 8) + +#define XDMAPS_CPC0_OFFSET 0x104 /* Channel Program Counter for DMA + * Channel 0 + */ +/* + * The offset for the rest of the CPC registers is calculated as + * CPC0 + dev_chan_num * 0x08 + */ +#define XDmaPs_CPCn_OFFSET(ch) (XDMAPS_CPC0_OFFSET + (ch) * 8) + +#define XDMAPS_SA_0_OFFSET 0x400 /* Source Address Register for DMA + * Channel 0 + */ +/* The offset for the rest of the SA registers is calculated as + * SA_0 + dev_chan_num * 0x20 + */ +#define XDmaPs_SA_n_OFFSET(ch) (XDMAPS_SA_0_OFFSET + (ch) * 0x20) + +#define XDMAPS_DA_0_OFFSET 0x404 /* Destination Address Register for + * DMA Channel 0 + */ +/* The offset for the rest of the DA registers is calculated as + * DA_0 + dev_chan_num * 0x20 + */ +#define XDmaPs_DA_n_OFFSET(ch) (XDMAPS_DA_0_OFFSET + (ch) * 0x20) + +#define XDMAPS_CC_0_OFFSET 0x408 /* Channel Control Register for + * DMA Channel 0 + */ +/* + * The offset for the rest of the CC registers is calculated as + * CC_0 + dev_chan_num * 0x20 + */ +#define XDmaPs_CC_n_OFFSET(ch) (XDMAPS_CC_0_OFFSET + (ch) * 0x20) + +#define XDMAPS_LC0_0_OFFSET 0x40C /* Loop Counter 0 for DMA Channel 0 */ +/* + * The offset for the rest of the LC0 registers is calculated as + * LC_0 + dev_chan_num * 0x20 + */ +#define XDmaPs_LC0_n_OFFSET(ch) (XDMAPS_LC0_0_OFFSET + (ch) * 0x20) +#define XDMAPS_LC1_0_OFFSET 0x410 /* Loop Counter 1 for DMA Channel 0 */ +/* + * The offset for the rest of the LC1 registers is calculated as + * LC_0 + dev_chan_num * 0x20 + */ +#define XDmaPs_LC1_n_OFFSET(ch) (XDMAPS_LC1_0_OFFSET + (ch) * 0x20) + +#define XDMAPS_DBGSTATUS_OFFSET 0xD00 /* Debug Status Register */ +#define XDMAPS_DBGCMD_OFFSET 0xD04 /* Debug Command Register */ +#define XDMAPS_DBGINST0_OFFSET 0xD08 /* Debug Instruction 0 Register */ +#define XDMAPS_DBGINST1_OFFSET 0xD0C /* Debug Instruction 1 Register */ + +#define XDMAPS_CR0_OFFSET 0xE00 /* Configuration Register 0 */ +#define XDMAPS_CR1_OFFSET 0xE04 /* Configuration Register 1 */ +#define XDMAPS_CR2_OFFSET 0xE08 /* Configuration Register 2 */ +#define XDMAPS_CR3_OFFSET 0xE0C /* Configuration Register 3 */ +#define XDMAPS_CR4_OFFSET 0xE10 /* Configuration Register 4 */ +#define XDMAPS_CRDN_OFFSET 0xE14 /* Configuration Register Dn */ + +#define XDMAPS_PERIPH_ID_0_OFFSET 0xFE0 /* Peripheral Identification + * Register 0 + */ +#define XDMAPS_PERIPH_ID_1_OFFSET 0xFE4 /* Peripheral Identification + * Register 1 + */ +#define XDMAPS_PERIPH_ID_2_OFFSET 0xFE8 /* Peripheral Identification + * Register 2 + */ +#define XDMAPS_PERIPH_ID_3_OFFSET 0xFEC /* Peripheral Identification + * Register 3 + */ +#define XDMAPS_PCELL_ID_0_OFFSET 0xFF0 /* PrimeCell Identification + * Register 0 + */ +#define XDMAPS_PCELL_ID_1_OFFSET 0xFF4 /* PrimeCell Identification + * Register 1 + */ +#define XDMAPS_PCELL_ID_2_OFFSET 0xFF8 /* PrimeCell Identification + * Register 2 + */ +#define XDMAPS_PCELL_ID_3_OFFSET 0xFFC /* PrimeCell Identification + * Register 3 + */ + +/* + * Some useful register masks + */ +#define XDMAPS_DS_DMA_STATUS 0x0F /* DMA status mask */ +#define XDMAPS_DS_DMA_STATUS_STOPPED 0x00 /* debug status busy mask */ + +#define XDMAPS_DBGSTATUS_BUSY 0x01 /* debug status busy mask */ + +#define XDMAPS_CS_ACTIVE_MASK 0x07 /* channel status active mask, + * llast 3 bits of CS register + */ + +#define XDMAPS_CR1_I_CACHE_LEN_MASK 0x07 /* i_cache_len mask */ + + +/* + * XDMAPS_DBGINST0 - constructs the word for the Debug Instruction-0 Register. + * @b1: Instruction byte 1 + * @b0: Instruction byte 0 + * @ch: Channel number + * @dbg_th: Debug thread encoding: 0 = DMA manager thread, 1 = DMA channel + */ +#define XDmaPs_DBGINST0(b1, b0, ch, dbg_th) \ + (((b1) << 24) | ((b0) << 16) | (((ch) & 0x7) << 8) | ((dbg_th & 0x1))) + +/* @} */ + +/** @name Control Register + * + * The Control register (CR) controls the major functions of the device. + * + * Control Register Bit Definition + */ + +/* @}*/ + + +#define XDMAPS_CHANNELS_PER_DEV 8 + + +/** @name Mode Register + * + * The mode register (MR) defines the mode of transfer as well as the data + * format. If this register is modified during transmission or reception, + * data validity cannot be guaranteed. + * + * Mode Register Bit Definition + * @{ + */ + +/* @} */ + + +/** @name Interrupt Registers + * + * Interrupt control logic uses the interrupt enable register (IER) and the + * interrupt disable register (IDR) to set the value of the bits in the + * interrupt mask register (IMR). The IMR determines whether to pass an + * interrupt to the interrupt status register (ISR). + * Writing a 1 to IER Enbables an interrupt, writing a 1 to IDR disables an + * interrupt. IMR and ISR are read only, and IER and IDR are write only. + * Reading either IER or IDR returns 0x00. + * + * All four registers have the same bit definitions. + * + * @{ + */ + +/* @} */ +#define XDMAPS_INTCLR_ALL_MASK 0xFF + +#define XDmaPs_ReadReg(BaseAddress, RegOffset) \ + Xil_In32((BaseAddress) + (RegOffset)) + +/***************************************************************************/ +/** +* Write a DMAC register. +* +* @param BaseAddress contains the base address of the device. +* @param RegOffset contains the offset from the base address of the device. +* @param RegisterValue is the value to be written to the register. +* +* @return None. +* +* @note +* C-Style signature: +* void XDmaPs_WriteReg(u32 BaseAddress, int RegOffset, +* u32 RegisterValue) +******************************************************************************/ +#define XDmaPs_WriteReg(BaseAddress, RegOffset, RegisterValue) \ + Xil_Out32((BaseAddress) + (RegOffset), (RegisterValue)) +/************************** Variable Definitions *****************************/ + +/************************** Function Prototypes *****************************/ +/* + * Perform reset operation to the dmaps interface + */ +void XDmaPs_ResetHw(u32 BaseAddr); +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps_selftest.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps_selftest.c new file mode 100644 index 0000000..37e70f8 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps_selftest.c @@ -0,0 +1,106 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xdmaps_selftest.c +* @addtogroup dmaps_v2_4 +* @{ +* +* This file contains the self-test functions for the XDmaPs driver. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who     Date     Changes
+* ----- ------ -------- -----------------------------------------------
+* 1.00	hbm 	03/29/2010 First Release
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xstatus.h" +#include "xdmaps.h" + +/************************** Constant Definitions *****************************/ + + +/**************************** Type Definitions *******************************/ + + +/***************** Macros (Inline Functions) Definitions *********************/ + + +/************************** Variable Definitions *****************************/ + + +/************************** Function Prototypes ******************************/ + + +/****************************************************************************/ +/** +* +* This function runs a self-test on the driver and hardware device. This self +* test performs a local loopback and verifies data can be sent and received. +* +* The time for this test is proportional to the baud rate that has been set +* prior to calling this function. +* +* The mode and control registers are restored before return. +* +* @param InstPtr is a pointer to the XDmaPs instance +* +* @return +* +* - XST_SUCCESS if the test was successful +* - XST_FAILURE if the test failed +* +* @note +* +* This function can hang if the hardware is not functioning properly. +* +******************************************************************************/ +int XDmaPs_SelfTest(XDmaPs *InstPtr) +{ + u32 BaseAddr = InstPtr->Config.BaseAddress; + int i; + + if (XDmaPs_ReadReg(BaseAddr, XDMAPS_DBGSTATUS_OFFSET) + & XDMAPS_DBGSTATUS_BUSY) + return XST_FAILURE; + + for (i = 0; i < XDMAPS_CHANNELS_PER_DEV; i++) { + if (XDmaPs_ReadReg(BaseAddr, + XDmaPs_CSn_OFFSET(i))) + return XST_FAILURE; + } + return XST_SUCCESS; +} +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps_sinit.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps_sinit.c new file mode 100644 index 0000000..e0b6fae --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps_sinit.c @@ -0,0 +1,100 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xdmaps_sinit.c +* @addtogroup dmaps_v2_4 +* @{ +* +* The implementation of the XDmaPs driver's static initialzation +* functionality. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00  hbm  08/13/10 First Release
+* 
+* +*****************************************************************************/ + +/***************************** Include Files ********************************/ + +#include "xstatus.h" +#include "xparameters.h" +#include "xdmaps.h" + +/************************** Constant Definitions ****************************/ + +/**************************** Type Definitions ******************************/ + + +/***************** Macros (Inline Functions) Definitions ********************/ + + +/************************** Variable Definitions ****************************/ +extern XDmaPs_Config XDmaPs_ConfigTable[]; + +/************************** Function Prototypes *****************************/ + +/****************************************************************************/ +/** +* +* Looks up the device configuration based on the unique device ID. The table +* contains the configuration info for each device in the system. +* +* @param DeviceId contains the ID of the device +* +* @return +* +* A pointer to the configuration structure or NULL if the specified device +* is not in the system. +* +* @note +* +* None. +* +******************************************************************************/ +XDmaPs_Config *XDmaPs_LookupConfig(u16 DeviceId) +{ + XDmaPs_Config *CfgPtr = NULL; + + int i; + + for (i = 0; i < XPAR_XDMAPS_NUM_INSTANCES; i++) { + if (XDmaPs_ConfigTable[i].DeviceId == DeviceId) { + CfgPtr = &XDmaPs_ConfigTable[i]; + break; + } + } + + return CfgPtr; +} +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/Makefile b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/Makefile new file mode 100644 index 0000000..8601ce4 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/Makefile @@ -0,0 +1,40 @@ +COMPILER= +ARCHIVER= +CP=cp +COMPILER_FLAGS= +EXTRA_COMPILER_FLAGS= +LIB=libxil.a + +CC_FLAGS = $(COMPILER_FLAGS) +ECC_FLAGS = $(EXTRA_COMPILER_FLAGS) + +RELEASEDIR=../../../lib +INCLUDEDIR=../../../include +INCLUDES=-I./. -I${INCLUDEDIR} + +OUTS = *.o + +LIBSOURCES:=*.c +INCLUDEFILES:=*.h + +OBJECTS = $(addsuffix .o, $(basename $(wildcard *.c))) + +libs: banner xgpiops_libs clean + +%.o: %.c + ${COMPILER} $(CC_FLAGS) $(ECC_FLAGS) $(INCLUDES) -o $@ $< + +banner: + echo "Compiling gpiops" + +xgpiops_libs: ${OBJECTS} + $(ARCHIVER) -r ${RELEASEDIR}/${LIB} ${OBJECTS} + +.PHONY: include +include: xgpiops_includes + +xgpiops_includes: + ${CP} ${INCLUDEFILES} ${INCLUDEDIR} + +clean: + rm -rf ${OBJECTS} diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops.c new file mode 100644 index 0000000..39bcc94 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops.c @@ -0,0 +1,830 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2019 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xgpiops.c +* @addtogroup gpiops_v3_5 +* @{ +* +* The XGpioPs driver. Functions in this file are the minimum required functions +* for this driver. See xgpiops.h for a detailed description of the driver. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a sv   01/15/10 First Release
+* 1.01a sv   04/15/12 Removed the APIs XGpioPs_SetMode, XGpioPs_SetModePin
+*                     XGpioPs_GetMode, XGpioPs_GetModePin as they are not
+*		      relevant to Zynq device. The interrupts are disabled
+*		      for output pins on all banks during initialization.
+* 2.1   hk   04/29/14 Use Input data register DATA_RO for read. CR# 771667.
+* 3.00  kvn  02/13/15 Modified code for MISRA-C:2012 compliance.
+* 3.1	kvn  04/13/15 Add support for Zynq Ultrascale+ MP. CR# 856980.
+* 3.1   aru  07/13/18 Resolved doxygen reported warnings. CR# 1006331.
+* 3.4   aru  08/17/18 Resolved MISRA-C mandatory violations. CR# 1007751
+* 3.5   sne  03/01/19 Fixes violations according to MISRAC-2012
+*                     in saftey mode and modified the code such as
+*                     Use of mixed mode arithmetic,Declared the poiner param
+*                     as Pointer to const,Casting operation to a pointer,
+*                     Literal value requires a U suffix.
+* 3.5   sne  03/13/19 Added Versal support.
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xgpiops.h" + +/************************** Constant Definitions *****************************/ +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Variable Definitions *****************************/ + + +/************************** Function Prototypes ******************************/ + +extern void StubHandler(void *CallBackRef, u32 Bank, u32 Status); + +/*****************************************************************************/ +/* +* +* This function initializes a XGpioPs instance/driver. +* All members of the XGpioPs instance structure are initialized and +* StubHandlers are assigned to the Bank Status Handlers. +* +* @param InstancePtr is a pointer to the XGpioPs instance. +* @param ConfigPtr points to the XGpioPs device configuration structure. +* @param EffectiveAddr is the device base address in the virtual memory +* address space. If the address translation is not used then the +* physical address should be passed. +* Unexpected errors may occur if the address mapping is changed +* after this function is invoked. +* +* @return XST_SUCCESS always. +* +* @note None. +* +******************************************************************************/ +s32 XGpioPs_CfgInitialize(XGpioPs *InstancePtr, const XGpioPs_Config *ConfigPtr, + u32 EffectiveAddr) +{ + s32 Status = XST_SUCCESS; + u8 i; + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(ConfigPtr != NULL); + Xil_AssertNonvoid(EffectiveAddr != (u32)0); + /* + * Set some default values for instance data, don't indicate the device + * is ready to use until everything has been initialized successfully. + */ + InstancePtr->IsReady = 0U; + InstancePtr->GpioConfig.BaseAddr = EffectiveAddr; + InstancePtr->GpioConfig.DeviceId = ConfigPtr->DeviceId; + InstancePtr->Handler = (XGpioPs_Handler)StubHandler; + InstancePtr->Platform = XGetPlatform_Info(); + + /* Initialize the Bank data based on platform */ + if (InstancePtr->Platform == (u32)XPLAT_ZYNQ_ULTRA_MP) { + /* + * Max pins in the ZynqMP GPIO device + * 0 - 25, Bank 0 + * 26 - 51, Bank 1 + * 52 - 77, Bank 2 + * 78 - 109, Bank 3 + * 110 - 141, Bank 4 + * 142 - 173, Bank 5 + */ + InstancePtr->MaxPinNum = (u32)174; + InstancePtr->MaxBanks = (u8)6; + } + else if (InstancePtr->Platform == (u32)XPLAT_versal) + { + if(InstancePtr->PmcGpio == (u32)FALSE) + { + /* Max pins in the PS_GPIO devices + * 0 -25, Bank 0 + * 26-57, Bank 3 + */ + InstancePtr->MaxPinNum = (u32)58; + InstancePtr->MaxBanks = (u8)4; + } + else + { + /* Max pins in the PMC_GPIO devices + * 0 - 25,Bank 0 + * 26 - 51,Bank 1 + * 52 - 83,Bank 3 + * 84 - 115, Bank 4 + */ + InstancePtr->MaxPinNum = (u32)116; + InstancePtr->MaxBanks = (u8)5; + } + } + else { + /* + * Max pins in the GPIO device + * 0 - 31, Bank 0 + * 32 - 53, Bank 1 + * 54 - 85, Bank 2 + * 86 - 117, Bank 3 + */ + InstancePtr->MaxPinNum = (u32)118; + InstancePtr->MaxBanks = (u8)4; + } + + /* + * By default, interrupts are not masked in GPIO. Disable + * interrupts for all pins in all the 4 banks. + */ + for (i=(u8)0U;iMaxBanks;i++) { + if (InstancePtr->Platform == XPLAT_versal){ + if(InstancePtr->PmcGpio == (u32)FALSE) + { + if((i== (u8)XGPIOPS_ONE)||(i== (u8)XGPIOPS_TWO)) + { + continue; + } + XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr, + ((u32)(i) * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_INTDIS_OFFSET, 0xFFFFFFFFU); + } + else + { + if(i==(u32)XGPIOPS_TWO) + { + continue; + } + XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr, + ((u32)(i) * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_INTDIS_OFFSET, 0xFFFFFFFFU); + + } + } + else + { + XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr, + ((u32)(i) * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_INTDIS_OFFSET, 0xFFFFFFFFU); + } + } + + /* Indicate the component is now ready to use. */ + InstancePtr->IsReady = XIL_COMPONENT_IS_READY; + + return Status; +} + +/****************************************************************************/ +/** +* +* Read the Data register of the specified GPIO bank. +* +* @param InstancePtr is a pointer to the XGpioPs instance. +* @param Bank is the bank number of the GPIO to operate on. +* Valid values are 0-3 in Zynq and 0-5 in Zynq Ultrascale+ MP. +* +* @return Current value of the Data register. +* +* @note This function is used for reading the state of all the GPIO pins +* of specified bank. +* +*****************************************************************************/ +u32 XGpioPs_Read(const XGpioPs *InstancePtr, u8 Bank) +{ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid(Bank < InstancePtr->MaxBanks); +#ifdef versal + if(InstancePtr->PmcGpio == TRUE) { + Xil_AssertNonvoid(Bank != XGPIOPS_TWO); + } else { + Xil_AssertNonvoid((Bank !=XGPIOPS_ONE) && (Bank !=XGPIOPS_TWO)); + } +#endif + + return XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr, + ((u32)(Bank) * XGPIOPS_DATA_BANK_OFFSET) + + XGPIOPS_DATA_RO_OFFSET); +} + +/****************************************************************************/ +/** +* +* Read Data from the specified pin. +* +* @param InstancePtr is a pointer to the XGpioPs instance. +* @param Pin is the pin number for which the data has to be read. +* Valid values are 0-117 in Zynq and 0-173 in Zynq Ultrascale+ MP. +* See xgpiops.h for the mapping of the pin numbers in the banks. +* +* @return Current value of the Pin (0 or 1). +* +* @note This function is used for reading the state of the specified +* GPIO pin. +* +*****************************************************************************/ +u32 XGpioPs_ReadPin(const XGpioPs *InstancePtr, u32 Pin) +{ + u8 Bank; + u8 PinNumber; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid(Pin < InstancePtr->MaxPinNum); + + /* Get the Bank number and Pin number within the bank. */ +#ifdef versal + XGpioPs_GetBankPin(InstancePtr,(u8)Pin, &Bank, &PinNumber); +#else + XGpioPs_GetBankPin((u8)Pin, &Bank, &PinNumber); +#endif + return (XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr, + ((u32)(Bank) * XGPIOPS_DATA_BANK_OFFSET) + + XGPIOPS_DATA_RO_OFFSET) >> (u32)PinNumber) & (u32)1; + +} + +/****************************************************************************/ +/** +* +* Write to the Data register of the specified GPIO bank. +* +* @param InstancePtr is a pointer to the XGpioPs instance. +* @param Bank is the bank number of the GPIO to operate on. +* Valid values are 0-3 in Zynq and 0-5 in Zynq Ultrascale+ MP. +* @param Data is the value to be written to the Data register. +* +* @return None. +* +* @note This function is used for writing to all the GPIO pins of +* the bank. The previous state of the pins is not maintained. +* +*****************************************************************************/ +void XGpioPs_Write(const XGpioPs *InstancePtr, u8 Bank, u32 Data) +{ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid(Bank < InstancePtr->MaxBanks); +#ifdef versal + if(InstancePtr->PmcGpio == TRUE) { + Xil_AssertVoid(Bank != XGPIOPS_TWO); + } else { + Xil_AssertVoid((Bank !=XGPIOPS_ONE) && (Bank !=XGPIOPS_TWO)); + } +#endif + + XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr, + ((u32)(Bank) * XGPIOPS_DATA_BANK_OFFSET) + + XGPIOPS_DATA_OFFSET, Data); +} + +/****************************************************************************/ +/** +* +* Write data to the specified pin. +* +* @param InstancePtr is a pointer to the XGpioPs instance. +* @param Pin is the pin number to which the Data is to be written. +* Valid values are 0-117 in Zynq and 0-173 in Zynq Ultrascale+ MP. +* @param Data is the data to be written to the specified pin (0 or 1). +* +* @return None. +* +* @note This function does a masked write to the specified pin of +* the specified GPIO bank. The previous state of other pins +* is maintained. +* +*****************************************************************************/ +void XGpioPs_WritePin(const XGpioPs *InstancePtr, u32 Pin, u32 Data) +{ + u32 RegOffset; + u32 Value; + u8 Bank; + u8 PinNumber; + u32 DataVar = Data; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid(Pin < InstancePtr->MaxPinNum); + + /* Get the Bank number and Pin number within the bank. */ +#ifdef versal + XGpioPs_GetBankPin(InstancePtr,(u8)Pin, &Bank, &PinNumber); +#else + XGpioPs_GetBankPin((u8)Pin, &Bank, &PinNumber); +#endif + + if (PinNumber > 15U) { + /* There are only 16 data bits in bit maskable register. */ + PinNumber -= (u8)16; + RegOffset = XGPIOPS_DATA_MSW_OFFSET; + } else { + RegOffset = XGPIOPS_DATA_LSW_OFFSET; + } + + /* + * Get the 32 bit value to be written to the Mask/Data register where + * the upper 16 bits is the mask and lower 16 bits is the data. + */ + DataVar &= (u32)0x01; + Value = ~((u32)1 << (PinNumber + 16U)) & ((DataVar << PinNumber) | 0xFFFF0000U); + XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr, + ((u32)(Bank) * XGPIOPS_DATA_MASK_OFFSET) + + RegOffset, Value); + +} + + + +/****************************************************************************/ +/** +* +* Set the Direction of the pins of the specified GPIO Bank. +* +* @param InstancePtr is a pointer to the XGpioPs instance. +* @param Bank is the bank number of the GPIO to operate on. +* Valid values are 0-3 in Zynq and 0-5 in Zynq Ultrascale+ MP. +* @param Direction is the 32 bit mask of the Pin direction to be set for +* all the pins in the Bank. Bits with 0 are set to Input mode, +* bits with 1 are set to Output Mode. +* +* @return None. +* +* @note This function is used for setting the direction of all the pins +* in the specified bank. The previous state of the pins is +* not maintained. +* +*****************************************************************************/ +void XGpioPs_SetDirection(const XGpioPs *InstancePtr, u8 Bank, u32 Direction) +{ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid(Bank < InstancePtr->MaxBanks); +#ifdef versal + if(InstancePtr->PmcGpio == TRUE) { + Xil_AssertVoid(Bank != XGPIOPS_TWO); + } else { + Xil_AssertVoid((Bank !=XGPIOPS_ONE) && (Bank !=XGPIOPS_TWO)); + } +#endif + + XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr, + ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_DIRM_OFFSET, Direction); +} + +/****************************************************************************/ +/** +* +* Set the Direction of the specified pin. +* +* @param InstancePtr is a pointer to the XGpioPs instance. +* @param Pin is the pin number to which the Data is to be written. +* Valid values are 0-117 in Zynq and 0-173 in Zynq Ultrascale+ MP. +* @param Direction is the direction to be set for the specified pin. +* Valid values are 0 for Input Direction, 1 for Output Direction. +* +* @return None. +* +*****************************************************************************/ +void XGpioPs_SetDirectionPin(const XGpioPs *InstancePtr, u32 Pin, u32 Direction) +{ + u8 Bank; + u8 PinNumber; + u32 DirModeReg; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid(Pin < InstancePtr->MaxPinNum); + Xil_AssertVoid(Direction <= (u32)1); + + /* Get the Bank number and Pin number within the bank. */ +#ifdef versal + XGpioPs_GetBankPin(InstancePtr,(u8)Pin, &Bank, &PinNumber); +#else + XGpioPs_GetBankPin((u8)Pin, &Bank, &PinNumber); +#endif + DirModeReg = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr, + ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_DIRM_OFFSET); + + if (Direction!=(u32)0) { /* Output Direction */ + DirModeReg |= ((u32)1 << (u32)PinNumber); + } else { /* Input Direction */ + DirModeReg &= ~ ((u32)1 << (u32)PinNumber); + } + + XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr, + ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_DIRM_OFFSET, DirModeReg); +} + +/****************************************************************************/ +/** +* +* Get the Direction of the pins of the specified GPIO Bank. +* +* @param InstancePtr is a pointer to the XGpioPs instance. +* @param Bank is the bank number of the GPIO to operate on. +* Valid values are 0-3 in Zynq and 0-5 in Zynq Ultrascale+ MP. +* +* @return Returns a 32 bit mask of the Direction register. Bits with 0 are +* in Input mode, bits with 1 are in Output Mode. +* +* @note None. +* +*****************************************************************************/ +u32 XGpioPs_GetDirection(const XGpioPs *InstancePtr, u8 Bank) +{ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid(Bank < InstancePtr->MaxBanks); +#ifdef versal + if(InstancePtr->PmcGpio == TRUE) { + Xil_AssertNonvoid(Bank != XGPIOPS_TWO); + } else { + Xil_AssertNonvoid((Bank !=XGPIOPS_ONE) && (Bank !=XGPIOPS_TWO)); + } +#endif + + return XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr, + ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_DIRM_OFFSET); +} + +/****************************************************************************/ +/** +* +* Get the Direction of the specified pin. +* +* @param InstancePtr is a pointer to the XGpioPs instance. +* @param Pin is the pin number for which the Direction is to be +* retrieved. +* Valid values are 0-117 in Zynq and 0-173 in Zynq Ultrascale+ MP. +* +* @return Direction of the specified pin. +* - 0 for Input Direction +* - 1 for Output Direction +* +* @note None. +* +*****************************************************************************/ +u32 XGpioPs_GetDirectionPin(const XGpioPs *InstancePtr, u32 Pin) +{ + u8 Bank; + u8 PinNumber; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid(Pin < InstancePtr->MaxPinNum); + + /* Get the Bank number and Pin number within the bank. */ +#ifdef versal + XGpioPs_GetBankPin(InstancePtr,(u8)Pin, &Bank, &PinNumber); +#else + XGpioPs_GetBankPin((u8)Pin, &Bank, &PinNumber); +#endif + + return (XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr, + ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_DIRM_OFFSET) >> (u32)PinNumber) & (u32)1; +} + +/****************************************************************************/ +/** +* +* Set the Output Enable of the pins of the specified GPIO Bank. +* +* @param InstancePtr is a pointer to the XGpioPs instance. +* @param Bank is the bank number of the GPIO to operate on. +* Valid values are 0-3 in Zynq and 0-5 in Zynq Ultrascale+ MP. +* @param OpEnable is the 32 bit mask of the Output Enables to be set for +* all the pins in the Bank. The Output Enable of bits with 0 are +* disabled, the Output Enable of bits with 1 are enabled. +* +* @return None. +* +* @note This function is used for setting the Output Enables of all the +* pins in the specified bank. The previous state of the Output +* Enables is not maintained. +* +*****************************************************************************/ +void XGpioPs_SetOutputEnable(const XGpioPs *InstancePtr, u8 Bank, u32 OpEnable) +{ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid(Bank < InstancePtr->MaxBanks); +#ifdef versal + if(InstancePtr->PmcGpio == TRUE) { + Xil_AssertVoid(Bank != XGPIOPS_TWO); + } else { + Xil_AssertVoid((Bank !=XGPIOPS_ONE) && (Bank !=XGPIOPS_TWO)); + } +#endif + + XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr, + ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_OUTEN_OFFSET, OpEnable); +} + +/****************************************************************************/ +/** +* +* Set the Output Enable of the specified pin. +* +* @param InstancePtr is a pointer to the XGpioPs instance. +* @param Pin is the pin number to which the Data is to be written. +* Valid values are 0-117 in Zynq and 0-173 in Zynq Ultrascale+ MP. +* @param OpEnable specifies whether the Output Enable for the specified +* pin should be enabled. +* Valid values are 0 for Disabling Output Enable, +* 1 for Enabling Output Enable. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XGpioPs_SetOutputEnablePin(const XGpioPs *InstancePtr, u32 Pin, u32 OpEnable) +{ + u8 Bank; + u8 PinNumber; + u32 OpEnableReg; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid(Pin < InstancePtr->MaxPinNum); + Xil_AssertVoid(OpEnable <= (u32)1); + + /* Get the Bank number and Pin number within the bank. */ +#ifdef versal + XGpioPs_GetBankPin(InstancePtr,(u8)Pin, &Bank, &PinNumber); +#else + XGpioPs_GetBankPin((u8)Pin, &Bank, &PinNumber); +#endif + + OpEnableReg = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr, + ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_OUTEN_OFFSET); + + if (OpEnable != (u32)0) { /* Enable Output Enable */ + OpEnableReg |= ((u32)1 << (u32)PinNumber); + } else { /* Disable Output Enable */ + OpEnableReg &= ~ ((u32)1 << (u32)PinNumber); + } + + XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr, + ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_OUTEN_OFFSET, OpEnableReg); +} +/****************************************************************************/ +/** +* +* Get the Output Enable status of the pins of the specified GPIO Bank. +* +* @param InstancePtr is a pointer to the XGpioPs instance. +* @param Bank is the bank number of the GPIO to operate on. +* Valid values are 0-3 in Zynq and 0-5 in Zynq Ultrascale+ MP. +* +* @return Returns a a 32 bit mask of the Output Enable register. +* Bits with 0 are in Disabled state, bits with 1 are in +* Enabled State. +* +* @note None. +* +*****************************************************************************/ +u32 XGpioPs_GetOutputEnable(const XGpioPs *InstancePtr, u8 Bank) +{ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid(Bank < InstancePtr->MaxBanks); +#ifdef versal + if(InstancePtr->PmcGpio == TRUE) { + Xil_AssertNonvoid(Bank != XGPIOPS_TWO); + } else { + Xil_AssertNonvoid((Bank !=XGPIOPS_ONE) && (Bank !=XGPIOPS_TWO)); + } +#endif + + return XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr, + ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_OUTEN_OFFSET); +} + +/****************************************************************************/ +/** +* +* Get the Output Enable status of the specified pin. +* +* @param InstancePtr is a pointer to the XGpioPs instance. +* @param Pin is the pin number for which the Output Enable status is to +* be retrieved. +* Valid values are 0-117 in Zynq and 0-173 in Zynq Ultrascale+ MP. +* +* @return Output Enable of the specified pin. +* - 0 if Output Enable is disabled for this pin +* - 1 if Output Enable is enabled for this pin +* +* @note None. +* +*****************************************************************************/ +u32 XGpioPs_GetOutputEnablePin(const XGpioPs *InstancePtr, u32 Pin) +{ + u8 Bank; + u8 PinNumber; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid(Pin < InstancePtr->MaxPinNum); + + /* Get the Bank number and Pin number within the bank. */ +#ifdef versal + XGpioPs_GetBankPin(InstancePtr,(u8)Pin, &Bank, &PinNumber); +#else + XGpioPs_GetBankPin((u8)Pin, &Bank, &PinNumber); +#endif + + return (XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr, + ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_OUTEN_OFFSET) >> (u32)PinNumber) & (u32)1; +} + +/****************************************************************************/ +/* +* +* Get the Bank number and the Pin number in the Bank, for the given PinNumber +* in the GPIO device. +* +* @param PinNumber is the Pin number in the GPIO device. +* @param BankNumber returns the Bank in which this GPIO pin is present. +* Valid values are 0 to XGPIOPS_MAX_BANKS - 1. +* @param PinNumberInBank returns the Pin Number within the Bank. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +#ifdef versal +void XGpioPs_GetBankPin(const XGpioPs *InstancePtr,u8 PinNumber, u8 *BankNumber, u8 *PinNumberInBank) +#else +void XGpioPs_GetBankPin(u8 PinNumber, u8 *BankNumber, u8 *PinNumberInBank) +#endif +{ + u32 XGpioPsPinTable[6] = {0}; +#ifdef versal + u8 i=(u8)0; +#endif + u32 Platform = XGetPlatform_Info(); + + if (Platform == (u32)XPLAT_ZYNQ_ULTRA_MP) { + /* + * This structure defines the mapping of the pin numbers to the banks when + * the driver APIs are used for working on the individual pins. + */ + + XGpioPsPinTable[0] = (u32)25; /* 0 - 25, Bank 0 */ + XGpioPsPinTable[1] = (u32)51; /* 26 - 51, Bank 1 */ + XGpioPsPinTable[2] = (u32)77; /* 52 - 77, Bank 2 */ + XGpioPsPinTable[3] = (u32)109; /* 78 - 109, Bank 3 */ + XGpioPsPinTable[4] = (u32)141; /* 110 - 141, Bank 4 */ + XGpioPsPinTable[5] = (u32)173; /* 142 - 173 Bank 5 */ + + *BankNumber = 0U; + while (*BankNumber < XGPIOPS_SIX) { + if (PinNumber <= XGpioPsPinTable[*BankNumber]) { + break; + } + (*BankNumber)++; + } + } +#ifdef versal + else if(Platform == XPLAT_versal) + { + if(InstancePtr->PmcGpio == (u32)(FALSE)) + { + XGpioPsPinTable[0] = (u32)25; /* 0 - 25, Bank 0 */ + XGpioPsPinTable[1] = (u32)57; /* 26 - 57, Bank 3 */ + *BankNumber =0U; + if(PinNumber <= XGpioPsPinTable[*BankNumber]) + { + *BankNumber = (u8)XGPIOPS_ZERO; + } + else + { + *BankNumber = (u8)XGPIOPS_THREE; + } + + } + else + { + XGpioPsPinTable[0] = (u32)25; /* 0 - 25, Bank 0 */ + XGpioPsPinTable[1] = (u32)51; /* 26 - 51, Bank 1 */ + XGpioPsPinTable[2] = (u32)83; /* 52 - 83, Bank 3 */ + XGpioPsPinTable[3] = (u32)115; /*84 - 115, Bank 4 */ + + *BankNumber =0U; + while(i < XGPIOPS_FOUR) + { + if(i <= (u8)XGPIOPS_ONE) + { + if (PinNumber <= XGpioPsPinTable[i]) + { + *BankNumber = (u8)i; + break; + } + i++; + } + else + { + if (PinNumber <= XGpioPsPinTable[i]) + { + *BankNumber = (u8)i+1U; + break; + } + i++; + } + + } + } + + } +#endif + else { + XGpioPsPinTable[0] = (u32)31; /* 0 - 31, Bank 0 */ + XGpioPsPinTable[1] = (u32)53; /* 32 - 53, Bank 1 */ + XGpioPsPinTable[2] = (u32)85; /* 54 - 85, Bank 2 */ + XGpioPsPinTable[3] = (u32)117; /* 86 - 117 Bank 3 */ + + *BankNumber = 0U; + while (*BankNumber < XGPIOPS_FOUR) { + if (PinNumber <= XGpioPsPinTable[*BankNumber]) { + break; + } + (*BankNumber)++; + } + } + if (*BankNumber == (u8)0) { + *PinNumberInBank = PinNumber; + } + +#ifdef versal + else if(Platform == XPLAT_versal) + { + if(InstancePtr->PmcGpio == (u32)(FALSE)) + { + *PinNumberInBank = (u8)((u32)PinNumber - (XGpioPsPinTable[0] + (u32)1)); + } + else { + if((*BankNumber ==(u8)XGPIOPS_THREE) || (*BankNumber ==(u8)XGPIOPS_FOUR)) + { + *PinNumberInBank = (u8)((u32)PinNumber % + (XGpioPsPinTable[*BankNumber - (u8)XGPIOPS_TWO] + (u32)1)); + } + else + { + *PinNumberInBank = (u8)((u32)PinNumber % + (XGpioPsPinTable[*BankNumber - (u8)1] + (u32)1)); + } + } + + } +#endif + + else { + *PinNumberInBank = (u8)((u32)PinNumber % + (XGpioPsPinTable[*BankNumber - (u8)1] + (u32)1)); + } +} +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops.h new file mode 100644 index 0000000..d0ff132 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops.h @@ -0,0 +1,283 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2019 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xgpiops.h +* @addtogroup gpiops_v3_5 +* @{ +* @details +* +* The Xilinx PS GPIO driver. This driver supports the Xilinx PS GPIO +* Controller. +* +* The GPIO Controller supports the following features: +* - 4 banks +* - Masked writes (There are no masked reads) +* - Bypass mode +* - Configurable Interrupts (Level/Edge) +* +* This driver is intended to be RTOS and processor independent. Any needs for +* dynamic memory management, threads or thread mutual exclusion, virtual +* memory, or cache control must be satisfied by the layer above this driver. + +* This driver supports all the features listed above, if applicable. +* +* Driver Description +* +* The device driver enables higher layer software (e.g., an application) to +* communicate to the GPIO. +* +* Interrupts +* +* The driver provides interrupt management functions and an interrupt handler. +* Users of this driver need to provide callback functions. An interrupt handler +* example is available with the driver. +* +* Threads +* +* This driver is not thread safe. Any needs for threads or thread mutual +* exclusion must be satisfied by the layer above this driver. +* +* Asserts +* +* Asserts are used within all Xilinx drivers to enforce constraints on argument +* values. Asserts can be turned off on a system-wide basis by defining, at +* compile time, the NDEBUG identifier. By default, asserts are turned on and it +* is recommended that users leave asserts on during development. +* +* Building the driver +* +* The XGpioPs driver is composed of several source files. This allows the user +* to build and link only those parts of the driver that are necessary. +*

+* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a sv   01/15/10 First Release
+* 1.01a sv   04/15/12 Removed the APIs XGpioPs_SetMode, XGpioPs_SetModePin
+*                     XGpioPs_GetMode, XGpioPs_GetModePin as they are not
+*		      relevant to Zynq device.The interrupts are disabled
+*		      for output pins on all banks during initialization.
+* 1.02a hk   08/22/13 Added low level reset API
+* 2.1   hk   04/29/14 Use Input data register DATA_RO for read. CR# 771667.
+* 2.2	sk	 10/13/14 Used Pin number in Bank instead of pin number
+* 					  passed to APIs. CR# 822636
+* 3.00  kvn  02/13/15 Modified code for MISRA-C:2012 compliance.
+* 3.1	kvn  04/13/15 Add support for Zynq Ultrascale+ MP. CR# 856980.
+*       ms   03/17/17 Added readme.txt file in examples folder for doxygen
+*                     generation.
+*       ms   04/05/17 Added tabspace for return statements in functions of
+*                     gpiops examples for proper documentation while
+*                     generating doxygen.
+* 3.3   ms   04/17/17 Added notes about gpio input and output pin description
+*                     for zcu102 and zc702 boards in polled and interrupt
+*                     example, configured Interrupt pin to input pin for
+*                     proper functioning of interrupt example.
+* 3.4   aru  08/17/18 Resolved MISRA-C mandatory violations. CR# 1007751
+* 3.5   sne  03/01/19 Fixes violations according to MISRAC-2012
+*                     in saftey mode and modified the code such as
+*                     Use of mixed mode arithmetic,Declared the poiner param
+*                     as Pointer to const,Casting operation to a pointer,
+*                     Literal value requires a U suffix.
+* 3.5   sne  03/14/19 Added Versal support.
+* 
+* +******************************************************************************/ +#ifndef XGPIOPS_H /* prevent circular inclusions */ +#define XGPIOPS_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +#include "xstatus.h" +#include "xgpiops_hw.h" +#include "xplatform_info.h" + +/************************** Constant Definitions *****************************/ + +/** @name Interrupt types + * @{ + * The following constants define the interrupt types that can be set for each + * GPIO pin. + */ +#define XGPIOPS_IRQ_TYPE_EDGE_RISING 0x00U /**< Interrupt on Rising edge */ +#define XGPIOPS_IRQ_TYPE_EDGE_FALLING 0x01U /**< Interrupt Falling edge */ +#define XGPIOPS_IRQ_TYPE_EDGE_BOTH 0x02U /**< Interrupt on both edges */ +#define XGPIOPS_IRQ_TYPE_LEVEL_HIGH 0x03U /**< Interrupt on high level */ +#define XGPIOPS_IRQ_TYPE_LEVEL_LOW 0x04U /**< Interrupt on low level */ +/*@}*/ + +#define XGPIOPS_BANK_MAX_PINS (u32)32 /**< Max pins in a GPIO bank */ +#define XGPIOPS_BANK0 0x00U /**< GPIO Bank 0 */ +#define XGPIOPS_BANK1 0x01U /**< GPIO Bank 1 */ +#define XGPIOPS_BANK2 0x02U /**< GPIO Bank 2 */ +#define XGPIOPS_BANK3 0x03U /**< GPIO Bank 3 */ + +#ifdef XPAR_PSU_GPIO_0_BASEADDR +#define XGPIOPS_BANK4 0x04U /**< GPIO Bank 4 */ +#define XGPIOPS_BANK5 0x05U /**< GPIO Bank 5 */ +#endif + +#define XGPIOPS_MAX_BANKS_ZYNQMP 0x06U /**< Max banks in a + * Zynq Ultrascale+ MP GPIO device + */ +#define XGPIOPS_MAX_BANKS 0x04U /**< Max banks in a Zynq GPIO device */ + +#define XGPIOPS_DEVICE_MAX_PIN_NUM_ZYNQMP (u32)174 /**< Max pins in the + * Zynq Ultrascale+ MP GPIO device + * 0 - 25, Bank 0 + * 26 - 51, Bank 1 + * 52 - 77, Bank 2 + * 78 - 109, Bank 3 + * 110 - 141, Bank 4 + * 142 - 173, Bank 5 + */ +#define XGPIOPS_DEVICE_MAX_PIN_NUM (u32)118 /**< Max pins in the Zynq GPIO device + * 0 - 31, Bank 0 + * 32 - 53, Bank 1 + * 54 - 85, Bank 2 + * 86 - 117, Bank 3 + */ + +/**************************** Type Definitions *******************************/ + +/****************************************************************************/ +/** + * This handler data type allows the user to define a callback function to + * handle the interrupts for the GPIO device. The application using this + * driver is expected to define a handler of this type, to support interrupt + * driven mode. The handler executes in an interrupt context such that minimal + * processing should be performed. + * + * @param CallBackRef is a callback reference passed in by the upper layer + * when setting the callback functions for a GPIO bank. It is + * passed back to the upper layer when the callback is invoked. Its + * type is not important to the driver component, so it is a void + * pointer. + * @param Bank is the bank for which the interrupt status has changed. + * @param Status is the Interrupt status of the GPIO bank. + * + *****************************************************************************/ +typedef void (*XGpioPs_Handler) (void *CallBackRef, u32 Bank, u32 Status); + +/** + * This typedef contains configuration information for a device. + */ +typedef struct { + u16 DeviceId; /**< Unique ID of device */ + u32 BaseAddr; /**< Register base address */ +} XGpioPs_Config; + +/** + * The XGpioPs driver instance data. The user is required to allocate a + * variable of this type for the GPIO device in the system. A pointer + * to a variable of this type is then passed to the driver API functions. + */ +typedef struct { + XGpioPs_Config GpioConfig; /**< Device configuration */ + u32 IsReady; /**< Device is initialized and ready */ + XGpioPs_Handler Handler; /**< Status handlers for all banks */ + void *CallBackRef; /**< Callback ref for bank handlers */ + u32 Platform; /**< Platform data */ + u32 MaxPinNum; /**< Max pins in the GPIO device */ + u8 MaxBanks; /**< Max banks in a GPIO device */ + u32 PmcGpio; /**< Flag for accessing PS GPIO for versal*/ +} XGpioPs; + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/* Functions in xgpiops.c */ +s32 XGpioPs_CfgInitialize(XGpioPs *InstancePtr, const XGpioPs_Config *ConfigPtr, + u32 EffectiveAddr); + +/* Bank APIs in xgpiops.c */ +u32 XGpioPs_Read(const XGpioPs *InstancePtr, u8 Bank); +void XGpioPs_Write(const XGpioPs *InstancePtr, u8 Bank, u32 Data); +void XGpioPs_SetDirection(const XGpioPs *InstancePtr, u8 Bank, u32 Direction); +u32 XGpioPs_GetDirection(const XGpioPs *InstancePtr, u8 Bank); +void XGpioPs_SetOutputEnable(const XGpioPs *InstancePtr, u8 Bank, u32 OpEnable); +u32 XGpioPs_GetOutputEnable(const XGpioPs *InstancePtr, u8 Bank); +#ifdef versal +void XGpioPs_GetBankPin(const XGpioPs *InstancePtr,u8 PinNumber,u8 *BankNumber, u8 *PinNumberInBank); +#else +void XGpioPs_GetBankPin(u8 PinNumber,u8 *BankNumber, u8 *PinNumberInBank); +#endif + +/* Pin APIs in xgpiops.c */ +u32 XGpioPs_ReadPin(const XGpioPs *InstancePtr, u32 Pin); +void XGpioPs_WritePin(const XGpioPs *InstancePtr, u32 Pin, u32 Data); +void XGpioPs_SetDirectionPin(const XGpioPs *InstancePtr, u32 Pin, u32 Direction); +u32 XGpioPs_GetDirectionPin(const XGpioPs *InstancePtr, u32 Pin); +void XGpioPs_SetOutputEnablePin(const XGpioPs *InstancePtr, u32 Pin, u32 OpEnable); +u32 XGpioPs_GetOutputEnablePin(const XGpioPs *InstancePtr, u32 Pin); + +/* Diagnostic functions in xgpiops_selftest.c */ +s32 XGpioPs_SelfTest(const XGpioPs *InstancePtr); + +/* Functions in xgpiops_intr.c */ +/* Bank APIs in xgpiops_intr.c */ +void XGpioPs_IntrEnable(const XGpioPs *InstancePtr, u8 Bank, u32 Mask); +void XGpioPs_IntrDisable(const XGpioPs *InstancePtr, u8 Bank, u32 Mask); +u32 XGpioPs_IntrGetEnabled(const XGpioPs *InstancePtr, u8 Bank); +u32 XGpioPs_IntrGetStatus(const XGpioPs *InstancePtr, u8 Bank); +void XGpioPs_IntrClear(const XGpioPs *InstancePtr, u8 Bank, u32 Mask); +void XGpioPs_SetIntrType(const XGpioPs *InstancePtr, u8 Bank, u32 IntrType, + u32 IntrPolarity, u32 IntrOnAny); +void XGpioPs_GetIntrType(const XGpioPs *InstancePtr, u8 Bank, u32 *IntrType, + u32 *IntrPolarity, u32 *IntrOnAny); +void XGpioPs_SetCallbackHandler(XGpioPs *InstancePtr, void *CallBackRef, + XGpioPs_Handler FuncPointer); +void XGpioPs_IntrHandler(const XGpioPs *InstancePtr); + +/* Pin APIs in xgpiops_intr.c */ +void XGpioPs_SetIntrTypePin(const XGpioPs *InstancePtr, u32 Pin, u8 IrqType); +u8 XGpioPs_GetIntrTypePin(const XGpioPs *InstancePtr, u32 Pin); + +void XGpioPs_IntrEnablePin(const XGpioPs *InstancePtr, u32 Pin); +void XGpioPs_IntrDisablePin(const XGpioPs *InstancePtr, u32 Pin); +u32 XGpioPs_IntrGetEnabledPin(const XGpioPs *InstancePtr, u32 Pin); +u32 XGpioPs_IntrGetStatusPin(const XGpioPs *InstancePtr, u32 Pin); +void XGpioPs_IntrClearPin(const XGpioPs *InstancePtr, u32 Pin); + +/* Functions in xgpiops_sinit.c */ +XGpioPs_Config *XGpioPs_LookupConfig(u16 DeviceId); +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops_g.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops_g.c new file mode 100644 index 0000000..ee60dd2 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops_g.c @@ -0,0 +1,51 @@ + +/******************************************************************* +* +* CAUTION: This file is automatically generated by HSI. +* Version: 2019.1.3 +* DO NOT EDIT. +* +* Copyright (C) 2010-2023 Xilinx, Inc. All Rights Reserved.* +*Permission is hereby granted, free of charge, to any person obtaining a copy +*of this software and associated documentation files (the Software), to deal +*in the Software without restriction, including without limitation the rights +*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +*copies of the Software, and to permit persons to whom the Software is +*furnished to do so, subject to the following conditions: +* +*The above copyright notice and this permission notice shall be included in +*all copies or substantial portions of the Software. +* +*THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +*XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +*OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*Except as contained in this notice, the name of the Xilinx shall not be used +*in advertising or otherwise to promote the sale, use or other dealings in +*this Software without prior written authorization from Xilinx. +* + +* +* Description: Driver configuration +* +*******************************************************************/ + +#include "xparameters.h" +#include "xgpiops.h" + +/* +* The configuration table for devices +*/ + +XGpioPs_Config XGpioPs_ConfigTable[XPAR_XGPIOPS_NUM_INSTANCES] = +{ + { + XPAR_PS7_GPIO_0_DEVICE_ID, + XPAR_PS7_GPIO_0_BASEADDR + } +}; + + diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops_hw.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops_hw.c new file mode 100644 index 0000000..4885c29 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops_hw.c @@ -0,0 +1,262 @@ +/****************************************************************************** +* +* Copyright (C) 2013 - 2019 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xgpiops_hw.c +* @addtogroup gpiops_v3_5 +* @{ +* +* This file contains low level GPIO functions. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.02a hk   08/22/13 First Release
+* 3.00  kvn  02/13/15 Modified code for MISRA-C:2012 compliance.
+* 3.1	kvn  04/13/15 Add support for Zynq Ultrascale+ MP. CR# 856980.
+* 3.5   sne  03/01/19 Fixes violations according to MISRAC-2012
+*                     in saftey mode and modified the code such as
+*                     Use of mixed mode arithmetic,Declared the poiner param
+*                     as Pointer to const,Casting operation to a pointer,
+*                     Literal value requires a U suffix.
+* 3.5   sne  03/14/19 Added versal support.
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xgpiops_hw.h" +#include "xgpiops.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Variable Definitions *****************************/ + +/************************** Function Prototypes ******************************/ + + +/*****************************************************************************/ +/* +* +* This function resets the GPIO module by writing reset values to +* all registers +* +* @param Base address of GPIO module +* +* @return None +* +* @note None. +* +******************************************************************************/ +void XGpioPs_ResetHw(u32 BaseAddress) +{ + u32 BankCount; + u32 Platform,MaxBanks; + + Platform = XGetPlatform_Info(); + if (Platform == (u32)XPLAT_ZYNQ_ULTRA_MP) { + MaxBanks = (u32)6; + } + else if(Platform == (u32)XPLAT_versal) + { + if (BaseAddress == (u32)XGPIOPS_PS_GPIO_BASEADDR) + { + MaxBanks = (u32)4; + } + else + { + MaxBanks = (u32)5; + } + } + else { + MaxBanks = (u32)4; + } + + if (Platform == (u32)XPLAT_versal) + { + /* Write reset values to all mask data registers */ + for(BankCount = 3U; BankCount < (u32)MaxBanks; BankCount++) { + + XGpioPs_WriteReg(BaseAddress, + ((BankCount * XGPIOPS_DATA_MASK_OFFSET) + + XGPIOPS_DATA_LSW_OFFSET), 0x0U); + XGpioPs_WriteReg(BaseAddress, + ((BankCount * XGPIOPS_DATA_MASK_OFFSET) + + XGPIOPS_DATA_MSW_OFFSET), 0x0U); + } + /* Write reset values to all output data registers */ + for(BankCount = 3U; BankCount < (u32)MaxBanks; BankCount++) { + + XGpioPs_WriteReg(BaseAddress, + ((BankCount * XGPIOPS_DATA_BANK_OFFSET) + + XGPIOPS_DATA_OFFSET), 0x0U); + } + + /* Reset all registers of all GPIO banks */ + for(BankCount = 0U; BankCount < (u32)MaxBanks; BankCount++) { + + + if((BaseAddress == (u32)XGPIOPS_PS_GPIO_BASEADDR) && ((BankCount == (u32)XGPIOPS_ONE) ||(BankCount == (u32)XGPIOPS_TWO))) + { + continue; + } + else + { + if((BaseAddress != (u32)XGPIOPS_PS_GPIO_BASEADDR) && (BankCount == (u32)XGPIOPS_ONE)) + { + continue; + } + } + XGpioPs_WriteReg(BaseAddress, + ((BankCount * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_DIRM_OFFSET), 0x0U); + XGpioPs_WriteReg(BaseAddress, + ((BankCount * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_OUTEN_OFFSET), 0x0U); + XGpioPs_WriteReg(BaseAddress, + ((BankCount * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_INTMASK_OFFSET), 0x0U); + XGpioPs_WriteReg(BaseAddress, + ((BankCount * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_INTEN_OFFSET), 0x0U); + XGpioPs_WriteReg(BaseAddress, + ((BankCount * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_INTDIS_OFFSET), 0x0U); + XGpioPs_WriteReg(BaseAddress, + ((BankCount * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_INTSTS_OFFSET), 0x0U); + XGpioPs_WriteReg(BaseAddress, + ((BankCount * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_INTPOL_OFFSET), 0x0U); + XGpioPs_WriteReg(BaseAddress, + ((BankCount * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_INTANY_OFFSET), 0x0U); + + } + + /* Bank 0 Int type */ + XGpioPs_WriteReg(BaseAddress, XGPIOPS_INTTYPE_OFFSET, + XGPIOPS_INTTYPE_BANK0_RESET); + /* Bank 1 Int type */ + XGpioPs_WriteReg(BaseAddress, + ((u32)XGPIOPS_REG_MASK_OFFSET + (u32)XGPIOPS_INTTYPE_OFFSET), + XGPIOPS_INTTYPE_BANK1_RESET); + /* Bank 3 Int type */ + XGpioPs_WriteReg(BaseAddress, + (((u32)3 * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_INTTYPE_OFFSET), + XGPIOPS_INTTYPE_BANK3_RESET); + /* Bank 4 Int type */ + XGpioPs_WriteReg(BaseAddress, + (((u32)4 * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_INTTYPE_OFFSET), + XGPIOPS_INTTYPE_BANK4_RESET); + } + else + { + /* Write reset values to all mask data registers */ + for(BankCount = 2U; BankCount < (u32)MaxBanks; BankCount++) { + + XGpioPs_WriteReg(BaseAddress, + ((BankCount * XGPIOPS_DATA_MASK_OFFSET) + + XGPIOPS_DATA_LSW_OFFSET), 0x0U); + XGpioPs_WriteReg(BaseAddress, + ((BankCount * XGPIOPS_DATA_MASK_OFFSET) + + XGPIOPS_DATA_MSW_OFFSET), 0x0U); + } + /* Write reset values to all output data registers */ + for(BankCount = 2U; BankCount < (u32)MaxBanks; BankCount++) { + + XGpioPs_WriteReg(BaseAddress, + ((BankCount * XGPIOPS_DATA_BANK_OFFSET) + + XGPIOPS_DATA_OFFSET), 0x0U); + } + /* Reset all registers of all GPIO banks */ + for(BankCount = 0U; BankCount < (u32)MaxBanks; BankCount++) { + + XGpioPs_WriteReg(BaseAddress, + ((BankCount * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_DIRM_OFFSET), 0x0U); + XGpioPs_WriteReg(BaseAddress, + ((BankCount * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_OUTEN_OFFSET), 0x0U); + XGpioPs_WriteReg(BaseAddress, + ((BankCount * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_INTMASK_OFFSET), 0x0U); + XGpioPs_WriteReg(BaseAddress, + ((BankCount * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_INTEN_OFFSET), 0x0U); + XGpioPs_WriteReg(BaseAddress, + ((BankCount * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_INTDIS_OFFSET), 0x0U); + XGpioPs_WriteReg(BaseAddress, + ((BankCount * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_INTSTS_OFFSET), 0x0U); + XGpioPs_WriteReg(BaseAddress, + ((BankCount * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_INTPOL_OFFSET), 0x0U); + XGpioPs_WriteReg(BaseAddress, + ((BankCount * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_INTANY_OFFSET), 0x0U); + } + /* Bank 0 Int type */ + XGpioPs_WriteReg(BaseAddress, XGPIOPS_INTTYPE_OFFSET, + XGPIOPS_INTTYPE_BANK0_RESET); + /* Bank 1 Int type */ + XGpioPs_WriteReg(BaseAddress, + ((u32)XGPIOPS_REG_MASK_OFFSET + (u32)XGPIOPS_INTTYPE_OFFSET), + XGPIOPS_INTTYPE_BANK1_RESET); + /* Bank 2 Int type */ + XGpioPs_WriteReg(BaseAddress, + (((u32)2 * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_INTTYPE_OFFSET), + XGPIOPS_INTTYPE_BANK2_RESET); + /* Bank 3 Int type */ + XGpioPs_WriteReg(BaseAddress, + (((u32)3 * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_INTTYPE_OFFSET), + XGPIOPS_INTTYPE_BANK3_RESET); + + if (Platform == (u32)XPLAT_ZYNQ_ULTRA_MP) { + /* Bank 4 Int type */ + XGpioPs_WriteReg(BaseAddress, + (((u32)4 * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_INTTYPE_OFFSET), + XGPIOPS_INTTYPE_BANK4_RESET); + /* Bank 5 Int type */ + XGpioPs_WriteReg(BaseAddress, + (((u32)5 * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_INTTYPE_OFFSET), + XGPIOPS_INTTYPE_BANK5_RESET); + } + } + +} +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops_hw.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops_hw.h new file mode 100644 index 0000000..599c7db --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops_hw.h @@ -0,0 +1,168 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2019 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xgpiops_hw.h +* @addtogroup gpiops_v3_5 +* @{ +* +* This header file contains the identifiers and basic driver functions (or +* macros) that can be used to access the device. Other driver functions +* are defined in xgpiops.h. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -------------------------------------------------
+* 1.00a sv   01/15/10 First Release
+* 1.02a hk   08/22/13 Added low level reset API function prototype and
+*                     related constant definitions
+* 3.00  kvn  02/13/15 Modified code for MISRA-C:2012 compliance.
+* 3.1	kvn  04/13/15 Corrected reset values of banks.
+* 3.5   sne  03/14/19 Added versal support.
+* 
+* +******************************************************************************/ +#ifndef XGPIOPS_HW_H /* prevent circular inclusions */ +#define XGPIOPS_HW_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/***************************** Include Files *********************************/ + +#include "xil_types.h" +#include "xil_assert.h" +#include "xil_io.h" + +/************************** Constant Definitions *****************************/ + +/** @name Register offsets for the GPIO. Each register is 32 bits. + * @{ + */ +#define XGPIOPS_DATA_LSW_OFFSET 0x00000000U /* Mask and Data Register LSW, WO */ +#define XGPIOPS_DATA_MSW_OFFSET 0x00000004U /* Mask and Data Register MSW, WO */ +#define XGPIOPS_DATA_OFFSET 0x00000040U /* Data Register, RW */ +#define XGPIOPS_DATA_RO_OFFSET 0x00000060U /* Data Register - Input, RO */ +#define XGPIOPS_DIRM_OFFSET 0x00000204U /* Direction Mode Register, RW */ +#define XGPIOPS_OUTEN_OFFSET 0x00000208U /* Output Enable Register, RW */ +#define XGPIOPS_INTMASK_OFFSET 0x0000020CU /* Interrupt Mask Register, RO */ +#define XGPIOPS_INTEN_OFFSET 0x00000210U /* Interrupt Enable Register, WO */ +#define XGPIOPS_INTDIS_OFFSET 0x00000214U /* Interrupt Disable Register, WO*/ +#define XGPIOPS_INTSTS_OFFSET 0x00000218U /* Interrupt Status Register, RO */ +#define XGPIOPS_INTTYPE_OFFSET 0x0000021CU /* Interrupt Type Register, RW */ +#define XGPIOPS_INTPOL_OFFSET 0x00000220U /* Interrupt Polarity Register, RW */ +#define XGPIOPS_INTANY_OFFSET 0x00000224U /* Interrupt On Any Register, RW */ +/* @} */ + +/** @name Register offsets for each Bank. + * @{ + */ +#define XGPIOPS_DATA_MASK_OFFSET 0x00000008U /* Data/Mask Registers offset */ +#define XGPIOPS_DATA_BANK_OFFSET 0x00000004U /* Data Registers offset */ +#define XGPIOPS_REG_MASK_OFFSET 0x00000040U /* Registers offset */ +/* @} */ + +/* For backwards compatibility */ +#define XGPIOPS_BYPM_MASK_OFFSET (u32)0x40 + +/** @name Interrupt type reset values for each bank + * @{ + */ +#ifdef XPAR_PSU_GPIO_0_BASEADDR +#define XGPIOPS_INTTYPE_BANK0_RESET 0x03FFFFFFU /* Resets specific to Zynq Ultrascale+ MP */ +#define XGPIOPS_INTTYPE_BANK1_RESET 0x03FFFFFFU +#define XGPIOPS_INTTYPE_BANK2_RESET 0x03FFFFFFU +#else +#define XGPIOPS_INTTYPE_BANK0_RESET 0xFFFFFFFFU /* Resets specific to Zynq */ +#define XGPIOPS_INTTYPE_BANK1_RESET 0x003FFFFFU +#define XGPIOPS_INTTYPE_BANK2_RESET 0xFFFFFFFFU +#endif + +#define XGPIOPS_INTTYPE_BANK3_RESET 0xFFFFFFFFU /* Reset common to both platforms */ +#define XGPIOPS_INTTYPE_BANK4_RESET 0xFFFFFFFFU /* Resets specific to Zynq Ultrascale+ MP */ +#define XGPIOPS_INTTYPE_BANK5_RESET 0xFFFFFFFFU +/* @} */ +#define XGPIOPS_PS_GPIO_BASEADDR 0xFF0B0000U /* Flag for Base Address for PS_GPIO in Versal */ +#define XGPIOPS_ZERO 0U /* Flag for 0 Value */ +#define XGPIOPS_ONE 1U /* Flag for 1 Value */ +#define XGPIOPS_TWO 2U /* Flag for 2 Value */ +#define XGPIOPS_THREE 3U /* Flag for 3 Value */ +#define XGPIOPS_FOUR 4U /* Flag for 4 Value */ +#define XGPIOPS_SIX 6U /* Flag for 6 Value */ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/****************************************************************************/ +/** +* +* This macro reads the given register. +* +* @param BaseAddr is the base address of the device. +* @param RegOffset is the register offset to be read. +* +* @return The 32-bit value of the register +* +* @note None. +* +*****************************************************************************/ +#define XGpioPs_ReadReg(BaseAddr, RegOffset) \ + Xil_In32((BaseAddr) + (u32)(RegOffset)) + +/****************************************************************************/ +/** +* +* This macro writes to the given register. +* +* @param BaseAddr is the base address of the device. +* @param RegOffset is the offset of the register to be written. +* @param Data is the 32-bit value to write to the register. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +#define XGpioPs_WriteReg(BaseAddr, RegOffset, Data) \ + Xil_Out32((BaseAddr) + (u32)(RegOffset), (u32)(Data)) + +/************************** Function Prototypes ******************************/ + +void XGpioPs_ResetHw(u32 BaseAddress); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* XGPIOPS_HW_H */ +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops_intr.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops_intr.c new file mode 100644 index 0000000..0730c91 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops_intr.c @@ -0,0 +1,813 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2019 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xgpiops_intr.c +* @addtogroup gpiops_v3_5 +* @{ +* +* This file contains functions related to GPIO interrupt handling. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a sv   01/18/10 First Release
+* 2.2	sk	 10/13/14 Used Pin number in Bank instead of pin number
+* 					  passed to API's. CR# 822636
+* 3.00  kvn  02/13/15 Modified code for MISRA-C:2012 compliance.
+* 3.1	kvn  04/13/15 Add support for Zynq Ultrascale+ MP. CR# 856980.
+* 3.1   aru  07/13/18 Ressolved doxygen reported warnings. CR# 1006331.
+* 3.4   aru  08/09/18 Ressolved cppcheck warnings.
+* 3.4   aru  08/17/18 Resolved MISRA-C mandatory violations. CR# 1007751
+* 3.5   sne  03/01/19 Fixes violations according to MISRAC-2012
+*                     in saftey mode and modified the code such as
+*                     Use of mixed mode arithmetic,Declared the poiner param
+*                     as Pointer to const,Casting operation to a pointer,
+*                     Literal value requires a U suffix.
+* 3.5   sne  03/14/19 Added Versal support.
+* 3.5   sne  03/20/19 Fixed multiple interrupts problem CR#1024556.
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xgpiops.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Variable Definitions *****************************/ + +/************************** Function Prototypes ******************************/ + +void StubHandler(const void *CallBackRef, u32 Bank, u32 Status); + +/****************************************************************************/ +/** +* +* This function enables the interrupts for the specified pins in the specified +* bank. +* +* @param InstancePtr is a pointer to the XGpioPs instance. +* @param Bank is the bank number of the GPIO to operate on. +* Valid values are 0-3 in Zynq and 0-5 in Zynq Ultrascale+ MP. +* @param Mask is the bit mask of the pins for which interrupts are to +* be enabled. Bit positions of 1 will be enabled. Bit positions +* of 0 will keep the previous setting. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XGpioPs_IntrEnable(const XGpioPs *InstancePtr, u8 Bank, u32 Mask) +{ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid(Bank < InstancePtr->MaxBanks); +#ifdef versal + if(InstancePtr->PmcGpio == TRUE) { + Xil_AssertVoid(Bank != XGPIOPS_TWO); + } else { + Xil_AssertVoid((Bank !=XGPIOPS_ONE) && (Bank !=XGPIOPS_TWO)); + } +#endif + + XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr, + ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_INTEN_OFFSET, Mask); +} + +/****************************************************************************/ +/** +* +* This function enables the interrupt for the specified pin. +* +* @param InstancePtr is a pointer to the XGpioPs instance. +* @param Pin is the pin number for which the interrupt is to be enabled. +* Valid values are 0-117 in Zynq and 0-173 in Zynq Ultrascale+ MP. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XGpioPs_IntrEnablePin(const XGpioPs *InstancePtr, u32 Pin) +{ + u8 Bank; + u8 PinNumber; + u32 IntrReg; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid(Pin < InstancePtr->MaxPinNum); + + /* Get the Bank number and Pin number within the bank. */ +#ifdef versal + XGpioPs_GetBankPin(InstancePtr,(u8)Pin, &Bank, &PinNumber); +#else + XGpioPs_GetBankPin((u8)Pin, &Bank, &PinNumber); +#endif + + IntrReg = ((u32)1 << (u32)PinNumber); + XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr, + ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_INTEN_OFFSET, IntrReg); +} + +/****************************************************************************/ +/** +* +* This function disables the interrupts for the specified pins in the specified +* bank. +* +* @param InstancePtr is a pointer to the XGpioPs instance. +* @param Bank is the bank number of the GPIO to operate on. +* Valid values are 0-3 in Zynq and 0-5 in Zynq Ultrascale+ MP. +* @param Mask is the bit mask of the pins for which interrupts are +* to be disabled. Bit positions of 1 will be disabled. Bit +* positions of 0 will keep the previous setting. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XGpioPs_IntrDisable(const XGpioPs *InstancePtr, u8 Bank, u32 Mask) +{ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid(Bank < InstancePtr->MaxBanks); +#ifdef versal + if(InstancePtr->PmcGpio == TRUE) { + Xil_AssertVoid(Bank != XGPIOPS_TWO); + } else { + Xil_AssertVoid((Bank !=XGPIOPS_ONE) && (Bank !=XGPIOPS_TWO)); + } +#endif + + XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr, + ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_INTDIS_OFFSET, Mask); +} + +/****************************************************************************/ +/** +* +* This function disables the interrupts for the specified pin. +* +* @param InstancePtr is a pointer to the XGpioPs instance. +* @param Pin is the pin number for which the interrupt is to be disabled. +* Valid values are 0-117 in Zynq and 0-173 in Zynq Ultrascale+ MP. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XGpioPs_IntrDisablePin(const XGpioPs *InstancePtr, u32 Pin) +{ + u8 Bank; + u8 PinNumber; + u32 IntrReg; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid(Pin < InstancePtr->MaxPinNum); + + /* Get the Bank number and Pin number within the bank. */ +#ifdef versal + XGpioPs_GetBankPin(InstancePtr,(u8)Pin, &Bank, &PinNumber); +#else + XGpioPs_GetBankPin((u8)Pin, &Bank, &PinNumber); +#endif + + IntrReg = ((u32)1 << (u32)PinNumber); + XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr, + ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_INTDIS_OFFSET, IntrReg); +} + +/****************************************************************************/ +/** +* +* This function returns the interrupt enable status for a bank. +* +* @param InstancePtr is a pointer to the XGpioPs instance. +* @param Bank is the bank number of the GPIO to operate on. +* Valid values are 0-3 in Zynq and 0-5 in Zynq Ultrascale+ MP. +* +* @return Enabled interrupt(s) in a 32-bit format. Bit positions with 1 +* indicate that the interrupt for that pin is enabled, bit +* positions with 0 indicate that the interrupt for that pin is +* disabled. +* +* @note None. +* +*****************************************************************************/ +u32 XGpioPs_IntrGetEnabled(const XGpioPs *InstancePtr, u8 Bank) +{ + u32 IntrMask; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid(Bank < InstancePtr->MaxBanks); +#ifdef versal + if(InstancePtr->PmcGpio == TRUE) { + Xil_AssertNonvoid(Bank != XGPIOPS_TWO); + } else { + Xil_AssertNonvoid((Bank !=XGPIOPS_ONE) && (Bank !=XGPIOPS_TWO)); + } +#endif + + IntrMask = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr, + ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_INTMASK_OFFSET); + return (~IntrMask); +} + +/****************************************************************************/ +/** +* +* This function returns whether interrupts are enabled for the specified pin. +* +* @param InstancePtr is a pointer to the XGpioPs instance. +* @param Pin is the pin number for which the interrupt enable status +* is to be known. +* Valid values are 0-117 in Zynq and 0-173 in Zynq Ultrascale+ MP. +* +* @return +* - TRUE if the interrupt is enabled. +* - FALSE if the interrupt is disabled. +* +* @note None. +* +*****************************************************************************/ +u32 XGpioPs_IntrGetEnabledPin(const XGpioPs *InstancePtr, u32 Pin) +{ + u8 Bank; + u8 PinNumber; + u32 IntrReg; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid(Pin < InstancePtr->MaxPinNum); + + /* Get the Bank number and Pin number within the bank. */ +#ifdef versal + XGpioPs_GetBankPin(InstancePtr,(u8)Pin, &Bank, &PinNumber); +#else + XGpioPs_GetBankPin((u8)Pin, &Bank, &PinNumber); +#endif + + IntrReg = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr, + ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_INTMASK_OFFSET); + + return (((IntrReg & ((u32)1 << PinNumber)) != (u32)0)? FALSE : TRUE); +} + +/****************************************************************************/ +/** +* +* This function returns interrupt status read from Interrupt Status Register. +* +* @param InstancePtr is a pointer to the XGpioPs instance. +* @param Bank is the bank number of the GPIO to operate on. +* Valid values are 0-3 in Zynq and 0-5 in Zynq Ultrascale+ MP. +* +* @return The value read from Interrupt Status Register. +* +* @note None. +* +*****************************************************************************/ +u32 XGpioPs_IntrGetStatus(const XGpioPs *InstancePtr, u8 Bank) +{ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid(Bank < InstancePtr->MaxBanks); +#ifdef versal + if(InstancePtr->PmcGpio == TRUE) { + Xil_AssertNonvoid(Bank != XGPIOPS_TWO); + } else { + Xil_AssertNonvoid((Bank !=XGPIOPS_ONE) && (Bank !=XGPIOPS_TWO)); + } +#endif + + return XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr, + ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_INTSTS_OFFSET); +} + +/****************************************************************************/ +/** +* +* This function returns interrupt enable status of the specified pin. +* +* @param InstancePtr is a pointer to the XGpioPs instance. +* @param Pin is the pin number for which the interrupt enable status +* is to be known. +* Valid values are 0-117 in Zynq and 0-173 in Zynq Ultrascale+ MP. +* +* @return +* - TRUE if the interrupt has occurred. +* - FALSE if the interrupt has not occurred. +* +* @note None. +* +*****************************************************************************/ +u32 XGpioPs_IntrGetStatusPin(const XGpioPs *InstancePtr, u32 Pin) +{ + u8 Bank; + u8 PinNumber; + u32 IntrReg; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid(Pin < InstancePtr->MaxPinNum); + + /* Get the Bank number and Pin number within the bank. */ +#ifdef versal + XGpioPs_GetBankPin(InstancePtr,(u8)Pin, &Bank, &PinNumber); +#else + XGpioPs_GetBankPin((u8)Pin, &Bank, &PinNumber); +#endif + + IntrReg = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr, + ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_INTSTS_OFFSET); + + return (((IntrReg & ((u32)1 << PinNumber)) != (u32)0)? TRUE : FALSE); +} + +/****************************************************************************/ +/** +* +* This function clears pending interrupt(s) with the provided mask. This +* function should be called after the software has serviced the interrupts +* that are pending. +* +* @param InstancePtr is a pointer to the XGpioPs instance. +* @param Bank is the bank number of the GPIO to operate on. +* Valid values are 0-3 in Zynq and 0-5 in Zynq Ultrascale+ MP. +* @param Mask is the mask of the interrupts to be cleared. Bit positions +* of 1 will be cleared. Bit positions of 0 will not change the +* previous interrupt status. +* +* @note None. +* +*****************************************************************************/ +void XGpioPs_IntrClear(const XGpioPs *InstancePtr, u8 Bank, u32 Mask) +{ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid(Bank < InstancePtr->MaxBanks); +#ifdef versal + if(InstancePtr->PmcGpio == TRUE) { + Xil_AssertVoid(Bank != XGPIOPS_TWO); + } else { + Xil_AssertVoid((Bank !=XGPIOPS_ONE) && (Bank !=XGPIOPS_TWO)); + } +#endif + + /* Clear the currently pending interrupts. */ + XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr, + ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_INTSTS_OFFSET, Mask); +} + +/****************************************************************************/ +/** +* +* This function clears the specified pending interrupt. This function should be +* called after the software has serviced the interrupts that are pending. +* +* @param InstancePtr is a pointer to the XGpioPs instance. +* @param Pin is the pin number for which the interrupt status is to be +* cleared. Valid values are 0-117 in Zynq and 0-173 in Zynq Ultrascale+ MP. +* +* @note None. +* +*****************************************************************************/ +void XGpioPs_IntrClearPin(const XGpioPs *InstancePtr, u32 Pin) +{ + u8 Bank; + u8 PinNumber; + u32 IntrReg; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid(Pin < InstancePtr->MaxPinNum); + + /* Get the Bank number and Pin number within the bank. */ +#ifdef versal + XGpioPs_GetBankPin(InstancePtr,(u8)Pin, &Bank, &PinNumber); +#else + XGpioPs_GetBankPin((u8)Pin, &Bank, &PinNumber); +#endif + + /* Clear the specified pending interrupts. */ + IntrReg = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr, + ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_INTSTS_OFFSET); + + IntrReg &= ((u32)1 << PinNumber); + XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr, + ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_INTSTS_OFFSET, IntrReg); +} + +/****************************************************************************/ +/** +* +* This function is used for setting the Interrupt Type, Interrupt Polarity and +* Interrupt On Any for the specified GPIO Bank pins. +* +* @param InstancePtr is a pointer to an XGpioPs instance. +* @param Bank is the bank number of the GPIO to operate on. +* Valid values are 0-3 in Zynq and 0-5 in Zynq Ultrascale+ MP. +* @param IntrType is the 32 bit mask of the interrupt type. +* 0 means Level Sensitive and 1 means Edge Sensitive. +* @param IntrPolarity is the 32 bit mask of the interrupt polarity. +* 0 means Active Low or Falling Edge and 1 means Active High or +* Rising Edge. +* @param IntrOnAny is the 32 bit mask of the interrupt trigger for +* edge triggered interrupts. 0 means trigger on single edge using +* the configured interrupt polarity and 1 means trigger on both +* edges. +* +* @return None. +* +* @note This function is used for setting the interrupt related +* properties of all the pins in the specified bank. The previous +* state of the pins is not maintained. +* To change the Interrupt properties of a single GPIO pin, use the +* function XGpioPs_SetPinIntrType(). +* +*****************************************************************************/ +void XGpioPs_SetIntrType(const XGpioPs *InstancePtr, u8 Bank, u32 IntrType, + u32 IntrPolarity, u32 IntrOnAny) +{ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid(Bank < InstancePtr->MaxBanks); +#ifdef versal + if(InstancePtr->PmcGpio == TRUE) { + Xil_AssertVoid(Bank != XGPIOPS_TWO); + } else { + Xil_AssertVoid((Bank !=XGPIOPS_ONE) && (Bank !=XGPIOPS_TWO)); + } +#endif + + XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr, + ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_INTTYPE_OFFSET, IntrType); + + XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr, + ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_INTPOL_OFFSET, IntrPolarity); + + XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr, + ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_INTANY_OFFSET, IntrOnAny); +} + +/****************************************************************************/ +/** +* +* This function is used for getting the Interrupt Type, Interrupt Polarity and +* Interrupt On Any for the specified GPIO Bank pins. +* +* @param InstancePtr is a pointer to an XGpioPs instance. +* @param Bank is the bank number of the GPIO to operate on. +* Valid values are 0-3 in Zynq and 0-5 in Zynq Ultrascale+ MP. +* @param IntrType returns the 32 bit mask of the interrupt type. +* 0 means Level Sensitive and 1 means Edge Sensitive. +* @param IntrPolarity returns the 32 bit mask of the interrupt +* polarity. 0 means Active Low or Falling Edge and 1 means +* Active High or Rising Edge. +* @param IntrOnAny returns the 32 bit mask of the interrupt trigger for +* edge triggered interrupts. 0 means trigger on single edge using +* the configured interrupt polarity and 1 means trigger on both +* edges. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XGpioPs_GetIntrType(const XGpioPs *InstancePtr, u8 Bank, u32 *IntrType, + u32 *IntrPolarity, u32 *IntrOnAny) + +{ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid(Bank < InstancePtr->MaxBanks); +#ifdef versal + if(InstancePtr->PmcGpio == TRUE) { + Xil_AssertVoid(Bank != XGPIOPS_TWO); + } else { + Xil_AssertVoid((Bank !=XGPIOPS_ONE) && (Bank !=XGPIOPS_TWO)); + } +#endif + + *IntrType = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr, + ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_INTTYPE_OFFSET); + + *IntrPolarity = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr, + ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_INTPOL_OFFSET); + + *IntrOnAny = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr, + ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_INTANY_OFFSET); +} + +/****************************************************************************/ +/** +* +* This function is used for setting the IRQ Type of a single GPIO pin. +* +* @param InstancePtr is a pointer to an XGpioPs instance. +* @param Pin is the pin number whose IRQ type is to be set. +* Valid values are 0-117 in Zynq and 0-173 in Zynq Ultrascale+ MP. +* @param IrqType is the IRQ type for GPIO Pin. Use XGPIOPS_IRQ_TYPE_* +* defined in xgpiops.h to specify the IRQ type. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XGpioPs_SetIntrTypePin(const XGpioPs *InstancePtr, u32 Pin, u8 IrqType) +{ + u32 IntrTypeReg; + u32 IntrPolReg; + u32 IntrOnAnyReg; + u8 Bank; + u8 PinNumber; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid(Pin < InstancePtr->MaxPinNum); + Xil_AssertVoid(IrqType <= XGPIOPS_IRQ_TYPE_LEVEL_LOW); + + /* Get the Bank number and Pin number within the bank. */ +#ifdef versal + XGpioPs_GetBankPin(InstancePtr,(u8)Pin, &Bank, &PinNumber); +#else + XGpioPs_GetBankPin((u8)Pin, &Bank, &PinNumber); +#endif + + IntrTypeReg = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr, + ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_INTTYPE_OFFSET); + + IntrPolReg = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr, + ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_INTPOL_OFFSET); + + IntrOnAnyReg = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr, + ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_INTANY_OFFSET); + + switch (IrqType) { + case XGPIOPS_IRQ_TYPE_EDGE_RISING: + IntrTypeReg |= ((u32)1 << (u32)PinNumber); + IntrPolReg |= ((u32)1 << (u32)PinNumber); + IntrOnAnyReg &= ~((u32)1 << (u32)PinNumber); + break; + case XGPIOPS_IRQ_TYPE_EDGE_FALLING: + IntrTypeReg |= ((u32)1 << (u32)PinNumber); + IntrPolReg &= ~((u32)1 << (u32)PinNumber); + IntrOnAnyReg &= ~((u32)1 << (u32)PinNumber); + break; + case XGPIOPS_IRQ_TYPE_EDGE_BOTH: + IntrTypeReg |= ((u32)1 << (u32)PinNumber); + IntrOnAnyReg |= ((u32)1 << (u32)PinNumber); + break; + case XGPIOPS_IRQ_TYPE_LEVEL_HIGH: + IntrTypeReg &= ~((u32)1 << (u32)PinNumber); + IntrPolReg |= ((u32)1 << (u32)PinNumber); + break; + case XGPIOPS_IRQ_TYPE_LEVEL_LOW: + IntrTypeReg &= ~((u32)1 << (u32)PinNumber); + IntrPolReg &= ~((u32)1 << (u32)PinNumber); + break; + default: + /**< Default statement is added for MISRA C compliance. */ + break; + } + + XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr, + ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_INTTYPE_OFFSET, IntrTypeReg); + + XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr, + ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_INTPOL_OFFSET, IntrPolReg); + + XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr, + ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_INTANY_OFFSET, IntrOnAnyReg); +} + +/****************************************************************************/ +/** +* +* This function returns the IRQ Type of a given GPIO pin. +* +* @param InstancePtr is a pointer to an XGpioPs instance. +* @param Pin is the pin number whose IRQ type is to be obtained. +* Valid values are 0-117 in Zynq and 0-173 in Zynq Ultrascale+ MP. +* +* @return None. +* +* @note Use XGPIOPS_IRQ_TYPE_* defined in xgpiops.h for the IRQ type +* returned by this function. +* +*****************************************************************************/ +u8 XGpioPs_GetIntrTypePin(const XGpioPs *InstancePtr, u32 Pin) +{ + u32 IntrType; + u32 IntrPol; + u32 IntrOnAny; + u8 Bank; + u8 PinNumber; + u8 IrqType; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid(Pin < InstancePtr->MaxPinNum); + + /* Get the Bank number and Pin number within the bank. */ +#ifdef versal + XGpioPs_GetBankPin(InstancePtr,(u8)Pin, &Bank, &PinNumber); +#else + XGpioPs_GetBankPin((u8)Pin, &Bank, &PinNumber); +#endif + + IntrType = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr, + ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_INTTYPE_OFFSET) & ((u32)1 << PinNumber); + + if (IntrType == ((u32)1 << PinNumber)) { + + IntrOnAny = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr, + ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_INTANY_OFFSET) & ((u32)1 << PinNumber); + + IntrPol = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr, + ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_INTPOL_OFFSET) & ((u32)1 << PinNumber); + + + if (IntrOnAny == ((u32)1 << PinNumber)) { + IrqType = XGPIOPS_IRQ_TYPE_EDGE_BOTH; + } else if (IntrPol == ((u32)1 << PinNumber)) { + IrqType = XGPIOPS_IRQ_TYPE_EDGE_RISING; + } else { + IrqType = XGPIOPS_IRQ_TYPE_EDGE_FALLING; + } + } else { + + IntrPol = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr, + ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) + + XGPIOPS_INTPOL_OFFSET) & ((u32)1 << PinNumber); + + if (IntrPol == ((u32)1 << PinNumber)) { + IrqType = XGPIOPS_IRQ_TYPE_LEVEL_HIGH; + } else { + IrqType = XGPIOPS_IRQ_TYPE_LEVEL_LOW; + } + } + + return IrqType; +} + +/*****************************************************************************/ +/** +* +* This function sets the status callback function. The callback function is +* called by the XGpioPs_IntrHandler when an interrupt occurs. +* +* @param InstancePtr is a pointer to the XGpioPs instance. +* @param CallBackRef is the upper layer callback reference passed back +* when the callback function is invoked. +* @param FuncPointer is the pointer to the callback function. +* +* +* @return None. +* +* @note The handler is called within interrupt context, so it should do +* its work quickly and queue potentially time-consuming work to a +* task-level thread. +* +******************************************************************************/ +void XGpioPs_SetCallbackHandler(XGpioPs *InstancePtr, void *CallBackRef, + XGpioPs_Handler FuncPointer) +{ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(FuncPointer != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + InstancePtr->Handler = FuncPointer; + InstancePtr->CallBackRef = CallBackRef; +} + +/*****************************************************************************/ +/** +* +* This function is the interrupt handler for GPIO interrupts.It checks the +* interrupt status registers of all the banks to determine the actual bank in +* which an interrupt has been triggered. It then calls the upper layer callback +* handler set by the function XGpioPs_SetBankHandler(). The callback is called +* when an interrupt +* +* @param InstancePtr is a pointer to the XGpioPs instance. +* +* @return None. +* +* @note This function does not save and restore the processor context +* such that the user must provide this processing. +* +******************************************************************************/ +void XGpioPs_IntrHandler(const XGpioPs *InstancePtr) +{ + u8 Bank; + u32 IntrStatus; + u32 IntrEnabled; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + for (Bank = 0U; Bank < InstancePtr->MaxBanks; Bank++) { + IntrStatus = XGpioPs_IntrGetStatus(InstancePtr, Bank); + IntrEnabled = XGpioPs_IntrGetEnabled(InstancePtr,Bank); + if ((IntrStatus & IntrEnabled) != (u32)0) { + XGpioPs_IntrClear(InstancePtr, Bank, + (IntrStatus & IntrEnabled)); + InstancePtr->Handler(InstancePtr-> + CallBackRef, Bank, + (IntrStatus & IntrEnabled)); + } + } +} + +/*****************************************************************************/ +/** +* +* This is a stub for the status callback. The stub is here in case the upper +* layers do not set the handler. +* +* @param CallBackRef is a pointer to the upper layer callback reference +* @param Bank is the GPIO Bank in which an interrupt occurred. +* @param Status is the Interrupt status of the GPIO bank. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void StubHandler(const void *CallBackRef, u32 Bank, u32 Status) +{ + (const void) CallBackRef; + (void) Bank; + (void) Status; + + Xil_AssertVoidAlways(); +} +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops_selftest.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops_selftest.c new file mode 100644 index 0000000..322ca74 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops_selftest.c @@ -0,0 +1,134 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2019 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xgpiops_selftest.c +* @addtogroup gpiops_v3_5 +* @{ +* +* This file contains a diagnostic self-test function for the XGpioPs driver. +* +* Read xgpiops.h file for more information. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a sv   01/18/10 First Release
+* 3.00  kvn  02/13/15 Modified code for MISRA-C:2012 compliance.
+* 3.5   sne  03/01/19 Fixes violations according to MISRAC-2012
+*                     in saftey mode and modified the code such as
+*                     Use of mixed mode arithmetic,Declared the poiner param
+*                     as Pointer to const,Casting operation to a pointer,
+*                     Literal value requires a U suffix.
+* 
+* +*****************************************************************************/ + +/***************************** Include Files ********************************/ + +#include "xstatus.h" +#include "xgpiops.h" + +/************************** Constant Definitions ****************************/ + + +/**************************** Type Definitions ******************************/ + +/***************** Macros (Inline Functions) Definitions ********************/ + +/************************** Variable Definitions ****************************/ + +/************************** Function Prototypes *****************************/ + +/*****************************************************************************/ +/** +* +* This function runs a self-test on the GPIO driver/device. This function +* does a register read/write test on some of the Interrupt Registers. +* +* @param InstancePtr is a pointer to the XGpioPs instance. +* +* @return +* - XST_SUCCESS if the self-test passed. +* - XST_FAILURE otherwise. +* +* +******************************************************************************/ +s32 XGpioPs_SelfTest(const XGpioPs *InstancePtr) +{ + s32 Status = XST_SUCCESS; + u32 IntrEnabled; + u32 CurrentIntrType = 0U; + u32 CurrentIntrPolarity = 0U; + u32 CurrentIntrOnAny = 0U; + u32 IntrType = 0U; + u32 IntrPolarity = 0U; + u32 IntrOnAny = 0U; + u32 IntrTestValue = 0x22U; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* Disable the Interrupts for Bank 0 . */ + IntrEnabled = XGpioPs_IntrGetEnabled(InstancePtr, XGPIOPS_BANK0); + XGpioPs_IntrDisable(InstancePtr, XGPIOPS_BANK0, IntrEnabled); + + /* + * Get the Current Interrupt properties for Bank 0. + * Set them to a known value, read it back and compare. + */ + XGpioPs_GetIntrType(InstancePtr, XGPIOPS_BANK0, &CurrentIntrType, + &CurrentIntrPolarity, &CurrentIntrOnAny); + + XGpioPs_SetIntrType(InstancePtr, XGPIOPS_BANK0, IntrTestValue, + IntrTestValue, IntrTestValue); + + XGpioPs_GetIntrType(InstancePtr, XGPIOPS_BANK0, &IntrType, + &IntrPolarity, &IntrOnAny); + + if ((IntrType != IntrTestValue) && (IntrPolarity != IntrTestValue) && + (IntrOnAny != IntrTestValue)) { + + Status = XST_FAILURE; + } + + /* + * Restore the contents of all the interrupt registers modified in this + * test. + */ + XGpioPs_SetIntrType(InstancePtr, XGPIOPS_BANK0, CurrentIntrType, + CurrentIntrPolarity, CurrentIntrOnAny); + + XGpioPs_IntrEnable(InstancePtr, XGPIOPS_BANK0, IntrEnabled); + + return Status; +} +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops_sinit.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops_sinit.c new file mode 100644 index 0000000..58ce55e --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops_sinit.c @@ -0,0 +1,97 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2019 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xgpiops_sinit.c +* @addtogroup gpiops_v3_5 +* @{ +* +* This file contains the implementation of the XGpioPs driver's static +* initialization functionality. +* +* @note None. +* +*
+*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a sv   01/15/10 First Release
+* 3.00  kvn  02/13/15 Modified code for MISRA-C:2012 compliance.
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xgpiops.h" +#include "xparameters.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/************************** Variable Definitions *****************************/ +extern XGpioPs_Config XGpioPs_ConfigTable[XPAR_XGPIOPS_NUM_INSTANCES]; + +/*****************************************************************************/ +/** +* +* This function looks for the device configuration based on the unique device +* ID. The table XGpioPs_ConfigTable[] contains the configuration information +* for each device in the system. +* +* @param DeviceId is the unique device ID of the device being looked up. +* +* @return A pointer to the configuration table entry corresponding to the +* given device ID, or NULL if no match is found. +* +* @note None. +* +******************************************************************************/ +XGpioPs_Config *XGpioPs_LookupConfig(u16 DeviceId) +{ + XGpioPs_Config *CfgPtr = NULL; + u32 Index; + + for (Index = 0U; Index < (u32)XPAR_XGPIOPS_NUM_INSTANCES; Index++) { + if (XGpioPs_ConfigTable[Index].DeviceId == DeviceId) { + CfgPtr = &XGpioPs_ConfigTable[Index]; + break; + } + } + + return (XGpioPs_Config *)CfgPtr; +} +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/Makefile b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/Makefile new file mode 100644 index 0000000..3600928 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/Makefile @@ -0,0 +1,40 @@ +COMPILER= +ARCHIVER= +CP=cp +COMPILER_FLAGS= +EXTRA_COMPILER_FLAGS= +LIB=libxil.a + +CC_FLAGS = $(COMPILER_FLAGS) +ECC_FLAGS = $(EXTRA_COMPILER_FLAGS) + +RELEASEDIR=../../../lib +INCLUDEDIR=../../../include +INCLUDES=-I./. -I${INCLUDEDIR} + +OUTS = *.o + +LIBSOURCES:=*.c +INCLUDEFILES:=*.h + +OBJECTS = $(addsuffix .o, $(basename $(wildcard *.c))) + +libs: banner xqspips_libs clean + +%.o: %.c + ${COMPILER} $(CC_FLAGS) $(ECC_FLAGS) $(INCLUDES) -o $@ $< + +banner: + echo "Compiling qspips" + +xqspips_libs: ${OBJECTS} + $(ARCHIVER) -r ${RELEASEDIR}/${LIB} ${OBJECTS} + +.PHONY: include +include: xqspips_includes + +xqspips_includes: + ${CP} ${INCLUDEFILES} ${INCLUDEDIR} + +clean: + rm -rf ${OBJECTS} diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips.c new file mode 100644 index 0000000..e82cab6 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips.c @@ -0,0 +1,1611 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2019 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xqspips.c +* @addtogroup qspips_v3_6 +* @{ +* +* Contains implements the interface functions of the XQspiPs driver. +* See xqspips.h for a detailed description of the device and driver. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who Date     Changes
+* ----- --- -------- -----------------------------------------------
+* 1.00  sdm 11/25/10 First release
+* 2.00a kka 07/25/12 Removed XQspiPs_GetWriteData API.
+*		     The XQspiPs_SetSlaveSelect has been modified to remove
+*		     the argument of the slave select as the QSPI controller
+*		     only supports one slave.
+* 		     XQspiPs_GetSlaveSelect API has been removed
+* 		     Added logic to XQspiPs_GetReadData to handle data
+*		     shift for normal data reads and instruction/status
+*		     reads differently based on the ShiftReadData flag.
+* 		     Removed the selection for the following options:
+*		     Master mode (XQSPIPS_MASTER_OPTION) and
+*		     Flash interface mode (XQSPIPS_FLASH_MODE_OPTION) option
+*		     as the QSPI driver supports the Master mode
+*		     and Flash Interface mode and doesnot support
+*		     Slave mode or the legacy mode.
+*		     Modified the XQspiPs_PolledTransfer and XQspiPs_Transfer
+*		     APIs so that the last argument (IsInst) specifying whether
+*		     it is instruction or data has been removed. The first byte
+*		     in the SendBufPtr argument of these APIs specify the
+*		     instruction to be sent to the Flash Device.
+*		     The XQspiPs_PolledTransfer function has been updated
+*		     to fill the data to fifo depth.
+*		     This version of the driver fixes CRs 670197/663787.
+* 2.01a sg  02/03/13 Added flash opcodes for DUAL_IO_READ,QUAD_IO_READ.
+*		     Created macros XQspiPs_IsManualStart and
+*		     XQspiPs_IsManualChipSelect.
+*		     Changed QSPI transfer logic for polled and interrupt
+*		     modes to be based on filled tx fifo count and receive
+*		     based on it. RXNEMPTY interrupt is not used.
+*		     Added assertions to XQspiPs_LqspiRead function.
+*
+* 2.02a hk  05/14/13 Added enable and disable to the XQspiPs_LqspiRead()
+*			 function
+*            Added instructions for bank selection, die erase and
+*            flag status register to the flash instruction table
+*            Handling for instructions not in flash instruction
+*			 table added. Checking for Tx FIFO empty when switching from
+*			 TXD1/2/3 to TXD0 added. If WRSR instruction is sent with
+*            byte count 3 (spansion), instruction size and TXD register
+*			 changed accordingly. CR# 712502 and 703869.
+*            Added (#ifdef linear base address) in the Linear read function.
+*            Changed  XPAR_XQSPIPS_0_LINEAR_BASEADDR to
+*            XPAR_PS7_QSPI_LINEAR_0_S_AXI_BASEADDR in
+*            XQspiPs_LqspiRead function. Fix for CR#718141
+*
+* 2.03a hk  09/05/13 Modified polled and interrupt transfers to make use of
+*                    thresholds. This is to improve performance.
+*                    Added RX and TX threshold reset to one in XQspiPs_Abort.
+*                    Added RX threshold reset(1) after transfer in polled and
+*                    interrupt transfers. Made changes to make sure threshold
+*                    change is done only when no transfer is in progress.
+* 3.1   hk  08/13/14 When writing to the configuration register, set/reset
+*                    required bits leaving reserved bits untouched. CR# 796813.
+* 3.2	sk	02/05/15 Add SLCR reset in abort function as a workaround because
+* 					 controller does not update FIFO status flags as expected
+* 					 when thresholds are used.
+* 3.3   sk  11/07/15 Modified the API prototypes according to MISRAC standards
+*                    to remove compilation warnings. CR# 868893.
+* 3.5	tjs 13/08/18 Fixed compilation warnings for ARMCC.
+* 3.6	akm 03/28/19 Fixed memory leak issue while reading from qspi.(CR#1016357)
+* 3.6 	akm 04/15/19 Modified the mask in XQspiPs_GetReadData() API to retrieve
+*		     configuration register values of both the Flashes in dual
+*		     parellel connection.
+*
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xqspips.h" + +/************************** Constant Definitions *****************************/ + + +/**************************** Type Definitions *******************************/ + +/** + * This typedef defines qspi flash instruction format + */ +typedef struct { + u8 OpCode; /**< Operational code of the instruction */ + u8 InstSize; /**< Size of the instruction including address bytes */ + u8 TxOffset; /**< Register address where instruction has to be + written */ +} XQspiPsInstFormat; + +/***************** Macros (Inline Functions) Definitions *********************/ + +#define ARRAY_SIZE(Array) (sizeof(Array) / sizeof((Array)[0])) + +/************************** Function Prototypes ******************************/ +static void XQspiPs_GetReadData(XQspiPs *InstancePtr, u32 Data, u8 Size); +static void StubStatusHandler(void *CallBackRef, u32 StatusEvent, + unsigned ByteCount); + +/************************** Variable Definitions *****************************/ + +/* + * List of all the QSPI instructions and its format + */ +static XQspiPsInstFormat FlashInst[] = { + { XQSPIPS_FLASH_OPCODE_WREN, 1, XQSPIPS_TXD_01_OFFSET }, + { XQSPIPS_FLASH_OPCODE_WRDS, 1, XQSPIPS_TXD_01_OFFSET }, + { XQSPIPS_FLASH_OPCODE_RDSR1, 2, XQSPIPS_TXD_10_OFFSET }, + { XQSPIPS_FLASH_OPCODE_RDSR2, 2, XQSPIPS_TXD_10_OFFSET }, + { XQSPIPS_FLASH_OPCODE_WRSR, 2, XQSPIPS_TXD_10_OFFSET }, + { XQSPIPS_FLASH_OPCODE_PP, 4, XQSPIPS_TXD_00_OFFSET }, + { XQSPIPS_FLASH_OPCODE_SE, 4, XQSPIPS_TXD_00_OFFSET }, + { XQSPIPS_FLASH_OPCODE_BE_32K, 4, XQSPIPS_TXD_00_OFFSET }, + { XQSPIPS_FLASH_OPCODE_BE_4K, 4, XQSPIPS_TXD_00_OFFSET }, + { XQSPIPS_FLASH_OPCODE_BE, 1, XQSPIPS_TXD_01_OFFSET }, + { XQSPIPS_FLASH_OPCODE_ERASE_SUS, 1, XQSPIPS_TXD_01_OFFSET }, + { XQSPIPS_FLASH_OPCODE_ERASE_RES, 1, XQSPIPS_TXD_01_OFFSET }, + { XQSPIPS_FLASH_OPCODE_RDID, 4, XQSPIPS_TXD_00_OFFSET }, + { XQSPIPS_FLASH_OPCODE_NORM_READ, 4, XQSPIPS_TXD_00_OFFSET }, + { XQSPIPS_FLASH_OPCODE_FAST_READ, 4, XQSPIPS_TXD_00_OFFSET }, + { XQSPIPS_FLASH_OPCODE_DUAL_READ, 4, XQSPIPS_TXD_00_OFFSET }, + { XQSPIPS_FLASH_OPCODE_QUAD_READ, 4, XQSPIPS_TXD_00_OFFSET }, + { XQSPIPS_FLASH_OPCODE_DUAL_IO_READ, 4, XQSPIPS_TXD_00_OFFSET }, + { XQSPIPS_FLASH_OPCODE_QUAD_IO_READ, 4, XQSPIPS_TXD_00_OFFSET }, + { XQSPIPS_FLASH_OPCODE_BRWR, 2, XQSPIPS_TXD_10_OFFSET }, + { XQSPIPS_FLASH_OPCODE_BRRD, 2, XQSPIPS_TXD_10_OFFSET }, + { XQSPIPS_FLASH_OPCODE_EARWR, 2, XQSPIPS_TXD_10_OFFSET }, + { XQSPIPS_FLASH_OPCODE_EARRD, 2, XQSPIPS_TXD_10_OFFSET }, + { XQSPIPS_FLASH_OPCODE_DIE_ERASE, 4, XQSPIPS_TXD_00_OFFSET }, + { XQSPIPS_FLASH_OPCODE_READ_FLAG_SR, 2, XQSPIPS_TXD_10_OFFSET }, + { XQSPIPS_FLASH_OPCODE_CLEAR_FLAG_SR, 1, XQSPIPS_TXD_01_OFFSET }, + /* Add all the instructions supported by the flash device */ +}; + +/*****************************************************************************/ +/** +* +* Initializes a specific XQspiPs instance such that the driver is ready to use. +* +* The state of the device after initialization is: +* - Master mode +* - Active high clock polarity +* - Clock phase 0 +* - Baud rate divisor 2 +* - Transfer width 32 +* - Master reference clock = pclk +* - No chip select active +* - Manual CS and Manual Start disabled +* +* @param InstancePtr is a pointer to the XQspiPs instance. +* @param ConfigPtr is a reference to a structure containing information +* about a specific QSPI device. This function initializes an +* InstancePtr object for a specific device specified by the +* contents of Config. +* @param EffectiveAddr is the device base address in the virtual memory +* address space. The caller is responsible for keeping the address +* mapping from EffectiveAddr to the device physical base address +* unchanged once this function is invoked. Unexpected errors may +* occur if the address mapping changes after this function is +* called. If address translation is not used, use +* ConfigPtr->Config.BaseAddress for this device. +* +* @return +* - XST_SUCCESS if successful. +* - XST_DEVICE_IS_STARTED if the device is already started. +* It must be stopped to re-initialize. +* +* @note None. +* +******************************************************************************/ +int XQspiPs_CfgInitialize(XQspiPs *InstancePtr, XQspiPs_Config *ConfigPtr, + u32 EffectiveAddr) +{ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(ConfigPtr != NULL); + + /* + * If the device is busy, disallow the initialize and return a status + * indicating it is already started. This allows the user to stop the + * device and re-initialize, but prevents a user from inadvertently + * initializing. This assumes the busy flag is cleared at startup. + */ + if (InstancePtr->IsBusy == TRUE) { + return XST_DEVICE_IS_STARTED; + } + + /* + * Set some default values. + */ + InstancePtr->IsBusy = FALSE; + + InstancePtr->Config.BaseAddress = EffectiveAddr; + InstancePtr->StatusHandler = StubStatusHandler; + + InstancePtr->SendBufferPtr = NULL; + InstancePtr->RecvBufferPtr = NULL; + InstancePtr->RequestedBytes = 0; + InstancePtr->RemainingBytes = 0; + InstancePtr->IsReady = XIL_COMPONENT_IS_READY; + + InstancePtr->Config.ConnectionMode = ConfigPtr->ConnectionMode; + + /* + * Reset the QSPI device to get it into its initial state. It is + * expected that device configuration will take place after this + * initialization is done, but before the device is started. + */ + XQspiPs_Reset(InstancePtr); + + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** +* +* Resets the QSPI device. Reset must only be called after the driver has been +* initialized. Any data transfer that is in progress is aborted. +* +* The upper layer software is responsible for re-configuring (if necessary) +* and restarting the QSPI device after the reset. +* +* @param InstancePtr is a pointer to the XQspiPs instance. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XQspiPs_Reset(XQspiPs *InstancePtr) +{ + u32 ConfigReg; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Abort any transfer that is in progress + */ + XQspiPs_Abort(InstancePtr); + + /* + * Write default value to configuration register. + * Do not modify reserved bits. + */ + ConfigReg = XQspiPs_ReadReg(InstancePtr->Config.BaseAddress, + XQSPIPS_CR_OFFSET); + ConfigReg |= XQSPIPS_CR_RESET_MASK_SET; + ConfigReg &= ~XQSPIPS_CR_RESET_MASK_CLR; + XQspiPs_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPS_CR_OFFSET, + ConfigReg); +} + +/*****************************************************************************/ +/** +* +* Aborts a transfer in progress by disabling the device and flush the RxFIFO. +* The byte counts are cleared, the busy flag is cleared. +* +* @param InstancePtr is a pointer to the XQspiPs instance. +* +* @return None. +* +* @note +* +* This function does a read/modify/write of the config register. The user of +* this function needs to take care of critical sections. +* +******************************************************************************/ +void XQspiPs_Abort(XQspiPs *InstancePtr) +{ + u32 ConfigReg; + u32 IsLock; + + XQspiPs_Disable(InstancePtr); + + /* + * De-assert slave select lines. + */ + ConfigReg = XQspiPs_ReadReg(InstancePtr->Config.BaseAddress, + XQSPIPS_CR_OFFSET); + ConfigReg |= (XQSPIPS_CR_SSCTRL_MASK | XQSPIPS_CR_SSFORCE_MASK); + XQspiPs_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPS_CR_OFFSET, ConfigReg); + + /* + * QSPI Software Reset + */ + IsLock = XQspiPs_ReadReg(XPAR_XSLCR_0_BASEADDR, SLCR_LOCKSTA); + if (IsLock) { + XQspiPs_WriteReg(XPAR_XSLCR_0_BASEADDR, SLCR_UNLOCK, + SLCR_UNLOCK_MASK); + } + XQspiPs_WriteReg(XPAR_XSLCR_0_BASEADDR, LQSPI_RST_CTRL, + LQSPI_RST_CTRL_MASK); + XQspiPs_WriteReg(XPAR_XSLCR_0_BASEADDR, LQSPI_RST_CTRL, 0x0); + if (IsLock) { + XQspiPs_WriteReg(XPAR_XSLCR_0_BASEADDR, SLCR_LOCK, + SLCR_LOCK_MASK); + } + + /* + * Set the RX and TX FIFO threshold to reset value (one) + */ + XQspiPs_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPS_RXWR_OFFSET, XQSPIPS_RXWR_RESET_VALUE); + + XQspiPs_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPS_TXWR_OFFSET, XQSPIPS_TXWR_RESET_VALUE); + + InstancePtr->RemainingBytes = 0; + InstancePtr->RequestedBytes = 0; + InstancePtr->IsBusy = FALSE; +} + +/*****************************************************************************/ +/** +* +* Transfers specified data on the QSPI bus. Initiates bus communication and +* sends/receives data to/from the selected QSPI slave. For every byte sent, +* a byte is received. +* +* The caller has the option of providing two different buffers for send and +* receive, or one buffer for both send and receive, or no buffer for receive. +* The receive buffer must be at least as big as the send buffer to prevent +* unwanted memory writes. This implies that the byte count passed in as an +* argument must be the smaller of the two buffers if they differ in size. +* Here are some sample usages: +*
+*   XQspiPs_Transfer(InstancePtr, SendBuf, RecvBuf, ByteCount)
+*	The caller wishes to send and receive, and provides two different
+*	buffers for send and receive.
+*
+*   XQspiPs_Transfer(InstancePtr, SendBuf, NULL, ByteCount)
+*	The caller wishes only to send and does not care about the received
+*	data. The driver ignores the received data in this case.
+*
+*   XQspiPs_Transfer(InstancePtr, SendBuf, SendBuf, ByteCount)
+*	The caller wishes to send and receive, but provides the same buffer
+*	for doing both. The driver sends the data and overwrites the send
+*	buffer with received data as it transfers the data.
+*
+*   XQspiPs_Transfer(InstancePtr, RecvBuf, RecvBuf, ByteCount)
+*	The caller wishes to only receive and does not care about sending
+*	data.  In this case, the caller must still provide a send buffer, but
+*	it can be the same as the receive buffer if the caller does not care
+*	what it sends.  The device must send N bytes of data if it wishes to
+*	receive N bytes of data.
+* 
+* Although this function takes entire buffers as arguments, the driver can only +* transfer a limited number of bytes at a time, limited by the size of the +* FIFO. A call to this function only starts the transfer, then subsequent +* transfers of the data is performed by the interrupt service routine until +* the entire buffer has been transferred. The status callback function is +* called when the entire buffer has been sent/received. +* +* This function is non-blocking. The SetSlaveSelect function must be called +* prior to this function. +* +* @param InstancePtr is a pointer to the XQspiPs instance. +* @param SendBufPtr is a pointer to a data buffer that needs to be +* transmitted. This buffer must not be NULL. +* @param RecvBufPtr is a pointer to a buffer for received data. +* This argument can be NULL if do not care about receiving. +* @param ByteCount contains the number of bytes to send/receive. +* The number of bytes received always equals the number of bytes +* sent. +* +* @return +* - XST_SUCCESS if the buffers are successfully handed off to the +* device for transfer. +* - XST_DEVICE_BUSY indicates that a data transfer is already in +* progress. This is determined by the driver. +* +* @note +* +* This function is not thread-safe. The higher layer software must ensure that +* no two threads are transferring data on the QSPI bus at the same time. +* +******************************************************************************/ +s32 XQspiPs_Transfer(XQspiPs *InstancePtr, u8 *SendBufPtr, u8 *RecvBufPtr, + u32 ByteCount) +{ + u32 StatusReg; + u32 ConfigReg; + u8 Instruction; + u32 Data; + unsigned int Index; + u8 TransCount = 0; + XQspiPsInstFormat *CurrInst; + XQspiPsInstFormat NewInst[2]; + u8 SwitchFlag = 0; + + CurrInst = &NewInst[0]; + + /* + * The RecvBufPtr argument can be null + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(SendBufPtr != NULL); + Xil_AssertNonvoid(ByteCount > 0); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Check whether there is another transfer in progress. Not thread-safe. + */ + if (InstancePtr->IsBusy) { + return XST_DEVICE_BUSY; + } + + /* + * Set the busy flag, which will be cleared in the ISR when the + * transfer is entirely done. + */ + InstancePtr->IsBusy = TRUE; + + /* + * Set up buffer pointers. + */ + InstancePtr->SendBufferPtr = SendBufPtr; + InstancePtr->RecvBufferPtr = RecvBufPtr; + + InstancePtr->RequestedBytes = ByteCount; + InstancePtr->RemainingBytes = ByteCount; + + /* + * The first byte with every chip-select assertion is always + * expected to be an instruction for flash interface mode + */ + Instruction = *InstancePtr->SendBufferPtr; + + for (Index = 0 ; Index < ARRAY_SIZE(FlashInst); Index++) { + if (Instruction == FlashInst[Index].OpCode) { + break; + } + } + + /* + * Set the RX FIFO threshold + */ + XQspiPs_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPS_RXWR_OFFSET, XQSPIPS_RXFIFO_THRESHOLD_OPT); + + /* + * If the slave select is "Forced" or under manual control, + * set the slave select now, before beginning the transfer. + */ + if (XQspiPs_IsManualChipSelect(InstancePtr)) { + ConfigReg = XQspiPs_ReadReg(InstancePtr->Config.BaseAddress, + XQSPIPS_CR_OFFSET); + ConfigReg &= ~XQSPIPS_CR_SSCTRL_MASK; + XQspiPs_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPS_CR_OFFSET, + ConfigReg); + } + + /* + * Enable the device. + */ + XQspiPs_Enable(InstancePtr); + + /* + * Clear all the interrrupts. + */ + XQspiPs_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPS_SR_OFFSET, + XQSPIPS_IXR_WR_TO_CLR_MASK); + + if (Index < ARRAY_SIZE(FlashInst)) { + CurrInst = &FlashInst[Index]; + /* + * Check for WRSR instruction which has different size for + * Spansion (3 bytes) and Micron (2 bytes) + */ + if ((CurrInst->OpCode == XQSPIPS_FLASH_OPCODE_WRSR) && + (ByteCount == 3)) { + CurrInst->InstSize = 3; + CurrInst->TxOffset = XQSPIPS_TXD_11_OFFSET; + } + } + + /* + * If instruction not present in table + */ + if (Index == ARRAY_SIZE(FlashInst)) { + /* + * Assign current instruction, size and TXD register to be used + * The InstSize mentioned in case of instructions greater than + * 4 bytes is not the actual size, but is indicative of + * the TXD register used. + * The remaining bytes of the instruction will be transmitted + * through TXD0 below. + */ + switch (ByteCount%4) { + case XQSPIPS_SIZE_ONE: + CurrInst->OpCode = Instruction; + CurrInst->InstSize = XQSPIPS_SIZE_ONE; + CurrInst->TxOffset = XQSPIPS_TXD_01_OFFSET; + if (ByteCount > 4) { + SwitchFlag = 1; + } + break; + case XQSPIPS_SIZE_TWO: + CurrInst->OpCode = Instruction; + CurrInst->InstSize = XQSPIPS_SIZE_TWO; + CurrInst->TxOffset = XQSPIPS_TXD_10_OFFSET; + if (ByteCount > 4) { + SwitchFlag = 1; + } + break; + case XQSPIPS_SIZE_THREE: + CurrInst->OpCode = Instruction; + CurrInst->InstSize = XQSPIPS_SIZE_THREE; + CurrInst->TxOffset = XQSPIPS_TXD_11_OFFSET; + if (ByteCount > 4) { + SwitchFlag = 1; + } + break; + default: + CurrInst->OpCode = Instruction; + CurrInst->InstSize = XQSPIPS_SIZE_FOUR; + CurrInst->TxOffset = XQSPIPS_TXD_00_OFFSET; + break; + } + } + + /* + * If the instruction size in not 4 bytes then the data received needs + * to be shifted + */ + if (CurrInst->InstSize != 4) { + InstancePtr->ShiftReadData = 1; + } else { + InstancePtr->ShiftReadData = 0; + } + + /* Get the complete command (flash inst + address/data) */ + Data = *((u32 *)InstancePtr->SendBufferPtr); + InstancePtr->SendBufferPtr += CurrInst->InstSize; + InstancePtr->RemainingBytes -= CurrInst->InstSize; + if (InstancePtr->RemainingBytes < 0) { + InstancePtr->RemainingBytes = 0; + } + + /* Write the command to the FIFO */ + XQspiPs_WriteReg(InstancePtr->Config.BaseAddress, + CurrInst->TxOffset, Data); + TransCount++; + + /* + * If switching from TXD1/2/3 to TXD0, then start transfer and + * check for FIFO empty + */ + if (SwitchFlag == 1) { + SwitchFlag = 0; + /* + * If, in Manual Start mode, start the transfer. + */ + if (XQspiPs_IsManualStart(InstancePtr)) { + ConfigReg = XQspiPs_ReadReg( + InstancePtr->Config.BaseAddress, + XQSPIPS_CR_OFFSET); + ConfigReg |= XQSPIPS_CR_MANSTRT_MASK; + XQspiPs_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPS_CR_OFFSET, ConfigReg); + } + /* + * Wait for the transfer to finish by polling Tx fifo status. + */ + do { + StatusReg = XQspiPs_ReadReg( + InstancePtr->Config.BaseAddress, + XQSPIPS_SR_OFFSET); + } while ((StatusReg & XQSPIPS_IXR_TXOW_MASK) == 0); + + } + + /* + * Fill the Tx FIFO with as many bytes as it takes (or as many as + * we have to send). + */ + while ((InstancePtr->RemainingBytes > 0) && + (TransCount < XQSPIPS_FIFO_DEPTH)) { + /* + * In case of Write fill the Tx FIFO with data to be transmitted. + * In case of Read fill the Tx FIFO with DUMMY bytes. + */ + if (!InstancePtr->RecvBufferPtr) { + XQspiPs_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPS_TXD_00_OFFSET, + *((u32 *)InstancePtr->SendBufferPtr)); + InstancePtr->SendBufferPtr += 4; + } else { + XQspiPs_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPS_TXD_00_OFFSET, + XQSPIPS_DUMMY_TX_DATA); + } + InstancePtr->RemainingBytes -= 4; + if (InstancePtr->RemainingBytes < 0) { + InstancePtr->RemainingBytes = 0; + } + TransCount++; + } + + /* + * Enable QSPI interrupts (connecting to the interrupt controller and + * enabling interrupts should have been done by the caller). + */ + XQspiPs_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPS_IER_OFFSET, XQSPIPS_IXR_RXNEMPTY_MASK | + XQSPIPS_IXR_TXOW_MASK | XQSPIPS_IXR_RXOVR_MASK | + XQSPIPS_IXR_TXUF_MASK); + + /* + * If, in Manual Start mode, Start the transfer. + */ + if (XQspiPs_IsManualStart(InstancePtr)) { + ConfigReg = XQspiPs_ReadReg(InstancePtr->Config.BaseAddress, + XQSPIPS_CR_OFFSET); + ConfigReg |= XQSPIPS_CR_MANSTRT_MASK; + XQspiPs_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPS_CR_OFFSET, ConfigReg); + } + + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** +* Transfers specified data on the QSPI bus in polled mode. +* +* The caller has the option of providing two different buffers for send and +* receive, or one buffer for both send and receive, or no buffer for receive. +* The receive buffer must be at least as big as the send buffer to prevent +* unwanted memory writes. This implies that the byte count passed in as an +* argument must be the smaller of the two buffers if they differ in size. +* Here are some sample usages: +*
+*   XQspiPs_PolledTransfer(InstancePtr, SendBuf, RecvBuf, ByteCount)
+*	The caller wishes to send and receive, and provides two different
+*	buffers for send and receive.
+*
+*   XQspiPs_PolledTransfer(InstancePtr, SendBuf, NULL, ByteCount)
+*	The caller wishes only to send and does not care about the received
+*	data. The driver ignores the received data in this case.
+*
+*   XQspiPs_PolledTransfer(InstancePtr, SendBuf, SendBuf, ByteCount)
+*	The caller wishes to send and receive, but provides the same buffer
+*	for doing both. The driver sends the data and overwrites the send
+*	buffer with received data as it transfers the data.
+*
+*   XQspiPs_PolledTransfer(InstancePtr, RecvBuf, RecvBuf, ByteCount)
+*	The caller wishes to only receive and does not care about sending
+*	data.  In this case, the caller must still provide a send buffer, but
+*	it can be the same as the receive buffer if the caller does not care
+*	what it sends.  The device must send N bytes of data if it wishes to
+*	receive N bytes of data.
+*
+* 
+* +* @param InstancePtr is a pointer to the XQspiPs instance. +* @param SendBufPtr is a pointer to a data buffer that needs to be +* transmitted. This buffer must not be NULL. +* @param RecvBufPtr is a pointer to a buffer for received data. +* This argument can be NULL if do not care about receiving. +* @param ByteCount contains the number of bytes to send/receive. +* The number of bytes received always equals the number of bytes +* sent. +* @return +* - XST_SUCCESS if the buffers are successfully handed off to the +* device for transfer. +* - XST_DEVICE_BUSY indicates that a data transfer is already in +* progress. This is determined by the driver. +* +* @note +* +* This function is not thread-safe. The higher layer software must ensure that +* no two threads are transferring data on the QSPI bus at the same time. +* +******************************************************************************/ +s32 XQspiPs_PolledTransfer(XQspiPs *InstancePtr, u8 *SendBufPtr, + u8 *RecvBufPtr, u32 ByteCount) +{ + u32 StatusReg; + u32 ConfigReg; + u8 Instruction; + u32 Data; + u8 TransCount; + unsigned int Index; + XQspiPsInstFormat *CurrInst; + XQspiPsInstFormat NewInst[2]; + u8 SwitchFlag = 0; + u8 IsManualStart = FALSE; + u32 RxCount = 0; + + CurrInst = &NewInst[0]; + /* + * The RecvBufPtr argument can be NULL. + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(SendBufPtr != NULL); + Xil_AssertNonvoid(ByteCount > 0); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Check whether there is another transfer in progress. Not thread-safe. + */ + if (InstancePtr->IsBusy) { + return XST_DEVICE_BUSY; + } + + /* + * Set the busy flag, which will be cleared when the transfer is + * entirely done. + */ + InstancePtr->IsBusy = TRUE; + + /* + * Set up buffer pointers. + */ + InstancePtr->SendBufferPtr = SendBufPtr; + InstancePtr->RecvBufferPtr = RecvBufPtr; + + InstancePtr->RequestedBytes = ByteCount; + InstancePtr->RemainingBytes = ByteCount; + + /* + * The first byte with every chip-select assertion is always + * expected to be an instruction for flash interface mode + */ + Instruction = *InstancePtr->SendBufferPtr; + + for (Index = 0 ; Index < ARRAY_SIZE(FlashInst); Index++) { + if (Instruction == FlashInst[Index].OpCode) { + break; + } + } + + /* + * Set the RX FIFO threshold + */ + XQspiPs_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPS_RXWR_OFFSET, XQSPIPS_RXFIFO_THRESHOLD_OPT); + + /* + * If the slave select is "Forced" or under manual control, + * set the slave select now, before beginning the transfer. + */ + if (XQspiPs_IsManualChipSelect(InstancePtr)) { + ConfigReg = XQspiPs_ReadReg(InstancePtr->Config.BaseAddress, + XQSPIPS_CR_OFFSET); + ConfigReg &= ~XQSPIPS_CR_SSCTRL_MASK; + XQspiPs_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPS_CR_OFFSET, + ConfigReg); + } + + /* + * Enable the device. + */ + XQspiPs_Enable(InstancePtr); + + if (Index < ARRAY_SIZE(FlashInst)) { + + CurrInst = &FlashInst[Index]; + /* + * Check for WRSR instruction which has different size for + * Spansion (3 bytes) and Micron (2 bytes) + */ + if ((CurrInst->OpCode == XQSPIPS_FLASH_OPCODE_WRSR) && + (ByteCount == 3)) { + CurrInst->InstSize = 3; + CurrInst->TxOffset = XQSPIPS_TXD_11_OFFSET; + } + } + + /* + * If instruction not present in table + */ + if (Index == ARRAY_SIZE(FlashInst)) { + /* + * Assign current instruction, size and TXD register to be used. + * The InstSize mentioned in case of instructions greater than 4 bytes + * is not the actual size, but is indicative of the TXD register used. + * The remaining bytes of the instruction will be transmitted + * through TXD0 below. + */ + switch (ByteCount % 4) { + case XQSPIPS_SIZE_ONE: + CurrInst->OpCode = Instruction; + CurrInst->InstSize = XQSPIPS_SIZE_ONE; + CurrInst->TxOffset = XQSPIPS_TXD_01_OFFSET; + if (ByteCount > 4) { + SwitchFlag = 1; + } + break; + case XQSPIPS_SIZE_TWO: + CurrInst->OpCode = Instruction; + CurrInst->InstSize = XQSPIPS_SIZE_TWO; + CurrInst->TxOffset = XQSPIPS_TXD_10_OFFSET; + if (ByteCount > 4) { + SwitchFlag = 1; + } + break; + case XQSPIPS_SIZE_THREE: + CurrInst->OpCode = Instruction; + CurrInst->InstSize = XQSPIPS_SIZE_THREE; + CurrInst->TxOffset = XQSPIPS_TXD_11_OFFSET; + if (ByteCount > 4) { + SwitchFlag = 1; + } + break; + default: + CurrInst->OpCode = Instruction; + CurrInst->InstSize = XQSPIPS_SIZE_FOUR; + CurrInst->TxOffset = XQSPIPS_TXD_00_OFFSET; + break; + } + } + + /* + * If the instruction size in not 4 bytes then the data received needs + * to be shifted + */ + if (CurrInst->InstSize != 4) { + InstancePtr->ShiftReadData = 1; + } else { + InstancePtr->ShiftReadData = 0; + } + TransCount = 0; + /* Get the complete command (flash inst + address/data) */ + Data = *((u32 *)InstancePtr->SendBufferPtr); + InstancePtr->SendBufferPtr += CurrInst->InstSize; + InstancePtr->RemainingBytes -= CurrInst->InstSize; + if (InstancePtr->RemainingBytes < 0) { + InstancePtr->RemainingBytes = 0; + } + + /* Write the command to the FIFO */ + XQspiPs_WriteReg(InstancePtr->Config.BaseAddress, + CurrInst->TxOffset, Data); + ++TransCount; + + /* + * If switching from TXD1/2/3 to TXD0, then start transfer and + * check for FIFO empty + */ + if (SwitchFlag == 1) { + SwitchFlag = 0; + /* + * If, in Manual Start mode, start the transfer. + */ + if (XQspiPs_IsManualStart(InstancePtr)) { + ConfigReg = XQspiPs_ReadReg( + InstancePtr->Config.BaseAddress, + XQSPIPS_CR_OFFSET); + ConfigReg |= XQSPIPS_CR_MANSTRT_MASK; + XQspiPs_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPS_CR_OFFSET, ConfigReg); + } + /* + * Wait for the transfer to finish by polling Tx fifo status. + */ + do { + StatusReg = XQspiPs_ReadReg( + InstancePtr->Config.BaseAddress, + XQSPIPS_SR_OFFSET); + } while ((StatusReg & XQSPIPS_IXR_TXOW_MASK) == 0); + + } + + /* + * Check if manual start is selected and store it in a + * local varibale for reference. This is to avoid reading + * the config register everytime. + */ + IsManualStart = XQspiPs_IsManualStart(InstancePtr); + + /* + * Fill the DTR/FIFO with as many bytes as it will take (or as + * many as we have to send). + */ + while ((InstancePtr->RemainingBytes > 0) && + (TransCount < XQSPIPS_FIFO_DEPTH)) { + /* + * In case of Write fill the Tx FIFO with data to be transmitted. + * In case of Read fill the Tx FIFO with DUMMY bytes. + */ + if (!InstancePtr->RecvBufferPtr) { + XQspiPs_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPS_TXD_00_OFFSET, + *((u32 *)InstancePtr->SendBufferPtr)); + InstancePtr->SendBufferPtr += 4; + } else { + XQspiPs_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPS_TXD_00_OFFSET, + XQSPIPS_DUMMY_TX_DATA); + } + InstancePtr->RemainingBytes -= 4; + if (InstancePtr->RemainingBytes < 0) { + InstancePtr->RemainingBytes = 0; + } + ++TransCount; + } + + while ((InstancePtr->RemainingBytes > 0) || + (InstancePtr->RequestedBytes > 0)) { + + /* + * Fill the TX FIFO with RX threshold no. of entries (or as + * many as we have to send, in case that's less). + */ + while ((InstancePtr->RemainingBytes > 0) && + (TransCount < XQSPIPS_RXFIFO_THRESHOLD_OPT)) { + /* + * In case of Write fill the Tx FIFO with data to be transmitted. + * In case of Read fill the Tx FIFO with DUMMY bytes. + */ + if (!InstancePtr->RecvBufferPtr) { + XQspiPs_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPS_TXD_00_OFFSET, + *((u32 *)InstancePtr->SendBufferPtr)); + InstancePtr->SendBufferPtr += 4; + } else { + XQspiPs_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPS_TXD_00_OFFSET, + XQSPIPS_DUMMY_TX_DATA); + } + InstancePtr->RemainingBytes -= 4; + if (InstancePtr->RemainingBytes < 0) { + InstancePtr->RemainingBytes = 0; + } + ++TransCount; + } + + /* + * If, in Manual Start mode, start the transfer. + */ + if (IsManualStart == TRUE) { + ConfigReg = XQspiPs_ReadReg( + InstancePtr->Config.BaseAddress, + XQSPIPS_CR_OFFSET); + ConfigReg |= XQSPIPS_CR_MANSTRT_MASK; + XQspiPs_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPS_CR_OFFSET, ConfigReg); + } + + /* + * Reset TransCount - this is only used to fill TX FIFO + * in the above loop; + * RxCount is used to keep track of data received + */ + TransCount = 0; + + /* + * Wait for RX FIFO to reach threshold (or) + * TX FIFO to become empty. + * The latter check is required for + * small transfers (<32 words) and + * when the last chunk in a large data transfer is < 32 words. + */ + + do { + StatusReg = XQspiPs_ReadReg( + InstancePtr->Config.BaseAddress, + XQSPIPS_SR_OFFSET); + } while (((StatusReg & XQSPIPS_IXR_TXOW_MASK) == 0) && + ((StatusReg & XQSPIPS_IXR_RXNEMPTY_MASK) == 0)); + + /* + * A transmit has just completed. Process received data + * and check for more data to transmit. + * First get the data received as a result of the + * transmit that just completed. Receive data based on the + * count obtained while filling tx fifo. Always get + * the received data, but only fill the receive + * buffer if it points to something (the upper layer + * software may not care to receive data). + */ + while ((InstancePtr->RequestedBytes > 0) && + (RxCount < XQSPIPS_RXFIFO_THRESHOLD_OPT)) { + u32 Data; + + RxCount++; + + if (InstancePtr->RecvBufferPtr != NULL) { + if (InstancePtr->RequestedBytes < 4) { + Data = XQspiPs_ReadReg(InstancePtr->Config.BaseAddress, + XQSPIPS_RXD_OFFSET); + XQspiPs_GetReadData(InstancePtr, Data, + InstancePtr->RequestedBytes); + } else { + (*(u32 *)InstancePtr->RecvBufferPtr) = + XQspiPs_ReadReg(InstancePtr->Config.BaseAddress, + XQSPIPS_RXD_OFFSET); + InstancePtr->RecvBufferPtr += 4; + InstancePtr->RequestedBytes -= 4; + if (InstancePtr->RequestedBytes < 0) { + InstancePtr->RequestedBytes = 0; + } + } + } else { + Data = XQspiPs_ReadReg(InstancePtr->Config.BaseAddress, + XQSPIPS_RXD_OFFSET); + InstancePtr->RequestedBytes -= 4; + } + } + RxCount = 0; + } + + /* + * If the Slave select lines are being manually controlled, disable + * them because the transfer is complete. + */ + if (XQspiPs_IsManualChipSelect(InstancePtr)) { + ConfigReg = XQspiPs_ReadReg(InstancePtr->Config.BaseAddress, + XQSPIPS_CR_OFFSET); + ConfigReg |= XQSPIPS_CR_SSCTRL_MASK; + XQspiPs_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPS_CR_OFFSET, ConfigReg); + } + + /* + * Clear the busy flag. + */ + InstancePtr->IsBusy = FALSE; + + /* + * Disable the device. + */ + XQspiPs_Disable(InstancePtr); + + /* + * Reset the RX FIFO threshold to one + */ + XQspiPs_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPS_RXWR_OFFSET, XQSPIPS_RXWR_RESET_VALUE); + + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** +* +* Read the flash in Linear QSPI mode. +* +* @param InstancePtr is a pointer to the XQspiPs instance. +* @param RecvBufPtr is a pointer to a buffer for received data. +* @param Address is the starting address within the flash from +* from where data needs to be read. +* @param ByteCount contains the number of bytes to receive. +* +* @return +* - XST_SUCCESS if read is performed +* - XST_FAILURE if Linear mode is not set +* +* @note None. +* +* +******************************************************************************/ +int XQspiPs_LqspiRead(XQspiPs *InstancePtr, u8 *RecvBufPtr, + u32 Address, unsigned ByteCount) +{ + int Status = (int)XST_SUCCESS; + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(RecvBufPtr != NULL); + Xil_AssertNonvoid(ByteCount > 0); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + +#ifndef XPAR_PS7_QSPI_LINEAR_0_S_AXI_BASEADDR +#define XPAR_PS7_QSPI_LINEAR_0_S_AXI_BASEADDR 0xFC000000 +#endif + /* + * Enable the controller + */ + XQspiPs_Enable(InstancePtr); + + if (XQspiPs_GetLqspiConfigReg(InstancePtr) & + XQSPIPS_LQSPI_CR_LINEAR_MASK) { + memcpy((void *)RecvBufPtr, + (const void *)(XPAR_PS7_QSPI_LINEAR_0_S_AXI_BASEADDR + + Address), + (size_t)ByteCount); + Status = (int)XST_SUCCESS; + } else { + Status = (int)XST_FAILURE; + } + + /* + * Disable the controller + */ + XQspiPs_Disable(InstancePtr); + + return Status; +} + +/*****************************************************************************/ +/** +* +* Selects the slave with which the master communicates. +* +* The user is not allowed to select the slave while a transfer is in progress. +* +* @param InstancePtr is a pointer to the XQspiPs instance. +* +* @return +* - XST_SUCCESS if the slave is selected or deselected +* successfully. +* - XST_DEVICE_BUSY if a transfer is in progress, slave cannot be +* changed. +* +* @note +* +* This function only sets the slave which will be selected when a transfer +* occurs. The slave is not selected when the QSPI is idle. +* +******************************************************************************/ +int XQspiPs_SetSlaveSelect(XQspiPs *InstancePtr) +{ + u32 ConfigReg; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Do not allow the slave select to change while a transfer is in + * progress. Not thread-safe. + */ + if (InstancePtr->IsBusy) { + return XST_DEVICE_BUSY; + } + + /* + * Select the slave + */ + ConfigReg = XQspiPs_ReadReg(InstancePtr->Config.BaseAddress, + XQSPIPS_CR_OFFSET); + ConfigReg &= ~XQSPIPS_CR_SSCTRL_MASK; + XQspiPs_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPS_CR_OFFSET, ConfigReg); + + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** +* +* Sets the status callback function, the status handler, which the driver +* calls when it encounters conditions that should be reported to upper +* layer software. The handler executes in an interrupt context, so it must +* minimize the amount of processing performed. One of the following status +* events is passed to the status handler. +* +*
+*
+* XST_SPI_TRANSFER_DONE		The requested data transfer is done
+*
+* XST_SPI_TRANSMIT_UNDERRUN	As a slave device, the master clocked data
+*				but there were none available in the transmit
+*				register/FIFO. This typically means the slave
+*				application did not issue a transfer request
+*				fast enough, or the processor/driver could not
+*				fill the transmit register/FIFO fast enough.
+*
+* XST_SPI_RECEIVE_OVERRUN	The QSPI device lost data. Data was received
+*				but the receive data register/FIFO was full.
+*
+* 
+* @param InstancePtr is a pointer to the XQspiPs instance. +* @param CallBackRef is the upper layer callback reference passed back +* when the callback function is invoked. +* @param FuncPtr is the pointer to the callback function. +* +* @return None. +* +* @note +* +* The handler is called within interrupt context, so it should do its work +* quickly and queue potentially time-consuming work to a task-level thread. +* +******************************************************************************/ +void XQspiPs_SetStatusHandler(XQspiPs *InstancePtr, void *CallBackRef, + XQspiPs_StatusHandler FuncPtr) +{ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(FuncPtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + InstancePtr->StatusHandler = FuncPtr; + InstancePtr->StatusRef = CallBackRef; +} + +/*****************************************************************************/ +/** +* +* This is a stub for the status callback. The stub is here in case the upper +* layers forget to set the handler. +* +* @param CallBackRef is a pointer to the upper layer callback reference +* @param StatusEvent is the event that just occurred. +* @param ByteCount is the number of bytes transferred up until the event +* occurred. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +static void StubStatusHandler(void *CallBackRef, u32 StatusEvent, + unsigned ByteCount) +{ + (void) CallBackRef; + (void) StatusEvent; + (void) ByteCount; + + Xil_AssertVoidAlways(); +} + +/*****************************************************************************/ +/** +* +* The interrupt handler for QSPI interrupts. This function must be connected +* by the user to an interrupt controller. +* +* The interrupts that are handled are: +* +* +* - Data Transmit Register (FIFO) Empty. This interrupt is generated when the +* transmit register or FIFO is empty. The driver uses this interrupt during a +* transmission to continually send/receive data until the transfer is done. +* +* - Data Transmit Register (FIFO) Underflow. This interrupt is generated when +* the QSPI device, when configured as a slave, attempts to read an empty +* DTR/FIFO. An empty DTR/FIFO usually means that software is not giving the +* device data in a timely manner. No action is taken by the driver other than +* to inform the upper layer software of the error. +* +* - Data Receive Register (FIFO) Overflow. This interrupt is generated when the +* QSPI device attempts to write a received byte to an already full DRR/FIFO. +* A full DRR/FIFO usually means software is not emptying the data in a timely +* manner. No action is taken by the driver other than to inform the upper +* layer software of the error. +* +* @param InstancePtr is a pointer to the XQspiPs instance. +* +* @return None. +* +* @note +* +* The slave select register is being set to deselect the slave when a transfer +* is complete. +* +******************************************************************************/ +void XQspiPs_InterruptHandler(void *InstancePtr) +{ + XQspiPs *QspiPtr = (XQspiPs *)InstancePtr; + u32 IntrStatus; + u32 ConfigReg; + u32 Data; + u32 TransCount; + u32 Count = 0; + unsigned BytesDone; /* Number of bytes done so far. */ + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(QspiPtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Immediately clear the interrupts in case the ISR causes another + * interrupt to be generated. If we clear at the end of the ISR, + * we may miss newly generated interrupts. This occurs because we + * transmit from within the ISR, which could potentially cause another + * TX_EMPTY interrupt. + */ + IntrStatus = XQspiPs_ReadReg(QspiPtr->Config.BaseAddress, + XQSPIPS_SR_OFFSET); + XQspiPs_WriteReg(QspiPtr->Config.BaseAddress, XQSPIPS_SR_OFFSET, + (IntrStatus & XQSPIPS_IXR_WR_TO_CLR_MASK)); + XQspiPs_WriteReg(QspiPtr->Config.BaseAddress, XQSPIPS_IDR_OFFSET, + XQSPIPS_IXR_TXOW_MASK | XQSPIPS_IXR_RXNEMPTY_MASK | + XQSPIPS_IXR_RXOVR_MASK | XQSPIPS_IXR_TXUF_MASK); + + if ((IntrStatus & XQSPIPS_IXR_TXOW_MASK) || + (IntrStatus & XQSPIPS_IXR_RXNEMPTY_MASK)) { + + /* + * Rx FIFO has just reached threshold no. of entries. + * Read threshold no. of entries from RX FIFO + * Another possiblity of entering this loop is when + * the last byte has been transmitted and TX FIFO is empty, + * in which case, read all the data from RX FIFO. + * Always get the received data, but only fill the + * receive buffer if it is not null (it can be null when + * the device does not care to receive data). + */ + TransCount = QspiPtr->RequestedBytes - QspiPtr->RemainingBytes; + if (TransCount % 4) { + TransCount = TransCount/4 + 1; + } else { + TransCount = TransCount/4; + } + + while ((Count < TransCount) && + (Count < XQSPIPS_RXFIFO_THRESHOLD_OPT)) { + + if (QspiPtr->RecvBufferPtr != NULL) { + if (QspiPtr->RequestedBytes < 4) { + Data = XQspiPs_ReadReg(QspiPtr->Config.BaseAddress, + XQSPIPS_RXD_OFFSET); + XQspiPs_GetReadData(QspiPtr, Data, + QspiPtr->RequestedBytes); + } else { + (*(u32 *)QspiPtr->RecvBufferPtr) = + XQspiPs_ReadReg(QspiPtr->Config.BaseAddress, + XQSPIPS_RXD_OFFSET); + QspiPtr->RecvBufferPtr += 4; + QspiPtr->RequestedBytes -= 4; + if (QspiPtr->RequestedBytes < 0) { + QspiPtr->RequestedBytes = 0; + } + } + } else { + XQspiPs_ReadReg(QspiPtr->Config.BaseAddress, + XQSPIPS_RXD_OFFSET); + QspiPtr->RequestedBytes -= 4; + if (QspiPtr->RequestedBytes < 0) { + QspiPtr->RequestedBytes = 0; + } + + } + Count++; + } + Count = 0; + /* + * Interrupt asserted as TX_OW got asserted + * See if there is more data to send. + * Fill TX FIFO with RX threshold no. of entries or + * remaining entries (in case that is less than threshold) + */ + while ((QspiPtr->RemainingBytes > 0) && + (Count < XQSPIPS_RXFIFO_THRESHOLD_OPT)) { + /* + * Send more data. + * In case of Write fill the Tx FIFO with data to be transmitted. + * In case of Read fill the Tx FIFO with DUMMY bytes. + */ + if (!QspiPtr->RecvBufferPtr) { + XQspiPs_WriteReg(QspiPtr->Config.BaseAddress, + XQSPIPS_TXD_00_OFFSET, + *((u32 *)QspiPtr->SendBufferPtr)); + QspiPtr->SendBufferPtr += 4; + } else { + XQspiPs_WriteReg(QspiPtr->Config.BaseAddress, + XQSPIPS_TXD_00_OFFSET, + XQSPIPS_DUMMY_TX_DATA); + } + QspiPtr->RemainingBytes -= 4; + if (QspiPtr->RemainingBytes < 0) { + QspiPtr->RemainingBytes = 0; + } + + Count++; + } + + if ((QspiPtr->RemainingBytes == 0) && + (QspiPtr->RequestedBytes == 0)) { + /* + * No more data to send. Disable the interrupt + * and inform the upper layer software that the + * transfer is done. The interrupt will be re-enabled + * when another transfer is initiated. + */ + XQspiPs_WriteReg(QspiPtr->Config.BaseAddress, + XQSPIPS_IDR_OFFSET, + XQSPIPS_IXR_RXNEMPTY_MASK | + XQSPIPS_IXR_TXOW_MASK | + XQSPIPS_IXR_RXOVR_MASK | + XQSPIPS_IXR_TXUF_MASK); + + /* + * If the Slave select is being manually controlled, + * disable it because the transfer is complete. + */ + if (XQspiPs_IsManualChipSelect(InstancePtr)) { + ConfigReg = XQspiPs_ReadReg( + QspiPtr->Config.BaseAddress, + XQSPIPS_CR_OFFSET); + ConfigReg |= XQSPIPS_CR_SSCTRL_MASK; + XQspiPs_WriteReg(QspiPtr->Config.BaseAddress, + XQSPIPS_CR_OFFSET, + ConfigReg); + } + + /* + * Clear the busy flag. + */ + QspiPtr->IsBusy = FALSE; + + /* + * Disable the device. + */ + XQspiPs_Disable(QspiPtr); + + /* + * Reset the RX FIFO threshold to one + */ + XQspiPs_WriteReg(QspiPtr->Config.BaseAddress, + XQSPIPS_RXWR_OFFSET, XQSPIPS_RXWR_RESET_VALUE); + + QspiPtr->StatusHandler(QspiPtr->StatusRef, + XST_SPI_TRANSFER_DONE, + QspiPtr->RequestedBytes); + } else { + /* + * Enable the TXOW interrupt. + */ + XQspiPs_WriteReg(QspiPtr->Config.BaseAddress, + XQSPIPS_IER_OFFSET, + XQSPIPS_IXR_RXNEMPTY_MASK | + XQSPIPS_IXR_TXOW_MASK | + XQSPIPS_IXR_RXOVR_MASK | + XQSPIPS_IXR_TXUF_MASK); + /* + * If, in Manual Start mode, start the transfer. + */ + if (XQspiPs_IsManualStart(QspiPtr)) { + ConfigReg = XQspiPs_ReadReg( + QspiPtr->Config.BaseAddress, + XQSPIPS_CR_OFFSET); + ConfigReg |= XQSPIPS_CR_MANSTRT_MASK; + XQspiPs_WriteReg( + QspiPtr->Config.BaseAddress, + XQSPIPS_CR_OFFSET, ConfigReg); + } + } + } + + /* + * Check for overflow and underflow errors. + */ + if (IntrStatus & XQSPIPS_IXR_RXOVR_MASK) { + BytesDone = QspiPtr->RequestedBytes - QspiPtr->RemainingBytes; + QspiPtr->IsBusy = FALSE; + + /* + * If the Slave select lines is being manually controlled, + * disable it because the transfer is complete. + */ + if (XQspiPs_IsManualChipSelect(InstancePtr)) { + ConfigReg = XQspiPs_ReadReg( + QspiPtr->Config.BaseAddress, + XQSPIPS_CR_OFFSET); + ConfigReg |= XQSPIPS_CR_SSCTRL_MASK; + XQspiPs_WriteReg(QspiPtr->Config.BaseAddress, + XQSPIPS_CR_OFFSET, ConfigReg); + } + + /* + * Disable the device. + */ + XQspiPs_Disable(QspiPtr); + + /* + * Reset the RX FIFO threshold to one + */ + XQspiPs_WriteReg(QspiPtr->Config.BaseAddress, + XQSPIPS_RXWR_OFFSET, XQSPIPS_RXWR_RESET_VALUE); + + QspiPtr->StatusHandler(QspiPtr->StatusRef, + XST_SPI_RECEIVE_OVERRUN, BytesDone); + } + + if (IntrStatus & XQSPIPS_IXR_TXUF_MASK) { + BytesDone = QspiPtr->RequestedBytes - QspiPtr->RemainingBytes; + + QspiPtr->IsBusy = FALSE; + /* + * If the Slave select lines is being manually controlled, + * disable it because the transfer is complete. + */ + if (XQspiPs_IsManualChipSelect(InstancePtr)) { + ConfigReg = XQspiPs_ReadReg( + QspiPtr->Config.BaseAddress, + XQSPIPS_CR_OFFSET); + ConfigReg |= XQSPIPS_CR_SSCTRL_MASK; + XQspiPs_WriteReg(QspiPtr->Config.BaseAddress, + XQSPIPS_CR_OFFSET, ConfigReg); + } + + /* + * Disable the device. + */ + XQspiPs_Disable(QspiPtr); + + /* + * Reset the RX FIFO threshold to one + */ + XQspiPs_WriteReg(QspiPtr->Config.BaseAddress, + XQSPIPS_RXWR_OFFSET, XQSPIPS_RXWR_RESET_VALUE); + + QspiPtr->StatusHandler(QspiPtr->StatusRef, + XST_SPI_TRANSMIT_UNDERRUN, BytesDone); + } +} + + +/*****************************************************************************/ +/** +* +* Copies data from Data to the Receive buffer. +* +* @param InstancePtr is a pointer to the XQspiPs instance. +* @param Data is the data which needs to be copied to the Rx buffer. +* @param Size is the number of bytes to be copied to the Receive buffer. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +static void XQspiPs_GetReadData(XQspiPs *InstancePtr, u32 Data, u8 Size) +{ + u8 DataByte3; + + if (InstancePtr->RecvBufferPtr) { + switch (Size) { + case 1: + if (InstancePtr->ShiftReadData == 1) { + *((u8 *)InstancePtr->RecvBufferPtr) = + ((Data & 0xFF000000) >> 24); + } else { + *((u8 *)InstancePtr->RecvBufferPtr) = + (Data & 0xFF); + } + InstancePtr->RecvBufferPtr += 1; + break; + case 2: + if (InstancePtr->ShiftReadData == 1) { + *((u16 *)InstancePtr->RecvBufferPtr) = + ((Data >> 16) & 0xFF00) | + ((Data >> 8) & 0xFF); + } else { + *((u16 *)InstancePtr->RecvBufferPtr) = + (Data & 0xFFFF); + } + InstancePtr->RecvBufferPtr += 2; + break; + case 3: + if (InstancePtr->ShiftReadData == 1) { + *((u16 *)InstancePtr->RecvBufferPtr) = + ((Data & 0x00FFFF00) >> 8); + InstancePtr->RecvBufferPtr += 2; + DataByte3 = ((Data & 0xFF000000) >> 24); + *((u8 *)InstancePtr->RecvBufferPtr) = DataByte3; + } else { + *((u16 *)InstancePtr->RecvBufferPtr) = + (Data & 0xFFFF); + InstancePtr->RecvBufferPtr += 2; + DataByte3 = ((Data & 0x00FF0000) >> 16); + *((u8 *)InstancePtr->RecvBufferPtr) = DataByte3; + } + InstancePtr->RecvBufferPtr += 1; + break; + default: + /* This will never execute */ + break; + } + } + InstancePtr->ShiftReadData = 0; + InstancePtr->RequestedBytes -= Size; + if (InstancePtr->RequestedBytes < 0) { + InstancePtr->RequestedBytes = 0; + } +} +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips.h new file mode 100644 index 0000000..0255bc2 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips.h @@ -0,0 +1,804 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2019 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xqspips.h +* @addtogroup qspips_v3_6 +* @{ +* @details +* +* This file contains the implementation of the XQspiPs driver. It supports only +* master mode. User documentation for the driver functions is contained in this +* file in the form of comment blocks at the front of each function. +* +* A QSPI device connects to an QSPI bus through a 4-wire serial interface. +* The QSPI bus is a full-duplex, synchronous bus that facilitates communication +* between one master and one slave. The device is always full-duplex, +* which means that for every byte sent, one is received, and vice-versa. +* The master controls the clock, so it can regulate when it wants to +* send or receive data. The slave is under control of the master, it must +* respond quickly since it has no control of the clock and must send/receive +* data as fast or as slow as the master does. +* +* Linear Mode +* The Linear Quad-SPI Controller extends the existing Quad-SPI Controller�s +* functionality by adding a linear addressing scheme that allows the SPI flash +* memory subsystem to behave like a typical ROM device. The new feature hides +* the normal SPI protocol from a master reading from the SPI flash memory. The +* feature improves both the user friendliness and the overall read memory +* throughput over that of the current Quad-SPI Controller by lessening the +* amount of software overheads required and by the use of the faster AXI +* interface. +* +* Initialization & Configuration +* +* The XQspiPs_Config structure is used by the driver to configure itself. This +* configuration structure is typically created by the tool-chain based on HW +* build properties. +* +* To support multiple runtime loading and initialization strategies employed by +* various operating systems, the driver instance can be initialized in the +* following way: +* - XQspiPs_LookupConfig(DeviceId) - Use the device identifier to find +* static configuration structure defined in xqspips_g.c. This is setup +* by the tools. For some operating systems the config structure will be +* initialized by the software and this call is not needed. +* - XQspiPs_CfgInitialize(InstancePtr, CfgPtr, EffectiveAddr) - Uses a +* configuration structure provided by the caller. If running in a system +* with address translation, the provided virtual memory base address +* replaces the physical address present in the configuration structure. +* +* Multiple Masters +* +* More than one master can exist, but arbitration is the responsibility of +* the higher layer software. The device driver does not perform any type of +* arbitration. +* +* Modes of Operation +* +* There are four modes to perform a data transfer and the selection of a mode +* is based on Chip Select(CS) and Start. These two options individually, can +* be controlled either by software(Manual) or hardware(Auto). +* - Auto CS: Chip select is automatically asserted as soon as the first word +* is written into the TXFIFO and de asserted when the TXFIFO becomes +* empty +* - Manual CS: Software must assert and de assert CS. +* - Auto Start: Data transmission starts as soon as there is data in the +* TXFIFO and stalls when the TXFIFO is empty +* - Manual Start: Software must start data transmission at the beginning of +* the transaction or whenever the TXFIFO has become empty +* +* The preferred combination is Manual CS and Auto Start. +* In this combination, the software asserts CS before loading any data into +* TXFIFO. In Auto Start mode, whenever data is in TXFIFO, controller sends it +* out until TXFIFO becomes empty. The software reads the RXFIFO whenever the +* data is available. If no further data, software disables CS. +* +* Risks/challenges of other combinations: +* - Manual CS and Manual Start: Manual Start bit should be set after each +* TXFIFO write otherwise there could be a race condition where the TXFIFO +* becomes empty before the new word is written. In that case the +* transmission stops. +* - Auto CS with Manual or Auto Start: It is very difficult for software to +* keep the TXFIFO filled. Whenever the TXFIFO runs empty, CS is de asserted. +* This results in a single transaction to be split into multiple pieces each +* with its own chip select. This will result in garbage data to be sent. +* +* Interrupts +* +* The user must connect the interrupt handler of the driver, +* XQspiPs_InterruptHandler, to an interrupt system such that it will be +* called when an interrupt occurs. This function does not save and restore +* the processor context such that the user must provide this processing. +* +* The driver handles the following interrupts: +* - Data Transmit Register/FIFO Underflow +* - Data Receive Register/FIFO Not Empty +* - Data Transmit Register/FIFO Overwater +* - Data Receive Register/FIFO Overrun +* +* The Data Transmit Register/FIFO Overwater interrupt -- indicates that the +* QSPI device has transmitted the data available to transmit, and now its data +* register and FIFO is ready to accept more data. The driver uses this +* interrupt to indicate progress while sending data. The driver may have +* more data to send, in which case the data transmit register and FIFO is +* filled for subsequent transmission. When this interrupt arrives and all +* the data has been sent, the driver invokes the status callback with a +* value of XST_SPI_TRANSFER_DONE to inform the upper layer software that +* all data has been sent. +* +* The Data Transmit Register/FIFO Underflow interrupt -- indicates that, +* as slave, the QSPI device was required to transmit but there was no data +* available to transmit in the transmit register (or FIFO). This may not +* be an error if the master is not expecting data. But in the case where +* the master is expecting data, this serves as a notification of such a +* condition. The driver reports this condition to the upper layer +* software through the status handler. +* +* The Data Receive Register/FIFO Overrun interrupt -- indicates that the QSPI +* device received data and subsequently dropped the data because the data +* receive register and FIFO was full. The driver reports this condition to the +* upper layer software through the status handler. This likely indicates a +* problem with the higher layer protocol, or a problem with the slave +* performance. +* +* +* Polled Operation +* +* Transfer in polled mode is supported through a separate interface function +* XQspiPs_PolledTransfer(). Unlike the transfer function in the interrupt mode, +* this function blocks until all data has been sent/received. +* +* Device Busy +* +* Some operations are disallowed when the device is busy. The driver tracks +* whether a device is busy. The device is considered busy when a data transfer +* request is outstanding, and is considered not busy only when that transfer +* completes (or is aborted with a mode fault error). +* +* Device Configuration +* +* The device can be configured in various ways during the FPGA implementation +* process. Configuration parameters are stored in the xqspips_g.c file or +* passed in via XQspiPs_CfgInitialize(). A table is defined where each entry +* contains configuration information for an QSPI device, including the base +* address for the device. +* +* RTOS Independence +* +* This driver is intended to be RTOS and processor independent. It works with +* physical addresses only. Any needs for dynamic memory management, threads or +* thread mutual exclusion, virtual memory, or cache control must be satisfied +* by the layer above this driver. +* +* NOTE: This driver was always tested with endianess set to little-endian. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who Date     Changes
+* ----- --- -------- -----------------------------------------------
+* 1.00a sdm 11/25/10 First release, based on the PS SPI driver...
+* 1.01a sdm 11/22/11 Added TCL file for generating QSPI parameters
+*		     in xparameters.h
+* 2.00a kka 07/25/12 Added a few register defines for CR 670297
+* 		     Removed code related to mode fault for CR 671468
+*		     The XQspiPs_SetSlaveSelect has been modified to remove
+*		     the argument of the slave select as the QSPI controller
+*		     only supports one slave.
+* 		     XQspiPs_GetSlaveSelect API has been removed
+* 		     Added a flag ShiftReadData to the instance structure
+*.		     and is used in the XQspiPs_GetReadData API.
+*		     The ShiftReadData Flag indicates whether the data
+*		     read from the Rx FIFO needs to be shifted
+*		     in cases where the data is less than 4  bytes
+* 		     Removed the selection for the following options:
+*		     Master mode (XQSPIPS_MASTER_OPTION) and
+*		     Flash interface mode (XQSPIPS_FLASH_MODE_OPTION) option
+*		     as the QSPI driver supports the Master mode
+*		     and Flash Interface mode and doesnot support
+*		     Slave mode or the legacy mode.
+*		     Modified the XQspiPs_PolledTransfer and XQspiPs_Transfer
+*		     APIs so that the last argument (IsInst) specifying whether
+*		     it is instruction or data has been removed. The first byte
+*		     in the SendBufPtr argument of these APIs specify the
+*		     instruction to be sent to the Flash Device.
+*		     This version of the driver fixes CRs 670197/663787/
+*		     670297/671468.
+* 		     Added the option for setting the Holdb_dr bit in the
+*		     configuration options, XQSPIPS_HOLD_B_DRIVE_OPTION
+*		     is the option to be used for setting this bit in the
+*		     configuration register.
+*		     The XQspiPs_PolledTransfer function has been updated
+*		     to fill the data to fifo depth.
+* 2.01a sg  02/03/13 Added flash opcodes for DUAL_IO_READ,QUAD_IO_READ.
+*		     Added macros for Set/Get Rx Watermark. Changed QSPI
+*		     Enable/Disable macro argument from BaseAddress to
+*		     Instance Pointer. Added DelayNss argument to SetDelays
+*		     and GetDelays API's.
+*		     Created macros XQspiPs_IsManualStart and
+*		     XQspiPs_IsManualChipSelect.
+*		     Changed QSPI transfer logic for polled and interrupt
+*		     modes to be based on filled tx fifo count and receive
+*		     based on it. RXNEMPTY interrupt is not used.
+*		     Added assertions to XQspiPs_LqspiRead function.
+*		     SetDelays and GetDelays API's include DelayNss parameter.
+*		     Added defines for DelayNss,Rx Watermark,Interrupts
+*		     which need write to clear. Removed Read zeros mask from
+*		     LQSPI Config register. Renamed Fixed burst error to
+*		     data FSM error in  LQSPI Status register.
+*
+* 2.02a hk  05/07/13 Added ConnectionMode to config structure.
+*			 Corresponds to C_QSPI_MODE - 0:Single, 1:Stacked, 2:Parallel
+*			 Added enable and disable to the XQspiPs_LqspiRead() function
+*			 Removed XQspi_Reset() in Set_Options() function when
+*			 LQSPI_MODE_OPTION is set.
+*            Added instructions for bank selection, die erase and
+*            flag status register to the flash instruction table
+*            Handling for instructions not in flash instruction
+*			 table added. Checking for Tx FIFO empty when switching from
+*			 TXD1/2/3 to TXD0 added. If WRSR instruction is sent with
+*            byte count 3 (spansion), instruction size and TXD register
+*			 changed accordingly. CR# 712502 and 703869.
+*            Added prefix to constant definitions for ConnectionMode
+*            Added (#ifdef linear base address) in the Linear read function.
+*            Changed  XPAR_XQSPIPS_0_LINEAR_BASEADDR to
+*            XPAR_PS7_QSPI_LINEAR_0_S_AXI_BASEADDR in
+*            XQspiPs_LqspiRead function. Fix for CR#718141.
+*
+* 2.03a hk  09/17/13 Modified polled and interrupt transfers to make use of
+*                    thresholds. This is to improve performance.
+*                    Added API's for QSPI reset and
+*                    linear mode initialization for boot.
+*                    Added RX and TX threshold reset to one in XQspiPs_Abort.
+*                    Added RX threshold reset(1) after transfer in polled and
+*                    interrupt transfers. Made changes to make sure threshold
+*                    change is done only when no transfer is in progress.
+*                    Updated linear init API for parallel and stacked modes.
+*                    CR#737760.
+* 3.1   hk  08/13/14 When writing to the configuration register, set/reset
+*                    required bits leaving reserved bits untouched. CR# 796813.
+* 3.2	sk	02/05/15 Add SLCR reset in abort function as a workaround because
+* 					 controller does not update FIFO status flags as expected
+* 					 when thresholds are used.
+* 3.3   sk  11/07/15 Modified the API prototypes according to MISRAC standards
+*                    to remove compilation warnings. CR# 868893.
+*       ms  03/17/17 Added readme.txt file in examples folder for doxygen
+*                    generation.
+*       ms  04/05/17 Modified Comment lines in functions of qspips
+*                    examples to recognize it as documentation block
+*                    and modified filename tag in
+*                    xqspips_dual_flash_stack_lqspi_example.c to include it in
+*                    doxygen examples.
+* 3.4   nsk 31/07/17 Added QSPI_BUS_WIDTH parameter in xparameters.h file
+* 3.5	tjs 08/21/18 Fixed compilation warnings for the ARMCC.
+* 3.5	tjs 07/16/18 Added support for low density ISSI flash parts.
+* 3.6   akm 03/28/19 Fixed memory leak issue while reading from qspi.(CR#1016357)
+* 3.6   akm 04/15/19 Modified FlashQuadEnable, FlashWrie and FlashErase APIs,
+*                    to wait for the on going operation to complete before
+*                    performing the next operation.
+* 3.6   akm 04/15/19 Modified the mask in XQspiPs_GetReadData() API to retrieve
+*                    configuration register values of both the Flashes in dual
+*                    parellel connection.
+*
+* 
+* +******************************************************************************/ +#ifndef XQSPIPS_H /* prevent circular inclusions */ +#define XQSPIPS_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +#include "xstatus.h" +#include "xqspips_hw.h" +#include + +/************************** Constant Definitions *****************************/ + +/** @name Configuration options + * + * The following options are supported to enable/disable certain features of + * an QSPI device. Each of the options is a bit mask, so more than one may be + * specified. + * + * + * The Active Low Clock option configures the device's clock polarity. + * Setting this option means the clock is active low and the SCK signal idles + * high. By default, the clock is active high and SCK idles low. + * + * The Clock Phase option configures the QSPI device for one of two + * transfer formats. A clock phase of 0, the default, means data is valid on + * the first SCK edge (rising or falling) after the slave select (SS) signal + * has been asserted. A clock phase of 1 means data is valid on the second SCK + * edge (rising or falling) after SS has been asserted. + * + * + * The QSPI Force Slave Select option is used to enable manual control of + * the slave select signal. + * 0: The SPI_SS signal is controlled by the QSPI controller during + * transfers. (Default) + * 1: The SPI_SS signal is forced active (driven low) regardless of any + * transfers in progress. + * + * NOTE: The driver will handle setting and clearing the Slave Select when + * the user sets the "FORCE_SSELECT_OPTION". Using this option will allow the + * QSPI clock to be set to a faster speed. If the QSPI clock is too fast, the + * processor cannot empty and refill the FIFOs before the TX FIFO is empty + * When the QSPI hardware is controlling the Slave Select signals, this + * will cause slave to be de-selected and terminate the transfer. + * + * The Manual Start option is used to enable manual control of + * the Start command to perform data transfer. + * 0: The Start command is controlled by the QSPI controller during + * transfers(Default). Data transmission starts as soon as there is data in + * the TXFIFO and stalls when the TXFIFO is empty + * 1: The Start command must be issued by software to perform data transfer. + * Bit 15 of Configuration register is used to issue Start command. This bit + * must be set whenever TXFIFO is filled with new data. + * + * NOTE: The driver will set the Manual Start Enable bit in Configuration + * Register, if Manual Start option is selected. Software will issue + * Manual Start command whenever TXFIFO is filled with data. When there is + * no further data, driver will clear the Manual Start Enable bit. + * + * @{ + */ +#define XQSPIPS_CLK_ACTIVE_LOW_OPTION 0x2 /**< Active Low Clock option */ +#define XQSPIPS_CLK_PHASE_1_OPTION 0x4 /**< Clock Phase one option */ +#define XQSPIPS_FORCE_SSELECT_OPTION 0x10 /**< Force Slave Select */ +#define XQSPIPS_MANUAL_START_OPTION 0x20 /**< Manual Start enable */ +#define XQSPIPS_LQSPI_MODE_OPTION 0x80 /**< Linear QPSI mode */ +#define XQSPIPS_HOLD_B_DRIVE_OPTION 0x100 /**< Drive HOLD_B Pin */ +/*@}*/ + + +/** @name QSPI Clock Prescaler options + * The QSPI Clock Prescaler Configuration bits are used to program master mode + * bit rate. The bit rate can be programmed in divide-by-two decrements from + * pclk/2 to pclk/256. + * + * @{ + */ +#define XQSPIPS_CLK_PRESCALE_2 0x00 /**< PCLK/2 Prescaler */ +#define XQSPIPS_CLK_PRESCALE_4 0x01 /**< PCLK/4 Prescaler */ +#define XQSPIPS_CLK_PRESCALE_8 0x02 /**< PCLK/8 Prescaler */ +#define XQSPIPS_CLK_PRESCALE_16 0x03 /**< PCLK/16 Prescaler */ +#define XQSPIPS_CLK_PRESCALE_32 0x04 /**< PCLK/32 Prescaler */ +#define XQSPIPS_CLK_PRESCALE_64 0x05 /**< PCLK/64 Prescaler */ +#define XQSPIPS_CLK_PRESCALE_128 0x06 /**< PCLK/128 Prescaler */ +#define XQSPIPS_CLK_PRESCALE_256 0x07 /**< PCLK/256 Prescaler */ + +/*@}*/ + + +/** @name Callback events + * + * These constants specify the handler events that are passed to + * a handler from the driver. These constants are not bit masks such that + * only one will be passed at a time to the handler. + * + * @{ + */ +#define XQSPIPS_EVENT_TRANSFER_DONE 2 /**< Transfer done */ +#define XQSPIPS_EVENT_TRANSMIT_UNDERRUN 3 /**< TX FIFO empty */ +#define XQSPIPS_EVENT_RECEIVE_OVERRUN 4 /**< Receive data loss because + * RX FIFO full + */ +/*@}*/ + +/** @name Flash commands + * + * The following constants define most of the commands supported by flash + * devices. Users can add more commands supported by the flash devices + * + * @{ + */ +#define XQSPIPS_FLASH_OPCODE_WRSR 0x01 /* Write status register */ +#define XQSPIPS_FLASH_OPCODE_PP 0x02 /* Page program */ +#define XQSPIPS_FLASH_OPCODE_NORM_READ 0x03 /* Normal read data bytes */ +#define XQSPIPS_FLASH_OPCODE_WRDS 0x04 /* Write disable */ +#define XQSPIPS_FLASH_OPCODE_RDSR1 0x05 /* Read status register 1 */ +#define XQSPIPS_FLASH_OPCODE_WREN 0x06 /* Write enable */ +#define XQSPIPS_FLASH_OPCODE_FAST_READ 0x0B /* Fast read data bytes */ +#define XQSPIPS_FLASH_OPCODE_BE_4K 0x20 /* Erase 4KiB block */ +#define XQSPIPS_FLASH_OPCODE_RDSR2 0x35 /* Read status register 2 */ +#define XQSPIPS_FLASH_OPCODE_DUAL_READ 0x3B /* Dual read data bytes */ +#define XQSPIPS_FLASH_OPCODE_BE_32K 0x52 /* Erase 32KiB block */ +#define XQSPIPS_FLASH_OPCODE_QUAD_READ 0x6B /* Quad read data bytes */ +#define XQSPIPS_FLASH_OPCODE_ERASE_SUS 0x75 /* Erase suspend */ +#define XQSPIPS_FLASH_OPCODE_ERASE_RES 0x7A /* Erase resume */ +#define XQSPIPS_FLASH_OPCODE_RDID 0x9F /* Read JEDEC ID */ +#define XQSPIPS_FLASH_OPCODE_BE 0xC7 /* Erase whole flash block */ +#define XQSPIPS_FLASH_OPCODE_SE 0xD8 /* Sector erase (usually 64KB)*/ +#define XQSPIPS_FLASH_OPCODE_DUAL_IO_READ 0xBB /* Read data using Dual I/O */ +#define XQSPIPS_FLASH_OPCODE_QUAD_IO_READ 0xEB /* Read data using Quad I/O */ +#define XQSPIPS_FLASH_OPCODE_BRWR 0x17 /* Bank Register Write */ +#define XQSPIPS_FLASH_OPCODE_BRRD 0x16 /* Bank Register Read */ +/* Extende Address Register Write - Micron's equivalent of Bank Register */ +#define XQSPIPS_FLASH_OPCODE_EARWR 0xC5 +/* Extende Address Register Read - Micron's equivalent of Bank Register */ +#define XQSPIPS_FLASH_OPCODE_EARRD 0xC8 +#define XQSPIPS_FLASH_OPCODE_DIE_ERASE 0xC4 +#define XQSPIPS_FLASH_OPCODE_READ_FLAG_SR 0x70 +#define XQSPIPS_FLASH_OPCODE_CLEAR_FLAG_SR 0x50 +#define XQSPIPS_FLASH_OPCODE_READ_LOCK_REG 0xE8 /* Lock Reg Read */ +#define XQSPIPS_FLASH_OPCODE_WRITE_LOCK_REG 0xE5 /* Lock Reg Write */ + +/*@}*/ + +/** @name Instruction size + * + * The following constants define numbers 1 to 4. + * Used to identify whether TXD0,1,2 or 3 is to be used. + * + * @{ + */ +#define XQSPIPS_SIZE_ONE 1 +#define XQSPIPS_SIZE_TWO 2 +#define XQSPIPS_SIZE_THREE 3 +#define XQSPIPS_SIZE_FOUR 4 + +/*@}*/ + +/** @name ConnectionMode + * + * The following constants are the possible values of ConnectionMode in + * Config structure. + * + * @{ + */ +#define XQSPIPS_CONNECTION_MODE_SINGLE 0 +#define XQSPIPS_CONNECTION_MODE_STACKED 1 +#define XQSPIPS_CONNECTION_MODE_PARALLEL 2 + +/*@}*/ + +/** @name FIFO threshold value + * + * This is the Rx FIFO threshold (in words) that was found to be most + * optimal in terms of performance + * + * @{ + */ +#define XQSPIPS_RXFIFO_THRESHOLD_OPT 32 + +/*@}*/ + +/**************************** Type Definitions *******************************/ +/** + * The handler data type allows the user to define a callback function to + * handle the asynchronous processing for the QSPI device. The application + * using this driver is expected to define a handler of this type to support + * interrupt driven mode. The handler executes in an interrupt context, so + * only minimal processing should be performed. + * + * @param CallBackRef is the callback reference passed in by the upper + * layer when setting the callback functions, and passed back to + * the upper layer when the callback is invoked. Its type is + * not important to the driver, so it is a void pointer. + * @param StatusEvent holds one or more status events that have occurred. + * See the XQspiPs_SetStatusHandler() for details on the status + * events that can be passed in the callback. + * @param ByteCount indicates how many bytes of data were successfully + * transferred. This may be less than the number of bytes + * requested if the status event indicates an error. + */ +typedef void (*XQspiPs_StatusHandler) (void *CallBackRef, u32 StatusEvent, + unsigned ByteCount); + +/** + * This typedef contains configuration information for the device. + */ +typedef struct { + u16 DeviceId; /**< Unique ID of device */ + u32 BaseAddress; /**< Base address of the device */ + u32 InputClockHz; /**< Input clock frequency */ + u8 ConnectionMode; /**< Single, Stacked and Parallel mode */ +} XQspiPs_Config; + +/** + * The XQspiPs driver instance data. The user is required to allocate a + * variable of this type for every QSPI device in the system. A pointer + * to a variable of this type is then passed to the driver API functions. + */ +typedef struct { + XQspiPs_Config Config; /**< Configuration structure */ + u32 IsReady; /**< Device is initialized and ready */ + + u8 *SendBufferPtr; /**< Buffer to send (state) */ + u8 *RecvBufferPtr; /**< Buffer to receive (state) */ + int RequestedBytes; /**< Number of bytes to transfer (state) */ + int RemainingBytes; /**< Number of bytes left to transfer(state) */ + u32 IsBusy; /**< A transfer is in progress (state) */ + XQspiPs_StatusHandler StatusHandler; + void *StatusRef; /**< Callback reference for status handler */ + u32 ShiftReadData; /**< Flag to indicate whether the data + * read from the Rx FIFO needs to be shifted + * in cases where the data is less than 4 + * bytes + */ +} XQspiPs; + +/***************** Macros (Inline Functions) Definitions *********************/ + +/****************************************************************************/ +/* +* +* Check in OptionsTable if Manual Start Option is enabled or disabled. +* +* @param InstancePtr is a pointer to the XQspiPs instance. +* +* @return +* - TRUE if option is set +* - FALSE if option is not set +* +* @note C-Style signature: +* u8 XQspiPs_IsManualStart(XQspiPs *InstancePtr); +* +*****************************************************************************/ +#define XQspiPs_IsManualStart(InstancePtr) \ + ((XQspiPs_GetOptions(InstancePtr) & \ + XQSPIPS_MANUAL_START_OPTION) ? TRUE : FALSE) + +/****************************************************************************/ +/* +* +* Check in OptionsTable if Manual Chip Select Option is enabled or disabled. +* +* @param InstancePtr is a pointer to the XSpiPs instance. +* +* @return +* - TRUE if option is set +* - FALSE if option is not set +* +* @note C-Style signature: +* u8 XQspiPs_IsManualChipSelect(XQspiPs *InstancePtr); +* +*****************************************************************************/ +#define XQspiPs_IsManualChipSelect(InstancePtr) \ + ((XQspiPs_GetOptions(InstancePtr) & \ + XQSPIPS_FORCE_SSELECT_OPTION) ? TRUE : FALSE) + +/****************************************************************************/ +/** +* +* Set the contents of the slave idle count register. +* +* @param InstancePtr is a pointer to the XQspiPs instance. +* @param RegisterValue is the value to be written, valid values are +* 0-255. +* +* @return None +* +* @note C-Style signature: +* void XQspiPs_SetSlaveIdle(XQspiPs *InstancePtr, +* u32 RegisterValue) +* +*****************************************************************************/ +#define XQspiPs_SetSlaveIdle(InstancePtr, RegisterValue) \ + XQspiPs_Out32(((InstancePtr)->Config.BaseAddress) + \ + XQSPIPS_SICR_OFFSET, (RegisterValue)) + +/****************************************************************************/ +/** +* +* Get the contents of the slave idle count register. Use the XQSPIPS_SICR_* +* constants defined in xqspips_hw.h to interpret the bit-mask returned. +* +* @param InstancePtr is a pointer to the XQspiPs instance. +* +* @return An 8-bit value representing Slave Idle Count. +* +* @note C-Style signature: +* u32 XQspiPs_GetSlaveIdle(XQspiPs *InstancePtr) +* +*****************************************************************************/ +#define XQspiPs_GetSlaveIdle(InstancePtr) \ + XQspiPs_In32(((InstancePtr)->Config.BaseAddress) + \ + XQSPIPS_SICR_OFFSET) + +/****************************************************************************/ +/** +* +* Set the contents of the transmit FIFO watermark register. +* +* @param InstancePtr is a pointer to the XQspiPs instance. +* @param RegisterValue is the value to be written, valid values are 1-63. +* +* @return None. +* +* @note C-Style signature: +* void XQspiPs_SetTXWatermark(XQspiPs *InstancePtr, +* u32 RegisterValue) +* +*****************************************************************************/ +#define XQspiPs_SetTXWatermark(InstancePtr, RegisterValue) \ + XQspiPs_Out32(((InstancePtr)->Config.BaseAddress) + \ + XQSPIPS_TXWR_OFFSET, (RegisterValue)) + +/****************************************************************************/ +/** +* +* Get the contents of the transmit FIFO watermark register. +* Valid values are in the range 1-63. +* +* @param InstancePtr is a pointer to the XQspiPs instance. +* +* @return A 6-bit value representing Tx Watermark level. +* +* @note C-Style signature: +* u32 XQspiPs_GetTXWatermark(XQspiPs *InstancePtr) +* +*****************************************************************************/ +#define XQspiPs_GetTXWatermark(InstancePtr) \ + XQspiPs_In32((InstancePtr->Config.BaseAddress) + XQSPIPS_TXWR_OFFSET) + +/****************************************************************************/ +/** +* +* Set the contents of the receive FIFO watermark register. +* +* @param InstancePtr is a pointer to the XQspiPs instance. +* @param RegisterValue is the value to be written, valid values are 1-63. +* +* @return None. +* +* @note C-Style signature: +* void XQspiPs_SetRXWatermark(XQspiPs *InstancePtr, +* u32 RegisterValue) +* +*****************************************************************************/ +#define XQspiPs_SetRXWatermark(InstancePtr, RegisterValue) \ + XQspiPs_Out32(((InstancePtr)->Config.BaseAddress) + \ + XQSPIPS_RXWR_OFFSET, (RegisterValue)) + +/****************************************************************************/ +/** +* +* Get the contents of the receive FIFO watermark register. +* Valid values are in the range 1-63. +* +* @param InstancePtr is a pointer to the XQspiPs instance. +* +* @return A 6-bit value representing Rx Watermark level. +* +* @note C-Style signature: +* u32 XQspiPs_GetRXWatermark(XQspiPs *InstancePtr) +* +*****************************************************************************/ +#define XQspiPs_GetRXWatermark(InstancePtr) \ + XQspiPs_In32((InstancePtr->Config.BaseAddress) + XQSPIPS_RXWR_OFFSET) + +/****************************************************************************/ +/** +* +* Enable the device and uninhibit master transactions. +* +* @param InstancePtr is a pointer to the XQspiPs instance. +* +* @return None. +* +* @note C-Style signature: +* void XQspiPs_Enable(XQspiPs *InstancePtr) +* +*****************************************************************************/ +#define XQspiPs_Enable(InstancePtr) \ + XQspiPs_Out32((InstancePtr->Config.BaseAddress) + XQSPIPS_ER_OFFSET, \ + XQSPIPS_ER_ENABLE_MASK) + +/****************************************************************************/ +/** +* +* Disable the device. +* +* @param InstancePtr is a pointer to the XQspiPs instance. +* +* @return None. +* +* @note C-Style signature: +* void XQspiPs_Disable(XQspiPs *InstancePtr) +* +*****************************************************************************/ +#define XQspiPs_Disable(InstancePtr) \ + XQspiPs_Out32((InstancePtr->Config.BaseAddress) + XQSPIPS_ER_OFFSET, 0) + +/****************************************************************************/ +/** +* +* Set the contents of the Linear QSPI Configuration register. +* +* @param InstancePtr is a pointer to the XQspiPs instance. +* @param RegisterValue is the value to be written to the Linear QSPI +* configuration register. +* +* @return None. +* +* @note C-Style signature: +* void XQspiPs_SetLqspiConfigReg(XQspiPs *InstancePtr, +* u32 RegisterValue) +* +*****************************************************************************/ +#define XQspiPs_SetLqspiConfigReg(InstancePtr, RegisterValue) \ + XQspiPs_Out32(((InstancePtr)->Config.BaseAddress) + \ + XQSPIPS_LQSPI_CR_OFFSET, (RegisterValue)) + +/****************************************************************************/ +/** +* +* Get the contents of the Linear QSPI Configuration register. +* +* @param InstancePtr is a pointer to the XQspiPs instance. +* +* @return A 32-bit value representing the contents of the LQSPI Config +* register. +* +* @note C-Style signature: +* u32 XQspiPs_GetLqspiConfigReg(u32 *InstancePtr) +* +*****************************************************************************/ +#define XQspiPs_GetLqspiConfigReg(InstancePtr) \ + XQspiPs_In32((InstancePtr->Config.BaseAddress) + \ + XQSPIPS_LQSPI_CR_OFFSET) + +/************************** Function Prototypes ******************************/ + +/* + * Initialization function, implemented in xqspips_sinit.c + */ +XQspiPs_Config *XQspiPs_LookupConfig(u16 DeviceId); + +/* + * Functions implemented in xqspips.c + */ +int XQspiPs_CfgInitialize(XQspiPs *InstancePtr, XQspiPs_Config *Config, + u32 EffectiveAddr); +void XQspiPs_Reset(XQspiPs *InstancePtr); +void XQspiPs_Abort(XQspiPs *InstancePtr); + +s32 XQspiPs_Transfer(XQspiPs *InstancePtr, u8 *SendBufPtr, u8 *RecvBufPtr, + u32 ByteCount); +s32 XQspiPs_PolledTransfer(XQspiPs *InstancePtr, u8 *SendBufPtr, + u8 *RecvBufPtr, u32 ByteCount); +int XQspiPs_LqspiRead(XQspiPs *InstancePtr, u8 *RecvBufPtr, + u32 Address, unsigned ByteCount); + +int XQspiPs_SetSlaveSelect(XQspiPs *InstancePtr); + +void XQspiPs_SetStatusHandler(XQspiPs *InstancePtr, void *CallBackRef, + XQspiPs_StatusHandler FuncPtr); +void XQspiPs_InterruptHandler(void *InstancePtr); + +/* + * Functions for selftest, in xqspips_selftest.c + */ +int XQspiPs_SelfTest(XQspiPs *InstancePtr); + +/* + * Functions for options, in xqspips_options.c + */ +s32 XQspiPs_SetOptions(XQspiPs *InstancePtr, u32 Options); +u32 XQspiPs_GetOptions(XQspiPs *InstancePtr); + +s32 XQspiPs_SetClkPrescaler(XQspiPs *InstancePtr, u8 Prescaler); +u8 XQspiPs_GetClkPrescaler(XQspiPs *InstancePtr); + +int XQspiPs_SetDelays(XQspiPs *InstancePtr, u8 DelayNss, u8 DelayBtwn, + u8 DelayAfter, u8 DelayInit); +void XQspiPs_GetDelays(XQspiPs *InstancePtr, u8 *DelayNss, u8 *DelayBtwn, + u8 *DelayAfter, u8 *DelayInit); +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips_g.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips_g.c new file mode 100644 index 0000000..479135c --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips_g.c @@ -0,0 +1,53 @@ + +/******************************************************************* +* +* CAUTION: This file is automatically generated by HSI. +* Version: 2019.1.3 +* DO NOT EDIT. +* +* Copyright (C) 2010-2023 Xilinx, Inc. All Rights Reserved.* +*Permission is hereby granted, free of charge, to any person obtaining a copy +*of this software and associated documentation files (the Software), to deal +*in the Software without restriction, including without limitation the rights +*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +*copies of the Software, and to permit persons to whom the Software is +*furnished to do so, subject to the following conditions: +* +*The above copyright notice and this permission notice shall be included in +*all copies or substantial portions of the Software. +* +*THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +*XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +*OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*Except as contained in this notice, the name of the Xilinx shall not be used +*in advertising or otherwise to promote the sale, use or other dealings in +*this Software without prior written authorization from Xilinx. +* + +* +* Description: Driver configuration +* +*******************************************************************/ + +#include "xparameters.h" +#include "xqspips.h" + +/* +* The configuration table for devices +*/ + +XQspiPs_Config XQspiPs_ConfigTable[XPAR_XQSPIPS_NUM_INSTANCES] = +{ + { + XPAR_PS7_QSPI_0_DEVICE_ID, + XPAR_PS7_QSPI_0_BASEADDR, + XPAR_PS7_QSPI_0_QSPI_CLK_FREQ_HZ, + XPAR_PS7_QSPI_0_QSPI_MODE + } +}; + + diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips_hw.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips_hw.c new file mode 100644 index 0000000..d5e0789 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips_hw.c @@ -0,0 +1,220 @@ +/****************************************************************************** +* +* Copyright (C) 2013 - 2019 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xqspips_hw.c +* @addtogroup qspips_v3_6 +* @{ +* +* Contains low level functions, primarily reset related. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who Date     Changes
+* ----- --- -------- -----------------------------------------------
+* 2.03a hk  09/17/13 First release
+* 3.1   hk  06/19/14 When writing to the configuration register, set/reset
+*                    required bits leaving reserved bits untouched. CR# 796813.
+*
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xqspips_hw.h" +#include "xqspips.h" + +/************************** Constant Definitions *****************************/ + +/** @name Pre-scaler value for divided by 4 + * + * Pre-scaler value for divided by 4 + * + * @{ + */ +#define XQSPIPS_CR_PRESC_DIV_BY_4 0x01 +/* @} */ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/************************** Variable Definitions *****************************/ + + +/*****************************************************************************/ +/** +* +* Resets QSPI by disabling the device and bringing it to reset state through +* register writes. +* +* @param None +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XQspiPs_ResetHw(u32 BaseAddress) +{ + u32 ConfigReg; + + /* + * Disable interrupts + */ + XQspiPs_WriteReg(BaseAddress, XQSPIPS_IDR_OFFSET, + XQSPIPS_IXR_DISABLE_ALL); + + /* + * Disable device + */ + XQspiPs_WriteReg(BaseAddress, XQSPIPS_ER_OFFSET, + 0); + + /* + * De-assert slave select lines. + */ + ConfigReg = XQspiPs_ReadReg(BaseAddress, XQSPIPS_CR_OFFSET); + ConfigReg |= (XQSPIPS_CR_SSCTRL_MASK | XQSPIPS_CR_SSFORCE_MASK); + XQspiPs_WriteReg(BaseAddress, XQSPIPS_CR_OFFSET, ConfigReg); + + /* + * Write default value to RX and TX threshold registers + * RX threshold should be set to 1 here because the corresponding + * status bit is used next to clear the RXFIFO + */ + XQspiPs_WriteReg(BaseAddress, XQSPIPS_TXWR_OFFSET, + (XQSPIPS_TXWR_RESET_VALUE & XQSPIPS_TXWR_MASK)); + XQspiPs_WriteReg(BaseAddress, XQSPIPS_RXWR_OFFSET, + (XQSPIPS_RXWR_RESET_VALUE & XQSPIPS_RXWR_MASK)); + + /* + * Clear RXFIFO + */ + while ((XQspiPs_ReadReg(BaseAddress,XQSPIPS_SR_OFFSET) & + XQSPIPS_IXR_RXNEMPTY_MASK) != 0) { + XQspiPs_ReadReg(BaseAddress, XQSPIPS_RXD_OFFSET); + } + + /* + * Clear status register by reading register and + * writing 1 to clear the write to clear bits + */ + XQspiPs_ReadReg(BaseAddress, XQSPIPS_SR_OFFSET); + XQspiPs_WriteReg(BaseAddress, XQSPIPS_SR_OFFSET, + XQSPIPS_IXR_WR_TO_CLR_MASK); + + /* + * Write default value to configuration register + */ + ConfigReg = XQspiPs_ReadReg(BaseAddress, XQSPIPS_CR_OFFSET); + ConfigReg |= XQSPIPS_CR_RESET_MASK_SET; + ConfigReg &= ~XQSPIPS_CR_RESET_MASK_CLR; + XQspiPs_WriteReg(BaseAddress, XQSPIPS_CR_OFFSET, ConfigReg); + + /* + * De-select linear mode + */ + XQspiPs_WriteReg(BaseAddress, XQSPIPS_LQSPI_CR_OFFSET, + 0x0); + +} + +/*****************************************************************************/ +/** +* +* Initializes QSPI to Linear mode with default QSPI boot settings. +* +* @param None +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XQspiPs_LinearInit(u32 BaseAddress) +{ + u32 BaudRateDiv; + u32 LinearCfg; + u32 ConfigReg; + + /* + * Baud rate divisor for dividing by 4. Value of CR bits [5:3] + * should be set to 0x001; hence shift the value and use the mask. + */ + BaudRateDiv = ( (XQSPIPS_CR_PRESC_DIV_BY_4) << + XQSPIPS_CR_PRESC_SHIFT) & XQSPIPS_CR_PRESC_MASK; + /* + * Write configuration register with default values, slave selected & + * pre-scaler value for divide by 4 + */ + ConfigReg = XQspiPs_ReadReg(BaseAddress, XQSPIPS_CR_OFFSET); + ConfigReg |= (XQSPIPS_CR_RESET_MASK_SET | BaudRateDiv); + ConfigReg &= ~(XQSPIPS_CR_RESET_MASK_CLR | XQSPIPS_CR_SSCTRL_MASK); + XQspiPs_WriteReg(BaseAddress, XQSPIPS_CR_OFFSET, ConfigReg); + + /* + * Write linear configuration register with default value - + * enable linear mode and use fast read. + */ + + if(XPAR_XQSPIPS_0_QSPI_MODE == XQSPIPS_CONNECTION_MODE_SINGLE){ + + LinearCfg = XQSPIPS_LQSPI_CR_RST_STATE; + + }else if(XPAR_XQSPIPS_0_QSPI_MODE == + XQSPIPS_CONNECTION_MODE_STACKED){ + + LinearCfg = XQSPIPS_LQSPI_CR_RST_STATE | + XQSPIPS_LQSPI_CR_TWO_MEM_MASK; + + }else if(XPAR_XQSPIPS_0_QSPI_MODE == + XQSPIPS_CONNECTION_MODE_PARALLEL){ + + LinearCfg = XQSPIPS_LQSPI_CR_RST_STATE | + XQSPIPS_LQSPI_CR_TWO_MEM_MASK | + XQSPIPS_LQSPI_CR_SEP_BUS_MASK; + + } + + XQspiPs_WriteReg(BaseAddress, XQSPIPS_LQSPI_CR_OFFSET, + LinearCfg); + + /* + * Enable device + */ + XQspiPs_WriteReg(BaseAddress, XQSPIPS_ER_OFFSET, + XQSPIPS_ER_ENABLE_MASK); + +} +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips_hw.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips_hw.h new file mode 100644 index 0000000..88c232e --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips_hw.h @@ -0,0 +1,421 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2019 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xqspips_hw.h +* @addtogroup qspips_v3_6 +* @{ +* +* This header file contains the identifiers and basic HW access driver +* functions (or macros) that can be used to access the device. Other driver +* functions are defined in xqspips.h. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who Date     Changes
+* ----- --- -------- -----------------------------------------------
+* 1.00  sdm 11/25/10 First release
+* 2.00a ka  07/25/12 Added a few register defines for CR 670297
+*		     and removed some defines of reserved fields for
+*		     CR 671468
+*		     Added define XQSPIPS_CR_HOLD_B_MASK for Holdb_dr
+*		     bit in Configuration register.
+* 2.01a sg  02/03/13 Added defines for DelayNss,Rx Watermark,Interrupts
+*		     which need write to clear. Removed Read zeros mask from
+*		     LQSPI Config register.
+* 2.03a hk  08/22/13 Added prototypes of API's for QSPI reset and
+*                    linear mode initialization for boot. Added related
+*                    constant definitions.
+* 3.1   hk  08/13/14 Changed definition of CR reset value masks to set/reset
+*                    required bits leaving reserved bits untouched. CR# 796813.
+* 3.2	sk	02/05/15 Add SLCR reset in abort function as a workaround because
+* 					 controller does not update FIFO status flags as expected
+* 					 when thresholds are used.
+* 3.6   akm 03/28/19 Fixed memory leak issue while reading from qspi.(CR#1016357)
+*
+* 
+* +******************************************************************************/ +#ifndef XQSPIPS_HW_H /* prevent circular inclusions */ +#define XQSPIPS_HW_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +#include "xil_types.h" +#include "xil_assert.h" +#include "xil_io.h" +#include "xparameters.h" + +/************************** Constant Definitions *****************************/ + +/** @name Register Map + * + * Register offsets from the base address of an QSPI device. + * @{ + */ +#define XQSPIPS_CR_OFFSET 0x00 /**< Configuration Register */ +#define XQSPIPS_SR_OFFSET 0x04 /**< Interrupt Status */ +#define XQSPIPS_IER_OFFSET 0x08 /**< Interrupt Enable */ +#define XQSPIPS_IDR_OFFSET 0x0c /**< Interrupt Disable */ +#define XQSPIPS_IMR_OFFSET 0x10 /**< Interrupt Enabled Mask */ +#define XQSPIPS_ER_OFFSET 0x14 /**< Enable/Disable Register */ +#define XQSPIPS_DR_OFFSET 0x18 /**< Delay Register */ +#define XQSPIPS_TXD_00_OFFSET 0x1C /**< Transmit 4-byte inst/data */ +#define XQSPIPS_RXD_OFFSET 0x20 /**< Data Receive Register */ +#define XQSPIPS_SICR_OFFSET 0x24 /**< Slave Idle Count */ +#define XQSPIPS_TXWR_OFFSET 0x28 /**< Transmit FIFO Watermark */ +#define XQSPIPS_RXWR_OFFSET 0x2C /**< Receive FIFO Watermark */ +#define XQSPIPS_GPIO_OFFSET 0x30 /**< GPIO Register */ +#define XQSPIPS_LPBK_DLY_ADJ_OFFSET 0x38 /**< Loopback Delay Adjust Reg */ +#define XQSPIPS_TXD_01_OFFSET 0x80 /**< Transmit 1-byte inst */ +#define XQSPIPS_TXD_10_OFFSET 0x84 /**< Transmit 2-byte inst */ +#define XQSPIPS_TXD_11_OFFSET 0x88 /**< Transmit 3-byte inst */ +#define XQSPIPS_LQSPI_CR_OFFSET 0xA0 /**< Linear QSPI config register */ +#define XQSPIPS_LQSPI_SR_OFFSET 0xA4 /**< Linear QSPI status register */ +#define XQSPIPS_MOD_ID_OFFSET 0xFC /**< Module ID register */ + +/* @} */ + +/** @name Configuration Register + * + * This register contains various control bits that + * affect the operation of the QSPI device. Read/Write. + * @{ + */ + +#define XQSPIPS_CR_IFMODE_MASK 0x80000000 /**< Flash mem interface mode */ +#define XQSPIPS_CR_ENDIAN_MASK 0x04000000 /**< Tx/Rx FIFO endianness */ +#define XQSPIPS_CR_MANSTRT_MASK 0x00010000 /**< Manual Transmission Start */ +#define XQSPIPS_CR_MANSTRTEN_MASK 0x00008000 /**< Manual Transmission Start + Enable */ +#define XQSPIPS_CR_SSFORCE_MASK 0x00004000 /**< Force Slave Select */ +#define XQSPIPS_CR_SSCTRL_MASK 0x00000400 /**< Slave Select Decode */ +#define XQSPIPS_CR_SSCTRL_SHIFT 10 /**< Slave Select Decode shift */ +#define XQSPIPS_CR_DATA_SZ_MASK 0x000000C0 /**< Size of word to be + transferred */ +#define XQSPIPS_CR_PRESC_MASK 0x00000038 /**< Prescaler Setting */ +#define XQSPIPS_CR_PRESC_SHIFT 3 /**< Prescaler shift */ +#define XQSPIPS_CR_PRESC_MAXIMUM 0x07 /**< Prescaler maximum value */ + +#define XQSPIPS_CR_CPHA_MASK 0x00000004 /**< Phase Configuration */ +#define XQSPIPS_CR_CPOL_MASK 0x00000002 /**< Polarity Configuration */ + +#define XQSPIPS_CR_MSTREN_MASK 0x00000001 /**< Master Mode Enable */ + +#define XQSPIPS_CR_HOLD_B_MASK 0x00080000 /**< HOLD_B Pin Drive Enable */ + +#define XQSPIPS_CR_REF_CLK_MASK 0x00000100 /**< Ref clk bit - should be 0 */ + +/* Deselect the Slave select line and set the transfer size to 32 at reset */ +#define XQSPIPS_CR_RESET_MASK_SET XQSPIPS_CR_IFMODE_MASK | \ + XQSPIPS_CR_SSCTRL_MASK | \ + XQSPIPS_CR_DATA_SZ_MASK | \ + XQSPIPS_CR_MSTREN_MASK | \ + XQSPIPS_CR_SSFORCE_MASK | \ + XQSPIPS_CR_HOLD_B_MASK +#define XQSPIPS_CR_RESET_MASK_CLR XQSPIPS_CR_CPOL_MASK | \ + XQSPIPS_CR_CPHA_MASK | \ + XQSPIPS_CR_PRESC_MASK | \ + XQSPIPS_CR_MANSTRTEN_MASK | \ + XQSPIPS_CR_MANSTRT_MASK | \ + XQSPIPS_CR_ENDIAN_MASK | \ + XQSPIPS_CR_REF_CLK_MASK +/* @} */ + + +/** @name QSPI Interrupt Registers + * + * QSPI Status Register + * + * This register holds the interrupt status flags for an QSPI device. Some + * of the flags are level triggered, which means that they are set as long + * as the interrupt condition exists. Other flags are edge triggered, + * which means they are set once the interrupt condition occurs and remain + * set until they are cleared by software. The interrupts are cleared by + * writing a '1' to the interrupt bit position in the Status Register. + * Read/Write. + * + * QSPI Interrupt Enable Register + * + * This register is used to enable chosen interrupts for an QSPI device. + * Writing a '1' to a bit in this register sets the corresponding bit in the + * QSPI Interrupt Mask register. Write only. + * + * QSPI Interrupt Disable Register + * + * This register is used to disable chosen interrupts for an QSPI device. + * Writing a '1' to a bit in this register clears the corresponding bit in the + * QSPI Interrupt Mask register. Write only. + * + * QSPI Interrupt Mask Register + * + * This register shows the enabled/disabled interrupts of an QSPI device. + * Read only. + * + * All four registers have the same bit definitions. They are only defined once + * for each of the Interrupt Enable Register, Interrupt Disable Register, + * Interrupt Mask Register, and Channel Interrupt Status Register + * @{ + */ + +#define XQSPIPS_IXR_TXUF_MASK 0x00000040 /**< QSPI Tx FIFO Underflow */ +#define XQSPIPS_IXR_RXFULL_MASK 0x00000020 /**< QSPI Rx FIFO Full */ +#define XQSPIPS_IXR_RXNEMPTY_MASK 0x00000010 /**< QSPI Rx FIFO Not Empty */ +#define XQSPIPS_IXR_TXFULL_MASK 0x00000008 /**< QSPI Tx FIFO Full */ +#define XQSPIPS_IXR_TXOW_MASK 0x00000004 /**< QSPI Tx FIFO Overwater */ +#define XQSPIPS_IXR_RXOVR_MASK 0x00000001 /**< QSPI Rx FIFO Overrun */ +#define XQSPIPS_IXR_DFLT_MASK 0x00000025 /**< QSPI default interrupts + mask */ +#define XQSPIPS_IXR_WR_TO_CLR_MASK 0x00000041 /**< Interrupts which + need write to clear */ +#define XQSPIPS_ISR_RESET_STATE 0x00000004 /**< Default to tx/rx empty */ +#define XQSPIPS_IXR_DISABLE_ALL 0x0000007D /**< Disable all interrupts */ +/* @} */ + + +/** @name Enable Register + * + * This register is used to enable or disable an QSPI device. + * Read/Write + * @{ + */ +#define XQSPIPS_ER_ENABLE_MASK 0x00000001 /**< QSPI Enable Bit Mask */ +/* @} */ + + +/** @name Delay Register + * + * This register is used to program timing delays in + * slave mode. Read/Write + * @{ + */ +#define XQSPIPS_DR_NSS_MASK 0xFF000000 /**< Delay to de-assert slave select + between two words mask */ +#define XQSPIPS_DR_NSS_SHIFT 24 /**< Delay to de-assert slave select + between two words shift */ +#define XQSPIPS_DR_BTWN_MASK 0x00FF0000 /**< Delay Between Transfers + mask */ +#define XQSPIPS_DR_BTWN_SHIFT 16 /**< Delay Between Transfers shift */ +#define XQSPIPS_DR_AFTER_MASK 0x0000FF00 /**< Delay After Transfers mask */ +#define XQSPIPS_DR_AFTER_SHIFT 8 /**< Delay After Transfers shift */ +#define XQSPIPS_DR_INIT_MASK 0x000000FF /**< Delay Initially mask */ +/* @} */ + +/** @name Slave Idle Count Registers + * + * This register defines the number of pclk cycles the slave waits for a the + * QSPI clock to become stable in quiescent state before it can detect the start + * of the next transfer in CPHA = 1 mode. + * Read/Write + * + * @{ + */ +#define XQSPIPS_SICR_MASK 0x000000FF /**< Slave Idle Count Mask */ +/* @} */ + + +/** @name Transmit FIFO Watermark Register + * + * This register defines the watermark setting for the Transmit FIFO. + * + * @{ + */ +#define XQSPIPS_TXWR_MASK 0x0000003F /**< Transmit Watermark Mask */ +#define XQSPIPS_TXWR_RESET_VALUE 0x00000001 /**< Transmit Watermark + * register reset value */ + +/* @} */ + +/** @name Receive FIFO Watermark Register + * + * This register defines the watermark setting for the Receive FIFO. + * + * @{ + */ +#define XQSPIPS_RXWR_MASK 0x0000003F /**< Receive Watermark Mask */ +#define XQSPIPS_RXWR_RESET_VALUE 0x00000001 /**< Receive Watermark + * register reset value */ + +/* @} */ + +/** @name FIFO Depth + * + * This macro provides the depth of transmit FIFO and receive FIFO. + * + * @{ + */ +#define XQSPIPS_FIFO_DEPTH 63 /**< FIFO depth (words) */ +/* @} */ + + +/** @name Linear QSPI Configuration Register + * + * This register contains various control bits that + * affect the operation of the Linear QSPI controller. Read/Write. + * + * @{ + */ +#define XQSPIPS_LQSPI_CR_LINEAR_MASK 0x80000000 /**< LQSPI mode enable */ +#define XQSPIPS_LQSPI_CR_TWO_MEM_MASK 0x40000000 /**< Both memories or one */ +#define XQSPIPS_LQSPI_CR_SEP_BUS_MASK 0x20000000 /**< Seperate memory bus */ +#define XQSPIPS_LQSPI_CR_U_PAGE_MASK 0x10000000 /**< Upper memory page */ +#define XQSPIPS_LQSPI_CR_MODE_EN_MASK 0x02000000 /**< Enable mode bits */ +#define XQSPIPS_LQSPI_CR_MODE_ON_MASK 0x01000000 /**< Mode on */ +#define XQSPIPS_LQSPI_CR_MODE_BITS_MASK 0x00FF0000 /**< Mode value for dual I/O + or quad I/O */ +#define XQSPIPS_LQSPI_CR_DUMMY_MASK 0x00000700 /**< Number of dummy bytes + between addr and return + read data */ +#define XQSPIPS_LQSPI_CR_INST_MASK 0x000000FF /**< Read instr code */ +#define XQSPIPS_LQSPI_CR_RST_STATE 0x8000016B /**< Default CR value */ +/* @} */ + +/** @name Linear QSPI Status Register + * + * This register contains various status bits of the Linear QSPI controller. + * Read/Write. + * + * @{ + */ +#define XQSPIPS_LQSPI_SR_D_FSM_ERR_MASK 0x00000004 /**< AXI Data FSM Error + received */ +#define XQSPIPS_LQSPI_SR_WR_RECVD_MASK 0x00000002 /**< AXI write command + received */ +/* @} */ + + +/** @name Loopback Delay Adjust Register + * + * This register contains various bit masks of Loopback Delay Adjust Register. + * + * @{ + */ + +#define XQSPIPS_LPBK_DLY_ADJ_USE_LPBK_MASK 0x00000020 /**< Loopback Bit */ + +/* @} */ + + +/** @name SLCR Register + * + * Register offsets from SLCR base address. + * + * @{ + */ + +#define SLCR_LOCK 0x00000004 /**< SLCR Write Protection Lock */ +#define SLCR_UNLOCK 0x00000008 /**< SLCR Write Protection Unlock */ +#define LQSPI_RST_CTRL 0x00000230 /**< Quad SPI Software Reset Control */ +#define SLCR_LOCKSTA 0x0000000C /**< SLCR Write Protection status */ + +/* @} */ + + +/** @name SLCR Register + * + * Bit Masks of above SLCR Registers . + * + * @{ + */ + +#ifndef XPAR_XSLCR_0_BASEADDR +#define XPAR_XSLCR_0_BASEADDR 0xF8000000 +#endif +#define SLCR_LOCK_MASK 0x767B /**< Write Protection Lock mask*/ +#define SLCR_UNLOCK_MASK 0xDF0D /**< SLCR Write Protection Unlock */ +#define LQSPI_RST_CTRL_MASK 0x3 /**< Quad SPI Software Reset Control */ + +/* @} */ + + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +#define XQspiPs_In32 Xil_In32 +#define XQspiPs_Out32 Xil_Out32 +#define XQSPIPS_DUMMY_TX_DATA 0xFFFFFFFF + +/****************************************************************************/ +/** +* Read a register. +* +* @param BaseAddress contains the base address of the device. +* @param RegOffset contains the offset from the 1st register of the +* device to the target register. +* +* @return The value read from the register. +* +* @note C-Style signature: +* u32 XQspiPs_ReadReg(u32 BaseAddress. int RegOffset) +* +******************************************************************************/ +#define XQspiPs_ReadReg(BaseAddress, RegOffset) \ + XQspiPs_In32((BaseAddress) + (RegOffset)) + +/***************************************************************************/ +/** +* Write to a register. +* +* @param BaseAddress contains the base address of the device. +* @param RegOffset contains the offset from the 1st register of the +* device to target register. +* @param RegisterValue is the value to be written to the register. +* +* @return None. +* +* @note C-Style signature: +* void XQspiPs_WriteReg(u32 BaseAddress, int RegOffset, +* u32 RegisterValue) +* +******************************************************************************/ +#define XQspiPs_WriteReg(BaseAddress, RegOffset, RegisterValue) \ + XQspiPs_Out32((BaseAddress) + (RegOffset), (RegisterValue)) + +/************************** Function Prototypes ******************************/ + +/* + * Functions implemented in xqspips_hw.c + */ +void XQspiPs_ResetHw(u32 BaseAddress); +void XQspiPs_LinearInit(u32 BaseAddress); + +/************************** Variable Definitions *****************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips_options.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips_options.c new file mode 100644 index 0000000..14d0ca0 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips_options.c @@ -0,0 +1,426 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2019 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xqspips_options.c +* @addtogroup qspips_v3_6 +* @{ +* +* Contains functions for the configuration of the XQspiPs driver component. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who Date     Changes
+* ----- --- -------- -----------------------------------------------
+* 1.00  sdm 11/25/10 First release
+* 2.00a kka 07/25/12 Removed the selection for the following options:
+*		     Master mode (XQSPIPS_MASTER_OPTION) and
+*		     Flash interface mode (XQSPIPS_FLASH_MODE_OPTION) option
+*		     as the QSPI driver supports the Master mode
+*		     and Flash Interface mode. The driver doesnot support
+*		     Slave mode or the legacy mode.
+* 		     Added the option for setting the Holdb_dr bit in the
+*		     configuration options, XQSPIPS_HOLD_B_DRIVE_OPTION
+*		     is the option to be used for setting this bit in the
+*		     configuration register.
+* 2.01a sg  02/03/13 SetDelays and GetDelays API's include DelayNss parameter.
+*
+* 2.02a hk  26/03/13 Removed XQspi_Reset() in Set_Options() function when
+*			 LQSPI_MODE_OPTION is set. Moved Enable() to XQpsiPs_LqspiRead().
+* 3.3   sk  11/07/15 Modified the API prototypes according to MISRAC standards
+*                    to remove compilation warnings. CR# 868893.
+*
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xqspips.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/************************** Variable Definitions *****************************/ + +/* + * Create the table of options which are processed to get/set the device + * options. These options are table driven to allow easy maintenance and + * expansion of the options. + */ +typedef struct { + u32 Option; + u32 Mask; +} OptionsMap; + +static OptionsMap OptionsTable[] = { + {XQSPIPS_CLK_ACTIVE_LOW_OPTION, XQSPIPS_CR_CPOL_MASK}, + {XQSPIPS_CLK_PHASE_1_OPTION, XQSPIPS_CR_CPHA_MASK}, + {XQSPIPS_FORCE_SSELECT_OPTION, XQSPIPS_CR_SSFORCE_MASK}, + {XQSPIPS_MANUAL_START_OPTION, XQSPIPS_CR_MANSTRTEN_MASK}, + {XQSPIPS_HOLD_B_DRIVE_OPTION, XQSPIPS_CR_HOLD_B_MASK}, +}; + +#define XQSPIPS_NUM_OPTIONS (sizeof(OptionsTable) / sizeof(OptionsMap)) + +/*****************************************************************************/ +/** +* +* This function sets the options for the QSPI device driver. The options control +* how the device behaves relative to the QSPI bus. The device must be idle +* rather than busy transferring data before setting these device options. +* +* @param InstancePtr is a pointer to the XQspiPs instance. +* @param Options contains the specified options to be set. This is a bit +* mask where a 1 means to turn the option on, and a 0 means to +* turn the option off. One or more bit values may be contained in +* the mask. See the bit definitions named XQSPIPS_*_OPTIONS in +* the file xqspips.h. +* +* @return +* - XST_SUCCESS if options are successfully set. +* - XST_DEVICE_BUSY if the device is currently transferring data. +* The transfer must complete or be aborted before setting options. +* +* @note +* This function is not thread-safe. +* +******************************************************************************/ +s32 XQspiPs_SetOptions(XQspiPs *InstancePtr, u32 Options) +{ + u32 ConfigReg; + unsigned int Index; + u32 QspiOptions; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Do not allow to modify the Control Register while a transfer is in + * progress. Not thread-safe. + */ + if (InstancePtr->IsBusy) { + return XST_DEVICE_BUSY; + } + + QspiOptions = Options & XQSPIPS_LQSPI_MODE_OPTION; + Options &= ~XQSPIPS_LQSPI_MODE_OPTION; + + ConfigReg = XQspiPs_ReadReg(InstancePtr->Config.BaseAddress, + XQSPIPS_CR_OFFSET); + + /* + * Loop through the options table, turning the option on or off + * depending on whether the bit is set in the incoming options flag. + */ + for (Index = 0; Index < XQSPIPS_NUM_OPTIONS; Index++) { + if (Options & OptionsTable[Index].Option) { + /* Turn it on */ + ConfigReg |= OptionsTable[Index].Mask; + } else { + /* Turn it off */ + ConfigReg &= ~(OptionsTable[Index].Mask); + } + } + + /* + * Now write the control register. Leave it to the upper layers + * to restart the device. + */ + XQspiPs_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPS_CR_OFFSET, + ConfigReg); + + /* + * Check for the LQSPI configuration options. + */ + ConfigReg = XQspiPs_ReadReg(InstancePtr->Config.BaseAddress, + XQSPIPS_LQSPI_CR_OFFSET); + + + if (QspiOptions & XQSPIPS_LQSPI_MODE_OPTION) { + XQspiPs_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPS_LQSPI_CR_OFFSET, + XQSPIPS_LQSPI_CR_RST_STATE); + XQspiPs_SetSlaveSelect(InstancePtr); + } else { + ConfigReg &= ~XQSPIPS_LQSPI_CR_LINEAR_MASK; + XQspiPs_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPS_LQSPI_CR_OFFSET, ConfigReg); + } + + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** +* +* This function gets the options for the QSPI device. The options control how +* the device behaves relative to the QSPI bus. +* +* @param InstancePtr is a pointer to the XQspiPs instance. +* +* @return +* +* Options contains the specified options currently set. This is a bit value +* where a 1 means the option is on, and a 0 means the option is off. +* See the bit definitions named XQSPIPS_*_OPTIONS in file xqspips.h. +* +* @note None. +* +******************************************************************************/ +u32 XQspiPs_GetOptions(XQspiPs *InstancePtr) +{ + u32 OptionsFlag = 0; + u32 ConfigReg; + unsigned int Index; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Get the current options from QSPI configuration register. + */ + ConfigReg = XQspiPs_ReadReg(InstancePtr->Config.BaseAddress, + XQSPIPS_CR_OFFSET); + + /* + * Loop through the options table to grab options + */ + for (Index = 0; Index < XQSPIPS_NUM_OPTIONS; Index++) { + if (ConfigReg & OptionsTable[Index].Mask) { + OptionsFlag |= OptionsTable[Index].Option; + } + } + + /* + * Check for the LQSPI configuration options. + */ + ConfigReg = XQspiPs_ReadReg(InstancePtr->Config.BaseAddress, + XQSPIPS_LQSPI_CR_OFFSET); + + if ((ConfigReg & XQSPIPS_LQSPI_CR_LINEAR_MASK) != 0) { + OptionsFlag |= XQSPIPS_LQSPI_MODE_OPTION; + } + + return OptionsFlag; +} + +/*****************************************************************************/ +/** +* +* This function sets the clock prescaler for an QSPI device. The device +* must be idle rather than busy transferring data before setting these device +* options. +* +* @param InstancePtr is a pointer to the XQspiPs instance. +* @param Prescaler is the value that determine how much the clock should +* be divided by. Use the XQSPIPS_CLK_PRESCALE_* constants defined +* in xqspips.h for this setting. +* +* @return +* - XST_SUCCESS if options are successfully set. +* - XST_DEVICE_BUSY if the device is currently transferring data. +* The transfer must complete or be aborted before setting options. +* +* @note +* This function is not thread-safe. +* +******************************************************************************/ +s32 XQspiPs_SetClkPrescaler(XQspiPs *InstancePtr, u8 Prescaler) +{ + u32 ConfigReg; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid(Prescaler <= XQSPIPS_CR_PRESC_MAXIMUM); + + /* + * Do not allow the slave select to change while a transfer is in + * progress. Not thread-safe. + */ + if (InstancePtr->IsBusy) { + return XST_DEVICE_BUSY; + } + + /* + * Read the configuration register, mask out the interesting bits, and set + * them with the shifted value passed into the function. Write the + * results back to the configuration register. + */ + ConfigReg = XQspiPs_ReadReg(InstancePtr->Config.BaseAddress, + XQSPIPS_CR_OFFSET); + + ConfigReg &= ~XQSPIPS_CR_PRESC_MASK; + ConfigReg |= (u32) (Prescaler & XQSPIPS_CR_PRESC_MAXIMUM) << + XQSPIPS_CR_PRESC_SHIFT; + + XQspiPs_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPS_CR_OFFSET, + ConfigReg); + + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** +* +* This function gets the clock prescaler of an QSPI device. +* +* @param InstancePtr is a pointer to the XQspiPs instance. +* +* @return The prescaler value. +* +* @note None. +* +* +******************************************************************************/ +u8 XQspiPs_GetClkPrescaler(XQspiPs *InstancePtr) +{ + u32 ConfigReg; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + ConfigReg = XQspiPs_ReadReg(InstancePtr->Config.BaseAddress, + XQSPIPS_CR_OFFSET); + + ConfigReg &= XQSPIPS_CR_PRESC_MASK; + + return (u8)(ConfigReg >> XQSPIPS_CR_PRESC_SHIFT); +} + +/*****************************************************************************/ +/** +* +* This function sets the delay register for the QSPI device driver. +* The delay register controls the Delay Between Transfers, Delay After +* Transfers, and the Delay Initially. The default value is 0x0. The range of +* each delay value is 0-255. +* +* @param InstancePtr is a pointer to the XQspiPs instance. +* @param DelayNss is the delay to de-assert slave select between +* two word transfers. +* @param DelayBtwn is the delay between one Slave Select being +* de-activated and the activation of another slave. The delay is +* the number of master clock periods given by DelayBtwn + 2. +* @param DelayAfter define the delay between the last bit of the current +* byte transfer and the first bit of the next byte transfer. +* The delay in number of master clock periods is given as: +* CHPA=0:DelayInit+DelayAfter+3 +* CHPA=1:DelayAfter+1 +* @param DelayInit is the delay between asserting the slave select signal +* and the first bit transfer. The delay int number of master clock +* periods is DelayInit+1. +* +* @return +* - XST_SUCCESS if delays are successfully set. +* - XST_DEVICE_BUSY if the device is currently transferring data. +* The transfer must complete or be aborted before setting options. +* +* @note None. +* +******************************************************************************/ +int XQspiPs_SetDelays(XQspiPs *InstancePtr, u8 DelayNss, u8 DelayBtwn, + u8 DelayAfter, u8 DelayInit) +{ + u32 DelayRegister; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Do not allow the delays to change while a transfer is in + * progress. Not thread-safe. + */ + if (InstancePtr->IsBusy) { + return XST_DEVICE_BUSY; + } + + /* Shift, Mask and OR the values to build the register settings */ + DelayRegister = (u32) DelayNss << XQSPIPS_DR_NSS_SHIFT; + DelayRegister |= (u32) DelayBtwn << XQSPIPS_DR_BTWN_SHIFT; + DelayRegister |= (u32) DelayAfter << XQSPIPS_DR_AFTER_SHIFT; + DelayRegister |= (u32) DelayInit; + + XQspiPs_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPS_DR_OFFSET, DelayRegister); + + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** +* +* This function gets the delay settings for an QSPI device. +* The delay register controls the Delay Between Transfers, Delay After +* Transfers, and the Delay Initially. The default value is 0x0. +* +* @param InstancePtr is a pointer to the XQspiPs instance. +* @param DelayNss is a pointer to the Delay to de-assert slave select +* between two word transfers. +* @param DelayBtwn is a pointer to the Delay Between transfers value. +* This is a return parameter. +* @param DelayAfter is a pointer to the Delay After transfer value. +* This is a return parameter. +* @param DelayInit is a pointer to the Delay Initially value. This is +* a return parameter. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XQspiPs_GetDelays(XQspiPs *InstancePtr, u8 *DelayNss, u8 *DelayBtwn, + u8 *DelayAfter, u8 *DelayInit) +{ + u32 DelayRegister; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + DelayRegister = XQspiPs_ReadReg(InstancePtr->Config.BaseAddress, + XQSPIPS_DR_OFFSET); + + *DelayInit = (u8)(DelayRegister & XQSPIPS_DR_INIT_MASK); + + *DelayAfter = (u8)((DelayRegister & XQSPIPS_DR_AFTER_MASK) >> + XQSPIPS_DR_AFTER_SHIFT); + + *DelayBtwn = (u8)((DelayRegister & XQSPIPS_DR_BTWN_MASK) >> + XQSPIPS_DR_BTWN_SHIFT); + + *DelayNss = (u8)((DelayRegister & XQSPIPS_DR_NSS_MASK) >> + XQSPIPS_DR_NSS_SHIFT); +} +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips_selftest.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips_selftest.c new file mode 100644 index 0000000..c72e952 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips_selftest.c @@ -0,0 +1,135 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2019 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xqspips_selftest.c +* @addtogroup qspips_v3_6 +* @{ +* +* This file contains the implementation of selftest function for the QSPI +* device. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who Date     Changes
+* ----- --- -------- -----------------------------------------------
+* 1.00  sdm 11/25/10 First release
+* 2.01a sg  02/03/13 Delay Register test is added with DelayNss parameter.
+* 3.1   hk  06/19/14 Remove checks for CR and ISR register values as they are
+*                    reset in the previous step.
+*
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xqspips.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/************************** Variable Definitions *****************************/ + +/*****************************************************************************/ +/** +* +* Runs a self-test on the driver/device. The self-test is destructive in that +* a reset of the device is performed in order to check the reset values of +* the registers and to get the device into a known state. +* +* Upon successful return from the self-test, the device is reset. +* +* @param InstancePtr is a pointer to the XQspiPs instance. +* +* @return +* - XST_SUCCESS if successful +* - XST_REGISTER_ERROR indicates a register did not read or write +* correctly. +* +* @note None. +* +******************************************************************************/ +int XQspiPs_SelfTest(XQspiPs *InstancePtr) +{ + int Status; + u8 DelayTestNss; + u8 DelayTestBtwn; + u8 DelayTestAfter; + u8 DelayTestInit; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Reset the QSPI device to leave it in a known good state + */ + XQspiPs_Reset(InstancePtr); + + DelayTestNss = 0x5A; + DelayTestBtwn = 0xA5; + DelayTestAfter = 0xAA; + DelayTestInit = 0x55; + + /* + * Write and read the delay register, just to be sure there is some + * hardware out there. + */ + Status = XQspiPs_SetDelays(InstancePtr, DelayTestNss, DelayTestBtwn, + DelayTestAfter, DelayTestInit); + if (Status != XST_SUCCESS) { + return Status; + } + + XQspiPs_GetDelays(InstancePtr, &DelayTestNss, &DelayTestBtwn, + &DelayTestAfter, &DelayTestInit); + if ((0x5A != DelayTestNss) || (0xA5 != DelayTestBtwn) || + (0xAA != DelayTestAfter) || (0x55 != DelayTestInit)) { + return XST_REGISTER_ERROR; + } + + Status = XQspiPs_SetDelays(InstancePtr, 0, 0, 0, 0); + if (Status != XST_SUCCESS) { + return Status; + } + + /* + * Reset the QSPI device to leave it in a known good state + */ + XQspiPs_Reset(InstancePtr); + + return XST_SUCCESS; +} +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips_sinit.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips_sinit.c new file mode 100644 index 0000000..da2dc1e --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips_sinit.c @@ -0,0 +1,96 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2019 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xqspips_sinit.c +* @addtogroup qspips_v3_6 +* @{ +* +* The implementation of the XQspiPs component's static initialization +* functionality. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who Date     Changes
+* ----- --- -------- -----------------------------------------------
+* 1.00  sdm 11/25/10 First release
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xstatus.h" +#include "xqspips.h" +#include "xparameters.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/************************** Variable Definitions *****************************/ + +extern XQspiPs_Config XQspiPs_ConfigTable[]; + +/*****************************************************************************/ +/** +* +* Looks up the device configuration based on the unique device ID. A table +* contains the configuration info for each device in the system. +* +* @param DeviceId contains the ID of the device to look up the +* configuration for. +* +* @return +* +* A pointer to the configuration found or NULL if the specified device ID was +* not found. See xqspips.h for the definition of XQspiPs_Config. +* +* @note None. +* +******************************************************************************/ +XQspiPs_Config *XQspiPs_LookupConfig(u16 DeviceId) +{ + XQspiPs_Config *CfgPtr = NULL; + int Index; + + for (Index = 0; Index < XPAR_XQSPIPS_NUM_INSTANCES; Index++) { + if (XQspiPs_ConfigTable[Index].DeviceId == DeviceId) { + CfgPtr = &XQspiPs_ConfigTable[Index]; + break; + } + } + return CfgPtr; +} +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/Makefile b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/Makefile new file mode 100644 index 0000000..04867a4 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/Makefile @@ -0,0 +1,40 @@ +COMPILER= +ARCHIVER= +CP=cp +COMPILER_FLAGS= +EXTRA_COMPILER_FLAGS= +LIB=libxil.a + +CC_FLAGS = $(COMPILER_FLAGS) +ECC_FLAGS = $(EXTRA_COMPILER_FLAGS) + +RELEASEDIR=../../../lib +INCLUDEDIR=../../../include +INCLUDES=-I./. -I${INCLUDEDIR} + +OUTS = *.o + +LIBSOURCES:=*.c +INCLUDEFILES:=*.h + +OBJECTS = $(addsuffix .o, $(basename $(wildcard *.c))) + +libs: banner scugic_libs clean + +%.o: %.c + ${COMPILER} $(CC_FLAGS) $(ECC_FLAGS) $(INCLUDES) -o $@ $< + +banner: + echo "Compiling scugic" + +scugic_libs: ${OBJECTS} + $(ARCHIVER) -r ${RELEASEDIR}/${LIB} ${OBJECTS} + +.PHONY: include +include: scugic_includes + +scugic_includes: + ${CP} ${INCLUDEFILES} ${INCLUDEDIR} + +clean: + rm -rf ${OBJECTS} diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic.c new file mode 100644 index 0000000..8a73638 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic.c @@ -0,0 +1,1133 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xscugic.c +* @addtogroup scugic_v4_0 +* @{ +* +* Contains required functions for the XScuGic driver for the Interrupt +* Controller. See xscugic.h for a detailed description of the driver. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- --------------------------------------------------------
+* 1.00a drg  01/19/10 First release
+* 1.01a sdm  11/09/11 Changes are made in function XScuGic_CfgInitialize
+*                     Since entry is now made as pointer in the XScuGic
+*                     structure, necessary changes are made.
+*                     The HandlerTable can now be populated through the low
+*                     level routine XScuGic_RegisterHandler added in this
+*                     release. Hence necessary checks are added not to
+*                     overwrite the HandlerTable entriesin function
+*                     XScuGic_CfgInitialize.
+* 1.03a srt  02/27/13 Added APIs
+*                       -XScuGic_SetPriTrigTypeByDistAddr()
+*                       -XScuGic_GetPriTrigTypeByDistAddr()
+*                     Removed Offset calculation macros, defined in _hw.h
+*                     (CR 702687)
+*                     added support to direct interrupts  to the appropriate
+*                     CPU Earlier interrupts were directed to CPU1
+*                     (hard coded).Now depending upon the CPU selected by the
+*                     user(xparameters.h), interrupts will be directed to
+*                     the  relevant CPU. This fixes CR 699688.
+*
+* 1.04a hk   05/04/13 Assigned EffectiveAddr to CpuBaseAddress in
+*                     XScuGic_CfgInitialize. Fix for CR#704400 to remove
+*                     warnings.
+*                     Moved functions XScuGic_SetPriTrigTypeByDistAddr and
+*                    XScuGic_GetPriTrigTypeByDistAddr to xscugic_hw.c.
+*                    This is fix for CR#705621.
+* 1.06a asa  16/11/13 Fix for CR#749178. Assignment for EffectiveAddr
+*                     in function XScuGic_CfgInitialize is removed as it was
+*                     a bug.
+* 3.00  kvn  02/13/14 Modified code for MISRA-C:2012 compliance.
+* 3.01  pkp  06/19/15 Added XScuGic_InterruptMaptoCpu API for an interrupt
+*                     target CPU mapping
+* 3.02  pkp  11/09/15 Modified DistributorInit function for AMP case to add
+*                     the current cpu to interrupt processor targets registers
+* 3.2   asa  02/29/16 Modified DistributorInit function for Zynq AMP case. The
+*                     distributor is left uninitialized for Zynq AMP. It is
+*                     assumed that the distributor will be initialized by
+*                     Linux master. However for CortexR5 case, the earlier code
+*                     is left unchanged where the the interrupt processor target
+*                     registers in the distributor is initialized with the
+*                     corresponding CPU ID on which the application built over
+*                     the scugic driver runs. These changes fix CR#937243.
+* 3.3   pkp  05/12/16 Modified XScuGic_InterruptMaptoCpu to write proper value
+*                     to interrupt target register to fix CR#951848
+*
+* 3.4   asa  04/07/16 Created a new static function DoDistributorInit to
+*                     simplify the flow and avoid code duplication. Changes are
+*                     made for USE_AMP use case for R5. In a scenario
+*                     (in R5 split mode) when one R5 is operating with A53 in
+*                     open amp config and other R5 running baremetal app, the
+*                     existing code had the potential to stop the whole AMP
+*                     solution to work(if for some reason the R5 running the
+*                     baremetal app tasked to initialize the Distributor hangs
+*                     or crashes before initializing).Changes are made so that
+*                     the R5 under AMP first checks if the distributor is
+*                     enabled or not and if not, it does the standard
+*                     Distributor initialization.This fixes the CR#952962.
+* 3.4   mus  09/08/16 Added assert to avoid invalid access of GIC from CPUID 1
+*                     for single core zynq-7000s
+* 3.5   mus  10/05/16 Modified DistributorInit function to avoid
+*                     re-initialization of distributor, If it is already
+*                     initialized by other CPU.
+* 3.5   pkp  10/17/16 Modified XScuGic_InterruptMaptoCpu to correct the CPU Id
+*                     value and properly mask interrupt target processor value
+*                     to modify interrupt target processor register for a given
+*                     interrupt ID and cpu ID
+* 3.6   pkp  20/01/17 Added new API XScuGic_Stop to Disable distributor and
+*                     interrupts in case they are being used only by current
+*                     cpu. It also removes current cpu from interrupt target
+*                     registers for all interrupts.
+*       kvn  02/17/17 Add support for changing GIC CPU master at run time.
+*       kvn  02/28/17 Make the CpuId as static variable and Added new
+*                     XScugiC_GetCpuId to access CpuId.
+* 3.9   mus  02/21/18 Added new API's XScuGic_UnmapAllInterruptsFromCpu and
+*                     XScuGic_InterruptUnmapFromCpu, These API's can be used
+*                     by applications to unmap specific/all interrupts from
+*                     target CPU. It fixes CR#992490.
+* 3.10  mus  07/17/18 Updated file to fix the various coding style issues
+*                     reported by checkpatch. It fixes CR#1006344.
+* 3.10  aru  08/23/18 Resolved MISRA-C:2012 compliance mandatory violations
+*                     It fixes CR#1007753.
+* 3.10  mus  09/19/18 Fix cppcheck warnings
+* 4.0   mus  11/22/18 Fixed bugs in software interrupt generation through 
+*                      XScuGic_SoftwareIntr API
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ +#include "xil_types.h" +#include "xil_assert.h" +#include "xscugic.h" + +/************************** Constant Definitions *****************************/ + + +/**************************** Type Definitions *******************************/ + + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Variable Definitions *****************************/ +static u32 CpuId = XPAR_CPU_ID; /**< CPU Core identifier */ + +/************************** Function Prototypes ******************************/ + +static void StubHandler(void *CallBackRef); + +/*****************************************************************************/ +/** +* +* DoDistributorInit initializes the distributor of the GIC. The +* initialization entails: +* +* - Write the trigger mode, priority and target CPU +* - All interrupt sources are disabled +* - Enable the distributor +* +* @param InstancePtr is a pointer to the XScuGic instance. +* @param CpuID is the Cpu ID to be initialized. +* +* @return None +* +* @note None. +* +******************************************************************************/ +static void DoDistributorInit(XScuGic *InstancePtr, u32 CpuID) +{ + u32 Int_Id; +#if !defined (versal) || defined (ARMR5) + u32 LocalCpuID = CpuID; +#endif + +#if defined (versal) && !defined(ARMR5) + u32 temp; + + temp = XScuGic_DistReadReg(InstancePtr, XSCUGIC_DIST_EN_OFFSET); + temp = (XSCUGIC500_DCTLR_ARE_NS_ENABLE | XSCUGIC500_DCTLR_ARE_S_ENABLE); + temp &= ~(XSCUGIC_EN_INT_MASK); + XScuGic_DistWriteReg(InstancePtr, XSCUGIC_DIST_EN_OFFSET, temp); +#else + XScuGic_DistWriteReg(InstancePtr, XSCUGIC_DIST_EN_OFFSET, 0U); +#endif + + /* + * Set the security domains in the int_security registers for + * non-secure interrupts + * All are secure, so leave at the default. Set to 1 for non-secure + * interrupts. + */ + + /* + * For the Shared Peripheral Interrupts INT_ID[MAX..32], set: + */ + + /* + * 1. The trigger mode in the int_config register + * Only write to the SPI interrupts, so start at 32 + */ + for (Int_Id = 32U; Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS; + Int_Id = Int_Id+16U) { + /* + * Each INT_ID uses two bits, or 16 INT_ID per register + * Set them all to be level sensitive, active HIGH. + */ + XScuGic_DistWriteReg(InstancePtr, + XSCUGIC_INT_CFG_OFFSET_CALC(Int_Id), + 0U); + } + + +#define DEFAULT_PRIORITY 0xa0a0a0a0U + for (Int_Id = 0U; Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS; + Int_Id = Int_Id+4U) { + /* + * 2. The priority using int the priority_level register + * The priority_level and spi_target registers use one byte per + * INT_ID. + * Write a default value that can be changed elsewhere. + */ + XScuGic_DistWriteReg(InstancePtr, + XSCUGIC_PRIORITY_OFFSET_CALC(Int_Id), + DEFAULT_PRIORITY); + } + +#if defined (versal) && !defined(ARMR5) +for (Int_Id = 32U; Int_IdBaseAddress for this parameters, passing the physical +* address instead. +* +* @return +* - XST_SUCCESS if initialization was successful +* +* @note None. +* +******************************************************************************/ +s32 XScuGic_CfgInitialize(XScuGic *InstancePtr, + XScuGic_Config *ConfigPtr, + u32 EffectiveAddr) +{ + u32 Int_Id; + u32 Cpu_Id = CpuId + (u32)1; + (void) EffectiveAddr; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(ConfigPtr != NULL); + /* + * Detect Zynq-7000 base silicon configuration,Dual or Single CPU. + * If it is single CPU cnfiguration then invoke assert for CPU ID=1 + */ +#ifdef ARMA9 + if (XPAR_CPU_ID == 0x01) { + Xil_AssertNonvoid((Xil_In32(XPS_EFUSE_BASEADDR + + EFUSE_STATUS_OFFSET) & EFUSE_STATUS_CPU_MASK) == 0); + } +#endif + + if(InstancePtr->IsReady != XIL_COMPONENT_IS_READY) { + + InstancePtr->IsReady = 0U; + InstancePtr->Config = ConfigPtr; + + + for (Int_Id = 0U; Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS; + Int_Id++) { + /* + * Initalize the handler to point to a stub to handle an + * interrupt which has not been connected to a handler + * Only initialize it if the handler is 0 which means it + * was not initialized statically by the tools/user. Set + * the callback reference to this instance so that + * unhandled interrupts can be tracked. + */ + if ((InstancePtr->Config->HandlerTable[Int_Id].Handler + == (Xil_InterruptHandler)NULL)) { + InstancePtr->Config->HandlerTable[Int_Id].Handler + = (Xil_InterruptHandler)StubHandler; + } + InstancePtr->Config->HandlerTable[Int_Id].CallBackRef = + InstancePtr; + } +#if defined (versal) && !defined(ARMR5) + u32 Waker_State; + xil_printf("Execuing on the a72\n"); + Waker_State = XScuGic_ReDistReadReg(InstancePtr,XSCUGIC_RDIST_WAKER_OFFSET); + XScuGic_ReDistWriteReg(InstancePtr,XSCUGIC_RDIST_WAKER_OFFSET, + Waker_State & (~ XSCUGIC_RDIST_WAKER_LOW_POWER_STATE_MASK)); + /* Enable system reg interface through ICC_SRE_EL1 */ + #if EL3 + XScuGic_Enable_SystemReg_CPU_Interface_EL3(); + #endif + XScuGic_Enable_SystemReg_CPU_Interface_EL1(); + isb(); +#endif + XScuGic_Stop(InstancePtr); + DistributorInit(InstancePtr, Cpu_Id); +#if defined (versal) && !defined(ARMR5) + XScuGic_set_priority_filter(0xff); +#else + CPUInitialize(InstancePtr); +#endif + + InstancePtr->IsReady = XIL_COMPONENT_IS_READY; + } + + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** +* +* Makes the connection between the Int_Id of the interrupt source and the +* associated handler that is to run when the interrupt is recognized. The +* argument provided in this call as the Callbackref is used as the argument +* for the handler when it is called. +* +* @param InstancePtr is a pointer to the XScuGic instance. +* @param Int_Id contains the ID of the interrupt source and should be +* in the range of 0 to XSCUGIC_MAX_NUM_INTR_INPUTS - 1 +* @param Handler to the handler for that interrupt. +* @param CallBackRef is the callback reference, usually the instance +* pointer of the connecting driver. +* +* @return +* +* - XST_SUCCESS if the handler was connected correctly. +* +* @note +* +* WARNING: The handler provided as an argument will overwrite any handler +* that was previously connected. +* +****************************************************************************/ +s32 XScuGic_Connect(XScuGic *InstancePtr, u32 Int_Id, + Xil_InterruptHandler Handler, void *CallBackRef) +{ + /* + * Assert the arguments + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS); + Xil_AssertNonvoid(Handler != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * The Int_Id is used as an index into the table to select the proper + * handler + */ + InstancePtr->Config->HandlerTable[Int_Id].Handler = (Xil_InterruptHandler)Handler; + InstancePtr->Config->HandlerTable[Int_Id].CallBackRef = CallBackRef; + + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** +* +* Updates the interrupt table with the Null Handler and NULL arguments at the +* location pointed at by the Int_Id. This effectively disconnects that interrupt +* source from any handler. The interrupt is disabled also. +* +* @param InstancePtr is a pointer to the XScuGic instance to be worked on. +* @param Int_Id contains the ID of the interrupt source and should +* be in the range of 0 to XSCUGIC_MAX_NUM_INTR_INPUTS - 1 +* +* @return None. +* +* @note None. +* +****************************************************************************/ +void XScuGic_Disconnect(XScuGic *InstancePtr, u32 Int_Id) +{ + u32 Mask; + + /* + * Assert the arguments + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * The Int_Id is used to create the appropriate mask for the + * desired bit position. Int_Id currently limited to 0 - 31 + */ + Mask = 0x00000001U << (Int_Id % 32U); + + /* + * Disable the interrupt such that it won't occur while disconnecting + * the handler, only disable the specified interrupt id without + * modifying the other interrupt ids + */ + XScuGic_DistWriteReg(InstancePtr, (u32)XSCUGIC_DISABLE_OFFSET + + ((Int_Id / 32U) * 4U), Mask); + + /* + * Disconnect the handler and connect a stub, the callback reference + * must be set to this instance to allow unhandled interrupts to be + * tracked + */ + InstancePtr->Config->HandlerTable[Int_Id].Handler = (Xil_InterruptHandler)StubHandler; + InstancePtr->Config->HandlerTable[Int_Id].CallBackRef = InstancePtr; +} + +/*****************************************************************************/ +/** +* +* Enables the interrupt source provided as the argument Int_Id. Any pending +* interrupt condition for the specified Int_Id will occur after this function is +* called. +* +* @param InstancePtr is a pointer to the XScuGic instance. +* @param Int_Id contains the ID of the interrupt source and should be +* in the range of 0 to XSCUGIC_MAX_NUM_INTR_INPUTS - 1 +* +* @return None. +* +* @note None. +* +****************************************************************************/ +void XScuGic_Enable(XScuGic *InstancePtr, u32 Int_Id) +{ + u32 Mask; +#if defined (versal) && !defined(ARMR5) + u32 temp; +#endif + /* + * Assert the arguments + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + +#if defined (versal) && !defined(ARMR5) + if (Int_Id < XSCUGIC_SPI_INT_ID_START) + { + + Int_Id &= 0x1f; + Int_Id = 1 << Int_Id; + + temp = XScuGic_ReDistSGIPPIReadReg(InstancePtr,XSCUGIC_RDIST_ISENABLE_OFFSET); + temp |= Int_Id; + XScuGic_ReDistSGIPPIWriteReg(InstancePtr,XSCUGIC_RDIST_ISENABLE_OFFSET,temp); + return; + } +#endif + /* + * The Int_Id is used to create the appropriate mask for the + * desired bit position. Int_Id currently limited to 0 - 31 + */ + Mask = 0x00000001U << (Int_Id % 32U); + + /* + * Enable the selected interrupt source by setting the + * corresponding bit in the Enable Set register. + */ + XScuGic_DistWriteReg(InstancePtr, (u32)XSCUGIC_ENABLE_SET_OFFSET + + ((Int_Id / 32U) * 4U), Mask); +} + +/*****************************************************************************/ +/** +* +* Disables the interrupt source provided as the argument Int_Id such that the +* interrupt controller will not cause interrupts for the specified Int_Id. The +* interrupt controller will continue to hold an interrupt condition for the +* Int_Id, but will not cause an interrupt. +* +* @param InstancePtr is a pointer to the XScuGic instance. +* @param Int_Id contains the ID of the interrupt source and should be +* in the range of 0 to XSCUGIC_MAX_NUM_INTR_INPUTS - 1 +* +* @return None. +* +* @note None. +* +****************************************************************************/ +void XScuGic_Disable(XScuGic *InstancePtr, u32 Int_Id) +{ + u32 Mask; + + /* + * Assert the arguments + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * The Int_Id is used to create the appropriate mask for the + * desired bit position. Int_Id currently limited to 0 - 31 + */ + Mask = 0x00000001U << (Int_Id % 32U); + + /* + * Disable the selected interrupt source by setting the + * corresponding bit in the IDR. + */ + XScuGic_DistWriteReg(InstancePtr, (u32)XSCUGIC_DISABLE_OFFSET + + ((Int_Id / 32U) * 4U), Mask); +} + +/*****************************************************************************/ +/** +* +* Allows software to simulate an interrupt in the interrupt controller. This +* function will only be successful when the interrupt controller has been +* started in simulation mode. A simulated interrupt allows the interrupt +* controller to be tested without any device to drive an interrupt input +* signal into it. +* +* @param InstancePtr is a pointer to the XScuGic instance. +* @param Int_Id is the software interrupt ID to simulate an interrupt. +* @param Cpu_Id is the list of CPUs to send the interrupt. +* +* @return +* +* XST_SUCCESS if successful, or XST_FAILURE if the interrupt could not be +* simulated +* +* @note None. +* +******************************************************************************/ +s32 XScuGic_SoftwareIntr(XScuGic *InstancePtr, u32 Int_Id, u32 Cpu_Id) +{ + u32 Mask; + + /* + * Assert the arguments + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid(Int_Id <= 15U); + Xil_AssertNonvoid(Cpu_Id <= 255U); + +#if defined (versal) && !defined(ARMR5) + Mask = (Cpu_Id | (Int_Id << XSCUGIC_SGIR_EL1_INITID_SHIFT)); +#if EL3 + XScuGic_WriteICC_SGI0R_EL1(Mask); +#else + XScuGic_WriteICC_SGI1R_EL1(Mask); +#endif +#else + + /* + * The Int_Id is used to create the appropriate mask for the + * desired interrupt. Int_Id currently limited to 0 - 15 + * Use the target list for the Cpu ID. + */ + Mask = ((Cpu_Id << 16U) | Int_Id) & + (XSCUGIC_SFI_TRIG_CPU_MASK | XSCUGIC_SFI_TRIG_INTID_MASK); + + /* + * Write to the Software interrupt trigger register. Use the appropriate + * CPU Int_Id. + */ + XScuGic_DistWriteReg(InstancePtr, XSCUGIC_SFI_TRIG_OFFSET, Mask); + + /* Indicate the interrupt was successfully simulated */ +#endif + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** +* +* A stub for the asynchronous callback. The stub is here in case the upper +* layers forget to set the handler. +* +* @param CallBackRef is a pointer to the upper layer callback reference +* +* @return None. +* +* @note None. +* +******************************************************************************/ +static void StubHandler(void *CallBackRef) +{ + /* + * verify that the inputs are valid + */ + Xil_AssertVoid(CallBackRef != NULL); + + /* + * Indicate another unhandled interrupt for stats + */ + ((XScuGic *)((void *)CallBackRef))->UnhandledInterrupts++; +} + +/****************************************************************************/ +/** +* Sets the interrupt priority and trigger type for the specificd IRQ source. +* +* @param InstancePtr is a pointer to the instance to be worked on. +* @param Int_Id is the IRQ source number to modify +* @param Priority is the new priority for the IRQ source. 0 is highest +* priority, 0xF8(248) is lowest. There are 32 priority levels +* supported with a step of 8. Hence the supported priorities are +* 0, 8, 16, 32, 40 ..., 248. +* @param Trigger is the new trigger type for the IRQ source. +* Each bit pair describes the configuration for an INT_ID. +* SFI Read Only b10 always +* PPI Read Only depending on how the PPIs are configured. +* b01 Active HIGH level sensitive +* b11 Rising edge sensitive +* SPI LSB is read only. +* b01 Active HIGH level sensitive +* b11 Rising edge sensitive/ +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XScuGic_SetPriorityTriggerType(XScuGic *InstancePtr, u32 Int_Id, + u8 Priority, u8 Trigger) +{ + u32 RegValue; +#if defined (versal) && !defined(ARMR5) + u32 temp,Index; +#endif + u8 LocalPriority; + LocalPriority = Priority; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid(Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS); + Xil_AssertVoid(Trigger <= (u8)XSCUGIC_INT_CFG_MASK); + Xil_AssertVoid(LocalPriority <= (u8)XSCUGIC_MAX_INTR_PRIO_VAL); +#if defined (versal) && !defined(ARMR5) + if (Int_Id < XSCUGIC_SPI_INT_ID_START ) + { + XScuGic_ReDistSGIPPIWriteReg(InstancePtr,XSCUGIC_RDIST_INT_PRIORITY_OFFSET_CALC(Int_Id),Priority); + temp = XScuGic_ReDistSGIPPIReadReg(InstancePtr,XSCUGIC_RDIST_INT_CONFIG_OFFSET_CALC(Int_Id)); + Index = XScuGic_Get_Rdist_Int_Trigger_Index(Int_Id); + temp |= (Trigger << Index); + XScuGic_ReDistSGIPPIWriteReg(InstancePtr,XSCUGIC_RDIST_INT_CONFIG_OFFSET_CALC(Int_Id),temp); + return; + } +#endif + + /* + * Determine the register to write to using the Int_Id. + */ + RegValue = XScuGic_DistReadReg(InstancePtr, + XSCUGIC_PRIORITY_OFFSET_CALC(Int_Id)); + + /* + * The priority bits are Bits 7 to 3 in GIC Priority Register. This + * means the number of priority levels supported are 32 and they are + * in steps of 8. The priorities can be 0, 8, 16, 32, 48, ... etc. + * The lower order 3 bits are masked before putting it in the register. + */ + LocalPriority = LocalPriority & (u8)XSCUGIC_INTR_PRIO_MASK; + /* + * Shift and Mask the correct bits for the priority and trigger in the + * register + */ + RegValue &= ~(XSCUGIC_PRIORITY_MASK << ((Int_Id%4U)*8U)); + RegValue |= (u32)LocalPriority << ((Int_Id%4U)*8U); + + /* + * Write the value back to the register. + */ + XScuGic_DistWriteReg(InstancePtr, XSCUGIC_PRIORITY_OFFSET_CALC(Int_Id), + RegValue); + + /* + * Determine the register to write to using the Int_Id. + */ + RegValue = XScuGic_DistReadReg(InstancePtr, + XSCUGIC_INT_CFG_OFFSET_CALC(Int_Id)); + + /* + * Shift and Mask the correct bits for the priority and trigger in the + * register + */ + RegValue &= ~(XSCUGIC_INT_CFG_MASK << ((Int_Id%16U)*2U)); + RegValue |= (u32)Trigger << ((Int_Id%16U)*2U); + + /* + * Write the value back to the register. + */ + XScuGic_DistWriteReg(InstancePtr, XSCUGIC_INT_CFG_OFFSET_CALC(Int_Id), + RegValue); + +} + +/****************************************************************************/ +/** +* Gets the interrupt priority and trigger type for the specificd IRQ source. +* +* @param InstancePtr is a pointer to the instance to be worked on. +* @param Int_Id is the IRQ source number to modify +* @param Priority is a pointer to the value of the priority of the IRQ +* source. This is a return value. +* @param Trigger is pointer to the value of the trigger of the IRQ +* source. This is a return value. +* +* @return None. +* +* @note None +* +*****************************************************************************/ +void XScuGic_GetPriorityTriggerType(XScuGic *InstancePtr, u32 Int_Id, + u8 *Priority, u8 *Trigger) +{ + u32 RegValue; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid(Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS); + Xil_AssertVoid(Priority != NULL); + Xil_AssertVoid(Trigger != NULL); + + /* + * Determine the register to read to using the Int_Id. + */ + RegValue = XScuGic_DistReadReg(InstancePtr, + XSCUGIC_PRIORITY_OFFSET_CALC(Int_Id)); + + /* + * Shift and Mask the correct bits for the priority and trigger in the + * register + */ + RegValue = RegValue >> ((Int_Id%4U)*8U); + *Priority = (u8)(RegValue & XSCUGIC_PRIORITY_MASK); + + /* + * Determine the register to read to using the Int_Id. + */ + RegValue = XScuGic_DistReadReg(InstancePtr, + XSCUGIC_INT_CFG_OFFSET_CALC(Int_Id)); + + /* + * Shift and Mask the correct bits for the priority and trigger in the + * register + */ + RegValue = RegValue >> ((Int_Id%16U)*2U); + + *Trigger = (u8)(RegValue & XSCUGIC_INT_CFG_MASK); +} +/****************************************************************************/ +/** +* Sets the target CPU for the interrupt of a peripheral +* +* @param InstancePtr is a pointer to the instance to be worked on. +* @param Cpu_Id is a CPU number for which the interrupt has to be targeted +* @param Int_Id is the IRQ source number to modify +* +* @return None. +* +* @note None +* +*****************************************************************************/ +void XScuGic_InterruptMaptoCpu(XScuGic *InstancePtr, u8 Cpu_Id, u32 Int_Id) +{ + u32 RegValue; + u32 Offset; + RegValue = XScuGic_DistReadReg(InstancePtr, + XSCUGIC_SPI_TARGET_OFFSET_CALC(Int_Id)); + + Offset = (Int_Id & 0x3U); + Cpu_Id = (0x1U << Cpu_Id); + + RegValue = (RegValue & (~(0xFFU << (Offset*8U)))); + RegValue |= ((Cpu_Id) << (Offset*8U)); + + XScuGic_DistWriteReg(InstancePtr, + XSCUGIC_SPI_TARGET_OFFSET_CALC(Int_Id), + RegValue); +} +/****************************************************************************/ +/** +* Unmaps specific SPI interrupt from the target CPU +* +* @param InstancePtr is a pointer to the instance to be worked on. +* @param Cpu_Id is a CPU number from which the interrupt has to be +* unmapped +* @param Int_Id is the IRQ source number to modify +* +* @return None. +* +* @note None +* +*****************************************************************************/ +void XScuGic_InterruptUnmapFromCpu(XScuGic *InstancePtr, u8 Cpu_Id, u32 Int_Id) +{ + u32 RegValue; + u8 BitPos; + + Xil_AssertVoid(InstancePtr != NULL); + + RegValue = XScuGic_DistReadReg(InstancePtr, + XSCUGIC_SPI_TARGET_OFFSET_CALC(Int_Id)); + + /* + * Identify bit position corresponding to Int_Id and Cpu_Id, + * in interrupt target register and clear it + */ + BitPos = ((Int_Id % 4U) * 8U) + Cpu_Id; + RegValue &= (~(1U << BitPos)); + XScuGic_DistWriteReg(InstancePtr, + XSCUGIC_SPI_TARGET_OFFSET_CALC(Int_Id), + RegValue); +} +/****************************************************************************/ +/** +* Unmaps all SPI interrupts from the target CPU +* +* @param InstancePtr is a pointer to the instance to be worked on. +* @param Cpu_Id is a CPU number from which the interrupts has to be +* unmapped +* +* @return None. +* +* @note None +* +*****************************************************************************/ +void XScuGic_UnmapAllInterruptsFromCpu(XScuGic *InstancePtr, u8 Cpu_Id) +{ + u32 Int_Id; + u32 Target_Cpu; + u32 LocalCpuID = (1U << Cpu_Id); + + Xil_AssertVoid(InstancePtr != NULL); + + LocalCpuID |= LocalCpuID << 8U; + LocalCpuID |= LocalCpuID << 16U; + + for (Int_Id = 32U; Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS; + Int_Id = Int_Id+4U) { + + Target_Cpu = XScuGic_DistReadReg(InstancePtr, + XSCUGIC_SPI_TARGET_OFFSET_CALC(Int_Id)); + /* Remove LocalCpuID from interrupt target register */ + Target_Cpu &= (~LocalCpuID); + XScuGic_DistWriteReg(InstancePtr, + XSCUGIC_SPI_TARGET_OFFSET_CALC(Int_Id), Target_Cpu); + + } +} +/****************************************************************************/ +/** +* It checks if the interrupt target register contains all interrupts to be +* targeted for current CPU. If they are programmed to be forwarded to current +* cpu, this API disable all interrupts and disable GIC distributor. +* This API also removes current CPU from interrupt target registers for all +* interrupt. +* +* @param InstancePtr is a pointer to the instance to be worked on. +* +* @return None. +* +* @note None +* +*****************************************************************************/ +void XScuGic_Stop(XScuGic *InstancePtr) +{ + u32 Int_Id; + u32 RegValue; + u32 Target_Cpu; + u32 DistDisable = 1; /* Track distributor status*/ + u32 LocalCpuID = ((u32)0x1 << CpuId); + + Xil_AssertVoid(InstancePtr != NULL); + + /* If distributor is already disabled, no need to do anything */ + RegValue = XScuGic_DistReadReg(InstancePtr, XSCUGIC_DIST_EN_OFFSET); + if ((RegValue & XSCUGIC_EN_INT_MASK) == 0U) { + return; + } + + LocalCpuID |= LocalCpuID << 8U; + LocalCpuID |= LocalCpuID << 16U; + + /* + * Check if the interrupt are targeted to current cpu only or not. + * Also remove current cpu from interrupt target register for all + * interrupts. + */ + for (Int_Id = 32U; Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS; + Int_Id = Int_Id+4U) { + + Target_Cpu = XScuGic_DistReadReg(InstancePtr, + XSCUGIC_SPI_TARGET_OFFSET_CALC(Int_Id)); + if ((Target_Cpu != LocalCpuID) && (Target_Cpu != 0)) { + /* + * If any other CPU is also programmed to target + * register, GIC distributor can not be disabled. + */ + DistDisable = 0; + } + + /* Remove current CPU from interrupt target register */ + Target_Cpu &= (~LocalCpuID); + XScuGic_DistWriteReg(InstancePtr, + XSCUGIC_SPI_TARGET_OFFSET_CALC(Int_Id), Target_Cpu); + + } + + /* + * If GIC distributor is safe to be disabled, disable all the interrupt + * and then disable distributor. + */ + if (DistDisable == 1) { + for (Int_Id = 0U; Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS; + Int_Id = Int_Id+32U) { + /* + * Disable all the interrupts + */ + XScuGic_DistWriteReg(InstancePtr, + XSCUGIC_EN_DIS_OFFSET_CALC(XSCUGIC_DISABLE_OFFSET, + Int_Id), + 0xFFFFFFFFU); + } + XScuGic_DistWriteReg(InstancePtr, XSCUGIC_DIST_EN_OFFSET, 0U); + } +} + +/****************************************************************************/ +/** +* This updates the CpuId global variable. +* +* @param CpuCoreId is the CPU core number. +* +* @return None. +* +* @note None +* +*****************************************************************************/ +void XScuGic_SetCpuID(u32 CpuCoreId) +{ + Xil_AssertVoid(CpuCoreId <= 1U); + + CpuId = CpuCoreId; +} + +/****************************************************************************/ +/** +* This function returns the CpuId variable. +* +* @return The CPU core number. +* +* @note None. +* +*****************************************************************************/ +u32 XScuGic_GetCpuID(void) +{ + return CpuId; +} +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic.h new file mode 100644 index 0000000..5502a20 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic.h @@ -0,0 +1,598 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xscugic.h +* @addtogroup scugic_v4_0 +* @{ +* @details +* +* The generic interrupt controller driver component. +* +* The interrupt controller driver uses the idea of priority for the various +* handlers. Priority is an integer within the range of 1 and 31 inclusive with +* default of 1 being the highest priority interrupt source. The priorities +* of the various sources can be dynamically altered as needed through +* hardware configuration. +* +* The generic interrupt controller supports the following +* features: +* +* - specific individual interrupt enabling/disabling +* - specific individual interrupt acknowledging +* - attaching specific callback function to handle interrupt source +* - assigning desired priority to interrupt source if default is not +* acceptable. +* +* Details about connecting the interrupt handler of the driver are contained +* in the source file specific to interrupt processing, xscugic_intr.c. +* +* This driver is intended to be RTOS and processor independent. It works with +* physical addresses only. Any needs for dynamic memory management, threads +* or thread mutual exclusion, virtual memory, or cache control must be +* satisfied by the layer above this driver. +* +* Interrupt Vector Tables +* +* The device ID of the interrupt controller device is used by the driver as a +* direct index into the configuration data table. The user should populate the +* vector table with handlers and callbacks at run-time using the +* XScuGic_Connect() and XScuGic_Disconnect() functions. +* +* Each vector table entry corresponds to a device that can generate an +* interrupt. Each entry contains an interrupt handler function and an +* argument to be passed to the handler when an interrupt occurs. The +* user must use XScuGic_Connect() when the interrupt handler takes an +* argument other than the base address. +* +* Nested Interrupts Processing +* +* Nested interrupts are not supported by this driver. +* +* NOTE: +* The generic interrupt controller is not a part of the snoop control unit +* as indicated by the prefix "scu" in the name of the driver. +* It is an independent module in APU. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- ---------------------------------------------------------
+* 1.00a drg  01/19/00 First release
+* 1.01a sdm  11/09/11 The XScuGic and XScuGic_Config structures have changed.
+*		      The HandlerTable (of type XScuGic_VectorTableEntry) is
+*		      moved to XScuGic_Config structure from XScuGic structure.
+*
+*		      The "Config" entry in XScuGic structure is made as
+*		      pointer for better efficiency.
+*
+*		      A new file named as xscugic_hw.c is now added. It is
+*		      to implement low level driver routines without using
+*		      any xscugic instance pointer. They are useful when the
+*		      user wants to use xscugic through device id or
+*		      base address. The driver routines provided are explained
+*		      below.
+*		      XScuGic_DeviceInitialize that takes device id as
+*		      argument and initializes the device (without calling
+*		      XScuGic_CfgInitialize).
+*		      XScuGic_DeviceInterruptHandler that takes device id
+*		      as argument and calls appropriate handlers from the
+*		      HandlerTable.
+*		      XScuGic_RegisterHandler that registers a new handler
+*		      by taking xscugic hardware base address as argument.
+*		      LookupConfigByBaseAddress is used to return the
+*		      corresponding config structure from XScuGic_ConfigTable
+*		      based on the scugic base address passed.
+* 1.02a sdm  12/20/11 Removed AckBeforeService from the XScuGic_Config
+*		      structure.
+* 1.03a srt  02/27/13 Moved Offset calculation macros from *.c and *_hw.c to
+*		      *_hw.h
+*		      Added APIs
+*			- XScuGic_SetPriTrigTypeByDistAddr()
+*			- XScuGic_GetPriTrigTypeByDistAddr()
+*		      (CR 702687)
+*			Added support to direct interrupts to the appropriate CPU. Earlier
+*			  interrupts were directed to CPU1 (hard coded). Now depending
+*			  upon the CPU selected by the user (xparameters.h), interrupts
+*			  will be directed to the relevant CPU. This fixes CR 699688.
+* 1.04a hk   05/04/13 Assigned EffectiveAddr to CpuBaseAddress in
+*			  XScuGic_CfgInitialize. Fix for CR#704400 to remove warnings.
+*			  Moved functions XScuGic_SetPriTrigTypeByDistAddr and
+*             XScuGic_GetPriTrigTypeByDistAddr to xscugic_hw.c.
+*			  This is fix for CR#705621.
+* 1.05a hk   06/26/13 Modified tcl to export external interrupts correctly to
+*                     xparameters.h. Fix for CR's 690505, 708928 & 719359.
+* 2.0   adk  12/10/13 Updated as per the New Tcl API's
+* 2.1   adk  25/04/14 Fixed the CR:789373 changes are made in the driver tcl file.
+* 3.00  kvn  02/13/15 Modified code for MISRA-C:2012 compliance.
+* 3.2   asa  02/29/16 Modified DistributorInit function for Zynq AMP case. The
+*			  distributor is left uninitialized for Zynq AMP. It is assumed
+*             that the distributor will be initialized by Linux master. However
+*             for CortexR5 case, the earlier code is left unchanged where the
+*             the interrupt processor target registers in the distributor is
+*             initialized with the corresponding CPU ID on which the application
+*             built over the scugic driver runs.
+*             These changes fix CR#937243.
+*
+* 3.4   asa  04/07/16 Created a new static function DoDistributorInit to simplify
+*            the flow and avoid code duplication. Changes are made for
+*            USE_AMP use case for R5. In a scenario (in R5 split mode) when
+*            one R5 is operating with A53 in open amp config and other
+*            R5 running baremetal app, the existing code
+*            had the potential to stop the whole AMP solution to work (if
+*            for some reason the R5 running the baremetal app tasked to
+*            initialize the Distributor hangs or crashes before initializing).
+*            Changes are made so that the R5 under AMP first checks if
+*            the distributor is enabled or not and if not, it does the
+*            standard Distributor initialization.
+*            This fixes the CR#952962.
+* 3.6   ms   01/23/17 Modified xil_printf statement in main function for all
+*                     examples to ensure that "Successfully ran" and "Failed"
+*                     strings are available in all examples. This is a fix
+*                     for CR-965028.
+*       kvn  02/17/17 Add support for changing GIC CPU master at run time.
+*       kvn  02/28/17 Make the CpuId as static variable and Added new
+*                     XScugiC_GetCpuId to access CpuId.
+*       ms   03/17/17 Added readme.txt file in examples folder for doxygen
+*                     generation.
+* 3.7   ms   04/11/17 Modified tcl file to add suffix U for all macro
+*                     definitions of scugic in xparameters.h
+* 3.8   mus  07/05/17 Updated scugic.tcl to add support for intrrupts connected
+*                     through util_reduced_vector IP(OR gate)
+*       mus  07/05/17 Updated xdefine_zynq_canonical_xpars proc to initialize
+*                     the HandlerTable in XScuGic_ConfigTable to 0, it removes
+*                     the compilation warning in xscugic_g.c. Fix for CR#978736.
+*       mus  07/25/17 Updated xdefine_gic_params proc to export correct canonical
+*                     definitions for pl to ps interrupts.Fix for CR#980534
+* 3.9   mus  02/21/18 Added new API's XScuGic_UnmapAllInterruptsFromCpu and
+*                     XScuGic_InterruptUnmapFromCpu, These API's can be used
+*                     by applications to unmap specific/all interrupts from
+*                     target CPU.
+* 3.10  aru  08/23/18 Resolved MISRA-C:2012 compliance mandatory violations
+* 4.0   mus  11/22/18 Fixed bugs in software interrupt generation through 
+*                      XScuGic_SoftwareIntr API
+*
+* 
+* +******************************************************************************/ + +#ifndef XSCUGIC_H /* prevent circular inclusions */ +#define XSCUGIC_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/***************************** Include Files *********************************/ + +#include "xstatus.h" +#include "xil_io.h" +#include "xscugic_hw.h" +#include "xil_exception.h" + +/************************** Constant Definitions *****************************/ + +#define EFUSE_STATUS_OFFSET 0x10 +#define EFUSE_STATUS_CPU_MASK 0x80 + +#if !defined (ARMR5) && !defined (__aarch64__) && !defined (ARMA53_32) +#define ARMA9 +#endif + +#define XSCUGIC500_DCTLR_ARE_NS_ENABLE 0x20 +#define XSCUGIC500_DCTLR_ARE_S_ENABLE 0x10 +/**************************** Type Definitions *******************************/ + +/* The following data type defines each entry in an interrupt vector table. + * The callback reference is the base address of the interrupting device + * for the low level driver and an instance pointer for the high level driver. + */ +typedef struct +{ + Xil_InterruptHandler Handler; + void *CallBackRef; +} XScuGic_VectorTableEntry; + +/** + * This typedef contains configuration information for the device. + */ +typedef struct +{ + u16 DeviceId; /**< Unique ID of device */ + u32 CpuBaseAddress; /**< CPU Interface Register base address */ + u32 DistBaseAddress; /**< Distributor Register base address */ + XScuGic_VectorTableEntry HandlerTable[XSCUGIC_MAX_NUM_INTR_INPUTS];/**< + Vector table of interrupt handlers */ +} XScuGic_Config; + +/** + * The XScuGic driver instance data. The user is required to allocate a + * variable of this type for every intc device in the system. A pointer + * to a variable of this type is then passed to the driver API functions. + */ +typedef struct +{ + XScuGic_Config *Config; /**< Configuration table entry */ + u32 IsReady; /**< Device is initialized and ready */ + u32 UnhandledInterrupts; /**< Intc Statistics */ +} XScuGic; + +/***************** Macros (Inline Functions) Definitions *********************/ + +/****************************************************************************/ +/** +* +* Write the given CPU Interface register +* +* @param InstancePtr is a pointer to the instance to be worked on. +* @param RegOffset is the register offset to be written +* @param Data is the 32-bit value to write to the register +* +* @return None. +* +* @note +* C-style signature: +* void XScuGic_CPUWriteReg(XScuGic *InstancePtr, u32 RegOffset, u32 Data) +* +*****************************************************************************/ +#define XScuGic_CPUWriteReg(InstancePtr, RegOffset, Data) \ +(XScuGic_WriteReg(((InstancePtr)->Config->CpuBaseAddress), (RegOffset), \ + ((u32)(Data)))) + +/****************************************************************************/ +/** +* +* Read the given CPU Interface register +* +* @param InstancePtr is a pointer to the instance to be worked on. +* @param RegOffset is the register offset to be read +* +* @return The 32-bit value of the register +* +* @note +* C-style signature: +* u32 XScuGic_CPUReadReg(XScuGic *InstancePtr, u32 RegOffset) +* +*****************************************************************************/ +#define XScuGic_CPUReadReg(InstancePtr, RegOffset) \ + (XScuGic_ReadReg(((InstancePtr)->Config->CpuBaseAddress), (RegOffset))) + +/****************************************************************************/ +/** +* +* Write the given Distributor Interface register +* +* @param InstancePtr is a pointer to the instance to be worked on. +* @param RegOffset is the register offset to be written +* @param Data is the 32-bit value to write to the register +* +* @return None. +* +* @note +* C-style signature: +* void XScuGic_DistWriteReg(XScuGic *InstancePtr, u32 RegOffset, u32 Data) +* +*****************************************************************************/ +#define XScuGic_DistWriteReg(InstancePtr, RegOffset, Data) \ +(XScuGic_WriteReg(((InstancePtr)->Config->DistBaseAddress), (RegOffset), \ + ((u32)(Data)))) + +/****************************************************************************/ +/** +* +* Read the given Distributor Interface register +* +* @param InstancePtr is a pointer to the instance to be worked on. +* @param RegOffset is the register offset to be read +* +* @return The 32-bit value of the register +* +* @note +* C-style signature: +* u32 XScuGic_DistReadReg(XScuGic *InstancePtr, u32 RegOffset) +* +*****************************************************************************/ +#define XScuGic_DistReadReg(InstancePtr, RegOffset) \ +(XScuGic_ReadReg(((InstancePtr)->Config->DistBaseAddress), (RegOffset))) + +/****************************************************************************/ +/** +* +* Write the given ReDistributor Interface register +* +* @param InstancePtr is a pointer to the instance to be worked on. +* @param RegOffset is the register offset to be written +* @param Data is the 32-bit value to write to the register +* +* @return None. +* +* @note +* C-style signature: +* void XScuGic_DistWriteReg(XScuGic *InstancePtr, u32 RegOffset, u32 Data) +* +*****************************************************************************/ +#define XScuGic_ReDistWriteReg(InstancePtr, RegOffset, Data) \ +(XScuGic_WriteReg(((InstancePtr)->Config->DistBaseAddress)+ \ + XSCUGIC_RDIST_OFFSET, (RegOffset), ((u32)(Data)))) + +/****************************************************************************/ +/** +* +* Read the given ReDistributor Interface register +* +* @param InstancePtr is a pointer to the instance to be worked on. +* @param RegOffset is the register offset to be read +* +* @return The 32-bit value of the register +* +* @note +* C-style signature: +* u32 XScuGic_DistReadReg(XScuGic *InstancePtr, u32 RegOffset) +* +*****************************************************************************/ +#define XScuGic_ReDistReadReg(InstancePtr, RegOffset) \ +(XScuGic_ReadReg((((InstancePtr)->Config->DistBaseAddress)+ \ +XSCUGIC_RDIST_OFFSET), (RegOffset))) + +/****************************************************************************/ +/** +* +* Write the given ReDistributor SGI PPI Interface register +* +* @param InstancePtr is a pointer to the instance to be worked on. +* @param RegOffset is the register offset to be written +* @param Data is the 32-bit value to write to the register +* +* @return None. +* +* @note +* C-style signature: +* void XScuGic_DistWriteReg(XScuGic *InstancePtr, u32 RegOffset, u32 Data) +* +*****************************************************************************/ +#define XScuGic_ReDistSGIPPIWriteReg(InstancePtr, RegOffset, Data) \ +(XScuGic_WriteReg(((InstancePtr)->Config->DistBaseAddress)+ \ + XSCUGIC_RDIST_SGI_PPI_OFFSET, (RegOffset), ((u32)(Data)))) + +/****************************************************************************/ +/** +* +* Read the given ReDistributor SGI PPI Interface register +* +* @param InstancePtr is a pointer to the instance to be worked on. +* @param RegOffset is the register offset to be read +* +* @return The 32-bit value of the register +* +* @note +* C-style signature: +* u32 XScuGic_DistReadReg(XScuGic *InstancePtr, u32 RegOffset) +* +*****************************************************************************/ +#define XScuGic_ReDistSGIPPIReadReg(InstancePtr, RegOffset) \ +(XScuGic_ReadReg((((InstancePtr)->Config->DistBaseAddress)+ \ + XSCUGIC_RDIST_SGI_PPI_OFFSET), (RegOffset))) + +/****************************************************************************/ +/** +* This function enables system register interface for GIC CPU Interface +* +* @param value to be written +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +#define XScuGic_Enable_SystemReg_CPU_Interface_EL3() mtcp(S3_6_C12_C12_5, 0xF); +#define XScuGic_Enable_SystemReg_CPU_Interface_EL1() mtcp(S3_0_C12_C12_5, 0xF); +/****************************************************************************/ +/** +* This function enables Grou0 interrupts +* +* @param None. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +#define XScuGic_Enable_Group0_Interrupts() mtcp(S3_0_C12_C12_6,0x1); +/****************************************************************************/ +/** +* This function enables Group1 interrupts +* +* @param None. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +#if defined (__aarch64__) +#if EL1_NONSECURE +#define XScuGic_Enable_Group1_Interrupts() \ + mtcp (S3_0_C12_C12_7, 0x1 | mfcp(S3_0_C12_C12_7) ); +#else +#define XScuGic_Enable_Group1_Interrupts() \ + mtcp (S3_6_C12_C12_7, 0x1 | mfcp(S3_6_C12_C12_7) ); +#endif +#endif +/****************************************************************************/ +/** +* This function writes to ICC_SGI0R_EL1 +* +* @param value to be written +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +#define XScuGic_WriteICC_SGI0R_EL1(val) mtcp(S3_0_C12_C11_7,val) + +/****************************************************************************/ +/** +* This function writes to ICC_SGI1R_EL1 +* +* @param value to be written +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +#define XScuGic_WriteICC_SGI1R_EL1(val) mtcp(S3_0_C12_C11_5,val) + +/****************************************************************************/ +/** +* This function reads ICC_SGI1R_EL1 register +* +* @param None +* +* @return Value of ICC_SGI1R_EL1 register +* +* @note None. +* +*****************************************************************************/ +#define XScuGic_ReadICC_SGI1R_EL1() mfcp(S3_0_C12_C11_5) +/****************************************************************************/ +/** +* This function sets interrupt priority filter +* +* @param None. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +#define XScuGic_set_priority_filter(val) __asm__ __volatile__("msr S3_0_C4_C6_0,%0" : : "r" (val)) +/****************************************************************************/ +/** +* This function returns interrupt id of highest priority pending interrupt +* +* @param None. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +#if defined (__aarch64__) +#if EL3 +#define XScuGic_get_IntID() mfcp(S3_0_C12_C8_0) +#else +#define XScuGic_get_IntID() mfcp(S3_0_C12_C12_0) +#endif +#endif +/****************************************************************************/ +/** +* This function acks the interrupt +* +* @param None. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +#if defined (__aarch64__) +#if EL3 +#define XScuGic_ack_Int(val) mtcp(S3_0_C12_C8_1,val) +#else +#define XScuGic_ack_Int(val) mtcp(S3_0_C12_C12_1,val) +#endif +#endif +/****************************************************************************/ +/** +* This macro returns bit position for the specific interrupt's trigger type +* configuration within GICR_ICFGR0/GICR_ICFGR1 register +* +* @param None. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +#define XScuGic_Get_Rdist_Int_Trigger_Index(IntrId) (((Int_Id%16) & 0x1f) << 2) +1 +/************************** Function Prototypes ******************************/ + +/* + * Required functions in xscugic.c + */ + +s32 XScuGic_Connect(XScuGic *InstancePtr, u32 Int_Id, + Xil_InterruptHandler Handler, void *CallBackRef); +void XScuGic_Disconnect(XScuGic *InstancePtr, u32 Int_Id); + +void XScuGic_Enable(XScuGic *InstancePtr, u32 Int_Id); +void XScuGic_Disable(XScuGic *InstancePtr, u32 Int_Id); + +s32 XScuGic_CfgInitialize(XScuGic *InstancePtr, XScuGic_Config *ConfigPtr, + u32 EffectiveAddr); + +s32 XScuGic_SoftwareIntr(XScuGic *InstancePtr, u32 Int_Id, u32 Cpu_Id); + +void XScuGic_GetPriorityTriggerType(XScuGic *InstancePtr, u32 Int_Id, + u8 *Priority, u8 *Trigger); +void XScuGic_SetPriorityTriggerType(XScuGic *InstancePtr, u32 Int_Id, + u8 Priority, u8 Trigger); +void XScuGic_InterruptMaptoCpu(XScuGic *InstancePtr, u8 Cpu_Id, u32 Int_Id); +void XScuGic_InterruptUnmapFromCpu(XScuGic *InstancePtr, u8 Cpu_Id, u32 Int_Id); +void XScuGic_UnmapAllInterruptsFromCpu(XScuGic *InstancePtr, u8 Cpu_Id); +void XScuGic_Stop(XScuGic *InstancePtr); +void XScuGic_SetCpuID(u32 CpuCoreId); +u32 XScuGic_GetCpuID(void); +/* + * Initialization functions in xscugic_sinit.c + */ +XScuGic_Config *XScuGic_LookupConfig(u16 DeviceId); + +/* + * Interrupt functions in xscugic_intr.c + */ +void XScuGic_InterruptHandler(XScuGic *InstancePtr); + +/* + * Self-test functions in xscugic_selftest.c + */ +s32 XScuGic_SelfTest(XScuGic *InstancePtr); + +void XScuGic_EnableSGI_PPI(XScuGic *InstancePtr,u32 ID); +void XScuGic_SetPPI_SGI_Priority(XScuGic *InstancePtr,u32 ID, u32 priority); +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic_g.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic_g.c new file mode 100644 index 0000000..7363203 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic_g.c @@ -0,0 +1,53 @@ + +/******************************************************************* +* +* CAUTION: This file is automatically generated by HSI. +* Version: 2019.1.3 +* DO NOT EDIT. +* +* Copyright (C) 2010-2023 Xilinx, Inc. All Rights Reserved.* +*Permission is hereby granted, free of charge, to any person obtaining a copy +*of this software and associated documentation files (the Software), to deal +*in the Software without restriction, including without limitation the rights +*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +*copies of the Software, and to permit persons to whom the Software is +*furnished to do so, subject to the following conditions: +* +*The above copyright notice and this permission notice shall be included in +*all copies or substantial portions of the Software. +* +*THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +*XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +*OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*Except as contained in this notice, the name of the Xilinx shall not be used +*in advertising or otherwise to promote the sale, use or other dealings in +*this Software without prior written authorization from Xilinx. +* + +* +* Description: Driver configuration +* +*******************************************************************/ + +#include "xparameters.h" +#include "xscugic.h" + +/* +* The configuration table for devices +*/ + +XScuGic_Config XScuGic_ConfigTable[XPAR_XSCUGIC_NUM_INSTANCES] = +{ + { + XPAR_PS7_SCUGIC_0_DEVICE_ID, + XPAR_PS7_SCUGIC_0_BASEADDR, + XPAR_PS7_SCUGIC_0_DIST_BASEADDR, + {{0}} /**< Initialize the HandlerTable to 0 */ + } +}; + + diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic_hw.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic_hw.c new file mode 100644 index 0000000..4193e80 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic_hw.c @@ -0,0 +1,652 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xscugic_hw.c +* @addtogroup scugic_v4_0 +* @{ +* +* This file contains low-level driver functions that can be used to access the +* device. The user should refer to the hardware device specification for more +* details of the device operation. +* These routines are used when the user does not want to create an instance of +* XScuGic structure but still wants to use the ScuGic device. Hence the +* routines provided here take device id or scugic base address as arguments. +* Separate static versions of DistInit and CPUInit are provided to implement +* the low level driver routines. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.01a sdm  07/18/11 First release
+* 1.03a srt  02/27/13 Moved Offset calculation macros from *_hw.c (CR
+*                     702687).
+*                     Added support to direct interrupts to the appropriate
+*                     CPU. Earlier interrupts were directed to CPU1
+*                     (hard coded). Now depending upon the CPU selected by
+*                     the user (xparameters.h), interrupts will be directed
+*                     to the relevant CPU.This fixes CR 699688.
+* 1.04a hk   05/04/13 Fix for CR#705621. Moved functions
+*                     XScuGic_SetPriTrigTypeByDistAddr and
+*                     XScuGic_GetPriTrigTypeByDistAddr here from xscugic.c
+* 3.00  kvn  02/13/15 Modified code for MISRA-C:2012 compliance.
+* 3.6   kvn  02/17/17 Add support for changing GIC CPU master at run time.
+*       kvn  02/28/17 Make the CpuId as static variable and Added new
+*                     XScugiC_GetCpuId to access CpuId.
+* 3.9   mus  02/21/18 Added new API's
+*                     XScuGic_InterruptUnmapFromCpuByDistAddr and
+*                     XScuGic_UnmapAllInterruptsFromCpuByDistAddr, These
+*                     API's can be used by applications to unmap
+*                     specific/all interrupts from target CPU. It fixes
+*                     CR#992490.
+* 3.10  mus  07/17/18 Updated XScuGic_DeviceInterruptHandler to fix array
+*                     overrun reported by coverity tool. It fixes
+*                     CR#1006344.
+* 3.10  mus  07/17/18 Updated file to fix the various coding style issues
+*                     reported by checkpatch. It fixes CR#1006344.
+* 3.10  aru  08/23/18 Resolved MISRA-C:2012 compliance mandatory violations
+*                     It fixes CR#1007753
+* 3.10  mus  09/19/18 Update documentation for XScuGic_RegisterHandler to
+*                     fix doxygen warnings.
+* 
+* +******************************************************************************/ + + +/***************************** Include Files *********************************/ + +#include "xil_types.h" +#include "xil_assert.h" +#include "xscugic.h" +#include "xparameters.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +static void DistInit(XScuGic_Config *Config, u32 CpuID); +static void CPUInit(XScuGic_Config *Config); +static XScuGic_Config *LookupConfigByBaseAddress(u32 CpuBaseAddress); + +/************************** Variable Definitions *****************************/ + +extern XScuGic_Config XScuGic_ConfigTable[XPAR_XSCUGIC_NUM_INSTANCES]; +extern u32 CpuId; + +/*****************************************************************************/ +/** +* +* DistInit initializes the distributor of the GIC. The +* initialization entails: +* +* - Write the trigger mode, priority and target CPU +* - All interrupt sources are disabled +* - Enable the distributor +* +* @param InstancePtr is a pointer to the XScuGic instance. +* @param CpuID is the Cpu ID to be initialized. +* +* @return None +* +* @note None. +* +******************************************************************************/ +static void DistInit(XScuGic_Config *Config, u32 CpuID) +{ + u32 Int_Id; + u32 LocalCpuID = CpuID; + +#if USE_AMP == 1 + #warning "Building GIC for AMP" + + /* + * The distrubutor should not be initialized by FreeRTOS in the case of + * AMP -- it is assumed that Linux is the master of this device in that + * case. + */ + return; +#endif + + XScuGic_WriteReg(Config->DistBaseAddress, XSCUGIC_DIST_EN_OFFSET, 0U); + + /* + * Set the security domains in the int_security registers for non-secure + * interrupts. All are secure, so leave at the default. Set to 1 for + * non-secure interrupts. + */ + + + /* + * For the Shared Peripheral Interrupts INT_ID[MAX..32], set: + */ + + /* + * 1. The trigger mode in the int_config register + * Only write to the SPI interrupts, so start at 32 + */ + for (Int_Id = 32U; Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS; + Int_Id = Int_Id+16U) { + /* + * Each INT_ID uses two bits, or 16 INT_ID per register + * Set them all to be level sensitive, active HIGH. + */ + XScuGic_WriteReg(Config->DistBaseAddress, + XSCUGIC_INT_CFG_OFFSET_CALC(Int_Id), 0U); + } + + +#define DEFAULT_PRIORITY 0xa0a0a0a0U + for (Int_Id = 0U; Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS; + Int_Id = Int_Id+4U) { + /* + * 2. The priority using int the priority_level register + * The priority_level and spi_target registers use one byte per + * INT_ID. + * Write a default value that can be changed elsewhere. + */ + XScuGic_WriteReg(Config->DistBaseAddress, + XSCUGIC_PRIORITY_OFFSET_CALC(Int_Id), + DEFAULT_PRIORITY); + } + + for (Int_Id = 32U; Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS; + Int_Id = Int_Id+4U) { + /* + * 3. The CPU interface in the spi_target register + * Only write to the SPI interrupts, so start at 32 + */ + LocalCpuID |= LocalCpuID << 8U; + LocalCpuID |= LocalCpuID << 16U; + + XScuGic_WriteReg(Config->DistBaseAddress, + XSCUGIC_SPI_TARGET_OFFSET_CALC(Int_Id), LocalCpuID); + } + + for (Int_Id = 0U; Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS; + Int_Id = Int_Id+32U) { + /* + * 4. Enable the SPI using the enable_set register. + * Leave all disabled for now. + */ + XScuGic_WriteReg(Config->DistBaseAddress, + XSCUGIC_EN_DIS_OFFSET_CALC(XSCUGIC_DISABLE_OFFSET, + Int_Id), + 0xFFFFFFFFU); + + } + + XScuGic_WriteReg(Config->DistBaseAddress, XSCUGIC_DIST_EN_OFFSET, + XSCUGIC_EN_INT_MASK); + +} + +/*****************************************************************************/ +/** +* +* CPUInit initializes the CPU Interface of the GIC. The initialization entails: +* +* - Set the priority of the CPU. +* - Enable the CPU interface +* +* @param ConfigPtr is a pointer to a config table for the particular +* device this driver is associated with. +* +* @return None +* +* @note None. +* +******************************************************************************/ +static void CPUInit(XScuGic_Config *Config) +{ + /* + * Program the priority mask of the CPU using the Priority mask + * register + */ + XScuGic_WriteReg(Config->CpuBaseAddress, XSCUGIC_CPU_PRIOR_OFFSET, + 0xF0U); + + /* + * If the CPU operates in both security domains, set parameters in the + * control_s register. + * 1. Set FIQen=1 to use FIQ for secure interrupts, + * 2. Program the AckCtl bit + * 3. Program the SBPR bit to select the binary pointer behavior + * 4. Set EnableS = 1 to enable secure interrupts + * 5. Set EnbleNS = 1 to enable non secure interrupts + */ + + /* + * If the CPU operates only in the secure domain, setup the + * control_s register. + * 1. Set FIQen=1, + * 2. Set EnableS=1, to enable the CPU interface to signal secure . + * interrupts Only enable the IRQ output unless secure interrupts + * are needed. + */ + XScuGic_WriteReg(Config->CpuBaseAddress, XSCUGIC_CONTROL_OFFSET, 0x07U); + +} + +/*****************************************************************************/ +/** +* +* Initialize the GIC based on the device id. The +* initialization entails: +* +* - Initialize distributor interface +* - Initialize cpu interface +* +* @param DeviceId is device id to be worked on. +* +* @return +* +* - XST_SUCCESS if initialization was successful +* +* @note +* +* None. +* +******************************************************************************/ +s32 XScuGic_DeviceInitialize(u32 DeviceId) +{ + XScuGic_Config *Config; + u32 Cpu_Id = XScuGic_GetCpuID() + (u32)1; + + Config = &XScuGic_ConfigTable[(u32)DeviceId]; + + DistInit(Config, Cpu_Id); + + CPUInit(Config); + + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** +* This function is the primary interrupt handler for the driver. It must be +* connected to the interrupt source such that it is called when an interrupt of +* the interrupt controller is active. It will resolve which interrupts are +* active and enabled and call the appropriate interrupt handler. It uses +* the Interrupt Type information to determine when to acknowledge the +* interrupt.Highest priority interrupts are serviced first. +* +* This function assumes that an interrupt vector table has been previously +* initialized. It does not verify that entries in the table are valid before +* calling an interrupt handler. +* +* @param DeviceId is the unique identifier for the ScuGic device. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XScuGic_DeviceInterruptHandler(void *DeviceId) +{ + + u32 InterruptID; + u32 IntIDFull; + XScuGic_VectorTableEntry *TablePtr; + XScuGic_Config *CfgPtr; + + CfgPtr = &XScuGic_ConfigTable[(INTPTR)DeviceId]; + + /* + * Read the int_ack register to identify the highest priority + * interrupt ID and make sure it is valid. Reading Int_Ack will + * clear the interrupt in the GIC. + */ + IntIDFull = XScuGic_ReadReg(CfgPtr->CpuBaseAddress, + XSCUGIC_INT_ACK_OFFSET); + InterruptID = IntIDFull & XSCUGIC_ACK_INTID_MASK; + if (XSCUGIC_MAX_NUM_INTR_INPUTS <= InterruptID) { + goto IntrExit; + } + + /* + * If the interrupt is shared, do some locking here if there are + * multiple processors. + */ + /* + * If pre-eption is required: + * Re-enable pre-emption by setting the CPSR I bit for non-secure , + * interrupts or the F bit for secure interrupts + */ + + /* + * If we need to change security domains, issue a SMC instruction here. + */ + + /* + * Execute the ISR. Jump into the Interrupt service routine based on + * the IRQSource. A software trigger is cleared by the ACK. + */ + TablePtr = &(CfgPtr->HandlerTable[InterruptID]); + if (TablePtr != NULL) { + TablePtr->Handler(TablePtr->CallBackRef); + } + +IntrExit: + /* + * Write to the EOI register, we are all done here. + * Let this function return, the boot code will restore the stack. + */ + XScuGic_WriteReg(CfgPtr->CpuBaseAddress, XSCUGIC_EOI_OFFSET, IntIDFull); + + /* + * Return from the interrupt. Change security domains could happen + * here. + */ +} + +/*****************************************************************************/ +/** +* +* Register a handler function for a specific interrupt ID. The vector table +* of the interrupt controller is updated, overwriting any previous handler. +* The handler function will be called when an interrupt occurs for the given +* interrupt ID. +* +* @param BaseAddress is the CPU Interface Register base address of the +* interrupt controller whose vector table will be modified. +* @param InterruptID is the interrupt ID to be associated with the input +* handler. +* @param IntrHandler is the function pointer that will be added to +* the vector table for the given interrupt ID. +* @param CallBackRef is the argument that will be passed to the new +* handler function when it is called. This is user-specific. +* +* @return None. +* +* @note +* +* Note that this function has no effect if the input base address is invalid. +* +******************************************************************************/ +void XScuGic_RegisterHandler(u32 BaseAddress, s32 InterruptID, + Xil_InterruptHandler IntrHandler, void *CallBackRef) +{ + XScuGic_Config *CfgPtr; + CfgPtr = LookupConfigByBaseAddress(BaseAddress); + + if (CfgPtr != NULL) { + if (IntrHandler != NULL) { + CfgPtr->HandlerTable[InterruptID].Handler = + (Xil_InterruptHandler)IntrHandler; + } + if (CallBackRef != NULL) { + CfgPtr->HandlerTable[InterruptID].CallBackRef = + CallBackRef; + } + } +} + +/*****************************************************************************/ +/** +* +* Looks up the device configuration based on the CPU interface base address of +* the device. A table contains the configuration info for each device in the +* system. +* +* @param CpuBaseAddress is the CPU Interface Register base address. +* +* @return A pointer to the configuration structure for the specified +* device, or NULL if the device was not found. +* +* @note None. +* +******************************************************************************/ +static XScuGic_Config *LookupConfigByBaseAddress(u32 CpuBaseAddress) +{ + XScuGic_Config *CfgPtr = NULL; + u32 Index; + + for (Index = 0U; Index < XPAR_SCUGIC_NUM_INSTANCES; Index++) { + if (XScuGic_ConfigTable[Index].CpuBaseAddress == + CpuBaseAddress) { + CfgPtr = &XScuGic_ConfigTable[Index]; + break; + } + } + + return (XScuGic_Config *)CfgPtr; +} + +/****************************************************************************/ +/** +* Sets the interrupt priority and trigger type for the specificd IRQ source. +* +* @param DistBaseAddress is the distributor base address +* @param Int_Id is the IRQ source number to modify +* @param Priority is the new priority for the IRQ source. 0 is highest +* priority, 0xF8(248) is lowest. There are 32 priority +* levels supported with a step of 8. Hence the supported +* priorities are 0, 8, 16, 32, 40 ..., 248. +* @param Trigger is the new trigger type for the IRQ source. +* Each bit pair describes the configuration for an INT_ID. +* SFI Read Only b10 always +* PPI Read Only depending on how the PPIs are configured. +* b01 Active HIGH level sensitive +* b11 Rising edge sensitive +* SPI LSB is read only. +* b01 Active HIGH level sensitive +* b11 Rising edge sensitive/ +* +* @return None. +* +* @note This API has the similar functionality of XScuGic_SetPriority +* TriggerType() and should be used when there is no InstancePtr. +* +*****************************************************************************/ +void XScuGic_SetPriTrigTypeByDistAddr(u32 DistBaseAddress, u32 Int_Id, + u8 Priority, u8 Trigger) +{ + u32 RegValue; + u8 LocalPriority = Priority; + + Xil_AssertVoid(Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS); + Xil_AssertVoid(Trigger <= XSCUGIC_INT_CFG_MASK); + Xil_AssertVoid(LocalPriority <= XSCUGIC_MAX_INTR_PRIO_VAL); + + /* + * Determine the register to write to using the Int_Id. + */ + RegValue = XScuGic_ReadReg(DistBaseAddress, + XSCUGIC_PRIORITY_OFFSET_CALC(Int_Id)); + + /* + * The priority bits are Bits 7 to 3 in GIC Priority Register. This + * means the number of priority levels supported are 32 and they are + * in steps of 8. The priorities can be 0, 8, 16, 32, 48, ... etc. + * The lower order 3 bits are masked before putting it in the register. + */ + LocalPriority = LocalPriority & XSCUGIC_INTR_PRIO_MASK; + /* + * Shift and Mask the correct bits for the priority and trigger in the + * register + */ + RegValue &= ~(XSCUGIC_PRIORITY_MASK << ((Int_Id%4U)*8U)); + RegValue |= (u32)LocalPriority << ((Int_Id%4U)*8U); + + /* + * Write the value back to the register. + */ + XScuGic_WriteReg(DistBaseAddress, XSCUGIC_PRIORITY_OFFSET_CALC(Int_Id), + RegValue); + /* + * Determine the register to write to using the Int_Id. + */ + RegValue = XScuGic_ReadReg(DistBaseAddress, + XSCUGIC_INT_CFG_OFFSET_CALC(Int_Id)); + + /* + * Shift and Mask the correct bits for the priority and trigger in the + * register + */ + RegValue &= ~(XSCUGIC_INT_CFG_MASK << ((Int_Id%16U)*2U)); + RegValue |= (u32)Trigger << ((Int_Id%16U)*2U); + + /* + * Write the value back to the register. + */ + XScuGic_WriteReg(DistBaseAddress, XSCUGIC_INT_CFG_OFFSET_CALC(Int_Id), + RegValue); +} + +/****************************************************************************/ +/** +* Gets the interrupt priority and trigger type for the specificd IRQ source. +* +* @param DistBaseAddress is the distributor base address +* @param Int_Id is the IRQ source number to modify +* @param Priority is a pointer to the value of the priority of the IRQ +* source. This is a return value. +* @param Trigger is pointer to the value of the trigger of the IRQ +* source. This is a return value. +* +* @return None. +* +* @note This API has the similar functionality of XScuGic_GetPriority +* TriggerType() and should be used when there is no InstancePtr. +* +*****************************************************************************/ +void XScuGic_GetPriTrigTypeByDistAddr(u32 DistBaseAddress, u32 Int_Id, + u8 *Priority, u8 *Trigger) +{ + u32 RegValue; + + Xil_AssertVoid(Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS); + Xil_AssertVoid(Priority != NULL); + Xil_AssertVoid(Trigger != NULL); + + /* + * Determine the register to read to using the Int_Id. + */ + RegValue = XScuGic_ReadReg(DistBaseAddress, + XSCUGIC_PRIORITY_OFFSET_CALC(Int_Id)); + + /* + * Shift and Mask the correct bits for the priority and trigger in the + * register + */ + RegValue = RegValue >> ((Int_Id%4U)*8U); + *Priority = (u8)(RegValue & XSCUGIC_PRIORITY_MASK); + + /* + * Determine the register to read to using the Int_Id. + */ + RegValue = XScuGic_ReadReg(DistBaseAddress, + XSCUGIC_INT_CFG_OFFSET_CALC(Int_Id)); + + /* + * Shift and Mask the correct bits for the priority and trigger in the + * register + */ + RegValue = RegValue >> ((Int_Id%16U)*2U); + + *Trigger = (u8)(RegValue & XSCUGIC_INT_CFG_MASK); +} + +/****************************************************************************/ +/** +* Unmaps specific SPI interrupt from the target CPU +* +* @param DistBaseAddress is the device base address +* @param Cpu_Id is a CPU number from which the interrupt has to be +* unmapped +* @param Int_Id is the IRQ source number to modify +* +* @return None. +* +* @note None +* +*****************************************************************************/ +void XScuGic_InterruptUnmapFromCpuByDistAddr(u32 DistBaseAddress, + u8 Cpu_Id, u32 Int_Id) +{ + u32 RegValue; + u8 BitPos; + + Xil_AssertVoid(Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS); + + RegValue = XScuGic_ReadReg(DistBaseAddress, + XSCUGIC_SPI_TARGET_OFFSET_CALC(Int_Id)); + + /* + * Identify bit position corresponding to Int_Id and Cpu_Id, + * in interrupt target register and clear it + */ + BitPos = ((Int_Id % 4U) * 8U) + Cpu_Id; + RegValue &= (~(1U << BitPos)); + XScuGic_WriteReg(DistBaseAddress, + XSCUGIC_SPI_TARGET_OFFSET_CALC(Int_Id), RegValue); +} + +/****************************************************************************/ +/** +* Unmaps all SPI interrupts from the target CPU +* +* @param DistBaseAddress is the device base address +* @param Cpu_Id is a CPU number from which the interrupts has to be +* unmapped +* +* @return None. +* +* @note None +* +*****************************************************************************/ +void XScuGic_UnmapAllInterruptsFromCpuByDistAddr(u32 DistBaseAddress, + u8 Cpu_Id) +{ + u32 Int_Id; + u32 Target_Cpu; + u32 LocalCpuID = (1U << Cpu_Id); + + LocalCpuID |= LocalCpuID << 8U; + LocalCpuID |= LocalCpuID << 16U; + + for (Int_Id = 32U; Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS; + Int_Id = Int_Id+4U) { + + Target_Cpu = XScuGic_ReadReg(DistBaseAddress, + XSCUGIC_SPI_TARGET_OFFSET_CALC(Int_Id)); + /* Remove LocalCpuID from interrupt target register */ + Target_Cpu &= (~LocalCpuID); + XScuGic_WriteReg(DistBaseAddress, + XSCUGIC_SPI_TARGET_OFFSET_CALC(Int_Id), Target_Cpu); + + } +} +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic_hw.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic_hw.h new file mode 100644 index 0000000..60d111f --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic_hw.h @@ -0,0 +1,753 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xscugic_hw.h +* @addtogroup scugic_v4_0 +* @{ +* +* This header file contains identifiers and HW access functions (or +* macros) that can be used to access the device. The user should refer to the +* hardware device specification for more details of the device operation. +* The driver functions/APIs are defined in xscugic.h. +* +* This GIC device has two parts, a distributor and CPU interface(s). Each part +* has separate register definition sections. +* +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------------
+* 1.00a drg  01/19/10 First release
+* 1.01a sdm  11/09/11 "xil_exception.h" added as include.
+*		      Macros XScuGic_EnableIntr and XScuGic_DisableIntr are
+*		      added to enable or disable interrupts based on
+*		      Distributor Register base address. Normally users use
+*		      XScuGic instance and call XScuGic_Enable or
+*		      XScuGic_Disable to enable/disable interrupts. These
+*		      new macros are provided when user does not want to
+*		      use an instance pointer but still wants to enable or
+*		      disable interrupts.
+*		      Function prototypes for functions (present in newly
+*		      added file xscugic_hw.c) are added.
+* 1.03a srt  02/27/13 Moved Offset calculation macros from *_hw.c (CR
+*		      702687).
+* 1.04a hk   05/04/13 Fix for CR#705621. Moved function prototypes
+*		      XScuGic_SetPriTrigTypeByDistAddr and
+*         	      XScuGic_GetPriTrigTypeByDistAddr here from xscugic.h
+* 3.0	pkp  12/09/14 changed XSCUGIC_MAX_NUM_INTR_INPUTS for
+*		      Zynq Ultrascale Mp
+* 3.0   kvn  02/13/14 Modified code for MISRA-C:2012 compliance.
+* 3.2	pkp  11/09/15 Corrected the interrupt processsor target mask value
+*					  for CPU interface 2 i.e. XSCUGIC_SPI_CPU2_MASK
+* 3.9   mus  02/21/18 Added new API's XScuGic_InterruptUnmapFromCpuByDistAddr
+*					  and XScuGic_UnmapAllInterruptsFromCpuByDistAddr, These
+*					  API's can be used by applications to unmap specific/all
+*					  interrupts from target CPU. It fixes CR#992490.
+* 3.10  aru  08/23/18 Resolved MISRA-C:2012 compliance mandatory violations
+*
+* 
+* +******************************************************************************/ + +#ifndef XSCUGIC_HW_H /* prevent circular inclusions */ +#define XSCUGIC_HW_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +#include "xil_types.h" +#include "xil_assert.h" +#include "xil_io.h" +#include "xil_exception.h" +#include "bspconfig.h" + +/************************** Constant Definitions *****************************/ + +/* + * The maximum number of interrupts supported by the hardware. + */ +#ifdef PLATFORM_ZYNQ +#define XSCUGIC_MAX_NUM_INTR_INPUTS 95U /* Maximum number of interrupt defined by Zynq */ +#elif defined (versal) && !defined(ARMR5) +#define XSCUGIC_MAX_NUM_INTR_INPUTS 191U +#else +#define XSCUGIC_MAX_NUM_INTR_INPUTS 195U /* Maximum number of interrupt defined by Zynq Ultrascale Mp */ +#endif + +/* + * First Interrupt Id for SPI interrupts. + */ +#define XSCUGIC_SPI_INT_ID_START 0x20 +/* + * The maximum priority value that can be used in the GIC. + */ +#define XSCUGIC_MAX_INTR_PRIO_VAL 248U +#define XSCUGIC_INTR_PRIO_MASK 0x000000F8U + +/** @name Distributor Interface Register Map + * + * Define the offsets from the base address for all Distributor registers of + * the interrupt controller, some registers may be reserved in the hardware + * device. + * @{ + */ +#define XSCUGIC_DIST_EN_OFFSET 0x00000000U /**< Distributor Enable + Register */ +#define XSCUGIC_IC_TYPE_OFFSET 0x00000004U /**< Interrupt Controller + Type Register */ +#define XSCUGIC_DIST_IDENT_OFFSET 0x00000008U /**< Implementor ID + Register */ +#define XSCUGIC_SECURITY_OFFSET 0x00000080U /**< Interrupt Security + Register */ +#define XSCUGIC_ENABLE_SET_OFFSET 0x00000100U /**< Enable Set + Register */ +#define XSCUGIC_DISABLE_OFFSET 0x00000180U /**< Enable Clear Register */ +#define XSCUGIC_PENDING_SET_OFFSET 0x00000200U /**< Pending Set + Register */ +#define XSCUGIC_PENDING_CLR_OFFSET 0x00000280U /**< Pending Clear + Register */ +#define XSCUGIC_ACTIVE_OFFSET 0x00000300U /**< Active Status Register */ +#define XSCUGIC_PRIORITY_OFFSET 0x00000400U /**< Priority Level Register */ +#define XSCUGIC_SPI_TARGET_OFFSET 0x00000800U /**< SPI Target + Register 0x800-0x8FB */ +#define XSCUGIC_INT_CFG_OFFSET 0x00000C00U /**< Interrupt Configuration + Register 0xC00-0xCFC */ +#define XSCUGIC_PPI_STAT_OFFSET 0x00000D00U /**< PPI Status Register */ +#define XSCUGIC_SPI_STAT_OFFSET 0x00000D04U /**< SPI Status Register + 0xd04-0xd7C */ +#define XSCUGIC_AHB_CONFIG_OFFSET 0x00000D80U /**< AHB Configuration + Register */ +#define XSCUGIC_SFI_TRIG_OFFSET 0x00000F00U /**< Software Triggered + Interrupt Register */ +#define XSCUGIC_PERPHID_OFFSET 0x00000FD0U /**< Peripheral ID Reg */ +#if defined (versal) && !defined(ARMR5) +#define XSCUGIC_PCELLID_OFFSET 0x0000FFF0U /**< Pcell ID Register */ +#else +#define XSCUGIC_PCELLID_OFFSET 0x00000FF0U /**< Pcell ID Register */ +#endif +/* @} */ + +/** @name Distributor Enable Register + * Controls if the distributor response to external interrupt inputs. + * @{ + */ +#if defined (versal) && !defined(ARMR5) +#define XSCUGIC_EN_INT_MASK 0x00000003U /**< Interrupt In Enable */ +#else +#define XSCUGIC_EN_INT_MASK 0x00000001U /**< Interrupt In Enable */ +#endif +/* @} */ + +/** @name Interrupt Controller Type Register + * @{ + */ +#define XSCUGIC_LSPI_MASK 0x0000F800U /**< Number of Lockable + Shared Peripheral + Interrupts*/ +#define XSCUGIC_DOMAIN_MASK 0x00000400U /**< Number os Security domains*/ +#define XSCUGIC_CPU_NUM_MASK 0x000000E0U /**< Number of CPU Interfaces */ +#define XSCUGIC_NUM_INT_MASK 0x0000001FU /**< Number of Interrupt IDs */ +/* @} */ + +/** @name Implementor ID Register + * Implementor and revision information. + * @{ + */ +#define XSCUGIC_REV_MASK 0x00FFF000U /**< Revision Number */ +#define XSCUGIC_IMPL_MASK 0x00000FFFU /**< Implementor */ +/* @} */ + +/** @name Interrupt Security Registers + * Each bit controls the security level of an interrupt, either secure or non + * secure. These registers can only be accessed using secure read and write. + * There are registers for each of the CPU interfaces at offset 0x080. A + * register set for the SPI interrupts is available to all CPU interfaces. + * There are up to 32 of these registers staring at location 0x084. + * @{ + */ +#define XSCUGIC_INT_NS_MASK 0x00000001U /**< Each bit corresponds to an + INT_ID */ +/* @} */ + +/** @name Enable Set Register + * Each bit controls the enabling of an interrupt, a 0 is disabled, a 1 is + * enabled. Writing a 0 has no effect. Use the ENABLE_CLR register to set a + * bit to 0. + * There are registers for each of the CPU interfaces at offset 0x100. With up + * to 8 registers aliased to the same address. A register set for the SPI + * interrupts is available to all CPU interfaces. + * There are up to 32 of these registers staring at location 0x104. + * @{ + */ +#define XSCUGIC_INT_EN_MASK 0x00000001U /**< Each bit corresponds to an + INT_ID */ +/* @} */ + +/** @name Enable Clear Register + * Each bit controls the disabling of an interrupt, a 0 is disabled, a 1 is + * enabled. Writing a 0 has no effect. Writing a 1 disables an interrupt and + * sets the corresponding bit to 0. + * There are registers for each of the CPU interfaces at offset 0x180. With up + * to 8 registers aliased to the same address. + * A register set for the SPI interrupts is available to all CPU interfaces. + * There are up to 32 of these registers staring at location 0x184. + * @{ + */ +#define XSCUGIC_INT_CLR_MASK 0x00000001U /**< Each bit corresponds to an + INT_ID */ +/* @} */ + +/** @name Pending Set Register + * Each bit controls the Pending or Active and Pending state of an interrupt, a + * 0 is not pending, a 1 is pending. Writing a 0 has no effect. Writing a 1 sets + * an interrupt to the pending state. + * There are registers for each of the CPU interfaces at offset 0x200. With up + * to 8 registers aliased to the same address. + * A register set for the SPI interrupts is available to all CPU interfaces. + * There are up to 32 of these registers staring at location 0x204. + * @{ + */ +#define XSCUGIC_PEND_SET_MASK 0x00000001U /**< Each bit corresponds to an + INT_ID */ +/* @} */ + +/** @name Pending Clear Register + * Each bit can clear the Pending or Active and Pending state of an interrupt, a + * 0 is not pending, a 1 is pending. Writing a 0 has no effect. Writing a 1 + * clears the pending state of an interrupt. + * There are registers for each of the CPU interfaces at offset 0x280. With up + * to 8 registers aliased to the same address. + * A register set for the SPI interrupts is available to all CPU interfaces. + * There are up to 32 of these registers staring at location 0x284. + * @{ + */ +#define XSCUGIC_PEND_CLR_MASK 0x00000001U /**< Each bit corresponds to an + INT_ID */ +/* @} */ + +/** @name Active Status Register + * Each bit provides the Active status of an interrupt, a + * 0 is not Active, a 1 is Active. This is a read only register. + * There are registers for each of the CPU interfaces at offset 0x300. With up + * to 8 registers aliased to each address. + * A register set for the SPI interrupts is available to all CPU interfaces. + * There are up to 32 of these registers staring at location 0x380. + * @{ + */ +#define XSCUGIC_ACTIVE_MASK 0x00000001U /**< Each bit corresponds to an + INT_ID */ +/* @} */ + +/** @name Priority Level Register + * Each byte in a Priority Level Register sets the priority level of an + * interrupt. Reading the register provides the priority level of an interrupt. + * There are registers for each of the CPU interfaces at offset 0x400 through + * 0x41C. With up to 8 registers aliased to each address. + * 0 is highest priority, 0xFF is lowest. + * A register set for the SPI interrupts is available to all CPU interfaces. + * There are up to 255 of these registers staring at location 0x420. + * @{ + */ +#define XSCUGIC_PRIORITY_MASK 0x000000FFU /**< Each Byte corresponds to an + INT_ID */ +#define XSCUGIC_PRIORITY_MAX 0x000000FFU /**< Highest value of a priority + actually the lowest priority*/ +/* @} */ + +/** @name SPI Target Register 0x800-0x8FB + * Each byte references a separate SPI and programs which of the up to 8 CPU + * interfaces are sent a Pending interrupt. + * There are registers for each of the CPU interfaces at offset 0x800 through + * 0x81C. With up to 8 registers aliased to each address. + * A register set for the SPI interrupts is available to all CPU interfaces. + * There are up to 255 of these registers staring at location 0x820. + * + * This driver does not support multiple CPU interfaces. These are included + * for complete documentation. + * @{ + */ +#define XSCUGIC_SPI_CPU7_MASK 0x00000080U /**< CPU 7 Mask*/ +#define XSCUGIC_SPI_CPU6_MASK 0x00000040U /**< CPU 6 Mask*/ +#define XSCUGIC_SPI_CPU5_MASK 0x00000020U /**< CPU 5 Mask*/ +#define XSCUGIC_SPI_CPU4_MASK 0x00000010U /**< CPU 4 Mask*/ +#define XSCUGIC_SPI_CPU3_MASK 0x00000008U /**< CPU 3 Mask*/ +#define XSCUGIC_SPI_CPU2_MASK 0x00000004U /**< CPU 2 Mask*/ +#define XSCUGIC_SPI_CPU1_MASK 0x00000002U /**< CPU 1 Mask*/ +#define XSCUGIC_SPI_CPU0_MASK 0x00000001U /**< CPU 0 Mask*/ +/* @} */ + +/** @name Interrupt Configuration Register 0xC00-0xCFC + * The interrupt configuration registers program an SFI to be active HIGH level + * sensitive or rising edge sensitive. + * Each bit pair describes the configuration for an INT_ID. + * SFI Read Only b10 always + * PPI Read Only depending on how the PPIs are configured. + * b01 Active HIGH level sensitive + * b11 Rising edge sensitive + * SPI LSB is read only. + * b01 Active HIGH level sensitive + * b11 Rising edge sensitive/ + * There are registers for each of the CPU interfaces at offset 0xC00 through + * 0xC04. With up to 8 registers aliased to each address. + * A register set for the SPI interrupts is available to all CPU interfaces. + * There are up to 255 of these registers staring at location 0xC08. + * @{ + */ +#define XSCUGIC_INT_CFG_MASK 0x00000003U /**< */ +/* @} */ + +/** @name PPI Status Register + * Enables an external AMBA master to access the status of the PPI inputs. + * A CPU can only read the status of its local PPI signals and cannot read the + * status for other CPUs. + * This register is aliased for each CPU interface. + * @{ + */ +#define XSCUGIC_PPI_C15_MASK 0x00008000U /**< PPI Status */ +#define XSCUGIC_PPI_C14_MASK 0x00004000U /**< PPI Status */ +#define XSCUGIC_PPI_C13_MASK 0x00002000U /**< PPI Status */ +#define XSCUGIC_PPI_C12_MASK 0x00001000U /**< PPI Status */ +#define XSCUGIC_PPI_C11_MASK 0x00000800U /**< PPI Status */ +#define XSCUGIC_PPI_C10_MASK 0x00000400U /**< PPI Status */ +#define XSCUGIC_PPI_C09_MASK 0x00000200U /**< PPI Status */ +#define XSCUGIC_PPI_C08_MASK 0x00000100U /**< PPI Status */ +#define XSCUGIC_PPI_C07_MASK 0x00000080U /**< PPI Status */ +#define XSCUGIC_PPI_C06_MASK 0x00000040U /**< PPI Status */ +#define XSCUGIC_PPI_C05_MASK 0x00000020U /**< PPI Status */ +#define XSCUGIC_PPI_C04_MASK 0x00000010U /**< PPI Status */ +#define XSCUGIC_PPI_C03_MASK 0x00000008U /**< PPI Status */ +#define XSCUGIC_PPI_C02_MASK 0x00000004U /**< PPI Status */ +#define XSCUGIC_PPI_C01_MASK 0x00000002U /**< PPI Status */ +#define XSCUGIC_PPI_C00_MASK 0x00000001U /**< PPI Status */ +/* @} */ + +/** @name SPI Status Register 0xd04-0xd7C + * Enables an external AMBA master to access the status of the SPI inputs. + * There are up to 63 registers if the maximum number of SPI inputs are + * configured. + * @{ + */ +#define XSCUGIC_SPI_N_MASK 0x00000001U /**< Each bit corresponds to an SPI + input */ +/* @} */ + +/** @name AHB Configuration Register + * Provides the status of the CFGBIGEND input signal and allows the endianess + * of the GIC to be set. + * @{ + */ +#define XSCUGIC_AHB_END_MASK 0x00000004U /**< 0-GIC uses little Endian, + 1-GIC uses Big Endian */ +#define XSCUGIC_AHB_ENDOVR_MASK 0x00000002U /**< 0-Uses CFGBIGEND control, + 1-use the AHB_END bit */ +#define XSCUGIC_AHB_TIE_OFF_MASK 0x00000001U /**< State of CFGBIGEND */ + +/* @} */ + +/** @name Software Triggered Interrupt Register + * Controls issueing of software interrupts. + * @{ + */ +#define XSCUGIC_SFI_SELFTRIG_MASK 0x02010000U +#define XSCUGIC_SFI_TRIG_TRGFILT_MASK 0x03000000U /**< Target List filter + b00-Use the target List + b01-All CPUs except requester + b10-To Requester + b11-reserved */ +#define XSCUGIC_SFI_TRIG_CPU_MASK 0x00FF0000U /**< CPU Target list */ +#define XSCUGIC_SFI_TRIG_SATT_MASK 0x00008000U /**< 0= Use a secure interrupt */ +#define XSCUGIC_SFI_TRIG_INTID_MASK 0x0000000FU /**< Set to the INTID + signaled to the CPU*/ +/* @} */ + +/** @name CPU Interface Register Map + * + * Define the offsets from the base address for all CPU registers of the + * interrupt controller, some registers may be reserved in the hardware device. + * @{ + */ +#define XSCUGIC_CONTROL_OFFSET 0x00000000U /**< CPU Interface Control + Register */ +#define XSCUGIC_CPU_PRIOR_OFFSET 0x00000004U /**< Priority Mask Reg */ +#define XSCUGIC_BIN_PT_OFFSET 0x00000008U /**< Binary Point Register */ +#define XSCUGIC_INT_ACK_OFFSET 0x0000000CU /**< Interrupt ACK Reg */ +#define XSCUGIC_EOI_OFFSET 0x00000010U /**< End of Interrupt Reg */ +#define XSCUGIC_RUN_PRIOR_OFFSET 0x00000014U /**< Running Priority Reg */ +#define XSCUGIC_HI_PEND_OFFSET 0x00000018U /**< Highest Pending Interrupt + Register */ +#define XSCUGIC_ALIAS_BIN_PT_OFFSET 0x0000001CU /**< Aliased non-Secure + Binary Point Register */ + +/**< 0x00000020 to 0x00000FBC are reserved and should not be read or written + * to. */ +/* @} */ + + +/** @name Control Register + * CPU Interface Control register definitions + * All bits are defined here although some are not available in the non-secure + * mode. + * @{ + */ +#define XSCUGIC_CNTR_SBPR_MASK 0x00000010U /**< Secure Binary Pointer, + 0=separate registers, + 1=both use bin_pt_s */ +#define XSCUGIC_CNTR_FIQEN_MASK 0x00000008U /**< Use nFIQ_C for secure + interrupts, + 0= use IRQ for both, + 1=Use FIQ for secure, IRQ for non*/ +#define XSCUGIC_CNTR_ACKCTL_MASK 0x00000004U /**< Ack control for secure or non secure */ +#define XSCUGIC_CNTR_EN_NS_MASK 0x00000002U /**< Non Secure enable */ +#define XSCUGIC_CNTR_EN_S_MASK 0x00000001U /**< Secure enable, 0=Disabled, 1=Enabled */ +/* @} */ + +/** @name Priority Mask Register + * Priority Mask register definitions + * The CPU interface does not send interrupt if the level of the interrupt is + * lower than the level of the register. + * @{ + */ +/*#define XSCUGIC_PRIORITY_MASK 0x000000FFU*/ /**< All interrupts */ +/* @} */ + +/** @name Binary Point Register + * Binary Point register definitions + * @{ + */ + +#define XSCUGIC_BIN_PT_MASK 0x00000007U /**< Binary point mask value + Value Secure Non-secure + b000 0xFE 0xFF + b001 0xFC 0xFE + b010 0xF8 0xFC + b011 0xF0 0xF8 + b100 0xE0 0xF0 + b101 0xC0 0xE0 + b110 0x80 0xC0 + b111 0x00 0x80 + */ +/*@}*/ + +/** @name Interrupt Acknowledge Register + * Interrupt Acknowledge register definitions + * Identifies the current Pending interrupt, and the CPU ID for software + * interrupts. + */ +#define XSCUGIC_ACK_INTID_MASK 0x000003FFU /**< Interrupt ID */ +#define XSCUGIC_CPUID_MASK 0x00000C00U /**< CPU ID */ +/* @} */ + +/** @name End of Interrupt Register + * End of Interrupt register definitions + * Allows the CPU to signal the GIC when it completes an interrupt service + * routine. + */ +#define XSCUGIC_EOI_INTID_MASK 0x000003FFU /**< Interrupt ID */ + +/* @} */ + +/** @name Running Priority Register + * Running Priority register definitions + * Identifies the interrupt priority level of the highest priority active + * interrupt. + */ +#define XSCUGIC_RUN_PRIORITY_MASK 0x000000FFU /**< Interrupt Priority */ +/* @} */ + +#if defined (versal) && !defined(ARMR5) +#define XSCUGIC_IROUTER_BASE_OFFSET 0x6000U +#endif +/* + * Highest Pending Interrupt register definitions + * Identifies the interrupt priority of the highest priority pending interupt + */ +#define XSCUGIC_PEND_INTID_MASK 0x000003FFU /**< Pending Interrupt ID */ +/*#define XSCUGIC_CPUID_MASK 0x00000C00U */ /**< CPU ID */ +/* @} */ +#if defined (versal) && !defined(ARMR5) +/** @name ReDistributor Interface Register Map + * + * @{ + */ +#define XSCUGIC_RDIST_OFFSET 0x80000U +#define XSCUGIC_RDIST_BASE_ADDRESS (XPAR_SCUGIC_0_DIST_BASEADDR + XSCUGIC_RDIST_OFFSET) +#define XSCUGIC_RDIST_SGI_PPI_OFFSET 0x90000U +#define XSCUGIC_RDIST_SGI_PPI_BASE_ADDRESS (XPAR_SCUGIC_0_DIST_BASEADDR + XSCUGIC_RDIST_SGI_PPI_OFFSET) +#define XSCUGIC_RDIST_ISENABLE_OFFSET 0x100U +#define XSCUGIC_RDIST_IPRIORITYR_OFFSET 0x400U +#define XSCUGIC_RDIST_IGROUPR_OFFSET 0x80U +#define XSCUGIC_RDIST_GRPMODR_OFFSET 0xD00U +#define XSCUGIC_RDIST_INT_CONFIG_OFFSET 0xC00U +#define XSCUGIC_RDIST_WAKER_OFFSET 0x14U +#define XSCUGIC_SGIR_EL1_INITID_SHIFT 24U + +/* + * GICR_IGROUPR register definitions + */ +#if EL3 +#define XSCUGIC_DEFAULT_SECURITY 0x0U +#else +#define XSCUGIC_DEFAULT_SECURITY 0xFFFFFFFFU +#endif +/* + * GICR_WAKER register definitions + */ +#define XSCUGIC_RDIST_WAKER_LOW_POWER_STATE_MASK 0x7 +#endif +/***************** Macros (Inline Functions) Definitions *********************/ + +/****************************************************************************/ +/** +* +* Read the Interrupt Configuration Register offset for an interrupt id. +* +* @param InterruptID is the interrupt number. +* +* @return The 32-bit value of the offset +* +* @note +* +*****************************************************************************/ +#define XSCUGIC_INT_CFG_OFFSET_CALC(InterruptID) \ + ((u32)XSCUGIC_INT_CFG_OFFSET + (((InterruptID)/16U) * 4U)) + +/****************************************************************************/ +/** +* +* Read the Interrupt Priority Register offset for an interrupt id. +* +* @param InterruptID is the interrupt number. +* +* @return The 32-bit value of the offset +* +* @note +* +*****************************************************************************/ +#define XSCUGIC_PRIORITY_OFFSET_CALC(InterruptID) \ + ((u32)XSCUGIC_PRIORITY_OFFSET + (((InterruptID)/4U) * 4U)) + +/****************************************************************************/ +/** +* +* Read the Interrupt Routing Register offset for an interrupt id. +* +* @param InterruptID is the interrupt number. +* +* @return The 32-bit value of the offset +* +* @note +* +*****************************************************************************/ +#define XSCUGIC_IROUTER_OFFSET_CALC(InterruptID) \ + ((u32)XSCUGIC_IROUTER_BASE_OFFSET + (InterruptID * 8)) + +/****************************************************************************/ +/** +* +* Read the SPI Target Register offset for an interrupt id. +* +* @param InterruptID is the interrupt number. +* +* @return The 32-bit value of the offset +* +* @note +* +*****************************************************************************/ +#define XSCUGIC_SPI_TARGET_OFFSET_CALC(InterruptID) \ + ((u32)XSCUGIC_SPI_TARGET_OFFSET + (((InterruptID)/4U) * 4U)) +/****************************************************************************/ +/** +* +* Read the SPI Target Register offset for an interrupt id. +* +* @param InterruptID is the interrupt number. +* +* @return The 32-bit value of the offset +* +* @note +* +*****************************************************************************/ +#define XSCUGIC_SECURITY_TARGET_OFFSET_CALC(InterruptID) \ + ((u32)XSCUGIC_SECURITY_OFFSET + (((InterruptID)/32U)*4U)) + +/****************************************************************************/ +/** +* +* Read the Re-distributor Interrupt configuration register offset +* +* @param InterruptID is the interrupt number. +* +* @return The 32-bit value of the offset +* +* @note +* +*****************************************************************************/ +#define XSCUGIC_RDIST_INT_CONFIG_OFFSET_CALC(InterruptID) \ + ((u32)XSCUGIC_RDIST_INT_CONFIG_OFFSET + ((InterruptID /16)*4)) + +/****************************************************************************/ +/** +* +* Read the Re-distributor Interrupt Priority register offset +* +* @param InterruptID is the interrupt number. +* +* @return The 32-bit value of the offset +* +* @note +* +*****************************************************************************/ +#define XSCUGIC_RDIST_INT_PRIORITY_OFFSET_CALC(InterruptID) \ + ((u32)XSCUGIC_RDIST_IPRIORITYR_OFFSET + (InterruptID * 4)) +/****************************************************************************/ +/** +* +* Read the Interrupt Clear-Enable Register offset for an interrupt ID +* +* @param Register is the register offset for the clear/enable bank. +* @param InterruptID is the interrupt number. +* +* @return The 32-bit value of the offset +* +* @note +* +*****************************************************************************/ +#define XSCUGIC_EN_DIS_OFFSET_CALC(Register, InterruptID) \ + ((Register) + (((InterruptID)/32U) * 4U)) + +/****************************************************************************/ +/** +* +* Read the given Intc register. +* +* @param BaseAddress is the base address of the device. +* @param RegOffset is the register offset to be read +* +* @return The 32-bit value of the register +* +* @note +* C-style signature: +* u32 XScuGic_ReadReg(u32 BaseAddress, u32 RegOffset) +* +*****************************************************************************/ +#define XScuGic_ReadReg(BaseAddress, RegOffset) \ + (Xil_In32((BaseAddress) + (RegOffset))) + + +/****************************************************************************/ +/** +* +* Write the given Intc register. +* +* @param BaseAddress is the base address of the device. +* @param RegOffset is the register offset to be written +* @param Data is the 32-bit value to write to the register +* +* @return None. +* +* @note +* C-style signature: +* void XScuGic_WriteReg(u32 BaseAddress, u32 RegOffset, u32 Data) +* +*****************************************************************************/ +#define XScuGic_WriteReg(BaseAddress, RegOffset, Data) \ + (Xil_Out32(((BaseAddress) + (RegOffset)), ((u32)(Data)))) + + +/****************************************************************************/ +/** +* +* Enable specific interrupt(s) in the interrupt controller. +* +* @param DistBaseAddress is the Distributor Register base address of the +* device +* @param Int_Id is the ID of the interrupt source and should be in the +* range of 0 to XSCUGIC_MAX_NUM_INTR_INPUTS - 1 +* +* @return None. +* +* @note C-style signature: +* void XScuGic_EnableIntr(u32 DistBaseAddress, u32 Int_Id) +* +*****************************************************************************/ +#define XScuGic_EnableIntr(DistBaseAddress, Int_Id) \ + XScuGic_WriteReg((DistBaseAddress), \ + XSCUGIC_ENABLE_SET_OFFSET + (((Int_Id) / 32U) * 4U), \ + (0x00000001U << ((Int_Id) % 32U))) + +/****************************************************************************/ +/** +* +* Disable specific interrupt(s) in the interrupt controller. +* +* @param DistBaseAddress is the Distributor Register base address of the +* device +* @param Int_Id is the ID of the interrupt source and should be in the +* range of 0 to XSCUGIC_MAX_NUM_INTR_INPUTS - 1 +* +* +* @return None. +* +* @note C-style signature: +* void XScuGic_DisableIntr(u32 DistBaseAddress, u32 Int_Id) +* +*****************************************************************************/ +#define XScuGic_DisableIntr(DistBaseAddress, Int_Id) \ + XScuGic_WriteReg((DistBaseAddress), \ + XSCUGIC_DISABLE_OFFSET + (((Int_Id) / 32U) * 4U), \ + (0x00000001U << ((Int_Id) % 32U))) + + +/************************** Function Prototypes ******************************/ + +void XScuGic_DeviceInterruptHandler(void *DeviceId); +s32 XScuGic_DeviceInitialize(u32 DeviceId); +void XScuGic_RegisterHandler(u32 BaseAddress, s32 InterruptID, + Xil_InterruptHandler Handler, void *CallBackRef); +void XScuGic_SetPriTrigTypeByDistAddr(u32 DistBaseAddress, u32 Int_Id, + u8 Priority, u8 Trigger); +void XScuGic_GetPriTrigTypeByDistAddr(u32 DistBaseAddress, u32 Int_Id, + u8 *Priority, u8 *Trigger); +void XScuGic_InterruptUnmapFromCpuByDistAddr(u32 DistBaseAddress, + u8 Cpu_Id, u32 Int_Id); +void XScuGic_UnmapAllInterruptsFromCpuByDistAddr(u32 DistBaseAddress, + u8 Cpu_Id); +/************************** Variable Definitions *****************************/ +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic_intr.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic_intr.c new file mode 100644 index 0000000..2157b4f --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic_intr.c @@ -0,0 +1,185 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xscugic_intr.c +* @addtogroup scugic_v4_0 +* @{ +* +* This file contains the interrupt processing for the driver for the Xilinx +* Interrupt Controller. The interrupt processing is partitioned separately such +* that users are not required to use the provided interrupt processing. This +* file requires other files of the driver to be linked in also. +* +* The interrupt handler, XScuGic_InterruptHandler, uses an input argument which +* is an instance pointer to an interrupt controller driver such that multiple +* interrupt controllers can be supported. This handler requires the calling +* function to pass it the appropriate argument, so another level of indirection +* may be required. +* +* The interrupt processing may be used by connecting the interrupt handler to +* the interrupt system. The handler does not save and restore the processor +* context but only handles the processing of the Interrupt Controller. The user +* is encouraged to supply their own interrupt handler when performance tuning is +* deemed necessary. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- ---------------------------------------------------------
+* 1.00a drg  01/19/10 First release
+* 1.01a sdm  11/09/11 XScuGic_InterruptHandler has changed correspondingly
+*		      since the HandlerTable has now moved to XScuGic_Config.
+* 3.00  kvn  02/13/15 Modified code for MISRA-C:2012 compliance.
+* 3.10  mus  07/17/18 Updated XScuGic_InterruptHandler to fix array overrun
+*                     reported by coverity tool. It fixes CR#1006344.
+* 3.10  mus  07/17/18 Updated file to fix the various coding style issues
+*                     reported by checkpatch. It fixes CR#1006344.
+*
+* 
+* +* @internal +* +* This driver assumes that the context of the processor has been saved prior to +* the calling of the Interrupt Controller interrupt handler and then restored +* after the handler returns. This requires either the running RTOS to save the +* state of the machine or that a wrapper be used as the destination of the +* interrupt vector to save the state of the processor and restore the state +* after the interrupt handler returns. +* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xil_types.h" +#include "xil_assert.h" +#include "xscugic.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/************************** Variable Definitions *****************************/ + +/*****************************************************************************/ +/** +* This function is the primary interrupt handler for the driver. It must be +* connected to the interrupt source such that it is called when an interrupt of +* the interrupt controller is active. It will resolve which interrupts are +* active and enabled and call the appropriate interrupt handler. It uses +* the Interrupt Type information to determine when to acknowledge the interrupt. +* Highest priority interrupts are serviced first. +* +* This function assumes that an interrupt vector table has been previously +* initialized. It does not verify that entries in the table are valid before +* calling an interrupt handler. +* +* +* @param InstancePtr is a pointer to the XScuGic instance. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XScuGic_InterruptHandler(XScuGic *InstancePtr) +{ + + u32 InterruptID; +#if !defined (versal) || defined (ARMR5) + u32 IntIDFull; +#endif + XScuGic_VectorTableEntry *TablePtr; + + /* Assert that the pointer to the instance is valid + */ + Xil_AssertVoid(InstancePtr != NULL); + + /* + * Read the int_ack register to identify the highest priority + * interrupt ID and make sure it is valid. Reading Int_Ack will + * clear the interrupt in the GIC. + */ +#if defined (versal) && !defined(ARMR5) + InterruptID = XScuGic_get_IntID(); +#else + IntIDFull = XScuGic_CPUReadReg(InstancePtr, XSCUGIC_INT_ACK_OFFSET); + InterruptID = IntIDFull & XSCUGIC_ACK_INTID_MASK; +#endif + if (XSCUGIC_MAX_NUM_INTR_INPUTS <= InterruptID) { + goto IntrExit; + } + + /* + * If the interrupt is shared, do some locking here if + * there are multiple processors. + */ + /* + * If pre-eption is required: + * Re-enable pre-emption by setting the CPSR I bit for non-secure , + * interrupts or the F bit for secure interrupts + */ + + /* + * If we need to change security domains, issue a SMC + * instruction here. + */ + + /* + * Execute the ISR. Jump into the Interrupt service routine + * based on the IRQSource. A software trigger is cleared by + *.the ACK. + */ + TablePtr = &(InstancePtr->Config->HandlerTable[InterruptID]); + if (TablePtr != NULL) { + TablePtr->Handler(TablePtr->CallBackRef); + } + +IntrExit: + /* + * Write to the EOI register, we are all done here. + * Let this function return, the boot code will restore the stack. + */ +#if defined (versal) && !defined(ARMR5) + XScuGic_ack_Int(InterruptID); + +#else + XScuGic_CPUWriteReg(InstancePtr, XSCUGIC_EOI_OFFSET, IntIDFull); +#endif + /* + * Return from the interrupt. Change security domains + * could happen here. + */ +} +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic_selftest.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic_selftest.c new file mode 100644 index 0000000..052ef43 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic_selftest.c @@ -0,0 +1,114 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xscugic_selftest.c +* @addtogroup scugic_v4_0 +* @{ +* +* Contains diagnostic self-test functions for the XScuGic driver. +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a drg  01/19/10 First release
+* 3.00  kvn  02/13/15 Modified code for MISRA-C:2012 compliance.
+* 3.10  mus  07/17/18 Updated file to fix the various coding style issues
+*                     reported by checkpatch. It fixes CR#1006344.
+*
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xil_types.h" +#include "xil_assert.h" +#include "xscugic.h" + +/************************** Constant Definitions *****************************/ + +#define XSCUGIC_PCELL_ID 0xB105F00DU + +/**************************** Type Definitions *******************************/ + + +/***************** Macros (Inline Functions) Definitions *********************/ + + +/************************** Function Prototypes ******************************/ + +/************************** Variable Definitions *****************************/ + +/*****************************************************************************/ +/** +* +* Run a self-test on the driver/device. This test reads the ID registers and +* compares them. +* +* @param InstancePtr is a pointer to the XScuGic instance. +* +* @return +* +* -XST_SUCCESS if self-test is successful. +* -XST_FAILURE if the self-test is not successful. +* +* @note None. +* +******************************************************************************/ +s32 XScuGic_SelfTest(XScuGic *InstancePtr) +{ + u32 RegValue1 = 0U; + u32 Index; + s32 Status; + + /* + * Assert the arguments + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the ID registers. + */ + for (Index = 0U; Index <= 3U; Index++) { + RegValue1 |= XScuGic_DistReadReg(InstancePtr, + ((u32)XSCUGIC_PCELLID_OFFSET + (Index * 4U))) << + (Index * 8U); + } + + if (XSCUGIC_PCELL_ID != RegValue1) { + Status = XST_FAILURE; + } else { + Status = XST_SUCCESS; + } + return Status; +} +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic_sinit.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic_sinit.c new file mode 100644 index 0000000..3a3d710 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic_sinit.c @@ -0,0 +1,101 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xscugic_sinit.c +* @addtogroup scugic_v4_0 +* @{ +* +* Contains static init functions for the XScuGic driver for the Interrupt +* Controller. See xscugic.h for a detailed description of the driver. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- --------------------------------------------------------
+* 1.00a drg  01/19/10 First release
+* 3.00  kvn  02/13/15 Modified code for MISRA-C:2012 compliance.
+* 3.10  mus  07/17/18 Updated file to fix the various coding style issues
+*                     reported by checkpatch. It fixes CR#1006344.
+*
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xil_types.h" +#include "xil_assert.h" +#include "xparameters.h" +#include "xscugic.h" + +/************************** Constant Definitions *****************************/ + + +/**************************** Type Definitions *******************************/ + + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Variable Definitions *****************************/ + +extern XScuGic_Config XScuGic_ConfigTable[XPAR_SCUGIC_NUM_INSTANCES]; + +/************************** Function Prototypes ******************************/ + +/*****************************************************************************/ +/** +* +* Looks up the device configuration based on the unique device ID. A table +* contains the configuration info for each device in the system. +* +* @param DeviceId is the unique identifier for a device. +* +* @return A pointer to the XScuGic configuration structure for the +* specified device, or NULL if the device was not found. +* +* @note None. +* +******************************************************************************/ +XScuGic_Config *XScuGic_LookupConfig(u16 DeviceId) +{ + XScuGic_Config *CfgPtr = NULL; + u32 Index; + + for (Index = 0U; Index < (u32)XPAR_SCUGIC_NUM_INSTANCES; Index++) { + if (XScuGic_ConfigTable[Index].DeviceId == DeviceId) { + CfgPtr = &XScuGic_ConfigTable[Index]; + break; + } + } + + return (XScuGic_Config *)CfgPtr; +} +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/Makefile b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/Makefile new file mode 100644 index 0000000..7c673d4 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/Makefile @@ -0,0 +1,40 @@ +COMPILER= +ARCHIVER= +CP=cp +COMPILER_FLAGS= +EXTRA_COMPILER_FLAGS= +LIB=libxil.a + +CC_FLAGS = $(COMPILER_FLAGS) +ECC_FLAGS = $(EXTRA_COMPILER_FLAGS) + +RELEASEDIR=../../../lib +INCLUDEDIR=../../../include +INCLUDES=-I./. -I${INCLUDEDIR} + +OUTS = *.o + +LIBSOURCES:=*.c +INCLUDEFILES:=*.h + +OBJECTS = $(addsuffix .o, $(basename $(wildcard *.c))) + +libs: banner scutimer_libs clean + +%.o: %.c + ${COMPILER} $(CC_FLAGS) $(ECC_FLAGS) $(INCLUDES) -o $@ $< + +banner: + echo "Compiling scutimer" + +scutimer_libs: ${OBJECTS} + $(ARCHIVER) -r ${RELEASEDIR}/${LIB} ${OBJECTS} + +.PHONY: include +include: scutimer_includes + +scutimer_includes: + ${CP} ${INCLUDEFILES} ${INCLUDEDIR} + +clean: + rm -rf ${OBJECTS} diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/xscutimer.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/xscutimer.c new file mode 100644 index 0000000..d7f6348 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/xscutimer.c @@ -0,0 +1,282 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xscutimer.c +* @addtogroup scutimer_v2_1 +* @{ +* +* Contains the implementation of interface functions of the SCU Timer driver. +* See xscutimer.h for a description of the driver. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who Date     Changes
+* ----- --- -------- ---------------------------------------------
+* 1.00a nm  03/10/10 First release
+* 2.1 	sk  02/26/15 Modified the code for MISRA-C:2012 compliance.
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xscutimer.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/************************** Variable Definitions *****************************/ + +/****************************************************************************/ +/** +* +* Initialize a specific timer instance/driver. This function must be called +* before other functions of the driver are called. +* +* @param InstancePtr is a pointer to the XScuTimer instance. +* @param ConfigPtr points to the XScuTimer configuration structure. +* @param EffectiveAddress is the base address for the device. It could be +* a virtual address if address translation is supported in the +* system, otherwise it is the physical address. +* +* @return +* - XST_SUCCESS if initialization was successful. +* - XST_DEVICE_IS_STARTED if the device has already been started. +* +* @note None. +* +******************************************************************************/ +s32 XScuTimer_CfgInitialize(XScuTimer *InstancePtr, + XScuTimer_Config *ConfigPtr, u32 EffectiveAddress) +{ + s32 Status; + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(ConfigPtr != NULL); + + /* + * If the device is started, disallow the initialize and return a + * status indicating it is started. This allows the user to stop the + * device and reinitialize, but prevents a user from inadvertently + * initializing. + */ + if (InstancePtr->IsStarted != XIL_COMPONENT_IS_STARTED) { + /* + * Copy configuration into the instance structure. + */ + InstancePtr->Config.DeviceId = ConfigPtr->DeviceId; + + /* + * Save the base address pointer such that the registers of the block + * can be accessed and indicate it has not been started yet. + */ + InstancePtr->Config.BaseAddr = EffectiveAddress; + + InstancePtr->IsStarted = (u32)0; + + /* + * Indicate the instance is ready to use, successfully initialized. + */ + InstancePtr->IsReady = XIL_COMPONENT_IS_READY; + + Status =(s32)XST_SUCCESS; + } + else { + Status = (s32)XST_DEVICE_IS_STARTED; + } + return Status; +} + +/****************************************************************************/ +/** +* +* Start the timer. +* +* @param InstancePtr is a pointer to the XScuTimer instance. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XScuTimer_Start(XScuTimer *InstancePtr) +{ + u32 Register; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the contents of the Control register. + */ + Register = XScuTimer_ReadReg(InstancePtr->Config.BaseAddr, + XSCUTIMER_CONTROL_OFFSET); + + /* + * Set the 'timer enable' bit in the register. + */ + Register |= XSCUTIMER_CONTROL_ENABLE_MASK; + + /* + * Update the Control register with the new value. + */ + XScuTimer_WriteReg(InstancePtr->Config.BaseAddr, + XSCUTIMER_CONTROL_OFFSET, Register); + + /* + * Indicate that the device is started. + */ + InstancePtr->IsStarted = XIL_COMPONENT_IS_STARTED; +} + +/****************************************************************************/ +/** +* +* Stop the timer. +* +* @param InstancePtr is a pointer to the XScuTimer instance. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XScuTimer_Stop(XScuTimer *InstancePtr) +{ + u32 Register; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the contents of the Control register. + */ + Register = XScuTimer_ReadReg(InstancePtr->Config.BaseAddr, + XSCUTIMER_CONTROL_OFFSET); + + /* + * Clear the 'timer enable' bit in the register. + */ + Register &= (u32)(~XSCUTIMER_CONTROL_ENABLE_MASK); + + /* + * Update the Control register with the new value. + */ + XScuTimer_WriteReg(InstancePtr->Config.BaseAddr, + XSCUTIMER_CONTROL_OFFSET, Register); + + /* + * Indicate that the device is stopped. + */ + InstancePtr->IsStarted = (u32)0; +} + +/*****************************************************************************/ +/** +* +* This function sets the prescaler bits in the timer control register. +* +* @param InstancePtr is a pointer to the XScuTimer instance. +* @param PrescalerValue is a 8 bit value that sets the prescaler to use. +* +* @return None +* +* @note None +* +****************************************************************************/ +void XScuTimer_SetPrescaler(XScuTimer *InstancePtr, u8 PrescalerValue) +{ + u32 ControlReg; + + /* + * Assert to validate input arguments. + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + /* + * Read the Timer control register. + */ + ControlReg = XScuTimer_ReadReg(InstancePtr->Config.BaseAddr, + XSCUTIMER_CONTROL_OFFSET); + + /* + * Clear all of the prescaler control bits in the register. + */ + ControlReg &= (u32)(~XSCUTIMER_CONTROL_PRESCALER_MASK); + + /* + * Set the prescaler value. + */ + ControlReg |= (((u32)PrescalerValue) << XSCUTIMER_CONTROL_PRESCALER_SHIFT); + + /* + * Write the register with the new values. + */ + XScuTimer_WriteReg(InstancePtr->Config.BaseAddr, + XSCUTIMER_CONTROL_OFFSET, ControlReg); +} + +/*****************************************************************************/ +/** +* +* This function returns the current prescaler value. +* +* @param InstancePtr is a pointer to the XScuTimer instance. +* +* @return The prescaler value. +* +* @note None. +* +****************************************************************************/ +u8 XScuTimer_GetPrescaler(XScuTimer *InstancePtr) +{ + u32 ControlReg; + + /* + * Assert to validate input arguments. + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the Timer control register. + */ + ControlReg = XScuTimer_ReadReg(InstancePtr->Config.BaseAddr, + XSCUTIMER_CONTROL_OFFSET); + ControlReg &= XSCUTIMER_CONTROL_PRESCALER_MASK; + + return (u8)(ControlReg >> XSCUTIMER_CONTROL_PRESCALER_SHIFT); +} +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/xscutimer.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/xscutimer.h new file mode 100644 index 0000000..5434684 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/xscutimer.h @@ -0,0 +1,364 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xscutimer.h +* @addtogroup scutimer_v2_1 +* @{ +* @details +* +* The timer driver supports the Cortex A9 private timer. +* +* The timer driver supports the following features: +* - Normal mode and Auto reload mode +* - Interrupts (Interrupt handler is not provided in this driver. Application +* has to register it's own handler) +* +* Initialization and Configuration +* +* The device driver enables higher layer software (e.g., an application) to +* communicate with the Timer. +* +* XScuTimer_CfgInitialize() API is used to initialize the Timer. The +* user needs to first call the XScuTimer_LookupConfig() API which returns +* the Configuration structure pointer which is passed as a parameter to +* the XScuTimer_CfgInitialize() API. +* +* Interrupts +* +* The Timer hardware supports interrupts. +* +* This driver does not provide a Interrupt Service Routine (ISR) for the device. +* It is the responsibility of the application to provide one if needed. Refer to +* the interrupt example provided with this driver for details on using the +* Timer in interrupt mode. +* +* Virtual Memory +* +* This driver supports Virtual Memory. The RTOS is responsible for calculating +* the correct device base address in Virtual Memory space. +* +* Threads +* +* This driver is not thread safe. Any needs for threads or thread mutual +* exclusion must be satisfied by the layer above this driver. +* +* Asserts +* +* Asserts are used within all Xilinx drivers to enforce constraints on argument +* values. Asserts can be turned off on a system-wide basis by defining, at +* compile time, the NDEBUG identifier. By default, asserts are turned on and it +* is recommended that users leave asserts on during development. +* +* Building the driver +* +* The XScuTimer driver is composed of several source files. This allows the user +* to build and link only those parts of the driver that are necessary. +* +*

+* +* NOTE: +* The timer is not a part of the snoop control unit as indicated by the +* prefix "scu" in the name of the driver. +* It is an independent module in APU. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who Date     Changes
+* ----- --- -------- ---------------------------------------------
+* 1.00a nm  03/10/10 First release
+* 1.02a sg  07/17/12 Included xil_assert.h for CR 667947. This is an issue
+*		     when the xstatus.h in the common driver overwrites
+*		     the xstatus.h of the standalone BSP during the
+*		     libgen.
+* 2.1 	sk  02/26/15 Modified the code for MISRA-C:2012 compliance.
+*       ms  03/17/17 Added readme.txt file in examples folder for doxygen
+*                    generation.
+* 
+* +******************************************************************************/ +#ifndef XSCUTIMER_H /* prevent circular inclusions */ +#define XSCUTIMER_H /* by using protection macros */ + +/***************************** Include Files *********************************/ + +#include "xstatus.h" +#include "xscutimer_hw.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/** + * This typedef contains configuration information for the device. + */ +typedef struct { + u16 DeviceId; /**< Unique ID of device */ + u32 BaseAddr; /**< Base address of the device */ +} XScuTimer_Config; + +/** + * The XScuTimer driver instance data. The user is required to allocate a + * variable of this type for every timer device in the system. + * A pointer to a variable of this type is then passed to the driver API + * functions. + */ +typedef struct { + XScuTimer_Config Config; /**< Hardware Configuration */ + u32 IsReady; /**< Device is initialized and ready */ + u32 IsStarted; /**< Device timer is running */ +} XScuTimer; + +/***************** Macros (Inline Functions) Definitions *********************/ + +/****************************************************************************/ +/** +* +* Check if the timer has expired. +* +* @param InstancePtr is a pointer to the XScuTimer instance. +* +* @return +* - TRUE if the timer has expired. +* - FALSE if the timer has not expired. +* +* @note C-style signature: +* int XScuTimer_IsExpired(XScuTimer *InstancePtr) +* +******************************************************************************/ +#define XScuTimer_IsExpired(InstancePtr) \ + ((XScuTimer_ReadReg((InstancePtr)->Config.BaseAddr, \ + XSCUTIMER_ISR_OFFSET) & \ + XSCUTIMER_ISR_EVENT_FLAG_MASK) == \ + XSCUTIMER_ISR_EVENT_FLAG_MASK) + +/****************************************************************************/ +/** +* +* Re-start the timer. This macro will read the timer load register +* and writes the same value to load register to update the counter register. +* +* @param InstancePtr is a pointer to the XScuTimer instance. +* +* @return None. +* +* @note C-style signature: +* void XScuTimer_RestartTimer(XScuTimer *InstancePtr) +* +******************************************************************************/ +#define XScuTimer_RestartTimer(InstancePtr) \ + XScuTimer_LoadTimer((InstancePtr), \ + XScuTimer_ReadReg((InstancePtr)->Config.BaseAddr, \ + XSCUTIMER_LOAD_OFFSET)) + +/****************************************************************************/ +/** +* +* Write to the timer load register. This will also update the +* timer counter register with the new value. This macro can be used to +* change the time-out value. +* +* @param InstancePtr is a pointer to the XScuTimer instance. +* @param Value is the count to be loaded in to the load register. +* +* @return None. +* +* @note C-style signature: +* void XScuTimer_LoadTimer(XScuTimer *InstancePtr, u32 Value) +* +******************************************************************************/ +#define XScuTimer_LoadTimer(InstancePtr, Value) \ + XScuTimer_WriteReg((InstancePtr)->Config.BaseAddr, \ + XSCUTIMER_LOAD_OFFSET, (Value)) + +/****************************************************************************/ +/** +* +* Returns the current timer counter register value. It can be called at any +* time. +* +* @param InstancePtr is a pointer to the XScuTimer instance. +* +* @return Contents of the timer counter register. +* +* @note C-style signature: + u32 XScuTimer_GetCounterValue(XScuTimer *InstancePtr) +* +******************************************************************************/ +#define XScuTimer_GetCounterValue(InstancePtr) \ + XScuTimer_ReadReg((InstancePtr)->Config.BaseAddr, \ + XSCUTIMER_COUNTER_OFFSET) + +/****************************************************************************/ +/** +* +* Enable auto-reload mode. +* +* @param InstancePtr is a pointer to the XScuTimer instance. +* +* @return None. +* +* @note C-style signature: +* void XScuTimer_EnableAutoReload(XScuTimer *InstancePtr) +* +******************************************************************************/ +#define XScuTimer_EnableAutoReload(InstancePtr) \ + XScuTimer_WriteReg((InstancePtr)->Config.BaseAddr, \ + XSCUTIMER_CONTROL_OFFSET, \ + (XScuTimer_ReadReg((InstancePtr)->Config.BaseAddr, \ + XSCUTIMER_CONTROL_OFFSET) | \ + XSCUTIMER_CONTROL_AUTO_RELOAD_MASK)) + +/****************************************************************************/ +/** +* +* Disable auto-reload mode. +* +* @param InstancePtr is a pointer to the XScuTimer instance. +* +* @return None. +* +* @note C-style signature: +* void XScuTimer_DisableAutoReload(XScuTimer *InstancePtr) +* +******************************************************************************/ +#define XScuTimer_DisableAutoReload(InstancePtr) \ + XScuTimer_WriteReg((InstancePtr)->Config.BaseAddr, \ + XSCUTIMER_CONTROL_OFFSET, \ + (XScuTimer_ReadReg((InstancePtr)->Config.BaseAddr, \ + XSCUTIMER_CONTROL_OFFSET) & \ + ~(XSCUTIMER_CONTROL_AUTO_RELOAD_MASK))) + +/****************************************************************************/ +/** +* +* Enable the Timer interrupt. +* +* @param InstancePtr is a pointer to the XScuTimer instance. +* +* @return None. +* +* @note C-style signature: +* void XScuTimer_EnableInterrupt(XScuTimer *InstancePtr) +* +******************************************************************************/ +#define XScuTimer_EnableInterrupt(InstancePtr) \ + XScuTimer_WriteReg((InstancePtr)->Config.BaseAddr, \ + XSCUTIMER_CONTROL_OFFSET, \ + (XScuTimer_ReadReg((InstancePtr)->Config.BaseAddr, \ + XSCUTIMER_CONTROL_OFFSET) | \ + XSCUTIMER_CONTROL_IRQ_ENABLE_MASK)) + +/****************************************************************************/ +/** +* +* Disable the Timer interrupt. +* +* @param InstancePtr is a pointer to the XScuTimer instance. +* +* @return None. +* +* @note C-style signature: +* void XScuTimer_DisableInterrupt(XScuTimer *InstancePtr) +* +******************************************************************************/ +#define XScuTimer_DisableInterrupt(InstancePtr) \ + XScuTimer_WriteReg((InstancePtr)->Config.BaseAddr, \ + XSCUTIMER_CONTROL_OFFSET, \ + (XScuTimer_ReadReg((InstancePtr)->Config.BaseAddr, \ + XSCUTIMER_CONTROL_OFFSET) & \ + ~(XSCUTIMER_CONTROL_IRQ_ENABLE_MASK))) + +/*****************************************************************************/ +/** +* +* This function reads the interrupt status. +* +* @param InstancePtr is a pointer to the XScuTimer instance. +* +* @return None. +* +* @note C-style signature: +* void XScuTimer_GetInterruptStatus(XScuTimer *InstancePtr) +* +******************************************************************************/ +#define XScuTimer_GetInterruptStatus(InstancePtr) \ + XScuTimer_ReadReg((InstancePtr)->Config.BaseAddr, \ + XSCUTIMER_ISR_OFFSET) + +/*****************************************************************************/ +/** +* +* This function clears the interrupt status. +* +* @param InstancePtr is a pointer to the XScuTimer instance. +* +* @return None. +* +* @note C-style signature: +* void XScuTimer_ClearInterruptStatus(XScuTimer *InstancePtr) +* +******************************************************************************/ +#define XScuTimer_ClearInterruptStatus(InstancePtr) \ + XScuTimer_WriteReg((InstancePtr)->Config.BaseAddr, \ + XSCUTIMER_ISR_OFFSET, XSCUTIMER_ISR_EVENT_FLAG_MASK) + +/************************** Function Prototypes ******************************/ + +/* + * Lookup configuration in xscutimer_sinit.c + */ +XScuTimer_Config *XScuTimer_LookupConfig(u16 DeviceId); + +/* + * Selftest function in xscutimer_selftest.c + */ +s32 XScuTimer_SelfTest(XScuTimer *InstancePtr); + +/* + * Interface functions in xscutimer.c + */ +s32 XScuTimer_CfgInitialize(XScuTimer *InstancePtr, + XScuTimer_Config *ConfigPtr, u32 EffectiveAddress); +void XScuTimer_Start(XScuTimer *InstancePtr); +void XScuTimer_Stop(XScuTimer *InstancePtr); +void XScuTimer_SetPrescaler(XScuTimer *InstancePtr, u8 PrescalerValue); +u8 XScuTimer_GetPrescaler(XScuTimer *InstancePtr); + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/xscutimer_g.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/xscutimer_g.c new file mode 100644 index 0000000..d1e3c24 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/xscutimer_g.c @@ -0,0 +1,51 @@ + +/******************************************************************* +* +* CAUTION: This file is automatically generated by HSI. +* Version: 2019.1.3 +* DO NOT EDIT. +* +* Copyright (C) 2010-2023 Xilinx, Inc. All Rights Reserved.* +*Permission is hereby granted, free of charge, to any person obtaining a copy +*of this software and associated documentation files (the Software), to deal +*in the Software without restriction, including without limitation the rights +*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +*copies of the Software, and to permit persons to whom the Software is +*furnished to do so, subject to the following conditions: +* +*The above copyright notice and this permission notice shall be included in +*all copies or substantial portions of the Software. +* +*THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +*XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +*OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*Except as contained in this notice, the name of the Xilinx shall not be used +*in advertising or otherwise to promote the sale, use or other dealings in +*this Software without prior written authorization from Xilinx. +* + +* +* Description: Driver configuration +* +*******************************************************************/ + +#include "xparameters.h" +#include "xscutimer.h" + +/* +* The configuration table for devices +*/ + +XScuTimer_Config XScuTimer_ConfigTable[XPAR_XSCUTIMER_NUM_INSTANCES] = +{ + { + XPAR_PS7_SCUTIMER_0_DEVICE_ID, + XPAR_PS7_SCUTIMER_0_BASEADDR + } +}; + + diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/xscutimer_hw.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/xscutimer_hw.h new file mode 100644 index 0000000..d577784 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/xscutimer_hw.h @@ -0,0 +1,283 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xscutimer_hw.h +* @addtogroup scutimer_v2_1 +* @{ +* +* This file contains the hardware interface to the Timer. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who Date     Changes
+* ----- --- -------- ---------------------------------------------
+* 1.00a nm  03/10/10 First release
+* 1.01a sdm 02/02/12 Added low level macros to read/write load, counter, control
+*		     and interrupt registers
+* 1.02a  sg 07/17/12 Included xil_assert.h for CR 667947. This is an issue
+*		     when the xstatus.h in the common driver overwrites
+*		     the xstatus.h of the standalone BSP during the
+*		     libgen.
+* 2.1 	sk  02/26/15 Modified the code for MISRA-C:2012 compliance.
+* 
+* +******************************************************************************/ +#ifndef XSCUTIMER_HW_H /* prevent circular inclusions */ +#define XSCUTIMER_HW_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ +#include "xil_types.h" +#include "xil_io.h" +#include "xil_assert.h" +/************************** Constant Definitions *****************************/ + +/** @name Register Map + * Offsets of registers from the start of the device + * @{ + */ + +#define XSCUTIMER_LOAD_OFFSET 0x00U /**< Timer Load Register */ +#define XSCUTIMER_COUNTER_OFFSET 0x04U /**< Timer Counter Register */ +#define XSCUTIMER_CONTROL_OFFSET 0x08U /**< Timer Control Register */ +#define XSCUTIMER_ISR_OFFSET 0x0CU /**< Timer Interrupt + Status Register */ +/* @} */ + +/** @name Timer Control register + * This register bits control the prescaler, Intr enable, + * auto-reload and timer enable. + * @{ + */ + +#define XSCUTIMER_CONTROL_PRESCALER_MASK 0x0000FF00U /**< Prescaler */ +#define XSCUTIMER_CONTROL_PRESCALER_SHIFT 8U +#define XSCUTIMER_CONTROL_IRQ_ENABLE_MASK 0x00000004U /**< Intr enable */ +#define XSCUTIMER_CONTROL_AUTO_RELOAD_MASK 0x00000002U /**< Auto-reload */ +#define XSCUTIMER_CONTROL_ENABLE_MASK 0x00000001U /**< Timer enable */ +/* @} */ + +/** @name Interrupt Status register + * This register indicates the Timer counter register has reached zero. + * @{ + */ + +#define XSCUTIMER_ISR_EVENT_FLAG_MASK 0x00000001U /**< Event flag */ +/*@}*/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/****************************************************************************/ +/** +* +* Write to the timer load register. This will also update the +* timer counter register with the new value. This macro can be used to +* change the time-out value. +* +* @param BaseAddr is the base address of the scu timer. +* @param Value is the count to be loaded in to the load register. +* +* @return None. +* +* @note C-style signature: +* void XScuTimer_SetLoadReg(u32 BaseAddr, u32 Value) +* +******************************************************************************/ +#define XScuTimer_SetLoadReg(BaseAddr, Value) \ + XScuTimer_WriteReg(BaseAddr, XSCUTIMER_LOAD_OFFSET, (Value)) + +/****************************************************************************/ +/** +* +* Returns the current timer load register value. +* +* @param BaseAddr is the base address of the scu timer. +* +* @return Contents of the timer load register. +* +* @note C-style signature: +* u32 XScuTimer_GetLoadReg(u32 BaseAddr) +* +******************************************************************************/ +#define XScuTimer_GetLoadReg(BaseAddr) \ + XScuTimer_ReadReg(BaseAddr, XSCUTIMER_LOAD_OFFSET) + +/****************************************************************************/ +/** +* +* Write to the timer counter register. +* +* @param BaseAddr is the base address of the scu timer. +* @param Value is the count to be loaded in to the counter register. +* +* @return None. +* +* @note C-style signature: +* void XScuTimer_SetCounterReg(u32 BaseAddr, u32 Value) +* +******************************************************************************/ +#define XScuTimer_SetCounterReg(BaseAddr, Value) \ + XScuTimer_WriteReg(BaseAddr, XSCUTIMER_COUNTER_OFFSET, (Value)) + +/****************************************************************************/ +/** +* +* Returns the current timer counter register value. +* +* @param BaseAddr is the base address of the scu timer. +* +* @return Contents of the timer counter register. +* +* @note C-style signature: + u32 XScuTimer_GetCounterReg(u32 BaseAddr) +* +******************************************************************************/ +#define XScuTimer_GetCounterReg(BaseAddr) \ + XScuTimer_ReadReg(BaseAddr, XSCUTIMER_COUNTER_OFFSET) + +/****************************************************************************/ +/** +* +* Write to the timer load register. This will also update the +* timer counter register with the new value. This macro can be used to +* change the time-out value. +* +* @param BaseAddr is the base address of the scu timer. +* @param Value is the count to be loaded in to the load register. +* +* @return None. +* +* @note C-style signature: +* void XScuTimer_SetControlReg(u32 BaseAddr, u32 Value) +* +******************************************************************************/ +#define XScuTimer_SetControlReg(BaseAddr, Value) \ + XScuTimer_WriteReg(BaseAddr, XSCUTIMER_CONTROL_OFFSET, (Value)) + +/****************************************************************************/ +/** +* +* Returns the current timer load register value. +* +* @param BaseAddr is the base address of the scu timer. +* +* @return Contents of the timer load register. +* +* @note C-style signature: + u32 XScuTimer_GetControlReg(u32 BaseAddr) +* +******************************************************************************/ +#define XScuTimer_GetControlReg(BaseAddr) \ + XScuTimer_ReadReg(BaseAddr, XSCUTIMER_CONTROL_OFFSET) + +/****************************************************************************/ +/** +* +* Write to the timer counter register. +* +* @param BaseAddr is the base address of the scu timer. +* @param Value is the count to be loaded in to the counter register. +* +* @return None. +* +* @note C-style signature: +* void XScuTimer_SetIntrReg(u32 BaseAddr, u32 Value) +* +******************************************************************************/ +#define XScuTimer_SetIntrReg(BaseAddr, Value) \ + XScuTimer_WriteReg(BaseAddr, XSCUTIMER_ISR_OFFSET, (Value)) + +/****************************************************************************/ +/** +* +* Returns the current timer counter register value. +* +* @param BaseAddr is the base address of the scu timer. +* +* @return Contents of the timer counter register. +* +* @note C-style signature: + u32 XScuTimer_GetIntrReg(u32 BaseAddr) +* +******************************************************************************/ +#define XScuTimer_GetIntrReg(BaseAddr) \ + XScuTimer_ReadReg(BaseAddr, XSCUTIMER_ISR_OFFSET) + +/****************************************************************************/ +/** +* +* Read from the given Timer register. +* +* @param BaseAddr is the base address of the device +* @param RegOffset is the register offset to be read +* +* @return The 32-bit value of the register +* +* @note C-style signature: +* u32 XScuTimer_ReadReg(u32 BaseAddr, u32 RegOffset) +* +*****************************************************************************/ +#define XScuTimer_ReadReg(BaseAddr, RegOffset) \ + Xil_In32((BaseAddr) + (RegOffset)) + +/****************************************************************************/ +/** +* +* Write to the given Timer register. +* +* @param BaseAddr is the base address of the device +* @param RegOffset is the register offset to be written +* @param Data is the 32-bit value to write to the register +* +* @return None. +* +* @note C-style signature: +* void XScuTimer_WriteReg(u32 BaseAddr, u32 RegOffset, u32 Data) +* +*****************************************************************************/ +#define XScuTimer_WriteReg(BaseAddr, RegOffset, Data) \ + Xil_Out32((BaseAddr) + (RegOffset), (Data)) + +/************************** Function Prototypes ******************************/ + +/************************** Variable Definitions *****************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/xscutimer_selftest.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/xscutimer_selftest.c new file mode 100644 index 0000000..b3464b6 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/xscutimer_selftest.c @@ -0,0 +1,135 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xscutimer_selftest.c +* @addtogroup scutimer_v2_1 +* @{ +* +* Contains diagnostic self-test functions for the XScuTimer driver. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who Date     Changes
+* ----- --- -------- ---------------------------------------------
+* 1.00a nm  03/10/10 First release
+* 2.1 	sk  02/26/15 Modified the code for MISRA-C:2012 compliance.
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xscutimer.h" + +/************************** Constant Definitions *****************************/ + +#define XSCUTIMER_SELFTEST_VALUE 0xA55AF00FU + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/************************** Variable Definitions *****************************/ + +/****************************************************************************/ +/** +* +* Run a self-test on the timer. This test clears the timer enable bit in +* the control register, writes to the timer load register and verifies the +* value read back matches the value written and restores the control register +* and the timer load register. +* +* @param InstancePtr is a pointer to the XScuTimer instance. +* +* @return +* - XST_SUCCESS if self-test was successful. +* - XST_FAILURE if self test was not successful. +* +* @note None. +* +******************************************************************************/ +s32 XScuTimer_SelfTest(XScuTimer *InstancePtr) +{ + u32 Register; + u32 CtrlOrig; + u32 LoadOrig; + s32 Status; + + /* + * Assert to ensure the inputs are valid and the instance has been + * initialized. + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Save the contents of the Control Register and stop the timer. + */ + CtrlOrig = XScuTimer_ReadReg(InstancePtr->Config.BaseAddr, + XSCUTIMER_CONTROL_OFFSET); + Register = CtrlOrig & (u32)(~XSCUTIMER_CONTROL_ENABLE_MASK); + XScuTimer_WriteReg(InstancePtr->Config.BaseAddr, + XSCUTIMER_CONTROL_OFFSET, Register); + + /* + * Save the contents of the Load Register. + * Load a new test value in the Load Register, read it back and + * compare it with the written value. + */ + LoadOrig = XScuTimer_ReadReg((InstancePtr)->Config.BaseAddr, + XSCUTIMER_LOAD_OFFSET); + XScuTimer_LoadTimer(InstancePtr, XSCUTIMER_SELFTEST_VALUE); + Register = XScuTimer_ReadReg((InstancePtr)->Config.BaseAddr, + XSCUTIMER_LOAD_OFFSET); + + /* + * Restore the contents of the Load Register and Control Register. + */ + XScuTimer_LoadTimer(InstancePtr, LoadOrig); + XScuTimer_WriteReg(InstancePtr->Config.BaseAddr, + XSCUTIMER_CONTROL_OFFSET, CtrlOrig); + + /* + * Return a Failure if the contents of the Load Register do not + * match with the value written to it. + */ + if (Register != XSCUTIMER_SELFTEST_VALUE) { + Status = (s32)XST_FAILURE; + } + else { + Status = (s32)XST_SUCCESS; + } + + return Status; +} +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/xscutimer_sinit.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/xscutimer_sinit.c new file mode 100644 index 0000000..0c5f671 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/xscutimer_sinit.c @@ -0,0 +1,92 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xscutimer_sinit.c +* @addtogroup scutimer_v2_1 +* @{ +* +* This file contains method for static initialization (compile-time) of the +* driver. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who Date     Changes
+* ----- --- -------- ---------------------------------------------
+* 1.00a nm  03/10/10 First release
+* 2.1 	sk  02/26/15 Modified the code for MISRA-C:2012 compliance.
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xscutimer.h" +#include "xparameters.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Variable Definitions ****************************/ +extern XScuTimer_Config XScuTimer_ConfigTable[XPAR_XSCUTIMER_NUM_INSTANCES]; + +/************************** Function Prototypes ******************************/ + +/*****************************************************************************/ +/** +* Lookup the device configuration based on the unique device ID. The table +* contains the configuration info for each device in the system. +* +* @param DeviceId is the unique device ID of the device being looked up. +* +* @return A pointer to the configuration table entry corresponding to the +* given device ID, or NULL if no match is found. +* +* @note None. +* +******************************************************************************/ +XScuTimer_Config *XScuTimer_LookupConfig(u16 DeviceId) +{ + XScuTimer_Config *CfgPtr = NULL; + u32 Index; + + for (Index = 0U; Index < XPAR_XSCUTIMER_NUM_INSTANCES; Index++) { + if (XScuTimer_ConfigTable[Index].DeviceId == DeviceId) { + CfgPtr = &XScuTimer_ConfigTable[Index]; + break; + } + } + + return (XScuTimer_Config *)CfgPtr; +} +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/Makefile b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/Makefile new file mode 100644 index 0000000..493ad9a --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/Makefile @@ -0,0 +1,40 @@ +COMPILER= +ARCHIVER= +CP=cp +COMPILER_FLAGS= +EXTRA_COMPILER_FLAGS= +LIB=libxil.a + +CC_FLAGS = $(COMPILER_FLAGS) +ECC_FLAGS = $(EXTRA_COMPILER_FLAGS) + +RELEASEDIR=../../../lib +INCLUDEDIR=../../../include +INCLUDES=-I./. -I${INCLUDEDIR} + +OUTS = *.o + +LIBSOURCES:=*.c +INCLUDEFILES:=*.h + +OBJECTS = $(addsuffix .o, $(basename $(wildcard *.c))) + +libs: banner scuwdt_libs clean + +%.o: %.c + ${COMPILER} $(CC_FLAGS) $(ECC_FLAGS) $(INCLUDES) -o $@ $< + +banner: + echo "Compiling scuwdt" + +scuwdt_libs: ${OBJECTS} + $(ARCHIVER) -r ${RELEASEDIR}/${LIB} ${OBJECTS} + +.PHONY: include +include: scuwdt_includes + +scuwdt_includes: + ${CP} ${INCLUDEFILES} ${INCLUDEDIR} + +clean: + rm -rf ${OBJECTS} diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/xscuwdt.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/xscuwdt.c new file mode 100644 index 0000000..85f0507 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/xscuwdt.c @@ -0,0 +1,213 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xscuwdt.c +* @addtogroup scuwdt_v2_1 +* @{ +* +* Contains the implementation of interface functions of the XScuWdt driver. +* See xscuwdt.h for a description of the driver. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who Date     Changes
+* ----- --- -------- ---------------------------------------------
+* 1.00a sdm 01/15/10 First release
+* 2.1 	sk  02/26/15 Modified the code for MISRA-C:2012 compliance.
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xscuwdt.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/************************** Variable Definitions *****************************/ + +/****************************************************************************/ +/** +* +* Initialize a specific watchdog timer instance/driver. This function +* must be called before other functions of the driver are called. +* +* @param InstancePtr is a pointer to the XScuWdt instance. +* @param ConfigPtr is the config structure. +* @param EffectiveAddress is the base address for the device. It could be +* a virtual address if address translation is supported in the +* system, otherwise it is the physical address. +* +* @return +* - XST_SUCCESS if initialization was successful. +* - XST_DEVICE_IS_STARTED if the device has already been started. +* +* @note This function enables the watchdog mode. +* +******************************************************************************/ +s32 XScuWdt_CfgInitialize(XScuWdt *InstancePtr, + XScuWdt_Config *ConfigPtr, u32 EffectiveAddress) +{ + s32 CfgStatus; + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(ConfigPtr != NULL); + Xil_AssertNonvoid(EffectiveAddress != 0x00U); + + /* + * If the device is started, disallow the initialize and return a + * status indicating it is started. This allows the user to stop the + * device and reinitialize, but prevents a user from inadvertently + * initializing. + */ + if (InstancePtr->IsStarted == XIL_COMPONENT_IS_STARTED) { + CfgStatus = (s32)XST_DEVICE_IS_STARTED; + } + else { + /* + * Copy configuration into instance. + */ + InstancePtr->Config.DeviceId = ConfigPtr->DeviceId; + + /* + * Save the base address pointer such that the registers of the block + * can be accessed and indicate it has not been started yet. + */ + InstancePtr->Config.BaseAddr = EffectiveAddress; + InstancePtr->IsStarted = 0U; + + /* + * Put the watchdog timer in Watchdog mode. + */ + XScuWdt_SetWdMode(InstancePtr); + + /* + * Indicate the instance is ready to use, successfully initialized. + */ + InstancePtr->IsReady = XIL_COMPONENT_IS_READY; + + CfgStatus =(s32)XST_SUCCESS; + } + return CfgStatus; +} + +/****************************************************************************/ +/** +* +* Start the watchdog counter of the device. +* +* @param InstancePtr is a pointer to the XScuWdt instance. +* +* @return None. +* +* @note User needs to select the appropriate mode (watchdog/timer) +* before using this API. +* See XScuWdt_SetWdMode/XScuWdt_SetTimerMode macros in +* xscuwdt.h. +* +******************************************************************************/ +void XScuWdt_Start(XScuWdt *InstancePtr) +{ + u32 Register; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the contents of the Control register. + */ + Register = XScuWdt_ReadReg(InstancePtr->Config.BaseAddr, + XSCUWDT_CONTROL_OFFSET); + + /* + * Set the 'watchdog enable' bit in the register. + */ + Register |= XSCUWDT_CONTROL_WD_ENABLE_MASK; + + /* + * Update the Control register with the new value. + */ + XScuWdt_WriteReg(InstancePtr->Config.BaseAddr, + XSCUWDT_CONTROL_OFFSET, Register); + + /* + * Indicate that the device is started. + */ + InstancePtr->IsStarted = XIL_COMPONENT_IS_STARTED; +} + +/****************************************************************************/ +/** +* +* Stop the watchdog timer. +* +* @param InstancePtr is a pointer to the XScuWdt instance. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XScuWdt_Stop(XScuWdt *InstancePtr) +{ + u32 Register; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the contents of the Control register. + */ + Register = XScuWdt_ReadReg(InstancePtr->Config.BaseAddr, + XSCUWDT_CONTROL_OFFSET); + + /* + * Clear the 'watchdog enable' bit in the register. + */ + Register &= (u32)(~XSCUWDT_CONTROL_WD_ENABLE_MASK); + + /* + * Update the Control register with the new value. + */ + XScuWdt_WriteReg(InstancePtr->Config.BaseAddr, + XSCUWDT_CONTROL_OFFSET, Register); + + /* + * Indicate that the device is stopped. + */ + InstancePtr->IsStarted = 0U; +} +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/xscuwdt.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/xscuwdt.h new file mode 100644 index 0000000..551eaf5 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/xscuwdt.h @@ -0,0 +1,379 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xscuwdt.h +* @addtogroup scuwdt_v2_1 +* @{ +* @details +* +* The Xilinx SCU watchdog timer driver (XScuWdt) supports the Xilinx SCU private +* watchdog timer hardware. +* +* The XScuWdt driver supports the following features: +* - Watchdog mode +* - Timer mode +* - Auto reload (timer mode only) +* +* The watchdog counter register is a down counter and starts decrementing when +* the watchdog is started. +* In watchdog mode, when the counter reaches 0, the Reset flag is set in the +* Reset status register and the WDRESETREQ pin is asserted, causing a system +* reset. The Reset flag is not reset by normal processor reset and is cleared +* when written with a value of 1. This enables the user to differentiate a +* normal reset and a reset caused by watchdog time-out. The user needs to call +* XScuWdt_RestartWdt() periodically, to avoid the watchdog from being timed-out. +* +* The IsWdtExpired function can be used to check if the watchdog was the cause +* of the last reset. In this situation, call Initialize then call IsWdtExpired. +* If the result is true, watchdog timeout caused the last system reset. The +* application then needs to clear the Reset flag. +* +* In timer mode, when the counter reaches 0, the Event flag is set in the +* Interrupt status register and if interrupts are enabled, interrupt ID 30 is +* set as pending in the interrupt distributor. The IsTimerExpired function +* is used to check if the watchdog counter has decremented to 0 in timer mode. +* If auto-reload mode is enabled, the Counter register is automatically reloaded +* from the Load register. +* +* Initialization and Configuration +* +* The device driver enables higher layer software (e.g., an application) to +* communicate with the Watchdog Timer. +* +* XScuWdt_CfgInitialize() API is used to initialize the Watchdog Timer. The +* user needs to first call the XScuWdt_LookupConfig() API which returns +* the Configuration structure pointer which is passed as a parameter to +* the XScuWdt_CfgInitialize() API. +* +* Interrupts +* +* The SCU Watchdog Timer supports interrupts in Timer mode. +* +* This driver does not provide a Interrupt Service Routine (ISR) for the device. +* It is the responsibility of the application to provide one if needed. Refer to +* the interrupt example provided with this driver for details on using the +* Timer in interrupt mode. +* +* Virtual Memory +* +* This driver supports Virtual Memory. The RTOS is responsible for calculating +* the correct device base address in Virtual Memory space. +* +* Threads +* +* This driver is not thread safe. Any needs for threads or thread mutual +* exclusion must be satisfied by the layer above this driver. +* +* Asserts +* +* Asserts are used within all Xilinx drivers to enforce constraints on argument +* values. Asserts can be turned off on a system-wide basis by defining, at +* compile time, the NDEBUG identifier. By default, asserts are turned on and it +* is recommended that users leave asserts on during development. +* +* Building the driver +* +* The XScuWdt driver is composed of several source files. This allows the user +* to build and link only those parts of the driver that are necessary. +* +*

+* +* NOTE: +* The watchdog timer is not a part of the snoop control unit as indicated +* by the prefix "scu" in the name of the driver. +* It is an independent module in APU. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who Date     Changes
+* ----- --- -------- ---------------------------------------------
+* 1.00a sdm 01/15/10 First release
+* 1.02a  sg 07/17/12 Included xil_assert.h for CR 667947. This is an issue
+*		     when the xstatus.h in the common driver overwrites
+*		     the xstatus.h of the standalone BSP during the
+*		     libgen.
+* 2.1 	sk  02/26/15 Modified the code for MISRA-C:2012 compliance.
+*       ms  03/17/17 Added readme.txt file in examples folder for doxygen
+*                    generation.
+* 
+* +******************************************************************************/ +#ifndef XSCUWDT_H /* prevent circular inclusions */ +#define XSCUWDT_H /* by using protection macros */ + +/***************************** Include Files *********************************/ + +#include "xstatus.h" +#include "xscuwdt_hw.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/** + * This typedef contains configuration information for the device. + */ +typedef struct { + u16 DeviceId; /**< Unique ID of device */ + u32 BaseAddr; /**< Base address of the device */ +} XScuWdt_Config; + +/** + * The XScuWdt driver instance data. The user is required to allocate a + * variable of this type for every watchdog/timer device in the system. + * A pointer to a variable of this type is then passed to the driver API + * functions. + */ +typedef struct { + XScuWdt_Config Config;/**< Hardware Configuration */ + u32 IsReady; /**< Device is initialized and ready */ + u32 IsStarted; /**< Device watchdog timer is running */ +} XScuWdt; + +/***************** Macros (Inline Functions) Definitions *********************/ +/****************************************************************************/ +/** +* +* This function is used to check if the watchdog has timed-out and the last +* reset was caused by the watchdog reset. +* +* @param InstancePtr is a pointer to the XScuWdt instance. +* +* @return +* - TRUE if the watchdog has expired. +* - FALSE if the watchdog has not expired. +* +* @note C-style signature: +* int XScuWdt_IsWdtExpired(XScuWdt *InstancePtr) +* +******************************************************************************/ +#define XScuWdt_IsWdtExpired(InstancePtr) \ + ((XScuWdt_ReadReg((InstancePtr)->Config.BaseAddr, \ + XSCUWDT_RST_STS_OFFSET) & \ + XSCUWDT_RST_STS_RESET_FLAG_MASK) == XSCUWDT_RST_STS_RESET_FLAG_MASK) + +/****************************************************************************/ +/** +* +* This function is used to check if the watchdog counter has reached 0 in timer +* mode. +* +* @param InstancePtr is a pointer to the XScuWdt instance. +* +* @return +* - TRUE if the watchdog has expired. +* - FALSE if the watchdog has not expired. +* +* @note C-style signature: +* int XScuWdt_IsTimerExpired(XScuWdt *InstancePtr) +* +******************************************************************************/ +#define XScuWdt_IsTimerExpired(InstancePtr) \ + ((XScuWdt_ReadReg((InstancePtr)->Config.BaseAddr, \ + XSCUWDT_ISR_OFFSET) & \ + XSCUWDT_ISR_EVENT_FLAG_MASK) == XSCUWDT_ISR_EVENT_FLAG_MASK) + +/****************************************************************************/ +/** +* +* Re-start the watchdog timer. This macro will read the watchdog load register +* and write the same value to load register to update the counter register. +* An application needs to call this function periodically to keep the watchdog +* from asserting the WDRESETREQ reset request output pin. +* +* @param InstancePtr is a pointer to the XScuWdt instance. +* +* @return None. +* +* @note C-style signature: +* void XScuWdt_RestartWdt(XScuWdt *InstancePtr) +* +******************************************************************************/ +#define XScuWdt_RestartWdt(InstancePtr) \ + XScuWdt_LoadWdt((InstancePtr), \ + (XScuWdt_ReadReg((InstancePtr)->Config.BaseAddr, \ + XSCUWDT_LOAD_OFFSET))) + +/****************************************************************************/ +/** +* +* Write to the watchdog timer load register. This will also update the +* watchdog counter register with the new value. This macro can be used to +* change the time-out value. +* +* @param InstancePtr is a pointer to the XScuWdt instance. +* @param Value is the value to be written to the Watchdog Load register. +* +* @return None. +* +* @note C-style signature: +* void XScuWdt_LoadWdt(XScuWdt *InstancePtr, u32 Value) +* +******************************************************************************/ +#define XScuWdt_LoadWdt(InstancePtr, Value) \ + XScuWdt_WriteReg((InstancePtr)->Config.BaseAddr, \ + XSCUWDT_LOAD_OFFSET, (Value)) + +/****************************************************************************/ +/** +* +* Put the watchdog timer in Watchdog mode by setting the WD mode bit of the +* Watchdog control register. +* +* @param InstancePtr is a pointer to the XScuWdt instance. +* +* @return None. +* +* @note C-style signature: +* void XScuWdt_SetWdMode(XScuWdt *InstancePtr) +* +******************************************************************************/ +#define XScuWdt_SetWdMode(InstancePtr) \ + XScuWdt_WriteReg((InstancePtr)->Config.BaseAddr, \ + XSCUWDT_CONTROL_OFFSET, \ + (XScuWdt_ReadReg((InstancePtr)->Config.BaseAddr, \ + XSCUWDT_CONTROL_OFFSET) | \ + (XSCUWDT_CONTROL_WD_MODE_MASK))) + +/****************************************************************************/ +/** +* +* Put the watchdog timer in Timer mode by writing 0x12345678 and 0x87654321 +* successively to the Watchdog Disable Register. +* The software must write 0x12345678 and 0x87654321 successively to the +* Watchdog Disable Register so that the watchdog mode bit in the Watchdog +* Control Register is set to zero. +* +* @param InstancePtr is a pointer to the XScuWdt instance. +* +* @return None. +* +* @note C-style signature: +* void XScuWdt_SetTimerMode(XScuWdt *InstancePtr) +* +******************************************************************************/ +#define XScuWdt_SetTimerMode(InstancePtr) \ +{ \ + XScuWdt_WriteReg((InstancePtr)->Config.BaseAddr, \ + XSCUWDT_DISABLE_OFFSET, \ + XSCUWDT_DISABLE_VALUE1); \ + XScuWdt_WriteReg((InstancePtr)->Config.BaseAddr, \ + XSCUWDT_DISABLE_OFFSET, \ + XSCUWDT_DISABLE_VALUE2); \ +} + +/****************************************************************************/ +/** +* +* Get the contents of the watchdog control register. +* +* @param InstancePtr is a pointer to the XScuWdt instance. +* +* @return Contents of the watchdog control register. +* +* @note C-style signature: + u32 XScuWdt_GetControlReg(XScuWdt *InstancePtr) +* +******************************************************************************/ +#define XScuWdt_GetControlReg(InstancePtr) \ + XScuWdt_ReadReg((InstancePtr)->Config.BaseAddr, \ + XSCUWDT_CONTROL_OFFSET) + +/****************************************************************************/ +/** +* +* Write to the watchdog control register. +* +* @param InstancePtr is a pointer to the XScuWdt instance. +* @param ControlReg is the value to be written to the watchdog control +* register. +* +* @return None. +* +* @note C-style signature: + void XScuWdt_SetControlReg(XScuWdt *InstancePtr, u32 ControlReg) +* +******************************************************************************/ +#define XScuWdt_SetControlReg(InstancePtr, ControlReg) \ + XScuWdt_WriteReg((InstancePtr)->Config.BaseAddr, \ + XSCUWDT_CONTROL_OFFSET, (ControlReg)) + +/****************************************************************************/ +/** +* +* Enable auto-reload mode. +* +* @param InstancePtr is a pointer to the XScuWdt instance. +* +* @return None. +* +* @note C-style signature: +* void XScuWdt_EnableAutoReload(XScuWdt *InstancePtr) +* +******************************************************************************/ +#define XScuWdt_EnableAutoReload(InstancePtr) \ + XScuWdt_SetControlReg((InstancePtr), \ + (XScuWdt_GetControlReg(InstancePtr) | \ + XSCUWDT_CONTROL_AUTO_RELOAD_MASK)) + +/************************** Function Prototypes ******************************/ + +/* + * Lookup configuration in xscuwdt_sinit.c. + */ +XScuWdt_Config *XScuWdt_LookupConfig(u16 DeviceId); + +/* + * Selftest function in xscuwdt_selftest.c + */ +s32 XScuWdt_SelfTest(XScuWdt *InstancePtr); + +/* + * Interface functions in xscuwdt.c + */ +s32 XScuWdt_CfgInitialize(XScuWdt *InstancePtr, + XScuWdt_Config *ConfigPtr, u32 EffectiveAddress); + +void XScuWdt_Start(XScuWdt *InstancePtr); + +void XScuWdt_Stop(XScuWdt *InstancePtr); + + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/xscuwdt_g.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/xscuwdt_g.c new file mode 100644 index 0000000..0097f71 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/xscuwdt_g.c @@ -0,0 +1,51 @@ + +/******************************************************************* +* +* CAUTION: This file is automatically generated by HSI. +* Version: 2019.1.3 +* DO NOT EDIT. +* +* Copyright (C) 2010-2023 Xilinx, Inc. All Rights Reserved.* +*Permission is hereby granted, free of charge, to any person obtaining a copy +*of this software and associated documentation files (the Software), to deal +*in the Software without restriction, including without limitation the rights +*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +*copies of the Software, and to permit persons to whom the Software is +*furnished to do so, subject to the following conditions: +* +*The above copyright notice and this permission notice shall be included in +*all copies or substantial portions of the Software. +* +*THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +*XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +*OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*Except as contained in this notice, the name of the Xilinx shall not be used +*in advertising or otherwise to promote the sale, use or other dealings in +*this Software without prior written authorization from Xilinx. +* + +* +* Description: Driver configuration +* +*******************************************************************/ + +#include "xparameters.h" +#include "xscuwdt.h" + +/* +* The configuration table for devices +*/ + +XScuWdt_Config XScuWdt_ConfigTable[XPAR_XSCUWDT_NUM_INSTANCES] = +{ + { + XPAR_PS7_SCUWDT_0_DEVICE_ID, + XPAR_PS7_SCUWDT_0_BASEADDR + } +}; + + diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/xscuwdt_hw.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/xscuwdt_hw.h new file mode 100644 index 0000000..ad87a05 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/xscuwdt_hw.h @@ -0,0 +1,178 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xscuwdt_hw.h +* @addtogroup scuwdt_v2_1 +* @{ +* +* This file contains the hardware interface to the Xilinx SCU private Watch Dog +* Timer (XSCUWDT). +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who Date     Changes
+* ----- --- -------- ---------------------------------------------
+* 1.00a sdm 01/15/10 First release
+* 1.01a bss 02/27/12 Updated the register offsets to start at 0x0 instead
+*                    of 0x20 as the base address obtained from the tools
+*		     starts at 0x20.
+* 1.02a  sg 07/17/12 Included xil_assert.h for CR 667947. This is an issue
+*		     when the xstatus.h in the common driver overwrites
+*		     the xstatus.h of the standalone BSP during the
+*		     libgen.
+* 2.1 	sk  02/26/15 Modified the code for MISRA-C:2012 compliance.
+* 
+* +******************************************************************************/ +#ifndef XSCUWDT_HW_H /* prevent circular inclusions */ +#define XSCUWDT_HW_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +#include "xil_types.h" +#include "xil_io.h" +#include "xil_assert.h" +/************************** Constant Definitions *****************************/ + +/** @name Register Map + * Offsets of registers from the start of the device. The WDT registers start at + * an offset 0x20 + * @{ + */ + +#define XSCUWDT_LOAD_OFFSET 0x00U /**< Watchdog Load Register */ +#define XSCUWDT_COUNTER_OFFSET 0x04U /**< Watchdog Counter Register */ +#define XSCUWDT_CONTROL_OFFSET 0x08U /**< Watchdog Control Register */ +#define XSCUWDT_ISR_OFFSET 0x0CU /**< Watchdog Interrupt Status Register */ +#define XSCUWDT_RST_STS_OFFSET 0x10U /**< Watchdog Reset Status Register */ +#define XSCUWDT_DISABLE_OFFSET 0x14U /**< Watchdog Disable Register */ +/* @} */ + +/** @name Watchdog Control register + * This register bits control the prescaler, WD/Timer mode, Intr enable, + * auto-reload, watchdog enable. + * @{ + */ + +#define XSCUWDT_CONTROL_PRESCALER_MASK 0x0000FF00U /**< Prescaler */ +#define XSCUWDT_CONTROL_PRESCALER_SHIFT 8U +#define XSCUWDT_CONTROL_WD_MODE_MASK 0x00000008U /**< Watchdog/Timer mode */ +#define XSCUWDT_CONTROL_IT_ENABLE_MASK 0x00000004U /**< Intr enable (in + timer mode) */ +#define XSCUWDT_CONTROL_AUTO_RELOAD_MASK 0x00000002U /**< Auto-reload (in + timer mode) */ +#define XSCUWDT_CONTROL_WD_ENABLE_MASK 0x00000001U /**< Watchdog enable */ +/* @} */ + +/** @name Interrupt Status register + * This register indicates the Counter register has reached zero in Counter + * mode. + * @{ + */ + +#define XSCUWDT_ISR_EVENT_FLAG_MASK 0x00000001U /**< Event flag */ +/*@}*/ + +/** @name Reset Status register + * This register indicates the Counter register has reached zero in Watchdog + * mode and a reset request is sent. + * @{ + */ + +#define XSCUWDT_RST_STS_RESET_FLAG_MASK 0x00000001U /**< Time out occured */ +/*@}*/ + +/** @name Disable register + * This register is used to switch from watchdog mode to timer mode. + * The software must write 0x12345678 and 0x87654321 successively to the + * Watchdog Disable Register so that the watchdog mode bit in the Watchdog + * Control Register is set to zero. + * @{ + */ +#define XSCUWDT_DISABLE_VALUE1 0x12345678U /**< Watchdog mode disable + value 1 */ +#define XSCUWDT_DISABLE_VALUE2 0x87654321U /**< Watchdog mode disable + value 2 */ +/*@}*/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/****************************************************************************/ +/** +* +* Read the given register. +* +* @param BaseAddr is the base address of the device +* @param RegOffset is the register offset to be read +* +* @return The 32-bit value of the register +* +* @note C-style signature: +* u32 XScuWdt_ReadReg(u32 BaseAddr, u32 RegOffset) +* +*****************************************************************************/ +#define XScuWdt_ReadReg(BaseAddr, RegOffset) \ + Xil_In32((BaseAddr) + ((u32)RegOffset)) + +/****************************************************************************/ +/** +* +* Write the given register. +* +* @param BaseAddr is the base address of the device +* @param RegOffset is the register offset to be written +* @param Data is the 32-bit value to write to the register +* +* @return None. +* +* @note C-style signature: +* void XScuWdt_WriteReg(u32 BaseAddr, u32 RegOffset, u32 Data) +* +*****************************************************************************/ +#define XScuWdt_WriteReg(BaseAddr, RegOffset, Data) \ + Xil_Out32((BaseAddr) + ((u32)RegOffset), ((u32)Data)) + +/************************** Function Prototypes ******************************/ + +/************************** Variable Definitions *****************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/xscuwdt_selftest.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/xscuwdt_selftest.c new file mode 100644 index 0000000..aa0cd39 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/xscuwdt_selftest.c @@ -0,0 +1,127 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xscuwdt_selftest.c +* @addtogroup scuwdt_v2_1 +* @{ +* +* Contains diagnostic self-test functions for the XScuWdt driver. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who Date     Changes
+* ----- --- -------- ---------------------------------------------
+* 1.00a sdm 01/15/10 First release
+* 2.1 	sk  02/26/15 Modified the code for MISRA-C:2012 compliance.
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xscuwdt.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/************************** Variable Definitions *****************************/ + +/****************************************************************************/ +/** +* +* Run a self-test on the WDT. This test stops the watchdog, writes a value to +* the watchdog load register, starts the watchdog and verifies that the value +* read from the counter register is less that the value written to the load +* register. It then restores the control register and the watchdog load +* register. +* +* @param InstancePtr is a pointer to the XScuWdt instance. +* +* @return +* - XST_SUCCESS if self-test was successful. +* - XST_FAILURE if the WDT is not decrementing. +* +* @note None. +* +******************************************************************************/ +s32 XScuWdt_SelfTest(XScuWdt *InstancePtr) +{ + s32 SelfTestStatus; + u32 Register; + u32 CtrlOrig; + u32 LoadOrig; + + /* + * Assert to ensure the inputs are valid and the instance has been + * initialized. + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Stop the watchdog timer. + */ + CtrlOrig = XScuWdt_GetControlReg(InstancePtr); + XScuWdt_SetControlReg(InstancePtr, + CtrlOrig & (u32)(~XSCUWDT_CONTROL_WD_ENABLE_MASK)); + + LoadOrig = XScuWdt_ReadReg((InstancePtr)->Config.BaseAddr, + XSCUWDT_LOAD_OFFSET); + XScuWdt_LoadWdt(InstancePtr, 0xFFFFFFFFU); + + /* + * Start the watchdog timer and check if the watchdog counter is + * decrementing. + */ + XScuWdt_SetControlReg(InstancePtr, + CtrlOrig | (u32)XSCUWDT_CONTROL_WD_ENABLE_MASK); + + Register = XScuWdt_ReadReg((InstancePtr)->Config.BaseAddr, + XSCUWDT_COUNTER_OFFSET); + + XScuWdt_LoadWdt(InstancePtr, LoadOrig); + XScuWdt_SetControlReg(InstancePtr, CtrlOrig); + + if (Register == 0xFFFFFFFFU) { + SelfTestStatus = (s32)XST_FAILURE; + } + else { + SelfTestStatus = (s32)XST_SUCCESS; + } + + return SelfTestStatus; +} +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/xscuwdt_sinit.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/xscuwdt_sinit.c new file mode 100644 index 0000000..e311a04 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/xscuwdt_sinit.c @@ -0,0 +1,92 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xscuwdt_sinit.c +* @addtogroup scuwdt_v2_1 +* @{ +* +* This file contains method for static initialization (compile-time) of the +* driver. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who Date     Changes
+* ----- --- -------- ---------------------------------------------
+* 1.00a sdm 01/15/10 First release
+* 2.1 	sk  02/26/15 Modified the code for MISRA-C:2012 compliance.
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xscuwdt.h" +#include "xparameters.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/************************** Variable Definitions *****************************/ +extern XScuWdt_Config XScuWdt_ConfigTable[XPAR_XSCUWDT_NUM_INSTANCES]; + +/*****************************************************************************/ +/** +* Lookup the device configuration based on the unique device ID. The table +* contains the configuration info for each device in the system. +* +* @param DeviceId is the unique device ID of the device being looked up. +* +* @return A pointer to the configuration table entry corresponding to the +* given device ID, or NULL if no match is found. +* +* @note None. +* +******************************************************************************/ +XScuWdt_Config *XScuWdt_LookupConfig(u16 DeviceId) +{ + XScuWdt_Config *CfgPtr = NULL; + u32 Index; + + for (Index = 0U; Index < XPAR_XSCUWDT_NUM_INSTANCES; Index++) { + if (XScuWdt_ConfigTable[Index].DeviceId == DeviceId) { + CfgPtr = &XScuWdt_ConfigTable[Index]; + break; + } + } + + return (XScuWdt_Config *)CfgPtr; +} +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/Makefile b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/Makefile new file mode 100644 index 0000000..186606f --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/Makefile @@ -0,0 +1,83 @@ +############################################################################### +# +# Copyright (C) 2011 - 2015 Xilinx, Inc. All rights reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# Except as contained in this notice, the name of the Xilinx shall not be used +# in advertising or otherwise to promote the sale, use or other dealings in +# this Software without prior written authorization from Xilinx. +# +############################################################################### + +include config.make + +CC=$(COMPILER) +AR=$(ARCHIVER) +CP=cp +COMPILER_FLAGS= +EXTRA_COMPILER_FLAGS= +LIB=libxil.a + +CC_FLAGS = $(subst -pg, -DPROFILING, $(COMPILER_FLAGS)) +ECC_FLAGS = $(subst -pg, -DPROFILING, $(EXTRA_COMPILER_FLAGS)) + +ifeq (($(notdir $(CC))) , arm-xilinx-eabi-gcc) +ECC_FLAGS += -nostartfiles\ + -march=armv7-a \ + -mfloat-abi=soft \ + -mfpu=neon +endif + +ifeq (($(notdir $(CC))) , $(CC)) +ECC_FLAGS += -nostartfiles +endif + +RELEASEDIR=../../../lib +INCLUDEDIR=../../../include +INCLUDES=-I./. -I${INCLUDEDIR} + +OUTS = *.o +OBJECTS = $(addsuffix .o, $(basename $(wildcard *.c))) +ASSEMBLY_OBJECTS = $(addsuffix .o, $(basename $(wildcard *.S))) +INCLUDEFILES=*.h + +libs: $(LIBS) + +standalone_libs: $(LIBSOURCES) + echo "Compiling standalone" + $(CC) $(CC_FLAGS) $(ECC_FLAGS) $(INCLUDES) $^ + $(AR) -r ${RELEASEDIR}/${LIB} ${OBJECTS} ${ASSEMBLY_OBJECTS} + +profile_libs: + $(MAKE) -C profile COMPILER_FLAGS="$(COMPILER_FLAGS)" EXTRA_COMPILER_FLAGS="$(EXTRA_COMPILER_FLAGS)" COMPILER="$(CC)" ARCHIVER="$(AR)" libs + +.PHONY: include +include: standalone_includes profile_includes + +standalone_includes: + ${CP} ${INCLUDEFILES} ${INCLUDEDIR} + +profile_includes: + $(MAKE) -C profile COMPILER_FLAGS="$(COMPILER_FLAGS)" EXTRA_COMPILER_FLAGS="$(EXTRA_COMPILER_FLAGS)" COMPILER="$(CC)" ARCHIVER="$(AR)" include + +clean: + rm -rf ${OBJECTS} + rm -rf ${ASSEMBLY_OBJECTS} + $(MAKE) -C profile COMPILER_FLAGS="$(COMPILER_FLAGS)" EXTRA_COMPILER_FLAGS="$(EXTRA_COMPILER_FLAGS)" COMPILER="$(CC)" ARCHIVER="$(AR)" clean diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/_exit.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/_exit.c new file mode 100644 index 0000000..87271ae --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/_exit.c @@ -0,0 +1,40 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ + +#include +#include "xil_types.h" + +/* _exit - Simple implementation. Does not return. +*/ +__attribute__((weak)) void _exit (sint32 status) +{ + (void)status; + while (1) { + ; + } +} diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/_open.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/_open.c new file mode 100644 index 0000000..4ef7441 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/_open.c @@ -0,0 +1,50 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +#ifndef UNDEFINE_FILE_OPS +#include +#include "xil_types.h" + +#ifdef __cplusplus +extern "C" { + __attribute__((weak)) s32 _open(const char8 *buf, s32 flags, s32 mode); +} +#endif + +/* + * _open -- open a file descriptor. We don't have a filesystem, so + * we return an error. + */ +__attribute__((weak)) s32 _open(const char8 *buf, s32 flags, s32 mode) +{ + (void)buf; + (void)flags; + (void)mode; + errno = EIO; + return (-1); +} +#endif diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/_sbrk.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/_sbrk.c new file mode 100644 index 0000000..1c39e3a --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/_sbrk.c @@ -0,0 +1,61 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ + +#include +#include "xil_types.h" + +extern u8 _heap_start[]; +extern u8 _heap_end[]; + +#ifdef __cplusplus +extern "C" { + __attribute__((weak)) caddr_t _sbrk ( s32 incr ); +} +#endif + +__attribute__((weak)) caddr_t _sbrk ( s32 incr ) +{ + static u8 *heap = NULL; + u8 *prev_heap; + static u8 *HeapEndPtr = (u8 *)&_heap_end; + caddr_t Status; + + if (heap == NULL) { + heap = (u8 *)&_heap_start; + } + prev_heap = heap; + + if (((heap + incr) <= HeapEndPtr) && (prev_heap != NULL)) { + heap += incr; + Status = (caddr_t) ((void *)prev_heap); + } else { + Status = (caddr_t) -1; + } + + return Status; +} diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/abort.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/abort.c new file mode 100644 index 0000000..78d3839 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/abort.c @@ -0,0 +1,38 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ + +#include +#include + +/* + * abort -- go out via exit... + */ +__attribute__((weak)) void abort(void) +{ + _exit(1); +} diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/asm_vectors.S b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/asm_vectors.S new file mode 100644 index 0000000..4fbfa2d --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/asm_vectors.S @@ -0,0 +1,199 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* @file asm_vectors.s +* +* This file contains the initial vector table for the Cortex A9 processor +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who     Date     Changes
+* ----- ------- -------- ---------------------------------------------------
+* 1.00a ecm/sdm 10/20/09 Initial version
+* 3.05a sdm	02/02/12 Save lr when profiling is enabled
+* 3.10a srt     04/18/13 Implemented ARM Erratas. Please refer to file
+*			 'xil_errata.h' for errata description
+* 4.00a pkp	22/01/14 Modified return addresses for interrupt
+*			 handlers (DataAbortHandler and SVCHandler)
+*			 to fix CR#767251
+* 5.1	pkp	05/13/15 Saved the addresses of instruction causing data
+*			 abort and prefetch abort into DataAbortAddr and
+*			 PrefetchAbortAddr for further use to fix CR#854523
+* 5.4	pkp	12/03/15 Added handler for undefined exception
+* 6.8	mus	04/27/18 Removed __ARM_NEON__ flag definition. Now,
+*			 saving/restoring of of HW floating point register
+*			 would be done through newly introduced flag
+*			 FPU_HARD_FLOAT_ABI_ENABLED. This new flag will be
+*			 configured based on the -mfpu-abi option in extra
+*			 compiler flags.
+* 
+* +* @note +* +* None. +* +******************************************************************************/ +#include "xil_errata.h" +#include "bspconfig.h" + +.org 0 +.text + +.globl _vector_table + +.section .vectors +_vector_table: + B _boot + B Undefined + B SVCHandler + B PrefetchAbortHandler + B DataAbortHandler + NOP /* Placeholder for address exception vector*/ + B IRQHandler + B FIQHandler + + +IRQHandler: /* IRQ vector handler */ + + stmdb sp!,{r0-r3,r12,lr} /* state save from compiled code*/ +#if FPU_HARD_FLOAT_ABI_ENABLED + vpush {d0-d7} + vpush {d16-d31} + vmrs r1, FPSCR + push {r1} + vmrs r1, FPEXC + push {r1} +#endif + +#ifdef PROFILING + ldr r2, =prof_pc + subs r3, lr, #0 + str r3, [r2] +#endif + + bl IRQInterrupt /* IRQ vector */ + +#if FPU_HARD_FLOAT_ABI_ENABLED + pop {r1} + vmsr FPEXC, r1 + pop {r1} + vmsr FPSCR, r1 + vpop {d16-d31} + vpop {d0-d7} +#endif + ldmia sp!,{r0-r3,r12,lr} /* state restore from compiled code */ + + + subs pc, lr, #4 /* adjust return */ + + +FIQHandler: /* FIQ vector handler */ + stmdb sp!,{r0-r3,r12,lr} /* state save from compiled code */ +#if FPU_HARD_FLOAT_ABI_ENABLED + vpush {d0-d7} + vpush {d16-d31} + vmrs r1, FPSCR + push {r1} + vmrs r1, FPEXC + push {r1} +#endif + +FIQLoop: + bl FIQInterrupt /* FIQ vector */ + +#if FPU_HARD_FLOAT_ABI_ENABLED + pop {r1} + vmsr FPEXC, r1 + pop {r1} + vmsr FPSCR, r1 + vpop {d16-d31} + vpop {d0-d7} +#endif + ldmia sp!,{r0-r3,r12,lr} /* state restore from compiled code */ + subs pc, lr, #4 /* adjust return */ + + +Undefined: /* Undefined handler */ + stmdb sp!,{r0-r3,r12,lr} /* state save from compiled code */ + ldr r0, =UndefinedExceptionAddr + sub r1, lr, #4 + str r1, [r0] /* Store address of instruction causing undefined exception */ + + bl UndefinedException /* UndefinedException: call C function here */ + ldmia sp!,{r0-r3,r12,lr} /* state restore from compiled code */ + movs pc, lr + +SVCHandler: /* SWI handler */ + stmdb sp!,{r0-r3,r12,lr} /* state save from compiled code */ + + tst r0, #0x20 /* check the T bit */ + ldrneh r0, [lr,#-2] /* Thumb mode */ + bicne r0, r0, #0xff00 /* Thumb mode */ + ldreq r0, [lr,#-4] /* ARM mode */ + biceq r0, r0, #0xff000000 /* ARM mode */ + + bl SWInterrupt /* SWInterrupt: call C function here */ + + ldmia sp!,{r0-r3,r12,lr} /* state restore from compiled code */ + + movs pc, lr /*return to the next instruction after the SWI instruction */ + + +DataAbortHandler: /* Data Abort handler */ +#ifdef CONFIG_ARM_ERRATA_775420 + dsb +#endif + stmdb sp!,{r0-r3,r12,lr} /* state save from compiled code */ + ldr r0, =DataAbortAddr + sub r1, lr, #8 + str r1, [r0] /* Stores instruction causing data abort */ + + bl DataAbortInterrupt /*DataAbortInterrupt :call C function here */ + + ldmia sp!,{r0-r3,r12,lr} /* state restore from compiled code */ + + subs pc, lr, #8 /* points to the instruction that caused the Data Abort exception */ + +PrefetchAbortHandler: /* Prefetch Abort handler */ +#ifdef CONFIG_ARM_ERRATA_775420 + dsb +#endif + stmdb sp!,{r0-r3,r12,lr} /* state save from compiled code */ + ldr r0, =PrefetchAbortAddr + sub r1, lr, #4 + str r1, [r0] /* Stores instruction causing prefetch abort */ + + bl PrefetchAbortInterrupt /* PrefetchAbortInterrupt: call C function here */ + + ldmia sp!,{r0-r3,r12,lr} /* state restore from compiled code */ + + subs pc, lr, #4 /* points to the instruction that caused the Prefetch Abort exception */ + +.end diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/boot.S b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/boot.S new file mode 100644 index 0000000..c8ebfd1 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/boot.S @@ -0,0 +1,492 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2016 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* @file boot.S +* +* @addtogroup a9_boot_code Cortex A9 Processor Boot Code +* @{ +*

boot.S

+* The boot code performs minimum configuration which is required for an +* application to run starting from processor's reset state. Below is a +* sequence illustrating what all configuration is performed before control +* reaches to main function. +* +* 1. Program vector table base for exception handling +* 2. Invalidate instruction cache, data cache and TLBs +* 3. Program stack pointer for various modes (IRQ, FIQ, supervisor, undefine, +* abort, system) +* 4. Configure MMU with short descriptor translation table format and program +* base address of translation table +* 5. Enable data cache, instruction cache and MMU +* 6. Enable Floating point unit +* 7. Transfer control to _start which clears BSS sections, initializes +* global timer and runs global constructor before jumping to main +* application +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who     Date     Changes
+* ----- ------- -------- ---------------------------------------------------
+* 1.00a ecm/sdm 10/20/09 Initial version
+* 3.06a sgd     05/15/12 Updated L2CC Auxiliary and Tag RAM Latency control
+*			 register settings.
+* 3.06a asa 	06/17/12 Modified the TTBR settings and L2 Cache auxiliary
+*		         register settings.
+* 3.07a asa     07/16/12 Modified the L2 Cache controller settings to improve
+*			 performance. Changed the property of the ".boot"
+*			 section.
+* 3.07a sgd     08/21/12 Modified the L2 Cache controller and cp15 Aux Control
+*               Register settings
+* 3.09a sgd     02/06/13 Updated SLCR l2c Ram Control register to a
+*               value of 0x00020202. Fix for CR 697094 (SI#687034).
+* 3.10a srt     04/18/13 Implemented ARM Erratas. Please refer to file
+*			 'xil_errata.h' for errata description
+* 4.2   pkp	06/19/14 Enabled asynchronous abort exception
+* 5.0	pkp	16/15/14 Modified initialization code to enable scu after
+*			 MMU is enabled
+* 5.1   pkp	05/13/15 Changed the initialization order so to first invalidate
+*			 caches and TLB, enable MMU and caches, then enable SMP
+*			 bit in ACTLR. L2Cache invalidation and enabling of L2Cache
+*			 is done later.
+* 5.4   asa     12/6/15  Added code to initialize SPSR for all relevant modes.
+* 6.0   mus     08/04/16 Added code to detect zynq-7000 base silicon configuration and
+*                        attempt to enable dual core behavior on single cpu zynq-7000s
+*                        devices is prevented from corrupting system behavior.
+* 6.0   mus     08/24/16 Check CPU core before putting cpu1 to reset for single core
+*                        zynq-7000s devices
+*
+* 
+* +* @note +* +* None. +* +******************************************************************************/ + +#include "xparameters.h" +#include "xil_errata.h" + +.globl MMUTable +.global _prestart +.global _boot +.global __stack +.global __irq_stack +.global __supervisor_stack +.global __abort_stack +.global __fiq_stack +.global __undef_stack +.global _vector_table + +.set PSS_L2CC_BASE_ADDR, 0xF8F02000 +.set PSS_SLCR_BASE_ADDR, 0xF8000000 + +.set RESERVED, 0x0fffff00 +.set TblBase , MMUTable +.set LRemap, 0xFE00000F /* set the base address of the peripheral block as not shared */ +.set L2CCWay, (PSS_L2CC_BASE_ADDR + 0x077C) /*(PSS_L2CC_BASE_ADDR + PSS_L2CC_CACHE_INVLD_WAY_OFFSET)*/ +.set L2CCSync, (PSS_L2CC_BASE_ADDR + 0x0730) /*(PSS_L2CC_BASE_ADDR + PSS_L2CC_CACHE_SYNC_OFFSET)*/ +.set L2CCCrtl, (PSS_L2CC_BASE_ADDR + 0x0100) /*(PSS_L2CC_BASE_ADDR + PSS_L2CC_CNTRL_OFFSET)*/ +.set L2CCAuxCrtl, (PSS_L2CC_BASE_ADDR + 0x0104) /*(PSS_L2CC_BASE_ADDR + XPSS_L2CC_AUX_CNTRL_OFFSET)*/ +.set L2CCTAGLatReg, (PSS_L2CC_BASE_ADDR + 0x0108) /*(PSS_L2CC_BASE_ADDR + XPSS_L2CC_TAG_RAM_CNTRL_OFFSET)*/ +.set L2CCDataLatReg, (PSS_L2CC_BASE_ADDR + 0x010C) /*(PSS_L2CC_BASE_ADDR + XPSS_L2CC_DATA_RAM_CNTRL_OFFSET)*/ +.set L2CCIntClear, (PSS_L2CC_BASE_ADDR + 0x0220) /*(PSS_L2CC_BASE_ADDR + XPSS_L2CC_IAR_OFFSET)*/ +.set L2CCIntRaw, (PSS_L2CC_BASE_ADDR + 0x021C) /*(PSS_L2CC_BASE_ADDR + XPSS_L2CC_ISR_OFFSET)*/ + +.set SLCRlockReg, (PSS_SLCR_BASE_ADDR + 0x04) /*(PSS_SLCR_BASE_ADDR + XPSS_SLCR_LOCK_OFFSET)*/ +.set SLCRUnlockReg, (PSS_SLCR_BASE_ADDR + 0x08) /*(PSS_SLCR_BASE_ADDR + XPSS_SLCR_UNLOCK_OFFSET)*/ +.set SLCRL2cRamReg, (PSS_SLCR_BASE_ADDR + 0xA1C) /*(PSS_SLCR_BASE_ADDR + XPSS_SLCR_L2C_RAM_OFFSET)*/ +.set SLCRCPURSTReg, (0xF8000000 + 0x244) /*(XPS_SYS_CTRL_BASEADDR + A9_CPU_RST_CTRL_OFFSET)*/ +.set EFUSEStaus, (0xF800D000 + 0x10) /*(XPS_EFUSE_BASEADDR + EFUSE_STATUS_OFFSET)*/ + +/* workaround for simulation not working when L1 D and I caches,MMU and L2 cache enabled - DT568997 */ +.if SIM_MODE == 1 +.set CRValMmuCac, 0b00000000000000 /* Disable IDC, and MMU */ +.else +.set CRValMmuCac, 0b01000000000101 /* Enable IDC, and MMU */ +.endif + +.set CRValHiVectorAddr, 0b10000000000000 /* Set the Vector address to high, 0xFFFF0000 */ + +.set L2CCAuxControl, 0x72360000 /* Enable all prefetching, Cache replacement policy, Parity enable, + Event monitor bus enable and Way Size (64 KB) */ +.set L2CCControl, 0x01 /* Enable L2CC */ +.set L2CCTAGLatency, 0x0111 /* latency for TAG RAM */ +.set L2CCDataLatency, 0x0121 /* latency for DATA RAM */ + +.set SLCRlockKey, 0x767B /* SLCR lock key */ +.set SLCRUnlockKey, 0xDF0D /* SLCR unlock key */ +.set SLCRL2cRamConfig, 0x00020202 /* SLCR L2C ram configuration */ + +/* Stack Pointer locations for boot code */ +.set Undef_stack, __undef_stack +.set FIQ_stack, __fiq_stack +.set Abort_stack, __abort_stack +.set SPV_stack, __supervisor_stack +.set IRQ_stack, __irq_stack +.set SYS_stack, __stack + +.set vector_base, _vector_table + +.set FPEXC_EN, 0x40000000 /* FPU enable bit, (1 << 30) */ + +.section .boot,"ax" + + +/* this initializes the various processor modes */ + +_prestart: +_boot: + +#if XPAR_CPU_ID==0 + /* only allow cpu0 through */ + mrc p15,0,r1,c0,c0,5 + and r1, r1, #0xf + cmp r1, #0 + beq CheckEFUSE + EndlessLoop0: + wfe + b EndlessLoop0 + +CheckEFUSE: + ldr r0,=EFUSEStaus + ldr r1,[r0] /* Read eFuse setting */ + ands r1,r1,#0x80 /* Check whether device is having single core */ + beq OKToRun + + /* single core device, reset cpu1 */ + ldr r0,=SLCRUnlockReg /* Load SLCR base address base + unlock register */ + ldr r1,=SLCRUnlockKey /* set unlock key */ + str r1, [r0] /* Unlock SLCR */ + + ldr r0,=SLCRCPURSTReg + ldr r1,[r0] /* Read CPU Software Reset Control register */ + orr r1,r1,#0x22 + str r1,[r0] /* Reset CPU1 */ + + ldr r0,=SLCRlockReg /* Load SLCR base address base + lock register */ + ldr r1,=SLCRlockKey /* set lock key */ + str r1, [r0] /* lock SLCR */ + +#elif XPAR_CPU_ID==1 + /* only allow cpu1 through */ + mrc p15,0,r1,c0,c0,5 + and r1, r1, #0xf + cmp r1, #1 + beq CheckEFUSE1 + b EndlessLoop1 + +CheckEFUSE1: + ldr r0,=EFUSEStaus + ldr r1,[r0] /* Read eFuse setting */ + ands r1,r1,#0x80 /* Check whether device is having single core */ + beq OKToRun + EndlessLoop1: + wfe + b EndlessLoop1 +#endif + +OKToRun: + mrc p15, 0, r0, c0, c0, 0 /* Get the revision */ + and r5, r0, #0x00f00000 + and r6, r0, #0x0000000f + orr r6, r6, r5, lsr #20-4 + +#ifdef CONFIG_ARM_ERRATA_742230 + cmp r6, #0x22 /* only present up to r2p2 */ + mrcle p15, 0, r10, c15, c0, 1 /* read diagnostic register */ + orrle r10, r10, #1 << 4 /* set bit #4 */ + mcrle p15, 0, r10, c15, c0, 1 /* write diagnostic register */ +#endif + +#ifdef CONFIG_ARM_ERRATA_743622 + teq r5, #0x00200000 /* only present in r2p* */ + mrceq p15, 0, r10, c15, c0, 1 /* read diagnostic register */ + orreq r10, r10, #1 << 6 /* set bit #6 */ + mcreq p15, 0, r10, c15, c0, 1 /* write diagnostic register */ +#endif + + /* set VBAR to the _vector_table address in linker script */ + ldr r0, =vector_base + mcr p15, 0, r0, c12, c0, 0 + + /*invalidate scu*/ + ldr r7, =0xf8f0000c + ldr r6, =0xffff + str r6, [r7] + + /* Invalidate caches and TLBs */ + mov r0,#0 /* r0 = 0 */ + mcr p15, 0, r0, c8, c7, 0 /* invalidate TLBs */ + mcr p15, 0, r0, c7, c5, 0 /* invalidate icache */ + mcr p15, 0, r0, c7, c5, 6 /* Invalidate branch predictor array */ + bl invalidate_dcache /* invalidate dcache */ + + /* Disable MMU, if enabled */ + mrc p15, 0, r0, c1, c0, 0 /* read CP15 register 1 */ + bic r0, r0, #0x1 /* clear bit 0 */ + mcr p15, 0, r0, c1, c0, 0 /* write value back */ + +#ifdef SHAREABLE_DDR + /* Mark the entire DDR memory as shareable */ + ldr r3, =0x3ff /* 1024 entries to cover 1G DDR */ + ldr r0, =TblBase /* MMU Table address in memory */ + ldr r2, =0x15de6 /* S=b1 TEX=b101 AP=b11, Domain=b1111, C=b0, B=b1 */ +shareable_loop: + str r2, [r0] /* write the entry to MMU table */ + add r0, r0, #0x4 /* next entry in the table */ + add r2, r2, #0x100000 /* next section */ + subs r3, r3, #1 + bge shareable_loop /* loop till 1G is covered */ +#endif + + mrs r0, cpsr /* get the current PSR */ + mvn r1, #0x1f /* set up the irq stack pointer */ + and r2, r1, r0 + orr r2, r2, #0x12 /* IRQ mode */ + msr cpsr, r2 + ldr r13,=IRQ_stack /* IRQ stack pointer */ + bic r2, r2, #(0x1 << 9) /* Set EE bit to little-endian */ + msr spsr_fsxc,r2 + + mrs r0, cpsr /* get the current PSR */ + mvn r1, #0x1f /* set up the supervisor stack pointer */ + and r2, r1, r0 + orr r2, r2, #0x13 /* supervisor mode */ + msr cpsr, r2 + ldr r13,=SPV_stack /* Supervisor stack pointer */ + bic r2, r2, #(0x1 << 9) /* Set EE bit to little-endian */ + msr spsr_fsxc,r2 + + mrs r0, cpsr /* get the current PSR */ + mvn r1, #0x1f /* set up the Abort stack pointer */ + and r2, r1, r0 + orr r2, r2, #0x17 /* Abort mode */ + msr cpsr, r2 + ldr r13,=Abort_stack /* Abort stack pointer */ + bic r2, r2, #(0x1 << 9) /* Set EE bit to little-endian */ + msr spsr_fsxc,r2 + + mrs r0, cpsr /* get the current PSR */ + mvn r1, #0x1f /* set up the FIQ stack pointer */ + and r2, r1, r0 + orr r2, r2, #0x11 /* FIQ mode */ + msr cpsr, r2 + ldr r13,=FIQ_stack /* FIQ stack pointer */ + bic r2, r2, #(0x1 << 9) /* Set EE bit to little-endian */ + msr spsr_fsxc,r2 + + mrs r0, cpsr /* get the current PSR */ + mvn r1, #0x1f /* set up the Undefine stack pointer */ + and r2, r1, r0 + orr r2, r2, #0x1b /* Undefine mode */ + msr cpsr, r2 + ldr r13,=Undef_stack /* Undefine stack pointer */ + bic r2, r2, #(0x1 << 9) /* Set EE bit to little-endian */ + msr spsr_fsxc,r2 + + mrs r0, cpsr /* get the current PSR */ + mvn r1, #0x1f /* set up the system stack pointer */ + and r2, r1, r0 + orr r2, r2, #0x1F /* SYS mode */ + msr cpsr, r2 + ldr r13,=SYS_stack /* SYS stack pointer */ + + /*set scu enable bit in scu*/ + ldr r7, =0xf8f00000 + ldr r0, [r7] + orr r0, r0, #0x1 + str r0, [r7] + + /* enable MMU and cache */ + + ldr r0,=TblBase /* Load MMU translation table base */ + orr r0, r0, #0x5B /* Outer-cacheable, WB */ + mcr 15, 0, r0, c2, c0, 0 /* TTB0 */ + + mvn r0,#0 /* Load MMU domains -- all ones=manager */ + mcr p15,0,r0,c3,c0,0 + + /* Enable mmu, icahce and dcache */ + ldr r0,=CRValMmuCac + mcr p15,0,r0,c1,c0,0 /* Enable cache and MMU */ + dsb /* dsb allow the MMU to start up */ + isb /* isb flush prefetch buffer */ + + /* Write to ACTLR */ + mrc p15, 0, r0, c1, c0, 1 /* Read ACTLR*/ + orr r0, r0, #(0x01 << 6) /* set SMP bit */ + orr r0, r0, #(0x01 ) /* Cache/TLB maintenance broadcast */ + mcr p15, 0, r0, c1, c0, 1 /* Write ACTLR*/ + +/* Invalidate L2 Cache and enable L2 Cache*/ +/* For AMP, assume running on CPU1. Don't initialize L2 Cache (up to Linux) */ +#if USE_AMP!=1 + ldr r0,=L2CCCrtl /* Load L2CC base address base + control register */ + mov r1, #0 /* force the disable bit */ + str r1, [r0] /* disable the L2 Caches */ + + ldr r0,=L2CCAuxCrtl /* Load L2CC base address base + Aux control register */ + ldr r1,[r0] /* read the register */ + ldr r2,=L2CCAuxControl /* set the default bits */ + orr r1,r1,r2 + str r1, [r0] /* store the Aux Control Register */ + + ldr r0,=L2CCTAGLatReg /* Load L2CC base address base + TAG Latency address */ + ldr r1,=L2CCTAGLatency /* set the latencies for the TAG*/ + str r1, [r0] /* store the TAG Latency register Register */ + + ldr r0,=L2CCDataLatReg /* Load L2CC base address base + Data Latency address */ + ldr r1,=L2CCDataLatency /* set the latencies for the Data*/ + str r1, [r0] /* store the Data Latency register Register */ + + ldr r0,=L2CCWay /* Load L2CC base address base + way register*/ + ldr r2, =0xFFFF + str r2, [r0] /* force invalidate */ + + ldr r0,=L2CCSync /* need to poll 0x730, PSS_L2CC_CACHE_SYNC_OFFSET */ + /* Load L2CC base address base + sync register*/ + /* poll for completion */ +Sync: ldr r1, [r0] + cmp r1, #0 + bne Sync + + ldr r0,=L2CCIntRaw /* clear pending interrupts */ + ldr r1,[r0] + ldr r0,=L2CCIntClear + str r1,[r0] + + ldr r0,=SLCRUnlockReg /* Load SLCR base address base + unlock register */ + ldr r1,=SLCRUnlockKey /* set unlock key */ + str r1, [r0] /* Unlock SLCR */ + + ldr r0,=SLCRL2cRamReg /* Load SLCR base address base + l2c Ram Control register */ + ldr r1,=SLCRL2cRamConfig /* set the configuration value */ + str r1, [r0] /* store the L2c Ram Control Register */ + + ldr r0,=SLCRlockReg /* Load SLCR base address base + lock register */ + ldr r1,=SLCRlockKey /* set lock key */ + str r1, [r0] /* lock SLCR */ + + ldr r0,=L2CCCrtl /* Load L2CC base address base + control register */ + ldr r1,[r0] /* read the register */ + mov r2, #L2CCControl /* set the enable bit */ + orr r1,r1,r2 + str r1, [r0] /* enable the L2 Caches */ +#endif + + mov r0, r0 + mrc p15, 0, r1, c1, c0, 2 /* read cp access control register (CACR) into r1 */ + orr r1, r1, #(0xf << 20) /* enable full access for p10 & p11 */ + mcr p15, 0, r1, c1, c0, 2 /* write back into CACR */ + + /* enable vfp */ + fmrx r1, FPEXC /* read the exception register */ + orr r1,r1, #FPEXC_EN /* set VFP enable bit, leave the others in orig state */ + fmxr FPEXC, r1 /* write back the exception register */ + + mrc p15,0,r0,c1,c0,0 /* flow prediction enable */ + orr r0, r0, #(0x01 << 11) /* #0x8000 */ + mcr p15,0,r0,c1,c0,0 + + mrc p15,0,r0,c1,c0,1 /* read Auxiliary Control Register */ + orr r0, r0, #(0x1 << 2) /* enable Dside prefetch */ + orr r0, r0, #(0x1 << 1) /* enable L2 Prefetch hint */ + mcr p15,0,r0,c1,c0,1 /* write Auxiliary Control Register */ + + mrs r0, cpsr /* get the current PSR */ + bic r0, r0, #0x100 /* enable asynchronous abort exception */ + msr cpsr_xsf, r0 + + + b _start /* jump to C startup code */ + and r0, r0, r0 /* no op */ + +.Ldone: b .Ldone /* Paranoia: we should never get here */ + + +/* + ************************************************************************* + * + * invalidate_dcache - invalidate the entire d-cache by set/way + * + * Note: for Cortex-A9, there is no cp instruction for invalidating + * the whole D-cache. Need to invalidate each line. + * + ************************************************************************* + */ +invalidate_dcache: + mrc p15, 1, r0, c0, c0, 1 /* read CLIDR */ + ands r3, r0, #0x7000000 + mov r3, r3, lsr #23 /* cache level value (naturally aligned) */ + beq finished + mov r10, #0 /* start with level 0 */ +loop1: + add r2, r10, r10, lsr #1 /* work out 3xcachelevel */ + mov r1, r0, lsr r2 /* bottom 3 bits are the Cache type for this level */ + and r1, r1, #7 /* get those 3 bits alone */ + cmp r1, #2 + blt skip /* no cache or only instruction cache at this level */ + mcr p15, 2, r10, c0, c0, 0 /* write the Cache Size selection register */ + isb /* isb to sync the change to the CacheSizeID reg */ + mrc p15, 1, r1, c0, c0, 0 /* reads current Cache Size ID register */ + and r2, r1, #7 /* extract the line length field */ + add r2, r2, #4 /* add 4 for the line length offset (log2 16 bytes) */ + ldr r4, =0x3ff + ands r4, r4, r1, lsr #3 /* r4 is the max number on the way size (right aligned) */ + clz r5, r4 /* r5 is the bit position of the way size increment */ + ldr r7, =0x7fff + ands r7, r7, r1, lsr #13 /* r7 is the max number of the index size (right aligned) */ +loop2: + mov r9, r4 /* r9 working copy of the max way size (right aligned) */ +loop3: + orr r11, r10, r9, lsl r5 /* factor in the way number and cache number into r11 */ + orr r11, r11, r7, lsl r2 /* factor in the index number */ + mcr p15, 0, r11, c7, c6, 2 /* invalidate by set/way */ + subs r9, r9, #1 /* decrement the way number */ + bge loop3 + subs r7, r7, #1 /* decrement the index */ + bge loop2 +skip: + add r10, r10, #2 /* increment the cache number */ + cmp r3, r10 + bgt loop1 + +finished: + mov r10, #0 /* swith back to cache level 0 */ + mcr p15, 2, r10, c0, c0, 0 /* select current cache level in cssr */ + dsb + isb + + bx lr + +.end +/** +* @} End of "addtogroup a9_boot_code". +*/ \ No newline at end of file diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/bspconfig.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/bspconfig.h new file mode 100644 index 0000000..488641c --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/bspconfig.h @@ -0,0 +1,44 @@ + +/******************************************************************* +* +* CAUTION: This file is automatically generated by HSI. +* Version: 2019.1.3 +* DO NOT EDIT. +* +* Copyright (C) 2010-2023 Xilinx, Inc. All Rights Reserved.* +*Permission is hereby granted, free of charge, to any person obtaining a copy +*of this software and associated documentation files (the Software), to deal +*in the Software without restriction, including without limitation the rights +*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +*copies of the Software, and to permit persons to whom the Software is +*furnished to do so, subject to the following conditions: +* +*The above copyright notice and this permission notice shall be included in +*all copies or substantial portions of the Software. +* +*THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +*XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +*OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*Except as contained in this notice, the name of the Xilinx shall not be used +*in advertising or otherwise to promote the sale, use or other dealings in +*this Software without prior written authorization from Xilinx. +* + +* +* Description: Configurations for Standalone BSP +* +*******************************************************************/ + +#ifndef BSPCONFIG_H /* prevent circular inclusions */ +#define BSPCONFIG_H /* by using protection macros */ + +#define MICROBLAZE_PVR_NONE + +/* Definition for hard-float ABI */ +#define FPU_HARD_FLOAT_ABI_ENABLED 1 + +#endif /*end of __BSPCONFIG_H_*/ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/changelog.txt b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/changelog.txt new file mode 100644 index 0000000..cdefb9f --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/changelog.txt @@ -0,0 +1,593 @@ +/***************************************************************************** + * MODIFICATION HISTORY: + * + * Ver Who Date Changes + * ----- ---- -------- --------------------------------------------------- + * 3.02a sdm 05/30/11 Added Xuint64 typedef and XUINT64_MSW/XUINT64_LSW macros + * 3.02a sdm 06/27/11 Added INST_SYNC and DATA_SYNC macros for all the CPUs + * 3.02a sdm 07/07/11 Updated ppc440 boot.S to set guarded bit for all but + * cacheable regions + * Update ppc440/xil_cache.c to use CACHEABLE_REGION_MASK + * generated by the cpu driver, for enabling caches + * 3.02a sdm 07/08/11 Updated microblaze cache flush APIs based on write-back/ + * write-thru caches + * 3.03a sdm 08/20/11 Updated the tag/data RAM latency values for L2CC + * Updated the MMU table to mark OCM in high address space + * as inner cacheable and reserved space as Invalid + * 3.03a sdm 08/20/11 Changes to support FreeRTOS + * Updated the MMU table to mark upper half of the DDR as + * non-cacheable + * Setup supervisor and abort mode stacks + * Do not initialize/enable L2CC in case of AMP + * Initialize UART1 for 9600bps in case of AMP + * 3.03a sdm 08/27/11 Setup abort and supervisor mode stacks and don't init SMC + * in case of AMP + * 3.03a sdm 09/14/11 Added code for performance monitor and L2CC event + * counters + * 3.03a sdm 11/08/11 Updated microblaze xil_cache.h file to include + * xparameters.h file for CR630532 - Xil_DCacheFlush()/ + * Xil_DCacheFlushRange() functions in standalone BSP v3_02a + * for MicroBlaze will invalidate data in the cache instead + * of flushing it for writeback caches + * 3.04a sdm 11/21/11 Updated to initialize stdio device for 115200bps, for PS7 + * 3.04a sdm 01/02/12 Updated to clear cp15 regs with unknown reset values + * Remove redundant dsb/dmb instructions in cache maintenance + * APIs + * Remove redundant dsb in mcr instruction + * 3.04a sdm 01/13/12 Updated MMU table to mark DDR memory as Shareable + * 3.05a sdm 02/02/12 Removed some of the defines as they are being generated through + * driver tcl in xparameters.h. Update the gcc/translationtable.s + * for the QSPI complete address range - DT644567 + * Removed profile directory for armcc compiler and changed + * profiling setting to false in standalone_v2_1_0.tcl file + * Deleting boot.S file after preprocessing for armcc compiler + * 3.05a asa 03/11/12 Updated the function Xil_EnableMMU in file xil_mmu.c to + * invalidate the caches before enabling back the MMU and + * D cache. + * 3.05a asa 04/15/12 Updated the function Xil_SetTlbAttributes in file + * xil_mmu.c. Now we invalidate UTLB, Branch predictor + * array, flush the D-cache before changing the attributes + * in translation table. The user need not call Xil_DisableMMU + * before calling Xil_SetTlbAttributes. + * 3.06a asa/ 06/17/12 Removed the UART initialization for Zynq. For PEEP, the UART + * sgd initialization is present. Changes for this were done in + * uart.c and xil-crt0.s. + * Made changes in xil_io.c to use volatile pointers. + * Made changes in xil_mmu.c to correct the function + * Xil_SetTlbAttributes. + * Changes are made xil-crt0.s to initialize the static + * C++ constructors. + * Changes are made in boot.s, to fix the TTBR settings, + * correct the L2 Cache Auxiliary register settings, L2 cache + * latency settings. + * 3.07a asa/ 07/16/12 Made changes in cortexa9/xtime_l.c, xtime_l.h, sleep.c + * sgd usleep.c to use global timer intstead of CP15. + * Made changes in cortexa9/gcc/translation_table.s to map + * the peripheral devices as shareable device memory. + * Made changes in cortexa9/gcc/xil-crt0.s to initialize + * the global timer. + * Made changes in cortexa9/armcc/boot.S to initialize + * the global timer. + * Made changes in cortexa9/armcc/translation_table.s to + * map the peripheral devices as shareable device memory. + * Made changes in cortexa9/gcc/boot.S to optimize the + * L2 cache settings. Changes the section properties for + * ".mmu_tbl" and ".boot" sections in cortexa9/gcc/boot.S + * and cortexa9/gcc/translation_table.S. + * Made changes in cortexa9/xil_cache.c to change the + * cache invalidation order. + * 3.07a asa 08/17/12 Made changes across files for Cortexa9 to remove + * compilation/linking issues for C++ compiler. + * Made changes in mb_interface.h to remove compilation/ + * linking issues for C++ compiler. + * Added macros for swapb and swaph microblaze instructions + * mb_interface.h + * Remove barrier usage (SYNCHRONIZE_IO) from xil_io.c + * for CortexA9. + * 3.07a asa 08/30/12 Updated for CR 675636 to provide the L2 Base Address + * 3.07a asa 08/31/12 Added xil_printf.h include + * 3.07a sgd 09/18/12 Corrected the L2 cache enable settings + * Corrected L2 cache sequence disable sequence + * 3.07a sgd 10/19/12 SMC NOR and SRAM initialization with compiler option + * 3.09a asa 01/25/13 Updated to push and pop neon registers into stack for + * irq/fiq handling. + * Relocated COUNTS_PER_SECOND from sleep.c to xtime_l.h. This + * fixes the CR #692094. + * 3.09a sgd 02/14/13 Fix for CRs 697094 (SI#687034) and 675552. + * 3.10a srt 04/18/13 Implemented ARM Erratas. + * Cortex A9 Errata - 742230, 743622, 775420, 794073 + * L2Cache PL310 Errata - 588369, 727915, 759370 + * Please refer to file 'xil_errata.h' for errata + * description. + * 3.10a asa 05/04/13 Added support for L2 cache in MicroBlaze BSP. The older + * cache APIs were corresponding to only Layer 1 cache + * memories. New APIs were now added and the existing cache + * related APIs were changed to provide a uniform interface + * to flush/invalidate/enable/disable the complete cache + * system which includes both L1 and L2 caches. The changes + * for these were done in: + * src/microblaze/xil_cache.c and src/microblaze/xil_cache.h + * files. + * Four new files were added for supporting L2 cache. They are: + * microblaze_flush_cache_ext.S-> Flushes L2 cache + * microblaze_flush_cache_ext_range.S -> Flushes a range of + * memory in L2 cache. + * microblaze_invalidate_cache_ext.S-> Invalidates L2 cache + * microblaze_invalidate_cache_ext_range -> Invalidates a + * range of memory in L2 cache. + * These changes are done to implement PR #697214. + * 3.10a asa 05/13/13 Modified cache disable APIs at src/cortexa9/xil_cache.c to + * fix the CR #706464. L2 cache disabling happens independent + * of L1 data cache disable operation. Changes are done in the + * same file in cache handling APIs to do a L2 cache sync + * (poll reg7_?cache_?sync). This fixes CR #700542. + * 3.10a asa 05/20/13 Added API/Macros for enabling and disabling nested + * interrupts for ARM. These are done to fix the CR#699680. + * 3.10a srt 05/20/13 Made changes in cache maintenance APIs to do a proper cach + * sync operation. This fixes the CR# 716781. + * 3.11a asa 09/07/13 Updated armcc specific BSP files to have proper support + * for armcc toolchain. + * Modified asm_vectors.S (gcc) and asm_vectors.s (armcc) to + * fix issues related to NEON context saving. The assembly + * routines for IRQ and FIQ handling are modified. + * Deprecated the older BSP (3.10a). + * 3.11a asa 09/22/13 Fix for CR#732704. Cache APIs are modified to avoid + * various potential issues. Made changes in the function + * Xil_SetAttributes in file xil_mmu.c. + * 3.11a asa 09/23/13 Added files xil_misc_psreset_api.c and xil_misc_psreset_api.h + * in src\cortexa9 and src\microblaze folders. + * 3.11a asa 09/28/13 Modified the cache APIs (src\cortexa9) to fix handling of + * L2 cache sync operation and to fix issues around complete + * L2 cache flush/invalidation by ways. + * 3.12a asa 10/22/13 Modified the files xpseudo_asm_rvct.c and xpseudo_asm_rvct.h + * to fix linking issues with armcc/DS-5. Modified the armcc + * makefile to fix issues. + * 3.12a asa 11/15/13 Fix for CR#754800. It fixes issues around profiling for MB. + * 4.0 hk 12/13/13 Added check for STDOUT_BASEADDRESS where outbyte is used. + * 4.0 pkp 22/01/14 Modified return addresses for interrupt handlers (DataAbortHandler + * and SWIHandler) in asm_vector.S (src\cortexa9\gcc\ and + * src\cortexa9\armcc\) to fix CR#767251 + * 4.0 pkp 24/01/14 Modified cache APIs (Xil_DCacheInvalidateRange and + * Xil_L1DCacheInvalidate) in xil_cache.c (src\cortexa9) to fix the bugs. + * Few cache lines were missed to invalidate when unaligned address + * invalidation was accommodated in Xil_DCacheInvalidateRange. + * In Xil_L1DCacheInvalidate, while invalidating all L1D cache + * stack memory (which contains return address) was invalidated. So + * stack memory is flushed first and then L1D cache is invalidated. + * This is done to fix CR #763829 + * 4.0 adk 22/02/2014 Fixed the CR:775379 removed unnecessay _t(unit32_t etc) from + * mblaze_nt_types.h file and replace uint32_t with u32 in the + * profile_hist.c to fix the above CR. + * 4.1 bss 04/14/14 Updated driver tcl to remove _interrupt_handler.o from libgloss.a + * instead of libxil.a and added prototypes for + * microblaze_invalidate_cache_ext and microblaze_flush_cache_ext in + * mb_interface.h + * 4.1 hk 04/18/14 Add sleep function. + * 4.1 asa 04/21/14 Fix for CR#764881. Added support for msrset and msrclr. Renamed + * some of the *.s files inMB BSP source to *.S. + * 4.1 asa 04/28/14 Fix for CR#772280. Made changes in file cortexa9/gcc/read.c. + * 4.1 bss 04/29/14 Modified driver tcl to use libxil.a if libgloss.a does not exist + * CR#794205 + * 4.1 asa 05/09/14 Fix for CR#798230. Made changes in cortexa9/xil_cache.c and + * common/xil_testcache.c + * Fix for CR#764881. + * 4.1 srt 06/27/14 Remove '#undef DEBUG' from src/common/xdebug.h, which allows to + * output the DEBUG logs when -DDEBUG flag is enabled in BSP. + * 4.2 pkp 06/27/14 Added support for IAR compiler in src/cortexa9/iccarm. + * Also added explanatory notes in cortexa9/xil_cache.c for CR#785243. + * 4.2 pkp 06/19/14 Asynchronous abort has been enabled into cortexa9/gcc/boot.s and + * cortexa9/armcc/boot.s. Added default exception handlers for data + * abort and prefetch abort using handlers called + * DataAbortHandler and PrefetchAbortHandler respectively in + * cortexa9/xil_exception.c to fix CR#802862. + * 4.2 pkp 06/30/14 MakeFile for cortexa9/armcc has been changed to fixes the + * issue of improper linking of translation_table.s + * 4.2 pkp 07/04/14 added weak attribute for the function in BSP which are also present + * in tool chain to avoid conflicts into some special cases + * 4.2 pkp 07/21/14 Corrected reset value of event counter in function + * Xpm_ResetEventCounters in src/cortexa9/xpm_counter.c to fix CR#796275 + * 4.2 pkp 07/21/14 Included xil_types.h file in xil_mmu.h which had contained a function + * containing type def u32 defined in xil_types.g to resolve issue of + * CR#805869 + * 4.2 pkp 08/04/14 Removed unimplemented nanosleep routine from cortexa9/usleep.c as + * it is not possible to generate timer in nanosecond due to limited + * cpu frequency + * 4.2 pkp 08/04/14 Removed PEEP board related code which contained initialization of + * uart, smc nor and sram from cortexa9/gcc/xil-crt0.s and armcc/boot.s + * and iccarm/boot.s. Also uart.c and smc.c have been removed. Also + * removed function definition of XSmc_NorInit and XSmc_NorInit from + * cortexa9/smc.h + * 4.2 bss 08/11/14 Added microblaze_flush_cache_ext_range and microblaze_invalidate_ + * cache_ext_range declarations in mb_interface.h CR#783821. + * Modified profile_mcount_mb.S to fix CR#808412. + * 4.2 pkp 08/21/14 modified makefile of iccarm for proper linking of objectfiles in + * cortexa9/iccarm to fix CR#816701 + * 4.2 pkp 09/02/14 modified translation table entries in cortexa9/gcc/translation_table.s, + * armcc/translation_table.s and iccarm/translation_table.s + * to properly defined reserved entries according to address map for + * fixing CR#820146 + * 4.2 pkp 09/11/14 modified translation table entries in cortexa9/iccarm/translation_table.s + * and cortexa9/armcc/translation_table.s to resolve compilation + * error for solving CR#822897 + * 5.0 kvn 12/9/14 Support for Zync Ultrascale Mp.Also modified code for + * MISRA-C:2012 compliance. + * 5.0 pkp 12/15/14 Added APIs to get information about the platforms running the code by + * adding src/common/xplatform_info.*s + * 5.0 pkp 16/12/14 Modified boot code to enable scu after MMU is enabled and + * removed incorrect initialization of TLB lockdown register to fix + * CR#830580 in cortexa9/gcc/boot.S & cpu_init.S, armcc/boot.S + * and iccarm/boot.s + * 5.0 pkp 25/02/15 Modified floating point flag to vfpv3 from vfpv3_d16 in BSP MakeFile + * for iccarm and armcc compiler of cortexA9 + * 5.1 pkp 05/13/15 Changed the initialization order in cortexa9/gcc/boot.S, iccarm/boot.s + * and armcc/boot.s so to first invalidate caches and TLB, enable MMU and + * caches, then enable SMP bit in ACTLR. L2Cache invalidation and enabling + * of L2Cache is done later. + * 5.1 pkp 12/05/15 Modified cortexa9/xil_cache.c to modify Xil_DCacheInvalidateRange and + * Xil_DCacheFlushRange to remove unnecessary dsb which is unnecessarily + * taking long time to fix CR#853097. L2CacheSync is added into + * Xil_L2CacheInvalidateRange API. Xil_L1DCacheInvalidate and + * Xil_L2CacheInvalidate APIs are modified to flush the complete stack + * instead of just System Stack + * 5.1 pkp 14/05/15 Modified cortexa9/gcc/Makefile to keep a correct check of a compiler + * to update ECC_FLAGS and also take the compiler and archiver as specified + * in settings instead of hardcoding it. + * 5.2 pkp 06/08/15 Modified cortexa9/gcc/translation_table.S to put a check for + * XPAR_PS7_DDR_0_S_AXI_BASEADDR to confirm if DDR is present or not and + * accordingly generate the translation table + * 5.2 pkp 23/07/15 Modified cortexa9/gcc/Makefile to keep a correct check of a compiler + * to update ECC_FLAGS to fix a bug introduced during new version creation + * of BSP. + * 5.3 pkp 10/07/15 Modified cortexa9/xil_cache.c file to change cache API so that L2 Cache + * functionalities are avoided for the OpenAMP slave application(when + * USE_AMP flag is defined for BSP) as master CPU would be utilizing L2 + * cache for its operation. Also file operations such as read, write, + * close, open are also avoided for OpenAMP support(when USE_AMP flag is + * defined for BSP) because XilOpenAMP library contains own file operation. + * The xil-crt0.S file is modified for not initializing global timer for + * OpenAMP application as it might be already in use by master CPU + * 5.3 pkp 10/09/15 Modified cortexa9/iccarm/xpseudo_asm_iccarm.h file to change function + * definition for dsb, isb and dmb to fix the compilation error when used + * kvn 16/10/15 Encapsulated assembly code into macros for R5 xil_cache file. + * 5.4 pkp 09/11/15 Modified cortexr5/gcc/boot.S to disable ACTLR.DBWR bit to avoid potential + * R5 deadlock for errata 780125 + * 5.4 pkp 09/11/15 Modified cortexa53/32bit/gcc/boot.S to enable I-Cache and D-Cache for a53 + * 32 bit BSP in the initialization + * 5.4 pkp 09/11/15 Modified cortexa9/xil_misc_psreset_api.c file to change the description + * for XOcm_Remap function + * 5.4 pkp 16/11/15 Modified microblaze/xil_misc_psreset_api.c file to change the description + * for XOcm_Remap function + * kvn 21/11/15 Added volatile keyword for ADDR varibles in Xil_Out API + * kvn 21/11/15 Changed ADDR variable type from u32 to UINTPTR. This is + * required for MISRA-C:2012 Compliance. + * 5.4 pkp 23/11/15 Added attribute definitions for Xil_SetTlbAttributes API of Cortex-A9 + * in cortexa9/xil_mmu.h + * 5.4 pkp 23/11/15 Added default undefined exception handler for Cortex-A9 + * 5.4 pkp 11/12/15 Modified common/xplatform_info.h to add #defines for silicon for + * checking the current executing platform + * 5.4 pkp 18/12/15 Modified cortexa53/32bit/gcc/xil-crt0.S and 64bit/gcc/xil-crt0.S + * to initialize global constructor for C++ applications + * 5.4 pkp 18/12/15 Modified cortexr5/gcc/xil-crt0.S to initialize global constructor for + * C++ applications + * 5.4 pkp 18/12/15 Modified cortexa53/32bit/gcc/translation_table.S and 64bit/gcc/ + * translation_table.S to update the translation table according to proper + * address map + * 5.4 pkp 18/12/15 Modified cortexar5/mpu.c to initialize the MPU according to proper + * address map + * 5.4 pkp 05/01/16 Modified cortexa53/64bit/boot.S to set the reset vector register RVBAR + * equivalent to vector table base address + * 5.4 pkp 08/01/16 Modified cortexa9/gcc/Makefile to update the extra compiler flag + * as per the toolchain update + * 5.4 pkp 12/01/16 Changed common/xplatform_info.* to add platform information support + * for Cortex-A53 32bit mode + * 5.4 pkp 28/01/16 Modified cortexa53/32bit/sleep.c and usleep.c & cortexa53/64bit/sleep.c + * and usleep.c to correct routines to avoid hardcoding the timer frequency, + * instead take it from xparameters.h to properly configure the timestamp + * clock frequency + * 5.4 asa 29/01/16 Modified microblaze/mb_interface.h to add macros that support the + * new instructions for MB address extension feature + * 5.4 kvn 30/01/16 Modified xparameters_ps.h file to add interrupt ID number for + * system monitor. + * 5.4 pkp 04/02/16 Modified cortexr5/gcc/boot.S to enable fault log for lock-step mode + * 5.4 pkp 19/02/16 Modified cortexr5/xtime_l.c to add an API XTime_StartTimer and updated + * cortexr5/xil-crt0.S to configure the TTC3 timer when present. Modified + * cortexr5/sleep.c, cortexr5/usleep.c to use TTC3 when present otherwise + * use set of assembly instructions to provide required delay to fix + * CR#913249. + * 5.4 asa 25/02/16 Made changes in xil-crt0.S for R5, A53 64 and 32 bit BSPs, to replace + * _exit with exit. We should not be directly calling _exit and should + * always use the library exit. This fixes the CR#937036. + * 5.4 pkp 25/02/16 Made change to cortexr5/gcc/boot.S to initialize the floating point + * registers, banked registers for various modes and enabled + * the cache ECC check before enabling the fault log for lock step mode + * Also modified the cortexr5/gcc/Makefile to support floating point + * registers initialization in boot code. + * 5.4 pkp 03/01/16 Updated the exit function in cortexr5/gcc/_exit.c to enable the debug + * logic in case of lock-step mode when fault log is enabled to fix + * CR#938281 + * 5.4 pkp 03/02/16 Modified cortexa9/iccarm/xpseudo_asm_iccarm.h file to include + * header file instrinsics.h which contains assembly instructions + * definitions which can be used by C + * 5.4 asa 03/02/16 Added print.c in MB BSP. Made other cosmetic changes to have uniform + * proto for all print.c across the BSPs. This patch fixes CR#938738. + * 5.4 pkp 03/09/16 Modified cortexr5/sleep.c and usleep.c to avoid disabling the + * interrupts when sleep/usleep is being executed using assembly + * instructions to fix CR#913249. + * 5.4 pkp 03/11/16 Modified cortexr5/xtime_l.c to avoid enabling overflow interrupt, + * instead modified cortexr5/sleep.c and usleep.c to poll the counter + * value and compare it with previous value to detect the overflow + * to fix CR#940209. + * 5.4 pkp 03/24/16 Modified cortexr5/boot.S to reset the dbg_lpd_reset before enabling + * the fault log to avoid intervention for lock-step mode and cortexr5/ + * _exit.c to enable the dbg_lpd_reset once the fault log is disabled + * to fix CR#947335 + * 5.5 pkp 04/11/16 Modified cortexr5/boot.S to enable comparators for non-JTAG bootmode + * in lock-step to avoid resetting the debug logic which restricts the + * access for debugger and removed enabling back of debug modules in + * cortexr5/_exit.c + * 5.5 pkp 04/13/16 Modified cortexa9/gcc/read.c to return correct number of bytes when + * read buffer is filled and removed the redundant NULL checking for + * buffer to simplify the code + * 5.5 pkp 04/13/16 Modified cortexa53/64bit/gcc/read.c and cortexa53/32bit/gcc/read.c + * to return correct number of bytes when read buffer is filled and + * removed the redundant NULL checking for buffer to simplify the code + * 5.5 pkp 04/13/16 Modified cortexr5/gcc/read.c to return correct number of bytes when + * read buffer is filled and removed the redundant NULL checking for + * buffer to simplify the code + * 5.5 pkp 04/13/16 Modified cortexa53/64bit/xpseudo_asm_gcc.h to add volatile to asm + * instruction macros to disable certain optimizations which may move + * code out of loops if optimizers believe that the code will always + * return the same result or discard asm statements if optimizers + * determine there is no need for the output variables + * 5.5 pkp 04/13/16 Modified cortexa53/64bit/xtime_l.c to add XTime_StartTimer which + * starts the timer if it is disabled and modified XTime_GetTime to + * enable the timer if it is not enabled. Also modified cortexa53/64bit/ + * sleep.c and cortexa53/64bit/usleep.c to enable the timer if it is + * disabled and read the counter value directly from register instead + * of using XTime_GetTime for optimization + * 5.5 pkp 04/13/16 Modified cortexa53/32bit/xtime_l.c to add XTime_StartTimer which + * starts the timer if it is disabled and modified XTime_GetTime to + * enable the timer if it is not enabled. Also modified cortexa53/32bit/ + * sleep.c and cortexa53/32bit/usleep.c to enable the timer if it is + * disabled and read the counter value directly from register instead + * of using XTime_GetTime for optimization + * 5.5 pkp 04/13/16 Modified cortexa53/32bit/xil_cache.c and cortexa53/64bit/xil_cache.c + * to update the Xil_DCacheInvalidate, Xil_DCacheInvalidateLine and + * Xil_DCacheInvalidateRange functions description for proper + * explaination to fix CR#949801 + * 5.5 asa 04/20/16 Added missing macros for hibernate and suspend in Microblaze BSP + * file mb_interface.h. This fixes the CR#949503. + * 5.5 asa 04/29/16 Fix for CR#951080. Updated cache APIs for HW designs where cache + * memory is not included for MicroBlaze. + * 5.5 pkp 05/06/16 Modified the cortexa9/xil_exception.h to update the macros + * Xil_EnableNestedInterrupts and Xil_DisableNestedInterrupts for fixing + * the issue of lr being corrupted to resolve CR#950468 + * 5.5 pkp 05/06/16 Modified the cortexr5/xil_exception.h to update the macros + * Xil_EnableNestedInterrupts and Xil_DisableNestedInterrupts for fixing + * the issue of lr being corrupted to resolve CR#950468 + * 6.0 kvn 05/31/16 Make Xil_AsserWait a global variable + * 6.0 pkp 06/27/16 Updated cortexr5/mpu.c to move the code related to Init_MPU to .boot + * section since it is part of boot process to fix CR#949555 + * hk 07/12/16 Correct masks for IOU SLCR GEM registers + * 6.0 pkp 07/25/16 Program the counter frequency in boot code for CortexA53 + * 6.0 asa 08/03/16 Updated sleep_common function in microblaze_sleep.c to improve the + * the accuracy of MB sleep functionality. This fixes the CR#954191. + * 6.0 mus 08/03/16 Restructured the BSP to avoid code duplication across all BSPs. + * Source code directories specific to ARM processor's are moved to src/arm + * directory(i.e. src/cortexa53,src/cortexa9 and src/cortexr5 moved to src/arm/cortexa53, + * src/arm/cortexa9 and src/arm/cortexr5 respectively).Files xil_printf.c,xil_printf.h, + * print.c,xil_io.c and xil_io.h are consolidated across all BSPs into common file each and + * consolidated files are kept at src/common directory.Files putnum.c,vectors.c,vectors.h, + * xil_exception.c and xil_exception.h are consolidated across all ARM BSPs + * into common file each and consolidated files are kept at src/arm/common directory. + * GCC source files related to file operations are consolidated and kept + * at src/arm/common/gcc directory. + * All io interfacing functions (i.e. All variants of xil_out, xil_in ) + * are made as static inline and implementation is kept in consolidated common/xil_io.h, + * xil_io.h must be included as a header file to access io interfacing functions. + * Added undefined exception handler for A53 32 bit and R5 processor + * 6.0 mus 08/11/16 Updated xtime_l.c in R5 BSP to remove implementation of XTime_SetTime API, since + * TTC counter value register is read only. + * 6.0 asa 08/15/16 Modified the signatures for functions sleep and usleep. This fixes + * the CR#956899. + * 6.0 mus 08/18/16 Defined ARMA53_32 flag in cortexa53/32bit/xparameters_ps.h and ARMR5 flag + * in cortexr5/xparameters_ps.h + * 6.0 mus 08/18/16 Added support for the the Zynq 7000s devices + * 6.0 mus 08/18/16 Removed unused variables from xil_printf.c and xplatform_info.c + * 6.0 mus 08/19/16 Modified xil_io.h to remove __LITTLE_ENDIAN__ flag check for all ARM processors + * 6.1 mus 11/03/16 Added APIs handle_stdin_parameter and handle_stdout_parameter in standalone tcl. + * ::hsi::utils::handle_stdin and ::hsi::utils::handle_stdout are taken as a base for + * these APIs and modifications are done on top of it to handle stdout/stdin + * parameters for design which doesnt have UART.It fixes CR#953681 + * 6.1 nsk 11/07/16 Added two new files xil_mem.c and xil_mem.h for xil_memcpy + * 6.2 pkp 12/14/16 Updated cortexa53/64bit/translation_table.S for upper ps DDR. The 0x800000000 - + * 0xFFFFFFFFF range is marked normal memory for the DDR size defined in hdf + * and rest of the memory in that 32GB region is marked as reserved to avoid + * any speculative access + * 6.2 pkp 12/23/16 Added support for floating point operation to Cortex-A53 64bit mode. It modified + * asm_vectors.S to implement lazy floating point context saving i.e. floating point + * access is enabled if there is any floating point operation, it is disabled by + * default. Also FPU is initally disabled for IRQ and none of the floating point + * registers are saved during normal context saving. If IRQ handler does not require + * floating point operation, the floating point registers are untouched and no need + * for saving/restoring. If IRQ handler uses any floating point operation, then floating + * point registers are saved and FPU is enabled for IRQ handler. Then floating point + * registers are restored back after servicing IRQ during normal context restoring. + * 6.2 mus 01/01/17 Updated makefiles of R5 and a53 64 bit/32 bit processors to fix error in clean + * target.It fixes the CR#966900 + * 6.2 pkp 01/22/17 Added support for EL1 non-secure execution and Hypervisor Baremetal for Cortex-A53 + * 64bit Mode. If Hypervisor_guest is selected as true in BSP settings, BSP will be built + * for EL1 Non-secure, else BSP will be built for EL3. By default hypervisor_guest is + * as false i.e. default bsp is EL3. + * 6.2 pkp 01/24/17 Updated cortexa53/64bit/boot.S to clear FPUStatus variable to make sure that it + * contains initial status of FPU i.e. disabled. In case of a warm restart execution + * when bss sections are not cleared, it may contain previously updated value which + * does not hold true once processor resumes. This fixes CR#966826. + * 6.2 asa 01/31/17 The existing Xil_DCacheDisable API first flushes the + * D caches and then disables it. The problem with that is, + * potentially there will be a small window after the cache + * flush operation and before the we disable D caches where + * we might have valid data in cache lines. In such a + * scenario disabling the D cache can lead to unknown behavior. + * The ideal solution to this is to use assembly code for + * the complete API and avoid any memory accesses. But with + * that we will end up having a huge amount on assembly code + * which is not maintainable. Changes are done to use a mix + * of assembly and C code. All local variables are put in + * registers. Also function calls are avoided in the API to + * avoid using stack memory. + * 6.2 mus 02/13/17 A53 CPU cache system can pre-fetch catch lines.So there are + * scenarios when an invalidated cache line can get pre fetched to cache. + * If that happens, the coherency between cache and memory is lost + * resulting in lost data. To avoid this kind of issue either + * user has to use dsb() or disable pre-fetching for L1 cache + * or else reduce maximum number of outstanding data prefetches allowed. + * Using dsb() while comparing data costing more performance compared to + * disabling pre-fetching/reducing maximum number of outstanding data + * prefetches for L1 Cache.The new api Xil_ConfigureL1Prefetch is added + * to disable pre-fetching/configure maximum number of outstanding data + * prefetches allowed in L1 cache system.This fixes CR#967864. + * 6.2 pkp 02/16/17 Added xil_smc.c file to provide a C wrapper for smc calling which can be + * used by cortex-A53 64bit EL1 Non-secure application. + * 6.2 kvn 03/03/17 Added support thumb mode + * 6.2 mus 03/13/17 Fixed MISRA C mandatory standard violations in ARM cortexr5 and cortexa53 BSP. + * It fixes CR#970543 + * 6.2 asa 03/16/17 Fix for CR#970859. For Mcroblaze BSP, when we enable intrusive + * profiling we see a crash. That is because the the tcl uses invalid + * HSI command. This change fixes it. + * 6.2 mus 03/22/17 Updated standalone tcl to generate xparameter XPAR_FPD_IS_CACHE_COHERENT, if + * any FPD peripheral is configured to use CCI.It fixes CR#972638 + * 6.3 mus 03/20/17 Updated cortex-r5 BSP, to add hard floating point support. + * 6.3 mus 04/17/17 Updated Cortex-a53 32 bit BSP boot code to fix bug in + * the HW coherency enablement. It fixes the CR#973287 + * 6.3 mus 04/20/17 Updated Cortex-A53 64 bit BSP boot code, to remove redundant write to the + * L2CTLR_EL1 register. It fixes the CR#974698 + * 6.4 mus 06/08/17 Updated arm/common/xil_exception.c to fix warnings in C level exception handlers + * of ARM 32 bit processor's. + * 6.4 mus 06/14/17 Updated cortexa53/64bit/gcc/asm_vectors.S to fix bug in IRQInterruptHandler code + * snippet, which checks for the FPEN bit of CPACR_EL1 register. + * 6.4 ms 05/23/17 Added PSU_PMU macro in xplatform_info.c, xparameters.h to support + * XGetPSVersion_Info function for PMUFW. + * ms 06/13/17 Added PSU_PMU macro in xplatform_info.c to support XGetPlatform_Info + * function for PMUFW. + * 6.4 mus 07/05/17 Updated Xil_In32BE function in xil_io.h to fix bug.It fixes CR#979740. + * 6.4 mus 07/25/17 Updated a53 32 bit boot code and vectors to support hard floating point + * operations.Now,VFP is being enabled in FPEXC register, through boot code + * and FPU registers are being saved/restored when irq/fiq vector is invoked. + * 6.4 adk 08/01/17 Updated standalone tcl to generate xparameter XPAR_PL_IS_CACHE_COHERENT, + * if h/w design configured with HPC port. + * 6.4 mus 08/10/17 Updated a53 64 bit translation table to mark memory as a outer shareable for + * EL1 NS execution. This change has been done to support CCI enabled IP's. + * 6.4 mus 08/11/17 Updated a53 64 bit boot code to implement ARM erratum 855873.This fixes + * CR#982209. + * 6.4 asa 08/16/17 Made several changes in the R5 MPU handling logic. Added new APIs to + * make RPU MPU handling user-friendly. This also fixes the CR-981028. + * 6.4 mus 08/17/17 Updated XGet_Zynq_UltraMp_Platform_info and XGetPSVersion_Info APIs to read + * version register through SMC call, over EL1 NS mode. This change has been done to + * support these APIs over EL1 NS mode. + * 6.5 mus 10/20/17 Updated standalone.tcl to fix bug in mb_can_handle_exceptions_in_delay_slots proc, + * it fixes CR#987464. + * 6.6 mus 12/07/17 Updated cortexa9/xil_errata.h and cortexa9/xil_cache.c to remove Errata 753970. + * It fixes CR#989132. + * srm 10/18/17 Updated all the sleep routines in a9,a53,R5,microblaze. Now the sleep routines + * will use the timer specified by the user to provide delay. A9 and A53 can use + * Global timer or TTC. R5 can use TTC or the machine cycles. Microblaze can use + * machine cycles or Axi timer. Updated standalone.tcl and standalone.mld files + * to support the sleep configuration Added new API's for the Axi timer in + * microblaze and TTC in ARM. Added two new files, xil_sleeptimer.c and + * xil_sleeptimer.h in ARM for the common sleep routines and 1 new file, + * xil_sleepcommon.c in Standalone-common for sleep/usleep API's. + * 6.6 hk 12/15/17 Export platform macros to bspconfig.h based on the processor. + * 6.6 asa 1/16/18 Ensure C stack information for A9 are flushed out from L1 D cache + * or L2 cache only when the respective caches are enabled. This fixes CR-922023. + * 6.6 mus 01/19/18 Updated asm_vectors.S and boot.S in Cortexa53 64 bit BSP, to add isb + * after writing to cpacr_el1/cptr_el3 registers. It would ensure + * disabling/enabling of floating-point unit, before any subsequent + * instruction. + * 6.6 hk 12/15/17 Export platform macros to xparameters.h based on the processor. + * 6.6 asa 1/16/18 Ensure C stack information for A9 are flushed out from L1 D cache + * or L2 cache only when the respective caches are enabled.This fixes CR-922023. + * + * 6.6 mus 01/19/18 Updated asm_vectors.S and boot.S in Cortexa53 64 bit BSP, to add isb + * after writing to cpacr_el1/cptr_el3 registers. It would ensure + * disabling/enabling of floating-point unit, before any subsequent + * instruction. + * 6.6 mus 01/30/18 Updated hypervisor enabled Cortexa53 64 bit BSP, to add xen PV console + * support. Now, xil_printf would use PV console instead of UART in case of + * hypervisor enabled BSP. + * 6.6 mus 02/02/18 Updated get_connected_if proc in standalone tcl to detect the HPC port + * configured with smart interconnect.It fixes CR#990318. + * 6.6 srm 02/10/18 Updated csu_wdt interrupt to the correct value. Fixes CR#992229 + * 6.6 asa 02/12/18 Fix for heap handling for ARM platforms. CR#993932. + * 6.6 mus 02/19/18 Updated standalone.tcl to fix bug in handle_profile_opbtimer proc, + * CR#995014. + * 6.6 mus 02/23/18 Presently Cortex R5 BSP boot code is disabling the debug logic in + * non-JTAG boot mode, when processor is in lockstep configuration. + * This behavior is restricting application debugging in non-JTAG boot + * mode. To get rid of this restriction, added new mld parameter + * "lockstep_mode_debug", to enable/disable debug logic from BSP + * settings. Now, debug logic can be enabled through BSP settings, + * by modifying value of parameter "lockstep_mode_debug" as "true". + * It fixes CR#993896. + * 6.6.mus 02/27/18 Updated Xil_DCacheInvalidateRange and + * Xil_ICacheInvalidateRange APIs in Cortexa53 64 bit BSP, to fix bug + * in handling upper DDR addresses.It fixes CR#995581. + * 6.6 mus 03/12/18 Updated makefile of Cortexa53 32bit BSP to add includes_ps directory + * in the list of include paths. This change allows applications/BSP + * files to include .h files in include_ps directory. + * 6.6 mus 03/16/18 By default CPUACTLR_EL1 is accessible only from EL3, it + * results into abort if accessed from EL1 non secure privilege + * level. Updated Xil_ConfigureL1Prefetch function in Cortexa53 64 bit BSP + * to avoid CPUACTLR_EL1 access from privile levels other than EL3. + * 6.6 mus 03/16/18 Updated hypervisor enabled BSP to use PV console, based on the + * XEN_USE_PV_CONSOLE flag. By deafault hypervisor enabled BSP would + * use UART console, PV console can be enabled by appending + * "-DXEN_USE_PV_CONSOLE" to the BSP extra compiler flags. + * 6.7 asa 04/26/18 Added API Xil_GetExceptionRegisterHandler for obtaining information + * on an already registered exception vector. + * 6.7 asa 05/18/18 Fixed bugss in the API Xil_GetExceptionRegisterHandler. + * 6.8 mus 04/27/18 Removed __ARM_NEON__ flag definition. Now, saving/restoring of of HW + * floating point register would be done through newly introduced flag + * FPU_HARD_FLOAT_ABI_ENABLED. This new flag will be configured based on + * the -mfpu-abi option in extra compiler flags.. This change has + * been done to avoid saving/restoring of HW floating point registers, + * when BSP is not compiled with HW floating point configuration. + * 6.8 aru 06/15/18 Removed unused variable in xil_cache.c for A53-32. It + * fixes CR1005118. + * 6.8 aru 07/02/18 Returned the pointer instead of address of that pointer in xil_mpu.c + * for R5 processor.It Fixes CR#1005119. + * 6.8 mus 07/12/18 Updated Cortexa9 translation table to mark DDR memory as inner cacheable, + * if BSP is built with the USE_AMP flag. It fixes CR#1006745. + * + * 6.8 aru 07/04/18 Optimized the code to use a loop and to remove redundant code + * in Xil_DCacheFlush() and Xil_DCacheInvalidate() + * of xil_cache.c for A53-32. + * 6.8 aru 07/26/18 added support in xil_printf.c to print u64 variabbles + * correctly in 32 bit processor.It fixes CR#1007207. + * 6.8 aru 09/03/18 Optimized the code to use a single function and removed + * code redundancy in xil_printf.c . It Fixes CR#1009654. + * 6.8 aru 09/06/18 Removed the compiler warnings for ARMCC toolchain. + * It fixes CR#1008309. + * 6.8 mus 09/20/18 Updated CortexR5 boot code to initialize CortexR5 core with LOVEC + * on reset. It fixes CR#1010656. + * 6.8 mus 10/04/18 Updated microblaze sleep functinality to execute default method of + * sleep implementation, incase of FreeRTOS BSP. + * 6.8 mus 10/25/18 Updated assembly code for cache APIs and inline assemby macros to + * to support 64 bit addresses. + * 6.8 asa 10/11/18 Updated the A53 32 bit cache APIs for Xil_DCacheFlush and + * Xil_DCacheInvalidate to fix various issues. These issues were not + * present in the previous releases but got introduced as part of + * optimization patches that got applied for 6.8 BSP version. These + * changes fix the CR#1016012. + * 7.0 rp 10/25/18 Added XST_NO_ACCESS status macros for generic access error. + * 7.0 mus 02/01/19 Added support for Versal. Cortea53 BSP will be re-used by Cortexa72, + * re-named cortexa53 directory as ARMv8, since files are generic for + * ARMv8 based processors. Created "platform" directory to place + * SoC based files. + * 7.0 mus 02/05/19 Updated Xil_MemCpy API to copy two bytes at a time from source to + * destination if byte count is <= 2. + * 7.0 mus 02/28/19 Added armclang complier support to the Cortexa53 64 bit BSP. + * 7.0 mus 04/08/19 Fix microblaze_disable_dcache for 64 bit microblaze + * 7.0 mus 04/26/19 Added frequently used functions in common area in xil_utils.c, + * so that other modules can make use of it. + *****************************************************************************************/ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/close.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/close.c new file mode 100644 index 0000000..64f7f49 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/close.c @@ -0,0 +1,45 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +#ifndef UNDEFINE_FILE_OPS +#include "xil_types.h" +#ifdef __cplusplus +extern "C" { + __attribute__((weak)) s32 _close(s32 fd); +} +#endif + +/* + * close -- We don't need to do anything, but pretend we did. + */ + +__attribute__((weak)) s32 _close(s32 fd) +{ + (void)fd; + return (0); +} +#endif diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/config.make b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/config.make new file mode 100644 index 0000000..2668199 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/config.make @@ -0,0 +1,3 @@ +LIBSOURCES = *.c *.S +PROFILE_ARCH_OBJS = profile_mcount_arm.o +LIBS = standalone_libs diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/cpu_init.S b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/cpu_init.S new file mode 100644 index 0000000..5b597be --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/cpu_init.S @@ -0,0 +1,76 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* @file cpu_init.s +* +* This file contains CPU specific initialization. Invoked from main CRT +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who     Date     Changes
+* ----- ------- -------- ---------------------------------------------------
+* 1.00a ecm/sdm 10/20/09 Initial version
+* 3.04a sdm	01/02/12 Updated to clear cp15 regs with unknown reset values
+* 5.0   pkp	12/16/14 removed incorrect initialization of TLB lockdown
+*			 register to fix CR#830580
+* 
+* +* @note +* +* None. +* +******************************************************************************/ + + .text + .global __cpu_init + .align 2 +__cpu_init: + +/* Clear cp15 regs with unknown reset values */ + mov r0, #0x0 + mcr p15, 0, r0, c5, c0, 0 /* DFSR */ + mcr p15, 0, r0, c5, c0, 1 /* IFSR */ + mcr p15, 0, r0, c6, c0, 0 /* DFAR */ + mcr p15, 0, r0, c6, c0, 2 /* IFAR */ + mcr p15, 0, r0, c9, c13, 2 /* PMXEVCNTR */ + mcr p15, 0, r0, c13, c0, 2 /* TPIDRURW */ + mcr p15, 0, r0, c13, c0, 3 /* TPIDRURO */ + +/* Reset and start Cycle Counter */ + mov r2, #0x80000000 /* clear overflow */ + mcr p15, 0, r2, c9, c12, 3 + mov r2, #0xd /* D, C, E */ + mcr p15, 0, r2, c9, c12, 0 + mov r2, #0x80000000 /* enable cycle counter */ + mcr p15, 0, r2, c9, c12, 1 + + bx lr + +.end diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/errno.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/errno.c new file mode 100644 index 0000000..3cdb751 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/errno.c @@ -0,0 +1,47 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ + +/* The errno variable is stored in the reentrancy structure. This + function returns its address for use by the macro errno defined in + errno.h. */ + +#include +#include +#include "xil_types.h" + +#ifdef __cplusplus +extern "C" { + __attribute__((weak)) sint32 * __errno (void); +} +#endif + +__attribute__((weak)) sint32 * +__errno (void) +{ + return &_REENT->_errno; +} diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/fcntl.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/fcntl.c new file mode 100644 index 0000000..42c2bff --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/fcntl.c @@ -0,0 +1,42 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ + +#include +#include "xil_types.h" + +/* + * fcntl -- Manipulate a file descriptor. + * We don't have a filesystem, so we do nothing. + */ +__attribute__((weak)) sint32 fcntl (sint32 fd, sint32 cmd, long arg) +{ + (void)fd; + (void)cmd; + (void)arg; + return 0; +} diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/fstat.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/fstat.c new file mode 100644 index 0000000..92a3ebf --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/fstat.c @@ -0,0 +1,46 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ + +#include +#include "xil_types.h" + +#ifdef __cplusplus +extern "C" { + __attribute__((weak)) s32 _fstat(s32 fd, struct stat *buf); +} +#endif +/* + * fstat -- Since we have no file system, we just return an error. + */ +__attribute__((weak)) s32 _fstat(s32 fd, struct stat *buf) +{ + (void)fd; + buf->st_mode = S_IFCHR; /* Always pretend to be a tty */ + + return (0); +} diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/getpid.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/getpid.c new file mode 100644 index 0000000..36c8769 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/getpid.c @@ -0,0 +1,47 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ + +#include "xil_types.h" +/* + * getpid -- only one process, so just return 1. + */ +#ifdef __cplusplus +extern "C" { + __attribute__((weak)) s32 _getpid(void); +} +#endif + +__attribute__((weak)) s32 getpid(void) +{ + return 1; +} + +__attribute__((weak)) s32 _getpid(void) +{ + return 1; +} diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/inbyte.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/inbyte.c new file mode 100644 index 0000000..0036459 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/inbyte.c @@ -0,0 +1,14 @@ +#include "xparameters.h" +#include "xuartps_hw.h" + +#ifdef __cplusplus +extern "C" { +#endif +char inbyte(void); +#ifdef __cplusplus +} +#endif + +char inbyte(void) { + return XUartPs_RecvByte(STDIN_BASEADDRESS); +} diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/isatty.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/isatty.c new file mode 100644 index 0000000..d1ef081 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/isatty.c @@ -0,0 +1,52 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +#include +#include "xil_types.h" + +#ifdef __cplusplus +extern "C" { + __attribute__((weak)) sint32 _isatty(sint32 fd); +} +#endif + +/* + * isatty -- returns 1 if connected to a terminal device, + * returns 0 if not. Since we're hooked up to a + * serial port, we'll say yes _AND return a 1. + */ +__attribute__((weak)) sint32 isatty(sint32 fd) +{ + (void)fd; + return (1); +} + +__attribute__((weak)) sint32 _isatty(sint32 fd) +{ + (void)fd; + return (1); +} diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/kill.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/kill.c new file mode 100644 index 0000000..22b66a2 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/kill.c @@ -0,0 +1,56 @@ +/****************************************************************************** +* +* Copyright (C) 2014 - 2016 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +#include +#include +#include "xil_types.h" + +#ifdef __cplusplus +extern "C" { + __attribute__((weak)) int _kill(pid_t pid, int sig); +} +#endif + +/* + * kill -- go out via exit... + */ + +__attribute__((weak)) int kill(pid_t pid, int sig) +{ + if(pid == 1) { + _exit(sig); + } + return 0; +} + +__attribute__((weak)) int _kill(pid_t pid, int sig) +{ + if(pid == 1) { + _exit(sig); + } + return 0; +} diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/lseek.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/lseek.c new file mode 100644 index 0000000..400d4cc --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/lseek.c @@ -0,0 +1,57 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ + +#include +#include +#include "xil_types.h" + +#ifdef __cplusplus +extern "C" { + __attribute__((weak)) off_t _lseek(s32 fd, off_t offset, s32 whence); +} +#endif +/* + * lseek -- Since a serial port is non-seekable, we return an error. + */ +__attribute__((weak)) off_t lseek(s32 fd, off_t offset, s32 whence) +{ + (void)fd; + (void)offset; + (void)whence; + errno = ESPIPE; + return ((off_t)-1); +} + +__attribute__((weak)) off_t _lseek(s32 fd, off_t offset, s32 whence) +{ + (void)fd; + (void)offset; + (void)whence; + errno = ESPIPE; + return ((off_t)-1); +} diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/open.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/open.c new file mode 100644 index 0000000..4c46b67 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/open.c @@ -0,0 +1,49 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +#ifndef UNDEFINE_FILE_OPS +#include +#include "xil_types.h" + +#ifdef __cplusplus +extern "C" { + __attribute__((weak)) s32 open(char8 *buf, s32 flags, s32 mode); +} +#endif +/* + * open -- open a file descriptor. We don't have a filesystem, so + * we return an error. + */ +__attribute__((weak)) s32 open(char8 *buf, s32 flags, s32 mode) +{ + (void)buf; + (void)flags; + (void)mode; + errno = EIO; + return (-1); +} +#endif diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/outbyte.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/outbyte.c new file mode 100644 index 0000000..8b56036 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/outbyte.c @@ -0,0 +1,15 @@ +#include "xparameters.h" +#include "xuartps_hw.h" + +#ifdef __cplusplus +extern "C" { +#endif +void outbyte(char c); + +#ifdef __cplusplus +} +#endif + +void outbyte(char c) { + XUartPs_SendByte(STDOUT_BASEADDRESS, c); +} diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/print.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/print.c new file mode 100644 index 0000000..da7e768 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/print.c @@ -0,0 +1,36 @@ +/* print.c -- print a string on the output device. + * + * Copyright (c) 1995 Cygnus Support + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + * + */ + +/* + * print -- do a raw print of a string + */ +#include "xil_printf.h" + +void print(const char8 *ptr) +{ +#if HYP_GUEST && EL1_NONSECURE && XEN_USE_PV_CONSOLE + XPVXenConsole_Write(ptr); +#else +#ifdef STDOUT_BASEADDRESS + while (*ptr != (char8)0) { + outbyte (*ptr); + ptr++; + } +#else +(void)ptr; +#endif +#endif +} diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/Makefile b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/Makefile new file mode 100644 index 0000000..53a288e --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/Makefile @@ -0,0 +1,74 @@ +############################################################################### +# +# Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# Except as contained in this notice, the name of the Xilinx shall not be used +# in advertising or otherwise to promote the sale, use or other dealings in +# this Software without prior written authorization from Xilinx. +# +############################################################################### +# +# Makefile for profiler +# +####################################################################### + +# PROFILE_ARCH_OBJS - Processor Architecture Dependent files defined here +include ../config.make + +AS=mb-as +COMPILER = mb-gcc +ARCHIVER = mb-ar +CP = cp +COMPILER_FLAGS=-O2 +EXTRA_COMPILER_FLAGS= +LIB = libxil.a +DUMMYLIB = libxilprofile.a + +CC_FLAGS = $(subst -pg, , $(COMPILER_FLAGS)) +ECC_FLAGS = $(subst -pg, , $(EXTRA_COMPILER_FLAGS)) + +RELEASEDIR = ../../../../lib +INCLUDEDIR = ../../../../include +INCLUDES = -I./. -I${INCLUDEDIR} + +OBJS = _profile_init.o _profile_clean.o _profile_timer_hw.o profile_hist.o profile_cg.o +DUMMYOBJ = dummy.o +INCLUDEFILES = profile.h mblaze_nt_types.h _profile_timer_hw.h + +libs : reallibs dummylibs + +reallibs : $(OBJS) $(PROFILE_ARCH_OBJS) + $(ARCHIVER) -r $(RELEASEDIR)/$(LIB) $(OBJS) $(PROFILE_ARCH_OBJS) + +dummylibs : $(DUMMYOBJ) + $(ARCHIVER) -r $(RELEASEDIR)/$(DUMMYLIB) $(DUMMYOBJ) + +%.o:%.c + $(COMPILER) $(CC_FLAGS) $(ECC_FLAGS) -c $< -o $@ $(INCLUDES) + +%.o:%.S + $(COMPILER) $(CC_FLAGS) $(ECC_FLAGS) -c $< -o $@ $(INCLUDES) + +include: + $(CP) -rf $(INCLUDEFILES) $(INCLUDEDIR) + +clean: + rm -f $(OBJS) $(PROFILE_ARCH_OBJS) $(LIB) diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/_profile_clean.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/_profile_clean.c new file mode 100644 index 0000000..b1c61f8 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/_profile_clean.c @@ -0,0 +1,43 @@ +/****************************************************************************** +* +* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ + +#include "profile.h" +#include "_profile_timer_hw.h" +#include "xil_exception.h" + +void _profile_clean( void ); + +/* + * This function is the exit routine and is called by the crtinit, when the + * program terminates. The name needs to be changed later.. + */ +void _profile_clean( void ) +{ + Xil_ExceptionDisable(); + disable_timer(); +} diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/_profile_init.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/_profile_init.c new file mode 100644 index 0000000..050b0a7 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/_profile_init.c @@ -0,0 +1,86 @@ +/****************************************************************************** +* +* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +****************************************************************************** +* +* _program_init.c: +* Initialize the Profiling Structures. +* +******************************************************************************/ + +#include "profile.h" + +/* XMD Initializes the following Global Variables Value during Program + * Download with appropriate values. */ + +#ifdef PROC_MICROBLAZE + +extern s32 microblaze_init(void); + +#elif defined PROC_PPC + +extern s32 powerpc405_init(void); + +#else + +extern s32 cortexa9_init(void); + +#endif + +s32 profile_version = 1; /* Version of S/W Intrusive Profiling library */ + +u32 binsize = (u32)BINSIZE; /* Histogram Bin Size */ +u32 cpu_clk_freq = (u32)CPU_FREQ_HZ ; /* CPU Clock Frequency */ +u32 sample_freq_hz = (u32)SAMPLE_FREQ_HZ ; /* Histogram Sampling Frequency */ +u32 timer_clk_ticks = (u32)TIMER_CLK_TICKS ;/* Timer Clock Ticks for the Timer */ + +/* Structure for Storing the Profiling Data */ +struct gmonparam *_gmonparam = (struct gmonparam *)(0xffffffffU); +s32 n_gmon_sections = 1; + +/* This is the initialization code, which is called from the crtinit. */ + +void _profile_init( void ) +{ +/* print("Gmon Init called....\r\n") */ +/* putnum(n_gmon_sections) , print("\r\n") */ +/* if( _gmonparam == 0xffffffff ) */ +/* printf("Gmonparam is NULL !!\r\n") */ +/* for( i = 0, i < n_gmon_sections, i++ )[ */ +/* putnum( _gmonparam[i].lowpc) , print("\t") */ +/* putnum( _gmonparam[i].highpc) , print("\r\n") */ +/* putnum( _gmonparam[i].textsize ), print("\r\n") */ +/* putnum( _gmonparam[i].kcountsize * sizeof(unsigned short)), print("\r\n") */ +/* ] */ + +#ifdef PROC_MICROBLAZE + (void)microblaze_init(); +#elif defined PROC_PPC + powerpc405_init(); +#else + (void)cortexa9_init(); +#endif +} diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/_profile_timer_hw.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/_profile_timer_hw.c new file mode 100644 index 0000000..c8243e5 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/_profile_timer_hw.c @@ -0,0 +1,383 @@ +/****************************************************************************** +* +* Copyright (C) 2004 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +****************************************************************************** +* +* _program_timer_hw.c: +* Timer related functions +* +******************************************************************************/ + +#include "profile.h" +#include "_profile_timer_hw.h" + +#include "xil_exception.h" + +#ifdef PROC_PPC +#include "xtime_l.h" +#include "xpseudo_asm.h" +#endif + +#ifdef TIMER_CONNECT_INTC +#include "xintc_l.h" +#include "xintc.h" +#endif /* TIMER_CONNECT_INTC */ + +/* #ifndef PPC_PIT_INTERRUPT */ +#if (!defined PPC_PIT_INTERRUPT && !defined PROC_CORTEXA9) +#include "xtmrctr_l.h" +#endif + +/* extern u32 timer_clk_ticks, */ + +#ifdef PROC_PPC405 +#ifdef PPC_PIT_INTERRUPT +s32 ppc_pit_init( void ); +#endif +s32 powerpc405_init() +#endif /* PROC_CORTEXA9 */ + +#ifdef PROC_PPC440 +#ifdef PPC_PIT_INTERRUPT +s32 ppc_dec_init( void ); +#endif +s32 powerpc405_init(void); +#endif /* PROC_PPC440 */ + +#if (!defined PPC_PIT_INTERRUPT && !defined PROC_CORTEXA9) +s32 opb_timer_init( void ); +#endif + +#ifdef PROC_MICROBLAZE +s32 microblaze_init(void); +#endif /* PROC_MICROBLAZE */ + +#ifdef PROC_CORTEXA9 +s32 scu_timer_init( void ); +s32 cortexa9_init(void); +#endif /* PROC_CORTEXA9 */ + + +/*-------------------------------------------------------------------- + * PowerPC Target - Timer related functions + *-------------------------------------------------------------------- */ +#ifdef PROC_PPC405 + + +/*-------------------------------------------------------------------- +* PowerPC PIT Timer Init. +* Defined only if PIT Timer is used for Profiling +* +*-------------------------------------------------------------------- */ +#ifdef PPC_PIT_INTERRUPT +int ppc_pit_init( void ) +{ + /* 1. Register Profile_intr_handler as Interrupt handler */ + /* 2. Set PIT Timer Interrupt and Enable it. */ + Xil_ExceptionRegisterHandler( XIL_EXCEPTION_ID_PIT_INT, + (Xil_ExceptionHandler)profile_intr_handler,NULL); + XTime_PITSetInterval( timer_clk_ticks ) ; + XTime_PITEnableAutoReload() ; + return 0; +} +#endif + + +/* -------------------------------------------------------------------- +* PowerPC Timer Initialization functions. +* For PowerPC, PIT and opb_timer can be used for Profiling. This +* is selected by the user in standalone BSP +* +*-------------------------------------------------------------------- */ +s32 powerpc405_init() +{ + Xil_ExceptionInit() ; + Xil_ExceptionDisableMask( XIL_EXCEPTION_NON_CRITICAL ) ; + + /* Initialize the Timer. + * 1. If PowerPC PIT Timer has to be used, initialize PIT timer. + * 2. Else use opb_timer. It can be directly connected or thru intc to PowerPC */ +#ifdef PPC_PIT_INTERRUPT + ppc_pit_init(); +#else +#ifdef TIMER_CONNECT_INTC + Xil_ExceptionRegisterHandler( XIL_EXCEPTION_ID_NON_CRITICAL_INT, + (Xil_ExceptionHandler)XIntc_DeviceInterruptHandler,NULL); + XIntc_RegisterHandler( INTC_BASEADDR, PROFILE_TIMER_INTR_ID, + (XInterruptHandler)profile_intr_handler,NULL); +#else + Xil_ExceptionRegisterHandler( XIL_EXCEPTION_ID_NON_CRITICAL_INT, + (Xil_ExceptionHandler)profile_intr_handler,NULL); +#endif + /* Initialize the timer with Timer Ticks */ + opb_timer_init() ; +#endif + + /* Enable Interrupts in the System, if Profile Timer is the only Interrupt + * in the System. */ +#ifdef ENABLE_SYS_INTR +#ifdef PPC_PIT_INTERRUPT + XTime_PITEnableInterrupt() ; +#elif TIMER_CONNECT_INTC + XIntc_MasterEnable( INTC_BASEADDR ); + XIntc_SetIntrSvcOption( INTC_BASEADDR, XIN_SVC_ALL_ISRS_OPTION); + XIntc_EnableIntr( INTC_BASEADDR, PROFILE_TIMER_INTR_MASK ); +#endif + Xil_ExceptionEnableMask( XIL_EXCEPTION_NON_CRITICAL ) ; +#endif + return 0; +} + +#endif /* PROC_PPC */ + + + +/*-------------------------------------------------------------------- + * PowerPC440 Target - Timer related functions + * -------------------------------------------------------------------- */ +#ifdef PROC_PPC440 + + +/*-------------------------------------------------------------------- + * PowerPC DEC Timer Init. + * Defined only if DEC Timer is used for Profiling + * + *-------------------------------------------------------------------- */ +#ifdef PPC_PIT_INTERRUPT +s32 ppc_dec_init( void ) +{ + /* 1. Register Profile_intr_handler as Interrupt handler */ + /* 2. Set DEC Timer Interrupt and Enable it. */ + Xil_ExceptionRegisterHandler( XIL_EXCEPTION_ID_DEC_INT, + (Xil_ExceptionHandler)profile_intr_handler,NULL); + XTime_DECSetInterval( timer_clk_ticks ) ; + XTime_DECEnableAutoReload() ; + return 0; +} +#endif + + +/*-------------------------------------------------------------------- + * PowerPC Timer Initialization functions. + * For PowerPC, DEC and opb_timer can be used for Profiling. This + * is selected by the user in standalone BSP + * + *-------------------------------------------------------------------- */ +s32 powerpc405_init(void) +{ + Xil_ExceptionInit(); + Xil_ExceptionDisableMask( XIL_EXCEPTION_NON_CRITICAL ) ; + + /* Initialize the Timer. + * 1. If PowerPC DEC Timer has to be used, initialize DEC timer. + * 2. Else use opb_timer. It can be directly connected or thru intc to PowerPC */ +#ifdef PPC_PIT_INTERRUPT + ppc_dec_init(); +#else +#ifdef TIMER_CONNECT_INTC + Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_NON_CRITICAL_INT, + (Xil_ExceptionHandler)XIntc_DeviceInterruptHandler,NULL); + + XIntc_RegisterHandler( INTC_BASEADDR, PROFILE_TIMER_INTR_ID, + (XInterruptHandler)profile_intr_handler,NULL); +#else + Xil_ExceptionRegisterHandler( XIL_EXCEPTION_ID_NON_CRITICAL_INT, + (Xil_ExceptionHandler)profile_intr_handler,NULL); + Xil_ExceptionRegisterHandler( XIL_EXCEPTION_ID_NON_CRITICAL_INT, + (Xil_ExceptionHandler)profile_intr_handler,NULL); +#endif + /* Initialize the timer with Timer Ticks */ + opb_timer_init() ; +#endif + + /* Enable Interrupts in the System, if Profile Timer is the only Interrupt + * in the System. */ +#ifdef ENABLE_SYS_INTR +#ifdef PPC_PIT_INTERRUPT + XTime_DECEnableInterrupt() ; +#elif TIMER_CONNECT_INTC + XIntc_MasterEnable( INTC_BASEADDR ); + XIntc_SetIntrSvcOption( INTC_BASEADDR, XIN_SVC_ALL_ISRS_OPTION); + XIntc_EnableIntr( INTC_BASEADDR, PROFILE_TIMER_INTR_MASK ); +#endif + Xil_ExceptionEnableMask( XEXC_NON_CRITICAL ) ; +#endif + return 0; +} + +#endif /* PROC_PPC440 */ + +/* -------------------------------------------------------------------- + * opb_timer Initialization for PowerPC and MicroBlaze. This function + * is not needed if DEC timer is used in PowerPC + * + *-------------------------------------------------------------------- */ +/* #ifndef PPC_PIT_INTERRUPT */ +#if (!defined PPC_PIT_INTERRUPT && !defined PROC_CORTEXA9) +s32 opb_timer_init( void ) +{ + /* set the number of cycles the timer counts before interrupting */ + XTmrCtr_SetLoadReg((u32)PROFILE_TIMER_BASEADDR, (u16)0, (u32)timer_clk_ticks); + + /* reset the timers, and clear interrupts */ + XTmrCtr_SetControlStatusReg((u32)PROFILE_TIMER_BASEADDR, (u16)0, + (u32)XTC_CSR_INT_OCCURED_MASK | (u32)XTC_CSR_LOAD_MASK ); + + /* start the timers */ + XTmrCtr_SetControlStatusReg((u32)PROFILE_TIMER_BASEADDR, (u16)0, (u32)XTC_CSR_ENABLE_TMR_MASK + | (u32)XTC_CSR_ENABLE_INT_MASK | (u32)XTC_CSR_AUTO_RELOAD_MASK | (u32)XTC_CSR_DOWN_COUNT_MASK); + return 0; +} +#endif + + +/*-------------------------------------------------------------------- + * MicroBlaze Target - Timer related functions + *-------------------------------------------------------------------- */ +#ifdef PROC_MICROBLAZE + +/* -------------------------------------------------------------------- + * Initialize the Profile Timer for MicroBlaze Target. + * For MicroBlaze, opb_timer is used. The opb_timer can be directly + * connected to MicroBlaze or connected through Interrupt Controller. + * + *-------------------------------------------------------------------- */ +s32 microblaze_init(void) +{ + /* Register profile_intr_handler + * 1. If timer is connected to Interrupt Controller, register the handler + * to Interrupt Controllers vector table. + * 2. If timer is directly connected to MicroBlaze, register the handler + * as Interrupt handler */ + Xil_ExceptionInit(); + +#ifdef TIMER_CONNECT_INTC + XIntc_RegisterHandler( INTC_BASEADDR, PROFILE_TIMER_INTR_ID, + (XInterruptHandler)profile_intr_handler,NULL); +#else + Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, + (Xil_ExceptionHandler)profile_intr_handler, + NULL) ; +#endif + + /* Initialize the timer with Timer Ticks */ + (void)opb_timer_init() ; + + /* Enable Interrupts in the System, if Profile Timer is the only Interrupt + * in the System. */ +#ifdef ENABLE_SYS_INTR +#ifdef TIMER_CONNECT_INTC + XIntc_MasterEnable((u32)INTC_BASEADDR ); + XIntc_SetIntrSvcOption( INTC_BASEADDR, XIN_SVC_ALL_ISRS_OPTION); + XIntc_EnableIntr( (u32)INTC_BASEADDR, PROFILE_TIMER_INTR_MASK ); + Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, + (Xil_ExceptionHandler)XIntc_DeviceInterruptHandler,NULL); +#endif + +#endif + + Xil_ExceptionEnable(); + + return 0; + +} + +#endif /* PROC_MICROBLAZE */ + + + +/* -------------------------------------------------------------------- + * Cortex A9 Target - Timer related functions + *-------------------------------------------------------------------- */ +#ifdef PROC_CORTEXA9 + +/* -------------------------------------------------------------------- + * Initialize the Profile Timer for Cortex A9 Target. + * The scu private timer is connected to the Scu GIC controller. + * + *-------------------------------------------------------------------- */ +s32 scu_timer_init( void ) +{ + /* set the number of cycles the timer counts before interrupting + * scu timer runs at half the cpu clock */ + XScuTimer_SetLoadReg(PROFILE_TIMER_BASEADDR, timer_clk_ticks/2U); + + /* clear any pending interrupts */ + XScuTimer_SetIntrReg(PROFILE_TIMER_BASEADDR, 1U); + + /* enable interrupts, auto-reload mode and start the timer */ + XScuTimer_SetControlReg(PROFILE_TIMER_BASEADDR, XSCUTIMER_CONTROL_IRQ_ENABLE_MASK | + XSCUTIMER_CONTROL_AUTO_RELOAD_MASK | XSCUTIMER_CONTROL_ENABLE_MASK); + + return 0; +} + +s32 cortexa9_init(void) +{ + + Xil_ExceptionInit(); + + XScuGic_DeviceInitialize(0); + + /* + * Connect the interrupt controller interrupt handler to the hardware + * interrupt handling logic in the processor. + */ + Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT, + (Xil_ExceptionHandler)XScuGic_DeviceInterruptHandler, + NULL); + + /* + * Connect the device driver handler that will be called when an + * interrupt for the device occurs, the handler defined above performs + * the specific interrupt processing for the device. + */ + XScuGic_RegisterHandler(SCUGIC_CPU_BASEADDR, + PROFILE_TIMER_INTR_ID, + (Xil_ExceptionHandler)profile_intr_handler, + NULL); + + /* + * Enable the interrupt for scu timer. + */ + XScuGic_EnableIntr(SCUGIC_DIST_BASEADDR, PROFILE_TIMER_INTR_ID); + + /* + * Enable interrupts in the Processor. + */ + Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ); + + /* + * Initialize the timer with Timer Ticks + */ + (void)scu_timer_init() ; + + Xil_ExceptionEnable(); + + return 0; +} + +#endif /* PROC_CORTEXA9 */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/_profile_timer_hw.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/_profile_timer_hw.h new file mode 100644 index 0000000..1647600 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/_profile_timer_hw.h @@ -0,0 +1,308 @@ +/****************************************************************************** +* +* Copyright (C) 2004 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +****************************************************************************** +* +* _program_timer_hw.h: +* Timer related functions +* +******************************************************************************/ + +#ifndef PROFILE_TIMER_HW_H +#define PROFILE_TIMER_HW_H + +#include "profile.h" + +#ifdef PROC_PPC +#if defined __GNUC__ +# define SYNCHRONIZE_IO __asm__ volatile ("eieio") +#elif defined __DCC__ +# define SYNCHRONIZE_IO __asm volatile(" eieio") +#else +# define SYNCHRONIZE_IO +#endif +#endif + +#ifdef PROC_PPC +#define ProfIo_In32(InputPtr) { (*(volatile u32 *)(InputPtr)); SYNCHRONIZE_IO; } +#define ProfIo_Out32(OutputPtr, Value) { (*(volatile u32 *)(OutputPtr) = Value); SYNCHRONIZE_IO; } +#else +#define ProfIo_In32(InputPtr) (*(volatile u32 *)(InputPtr)); +#define ProfIo_Out32(OutputPtr, Value) { (*(volatile u32 *)(OutputPtr) = (Value)); } +#endif + +#define ProfTmrCtr_mWriteReg(BaseAddress, TmrCtrNumber, RegOffset, ValueToWrite)\ + ProfIo_Out32(((u32)(BaseAddress) + (u32)XTmrCtr_Offsets[(TmrCtrNumber)] + \ + (u32)(RegOffset)), (u32)(ValueToWrite)) + +#define ProfTimerCtr_mReadReg(BaseAddress, TmrCtrNumber, RegOffset) \ + ProfIo_In32((u32)(BaseAddress) + (u32)XTmrCtr_Offsets[(TmrCtrNumber)] + (u32)(RegOffset)) + +#define ProfTmrCtr_mSetControlStatusReg(BaseAddress, TmrCtrNumber, RegisterValue)\ + ProfTmrCtr_mWriteReg((BaseAddress), (TmrCtrNumber), XTC_TCSR_OFFSET, \ + (RegisterValue)) + +#define ProfTmrCtr_mGetControlStatusReg(BaseAddress, TmrCtrNumber) \ + ProfTimerCtr_mReadReg((u32)(BaseAddress), (TmrCtrNumber), XTC_TCSR_OFFSET) + + + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef PROC_PPC +#include "xexception_l.h" +#include "xtime_l.h" +#include "xpseudo_asm.h" +#endif + +#ifdef TIMER_CONNECT_INTC +#include "xintc_l.h" +#include "xintc.h" +#endif /* TIMER_CONNECT_INTC */ + +#if (!defined PPC_PIT_INTERRUPT && !defined PROC_CORTEXA9) +#include "xtmrctr_l.h" +#endif + +#ifdef PROC_CORTEXA9 +#include "xscutimer_hw.h" +#include "xscugic.h" +#endif + +extern u32 timer_clk_ticks ; + +/*-------------------------------------------------------------------- + * PowerPC Target - Timer related functions + *-------------------------------------------------------------------- */ +#ifdef PROC_PPC + +#ifdef PPC_PIT_INTERRUPT +u32 timer_lo_clk_ticks ; /* Clk ticks when Timer is disabled in CG */ +#endif + +#ifdef PROC_PPC440 +#define XREG_TCR_PIT_INTERRUPT_ENABLE XREG_TCR_DEC_INTERRUPT_ENABLE +#define XREG_TSR_PIT_INTERRUPT_STATUS XREG_TSR_DEC_INTERRUPT_STATUS +#define XREG_SPR_PIT XREG_SPR_DEC +#define XEXC_ID_PIT_INT XEXC_ID_DEC_INT +#endif + +/* -------------------------------------------------------------------- + * Disable the Timer - During Profiling + * + * For PIT Timer - + * 1. XTime_PITDisableInterrupt() ; + * 2. Store the remaining timer clk tick + * 3. Stop the PIT Timer + *-------------------------------------------------------------------- */ + +#ifdef PPC_PIT_INTERRUPT +#define disable_timer() \ + { \ + u32 val; \ + val=mfspr(XREG_SPR_TCR); \ + mtspr(XREG_SPR_TCR, val & (~XREG_TCR_PIT_INTERRUPT_ENABLE)); \ + timer_lo_clk_ticks = mfspr(XREG_SPR_PIT); \ + mtspr(XREG_SPR_PIT, 0); \ + } +#else +#define disable_timer() \ + { \ + u32 addr = (PROFILE_TIMER_BASEADDR) + XTmrCtr_Offsets[(0)] + XTC_TCSR_OFFSET; \ + u32 tmp_v = ProfIo_In32(addr); \ + tmp_v = tmp_v & (~XTC_CSR_ENABLE_TMR_MASK); \ + ProfIo_Out32((PROFILE_TIMER_BASEADDR) + XTmrCtr_Offsets[(0)] + XTC_TCSR_OFFSET, tmp_v); \ + } +#endif + + + +/* -------------------------------------------------------------------- + * Enable the Timer + * + * For PIT Timer - + * 1. Load the remaining timer clk ticks + * 2. XTime_PITEnableInterrupt() ; + *-------------------------------------------------------------------- */ +#ifdef PPC_PIT_INTERRUPT +#define enable_timer() \ + { \ + u32 val; \ + val=mfspr(XREG_SPR_TCR); \ + mtspr(XREG_SPR_PIT, timer_lo_clk_ticks); \ + mtspr(XREG_SPR_TCR, val | XREG_TCR_PIT_INTERRUPT_ENABLE); \ + } +#else +#define enable_timer() \ + { \ + u32 addr = (PROFILE_TIMER_BASEADDR) + XTmrCtr_Offsets[(0)] + XTC_TCSR_OFFSET; \ + u32 tmp_v = ProfIo_In32(addr); \ + tmp_v = tmp_v | XTC_CSR_ENABLE_TMR_MASK; \ + ProfIo_Out32((PROFILE_TIMER_BASEADDR) + XTmrCtr_Offsets[(0)] + XTC_TCSR_OFFSET, tmp_v); \ + } +#endif + + + +/* -------------------------------------------------------------------- + * Send Ack to Timer Interrupt + * + * For PIT Timer - + * 1. Load the timer clk ticks + * 2. Enable AutoReload and Interrupt + * 3. Clear PIT Timer Status bits + *-------------------------------------------------------------------- */ +#ifdef PPC_PIT_INTERRUPT +#define timer_ack() \ + { \ + u32 val; \ + mtspr(XREG_SPR_PIT, timer_clk_ticks); \ + mtspr(XREG_SPR_TSR, XREG_TSR_PIT_INTERRUPT_STATUS); \ + val=mfspr(XREG_SPR_TCR); \ + mtspr(XREG_SPR_TCR, val| XREG_TCR_PIT_INTERRUPT_ENABLE| XREG_TCR_AUTORELOAD_ENABLE); \ + } +#else +#define timer_ack() \ + { \ + u32 csr; \ + csr = ProfTmrCtr_mGetControlStatusReg(PROFILE_TIMER_BASEADDR, 0); \ + ProfTmrCtr_mSetControlStatusReg(PROFILE_TIMER_BASEADDR, 0, csr); \ + } +#endif + +/*-------------------------------------------------------------------- */ +#endif /* PROC_PPC */ +/* -------------------------------------------------------------------- */ + + + + +/* -------------------------------------------------------------------- + * MicroBlaze Target - Timer related functions + *-------------------------------------------------------------------- */ +#ifdef PROC_MICROBLAZE + +/* -------------------------------------------------------------------- + * Disable the Timer during Call-Graph Data collection + * + *-------------------------------------------------------------------- */ +#define disable_timer() \ + { \ + u32 Addr = ((u32)PROFILE_TIMER_BASEADDR); \ + Addr += (u32)XTmrCtr_Offsets[(u16)(0)]; \ + Addr += (u32)XTC_TCSR_OFFSET; \ + u32 tmp_v = ProfIo_In32(Addr); \ + tmp_v = tmp_v & (u32)(~XTC_CSR_ENABLE_TMR_MASK); \ + u32 OutAddr = (u32)PROFILE_TIMER_BASEADDR; \ + OutAddr += (u32)XTmrCtr_Offsets[(u16)(0)]; \ + OutAddr += (u32)XTC_TCSR_OFFSET; \ + ProfIo_Out32(OutAddr, (u32)tmp_v); \ + } + + +/* -------------------------------------------------------------------- + * Enable the Timer after Call-Graph Data collection + * + *-------------------------------------------------------------------- */ +#define enable_timer() \ + { \ + u32 Addr = ((u32)PROFILE_TIMER_BASEADDR); \ + Addr += (u32)XTmrCtr_Offsets[(u16)(0)]; \ + Addr += (u32)XTC_TCSR_OFFSET; \ + u32 tmp_v = (u32)ProfIo_In32(Addr); \ + tmp_v = tmp_v | (u32)XTC_CSR_ENABLE_TMR_MASK; \ + ProfIo_Out32((u32)(PROFILE_TIMER_BASEADDR) + (u32)XTmrCtr_Offsets[(u16)(0)] + (u32)XTC_TCSR_OFFSET, (u32)tmp_v); \ + } + + +/* -------------------------------------------------------------------- + * Send Ack to Timer Interrupt + * + *-------------------------------------------------------------------- */ +#define timer_ack() \ + { \ + u32 csr; \ + csr = ProfTmrCtr_mGetControlStatusReg((u32)PROFILE_TIMER_BASEADDR, (u16)0); \ + ProfTmrCtr_mSetControlStatusReg((u32)PROFILE_TIMER_BASEADDR, (u16)0, (u32)csr); \ + } + +/*-------------------------------------------------------------------- */ +#endif /* PROC_MICROBLAZE */ +/*-------------------------------------------------------------------- */ + +/* -------------------------------------------------------------------- + * Cortex A9 Target - Timer related functions + *-------------------------------------------------------------------- */ +#ifdef PROC_CORTEXA9 + +/* -------------------------------------------------------------------- + * Disable the Timer during Call-Graph Data collection + * + *-------------------------------------------------------------------- */ +#define disable_timer() \ +{ \ + u32 Reg; \ + Reg = Xil_In32(PROFILE_TIMER_BASEADDR + XSCUTIMER_CONTROL_OFFSET); \ + Reg &= (~XSCUTIMER_CONTROL_ENABLE_MASK);\ + Xil_Out32(PROFILE_TIMER_BASEADDR + XSCUTIMER_CONTROL_OFFSET, Reg);\ +} + + +/* -------------------------------------------------------------------- + * Enable the Timer after Call-Graph Data collection + * + *-------------------------------------------------------------------- */ +#define enable_timer() \ +{ \ + u32 Reg; \ + Reg = Xil_In32(PROFILE_TIMER_BASEADDR + XSCUTIMER_CONTROL_OFFSET); \ + Reg |= XSCUTIMER_CONTROL_ENABLE_MASK; \ + Xil_Out32(PROFILE_TIMER_BASEADDR + XSCUTIMER_CONTROL_OFFSET, Reg);\ +} + + +/* -------------------------------------------------------------------- + * Send Ack to Timer Interrupt + * + *-------------------------------------------------------------------- */ +#define timer_ack() \ +{ \ + Xil_Out32((u32)PROFILE_TIMER_BASEADDR + (u32)XSCUTIMER_ISR_OFFSET, \ + (u32)XSCUTIMER_ISR_EVENT_FLAG_MASK);\ +} + +/*-------------------------------------------------------------------- */ +#endif /* PROC_CORTEXA9 */ +/*-------------------------------------------------------------------- */ + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/dummy.S b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/dummy.S new file mode 100644 index 0000000..f4ff406 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/dummy.S @@ -0,0 +1,60 @@ +/****************************************************************************** +* +* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ + + .globl dummy_f + +#ifdef PROC_MICROBLAZE + .text + .align 2 + .ent dummy_f + +dummy_f: + nop + + .end dummy_f +#endif + +#ifdef PROC_PPC + .section .text + .align 2 + .type dummy_f@function + +dummy_f: + b dummy_f + +#endif + +#ifdef PROC_CORTEXA9 + .section .text + .align 2 + .type dummy_f, %function + +dummy_f: + b dummy_f + +#endif diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/mblaze_nt_types.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/mblaze_nt_types.h new file mode 100644 index 0000000..807dda3 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/mblaze_nt_types.h @@ -0,0 +1,50 @@ +/****************************************************************************** +* +* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ + + +#ifndef _MBLAZE_NT_TYPES_H +#define _MBLAZE_NT_TYPES_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef char byte; +typedef short half; +typedef int word; +typedef unsigned char ubyte; +typedef unsigned short uhalf; +typedef unsigned int uword; +typedef ubyte boolean; + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/profile.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/profile.h new file mode 100644 index 0000000..63f503a --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/profile.h @@ -0,0 +1,127 @@ +/****************************************************************************** +* +* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ + +#ifndef PROFILE_H +#define PROFILE_H 1 + +#include +#include "xil_types.h" +#include "profile_config.h" + +#ifdef PROC_MICROBLAZE +#include "mblaze_nt_types.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +void _system_init( void ) ; +void _system_clean( void ) ; +void mcount(u32 frompc, u32 selfpc); +void profile_intr_handler( void ) ; +void _profile_init( void ); + + + +/**************************************************************************** + * Profiling on hardware - Hash table maintained on hardware and data sent + * to xmd for gmon.out generation. + ****************************************************************************/ +/* + * histogram counters are unsigned shorts (according to the kernel). + */ +#define HISTCOUNTER u16 + +struct tostruct { + u32 selfpc; + s32 count; + s16 link; + u16 pad; +}; + +struct fromstruct { + u32 frompc ; + s16 link ; + u16 pad ; +} ; + +/* + * general rounding functions. + */ +#define ROUNDDOWN(x,y) (((x)/(y))*(y)) +#define ROUNDUP(x,y) ((((x)+(y)-1)/(y))*(y)) + +/* + * The profiling data structures are housed in this structure. + */ +struct gmonparam { + s32 state; + + /* Histogram Information */ + u16 *kcount; /* No. of bins in histogram */ + u32 kcountsize; /* Histogram samples */ + + /* Call-graph Information */ + struct fromstruct *froms; + u32 fromssize; + struct tostruct *tos; + u32 tossize; + + /* Initialization I/Ps */ + u32 lowpc; + u32 highpc; + u32 textsize; + /* u32 cg_froms, */ + /* u32 cg_tos, */ +}; +extern struct gmonparam *_gmonparam; +extern s32 n_gmon_sections; + +/* + * Possible states of profiling. + */ +#define GMON_PROF_ON 0 +#define GMON_PROF_BUSY 1 +#define GMON_PROF_ERROR 2 +#define GMON_PROF_OFF 3 + +/* + * Sysctl definitions for extracting profiling information from the kernel. + */ +#define GPROF_STATE 0 /* int: profiling enabling variable */ +#define GPROF_COUNT 1 /* struct: profile tick count buffer */ +#define GPROF_FROMS 2 /* struct: from location hash bucket */ +#define GPROF_TOS 3 /* struct: destination/count structure */ +#define GPROF_GMONPARAM 4 /* struct: profiling parameters (see above) */ + +#ifdef __cplusplus +} +#endif + +#endif /* PROFILE_H */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/profile_cg.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/profile_cg.c new file mode 100644 index 0000000..328e6fc --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/profile_cg.c @@ -0,0 +1,167 @@ +/****************************************************************************** +* +* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ + +#include "profile.h" +#include "_profile_timer_hw.h" +#ifdef PROC_MICROBLAZE +#include "mblaze_nt_types.h" +#endif + +/* + * The mcount fucntion is excluded from the library, if the user defines + * PROFILE_NO_GRAPH. + */ +#ifndef PROFILE_NO_GRAPH + +#include +#include +#include + +#ifdef PROFILE_NO_FUNCPTR +s32 searchpc(const struct fromto_struct *cgtable, s32 cgtable_size, u32 frompc ); +#else +s32 searchpc(const struct fromstruct *froms, s32 fromssize, u32 frompc ); +#endif + +/*extern struct gmonparam *_gmonparam, */ + +#ifdef PROFILE_NO_FUNCPTR +s32 searchpc(const struct fromto_struct *cgtable, s32 cgtable_size, u32 frompc ) +{ + s32 index = 0 ; + + while( (index < cgtable_size) && (cgtable[index].frompc != frompc) ){ + index++ ; + } + if( index == cgtable_size ) { + return -1 ; + } else { + return index ; + } +} +#else +s32 searchpc(const struct fromstruct *froms, s32 fromssize, u32 frompc ) +{ + s32 index = 0 ; + s32 Status; + + while( (index < fromssize) && (froms[index].frompc != frompc) ){ + index++ ; + } + if( index == fromssize ) { + Status = -1 ; + } else { + Status = index ; + } + return Status; +} +#endif /* PROFILE_NO_FUNCPTR */ + + +void mcount( u32 frompc, u32 selfpc ) +{ + register struct gmonparam *p = NULL; + register s32 toindex, fromindex; + s32 j; + + disable_timer(); + + /*print("CG: "), putnum(frompc), print("->"), putnum(selfpc), print("\r\n") , + * check that frompcindex is a reasonable pc value. + * for example: signal catchers get called from the stack, + * not from text space. too bad. + */ + for(j = 0; j < n_gmon_sections; j++ ){ + if((frompc >= _gmonparam[j].lowpc) && (frompc < _gmonparam[j].highpc)) { + p = &_gmonparam[j]; + break; + } + } + if( j == n_gmon_sections ) { + goto done; + } + +#ifdef PROFILE_NO_FUNCPTR + fromindex = searchpc( p->cgtable, p->cgtable_size, frompc ) ; + if( fromindex == -1 ) { + fromindex = p->cgtable_size ; + p->cgtable_size++ ; + p->cgtable[fromindex].frompc = frompc ; + p->cgtable[fromindex].selfpc = selfpc ; + p->cgtable[fromindex].count = 1 ; + goto done ; + } + p->cgtable[fromindex].count++ ; +#else + fromindex = (s32)searchpc( p->froms, ((s32)p->fromssize), frompc ) ; + if( fromindex == -1 ) { + fromindex = (s32)p->fromssize ; + p->fromssize++ ; + /*if( fromindex >= N_FROMS ) { + * print("Error : From PC table overflow\r\n") + * goto overflow + *}*/ + p->froms[fromindex].frompc = frompc ; + p->froms[fromindex].link = -1 ; + }else { + toindex = ((s32)(p->froms[fromindex].link)); + while(toindex != -1) { + toindex = (((s32)p->tossize) - toindex)-1 ; + if( p->tos[toindex].selfpc == selfpc ) { + p->tos[toindex].count++ ; + goto done ; + } + toindex = ((s32)(p->tos[toindex].link)) ; + } + } + + /*if( toindex == -1 ) { */ + p->tos-- ; + p->tossize++ ; + /* if( toindex >= N_TOS ) { + * print("Error : To PC table overflow\r\n") + * goto overflow + *} */ + p->tos[0].selfpc = selfpc ; + p->tos[0].count = 1 ; + p->tos[0].link = p->froms[fromindex].link ; + p->froms[fromindex].link = ((s32)(p->tossize))-((s32)1); +#endif + + done: + p->state = GMON_PROF_ON; + goto enable_timer_label ; + /* overflow: */ + /*p->state = GMON_PROF_ERROR */ + enable_timer_label: + enable_timer(); + return ; +} + + +#endif /* PROFILE_NO_GRAPH */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/profile_config.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/profile_config.h new file mode 100644 index 0000000..5d66311 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/profile_config.h @@ -0,0 +1,52 @@ +/****************************************************************************** +* +* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ + + +#ifndef _PROFILE_CONFIG_H +#define _PROFILE_CONFIG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define BINSIZE 4U +#define SAMPLE_FREQ_HZ 100000U +#define TIMER_CLK_TICKS 1000U + +#define PROFILE_NO_FUNCPTR_FLAG 0 + +#define PROFILE_TIMER_BASEADDR 0x00608000U +#define PROFILE_TIMER_INTR_ID 0U + +#define TIMER_CONNECT_INTC + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/profile_hist.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/profile_hist.c new file mode 100644 index 0000000..b3e237b --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/profile_hist.c @@ -0,0 +1,67 @@ +/****************************************************************************** +* +* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ + +#include "profile.h" +#include "_profile_timer_hw.h" + +#ifdef PROC_MICROBLAZE +#include "mblaze_nt_types.h" +#endif + +#ifdef PROC_PPC +#include "xpseudo_asm.h" +#define SPR_SRR0 0x01A +#endif + +#include "xil_types.h" + +extern u32 binsize ; +u32 prof_pc ; + +void profile_intr_handler( void ) +{ + + s32 j; + +#ifdef PROC_MICROBLAZE + asm( "swi r14, r0, prof_pc" ) ; +#elif defined PROC_PPC + prof_pc = mfspr(SPR_SRR0); +#else + /* for cortexa9, lr is saved in asm interrupt handler */ +#endif + /* print("PC: "), putnum(prof_pc), print("\r\n"), */ + for(j = 0; j < n_gmon_sections; j++ ){ + if((prof_pc >= ((u32)_gmonparam[j].lowpc)) && (prof_pc < ((u32)_gmonparam[j].highpc))) { + _gmonparam[j].kcount[(prof_pc-_gmonparam[j].lowpc)/((u32)4 * binsize)]++; + break; + } + } + /* Ack the Timer Interrupt */ + timer_ack(); +} diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/profile_mcount_arm.S b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/profile_mcount_arm.S new file mode 100644 index 0000000..9a84363 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/profile_mcount_arm.S @@ -0,0 +1,41 @@ +/****************************************************************************** +* +* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +// based on "ARM Profiling Implementation" from Sourcery G++ Lite for ARM EABI + +.globl __gnu_mcount_nc +.type __gnu_mcount_nc, %function + +__gnu_mcount_nc: + push {r0, r1, r2, r3, lr} + subs r1, lr, #0 /* callee - current lr */ + ldr r0, [sp, #20] /* caller - at the top of the stack */ + bl mcount /* when __gnu_mcount_nc is called */ + pop {r0, r1, r2, r3, ip, lr} + bx ip + + .end __gnu_mcount_nc diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/profile_mcount_mb.S b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/profile_mcount_mb.S new file mode 100644 index 0000000..21ab5b4 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/profile_mcount_mb.S @@ -0,0 +1,65 @@ +/****************************************************************************** +* +* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ + + .globl _mcount + .text + .align 2 + .ent _mcount + + #ifndef PROFILE_NO_GRAPH + +_mcount: + addi r1, r1, -48 + swi r11, r1, 44 + swi r12, r1, 40 + swi r5, r1, 36 + swi r6, r1, 32 + swi r7, r1, 28 + swi r8, r1, 24 + swi r9, r1, 20 + swi r10, r1, 16 + swi r15, r1, 12 + add r5, r0, r15 + brlid r15, mcount + add r6, r0, r16 + + lwi r11, r1, 44 + lwi r12, r1, 40 + lwi r5, r1, 36 + lwi r6, r1, 32 + lwi r7, r1, 28 + lwi r8, r1, 24 + lwi r9, r1, 20 + lwi r10, r1, 16 + lwi r15, r1, 12 + rtsd r15, 4 + addi r1, r1, 48 + + #endif /* PROFILE_NO_GRAPH */ + + .end _mcount diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/profile_mcount_ppc.S b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/profile_mcount_ppc.S new file mode 100644 index 0000000..230df08 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/profile_mcount_ppc.S @@ -0,0 +1,67 @@ +/****************************************************************************** +* +* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ + + .globl _mcount + + #define _MCOUNT_STACK_FRAME 48 + .section .text + .align 2 + .type _mcount@function + + +_mcount: + stwu 1, -_MCOUNT_STACK_FRAME(1) + stw 3, 8(1) + stw 4, 12(1) + stw 5, 16(1) + stw 6, 20(1) + stw 7, 24(1) + stw 8, 28(1) + stw 9, 32(1) + stw 10, 36(1) + stw 11, 40(1) + stw 12, 44(1) + mflr 4 + stw 4, (_MCOUNT_STACK_FRAME+4)(1) + lwz 3, (_MCOUNT_STACK_FRAME)(1) + lwz 3, 4(3) + bl mcount + lwz 4, (_MCOUNT_STACK_FRAME+4)(1) + mtlr 4 + lwz 12, 44(1) + lwz 11, 40(1) + lwz 10, 36(1) + lwz 9, 32(1) + lwz 8, 28(1) + lwz 7, 24(1) + lwz 6, 20(1) + lwz 5, 16(1) + lwz 4, 12(1) + lwz 3, 8(1) + addi 1,1, _MCOUNT_STACK_FRAME + blr diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/putnum.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/putnum.c new file mode 100644 index 0000000..aaf9ede --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/putnum.c @@ -0,0 +1,59 @@ +/* putnum.c -- put a hex number on the output device. + * + * Copyright (c) 1995 Cygnus Support + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ + +/* + * putnum -- print a 32 bit number in hex + */ + +/***************************** Include Files *********************************/ +#include "xil_types.h" + +/************************** Function Prototypes ******************************/ +extern void print (const char8 *ptr); +void putnum(u32 num); + +void putnum(u32 num) +{ + char8 buf[9]; + s32 cnt; + s32 i; + char8 *ptr; + u32 digit; + for(i = 0; i<9; i++) { + buf[i] = '0'; + } + + ptr = buf; + for (cnt = 7 ; cnt >= 0 ; cnt--) { + digit = (num >> (cnt * 4U)) & 0x0000000fU; + + if ((digit <= 9U) && (ptr != NULL)) { + digit += (u32)'0'; + *ptr = ((char8) digit); + ptr += 1; + } else if (ptr != NULL) { + digit += ((u32)'a' - (u32)10); + *ptr = ((char8)digit); + ptr += 1; + } else { + /*Made for MisraC Compliance*/; + } + } + + if(ptr != NULL) { + *ptr = (char8) 0; + } + print (buf); +} diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/read.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/read.c new file mode 100644 index 0000000..9900842 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/read.c @@ -0,0 +1,100 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ + +/* read.c -- read bytes from a input device. + */ +#ifndef UNDEFINE_FILE_OPS +#include "xil_printf.h" +#include "xparameters.h" + +#ifdef __cplusplus +extern "C" { + __attribute__((weak)) s32 _read (s32 fd, char8* buf, s32 nbytes); +} +#endif + +/* + * read -- read bytes from the serial port. Ignore fd, since + * we only have stdin. + */ +__attribute__((weak)) s32 +read (s32 fd, char8* buf, s32 nbytes) +{ +#ifdef STDIN_BASEADDRESS + s32 i; + s32 numbytes = 0; + char8* LocalBuf = buf; + + (void)fd; + if(LocalBuf != NULL) { + for (i = 0; i < nbytes; i++) { + numbytes++; + *(LocalBuf + i) = inbyte(); + if ((*(LocalBuf + i) == '\n' )|| (*(LocalBuf + i) == '\r')) { + break; + } + } + } + + return numbytes; +#else + (void)fd; + (void)buf; + (void)nbytes; + return 0; +#endif +} + +__attribute__((weak)) s32 +_read (s32 fd, char8* buf, s32 nbytes) +{ +#ifdef STDIN_BASEADDRESS + s32 i; + s32 numbytes = 0; + char8* LocalBuf = buf; + + (void)fd; + if(LocalBuf != NULL) { + for (i = 0; i < nbytes; i++) { + numbytes++; + *(LocalBuf + i) = inbyte(); + if ((*(LocalBuf + i) == '\n' )|| (*(LocalBuf + i) == '\r')) { + break; + } + } + } + + return numbytes; +#else + (void)fd; + (void)buf; + (void)nbytes; + return 0; +#endif +} +#endif diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/sbrk.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/sbrk.c new file mode 100644 index 0000000..7f91b9c --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/sbrk.c @@ -0,0 +1,57 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ + +#include +#include "xil_types.h" +#ifdef __cplusplus +extern "C" { + __attribute__((weak)) char8 *sbrk (s32 nbytes); +} +#endif + +extern u8 _heap_start[]; +extern u8 _heap_end[]; +extern char8 HeapBase[]; +extern char8 HeapLimit[]; + + + +__attribute__((weak)) char8 *sbrk (s32 nbytes) +{ + char8 *base; + static char8 *heap_ptr = HeapBase; + + base = heap_ptr; + if((heap_ptr != NULL) && (heap_ptr + nbytes <= (char8 *)&HeapLimit + 1)) { + heap_ptr += nbytes; + return base; + } else { + errno = ENOMEM; + return ((char8 *)-1); + } +} diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/sleep.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/sleep.c new file mode 100644 index 0000000..659c21b --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/sleep.c @@ -0,0 +1,88 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2017 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/***************************************************************************** +* +* @file sleep.c +* +* This function provides a second delay using the Global Timer register in +* the ARM Cortex A9 MP core. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who      Date     Changes
+* ----- -------- -------- -----------------------------------------------
+* 1.00a ecm/sdm  11/11/09 First release
+* 3.07a sgd      07/05/12 Updated sleep function to make use Global
+* 6.0   asa      08/15/16 Updated the sleep signature. Fix for CR#956899.
+* 6.6	srm      10/18/17 Updated sleep routines to support user configurable
+*			  implementation. Now sleep routines will use Timer
+*                         specified by the user (i.e. Global timer/TTC timer)
+*
+* 
+* +******************************************************************************/ +/***************************** Include Files *********************************/ + +#include "sleep.h" +#include "xtime_l.h" +#include "xparameters.h" + +#if defined (SLEEP_TIMER_BASEADDR) +#include "xil_sleeptimer.h" +#endif + +/*****************************************************************************/ +/* +* +* This API is used to provide delays in seconds +* +* @param seconds requested +* +* @return 0 always +* +* @note None. +* +****************************************************************************/ +unsigned sleep_A9(unsigned int seconds) +{ +#if defined (SLEEP_TIMER_BASEADDR) + Xil_SleepTTCCommon(seconds, COUNTS_PER_SECOND); +#else + XTime tEnd, tCur; + + XTime_GetTime(&tCur); + tEnd = tCur + (((XTime) seconds) * COUNTS_PER_SECOND); + do + { + XTime_GetTime(&tCur); + } while (tCur < tEnd); +#endif + + return 0; +} diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/sleep.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/sleep.h new file mode 100644 index 0000000..f3a632b --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/sleep.h @@ -0,0 +1,115 @@ +/****************************************************************************** +* +* Copyright (C) 2014 - 2017 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ + +/*****************************************************************************/ +/** +* @file sleep.h +* +* This header file contains ARM Cortex A53,A9,R5,Microblaze specific sleep +* related APIs. +* +*
+* MODIFICATION HISTORY :
+*
+* Ver   Who  Date	 Changes
+* ----- ---- -------- -------------------------------------------------------
+* 6.6   srm  11/02/17 Added processor specific sleep rountines
+*								 function prototypes.
+*
+* 
+* +******************************************************************************/ + +#ifndef SLEEP_H +#define SLEEP_H + +#include "xil_types.h" +#include "xil_io.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*****************************************************************************/ +/** +* +* This macro polls an address periodically until a condition is met or till the +* timeout occurs. +* The minimum timeout for calling this macro is 100us. If the timeout is less +* than 100us, it still waits for 100us. Also the unit for the timeout is 100us. +* If the timeout is not a multiple of 100us, it waits for a timeout of +* the next usec value which is a multiple of 100us. +* +* @param IO_func - accessor function to read the register contents. +* Depends on the register width. +* @param ADDR - Address to be polled +* @param VALUE - variable to read the value +* @param COND - Condition to checked (usually involves VALUE) +* @param TIMEOUT_US - timeout in micro seconds +* +* @return 0 - when the condition is met +* -1 - when the condition is not met till the timeout period +* +* @note none +* +*****************************************************************************/ +#define Xil_poll_timeout(IO_func, ADDR, VALUE, COND, TIMEOUT_US) \ + ( { \ + u64 timeout = TIMEOUT_US/100; \ + if(TIMEOUT_US%100!=0) \ + timeout++; \ + for(;;) { \ + VALUE = IO_func(ADDR); \ + if(COND) \ + break; \ + else { \ + usleep(100); \ + timeout--; \ + if(timeout==0) \ + break; \ + } \ + } \ + (timeout>0) ? 0 : -1; \ + } ) + +void usleep(unsigned long useconds); +void sleep(unsigned int seconds); +int usleep_R5(unsigned long useconds); +unsigned sleep_R5(unsigned int seconds); +int usleep_MB(unsigned long useconds); +unsigned sleep_MB(unsigned int seconds); +int usleep_A53(unsigned long useconds); +unsigned sleep_A53(unsigned int seconds); +int usleep_A9(unsigned long useconds); +unsigned sleep_A9(unsigned int seconds); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/smc.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/smc.h new file mode 100644 index 0000000..f7cc91c --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/smc.h @@ -0,0 +1,110 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* @file smc.h +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- ---------------------------------------------------
+* 1.00a sdm  11/03/09 Initial release.
+* 4.2	pkp	 08/04/14 Removed function definition of XSmc_NorInit and XSmc_NorInit
+*					  as smc.c is removed
+* 
+* +* @note None. +* +******************************************************************************/ + +#ifndef SMC_H /* prevent circular inclusions */ +#define SMC_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +#include "xparameters.h" +#include "xil_io.h" + +/***************** Macros (Inline Functions) Definitions *********************/ + +/**************************** Type Definitions *******************************/ + +/************************** Constant Definitions *****************************/ + +/* Memory controller configuration register offset */ +#define XSMCPSS_MC_STATUS 0x000U /* Controller status reg, RO */ +#define XSMCPSS_MC_INTERFACE_CONFIG 0x004U /* Interface config reg, RO */ +#define XSMCPSS_MC_SET_CONFIG 0x008U /* Set configuration reg, WO */ +#define XSMCPSS_MC_CLR_CONFIG 0x00CU /* Clear config reg, WO */ +#define XSMCPSS_MC_DIRECT_CMD 0x010U /* Direct command reg, WO */ +#define XSMCPSS_MC_SET_CYCLES 0x014U /* Set cycles register, WO */ +#define XSMCPSS_MC_SET_OPMODE 0x018U /* Set opmode register, WO */ +#define XSMCPSS_MC_REFRESH_PERIOD_0 0x020U /* Refresh period_0 reg, RW */ +#define XSMCPSS_MC_REFRESH_PERIOD_1 0x024U /* Refresh period_1 reg, RW */ + +/* Chip select configuration register offset */ +#define XSMCPSS_CS_IF0_CHIP_0_OFFSET 0x100U /* Interface 0 chip 0 config */ +#define XSMCPSS_CS_IF0_CHIP_1_OFFSET 0x120U /* Interface 0 chip 1 config */ +#define XSMCPSS_CS_IF0_CHIP_2_OFFSET 0x140U /* Interface 0 chip 2 config */ +#define XSMCPSS_CS_IF0_CHIP_3_OFFSET 0x160U /* Interface 0 chip 3 config */ +#define XSMCPSS_CS_IF1_CHIP_0_OFFSET 0x180U /* Interface 1 chip 0 config */ +#define XSMCPSS_CS_IF1_CHIP_1_OFFSET 0x1A0U /* Interface 1 chip 1 config */ +#define XSMCPSS_CS_IF1_CHIP_2_OFFSET 0x1C0U /* Interface 1 chip 2 config */ +#define XSMCPSS_CS_IF1_CHIP_3_OFFSET 0x1E0U /* Interface 1 chip 3 config */ + +/* User configuration register offset */ +#define XSMCPSS_UC_STATUS_OFFSET 0x200U /* User status reg, RO */ +#define XSMCPSS_UC_CONFIG_OFFSET 0x204U /* User config reg, WO */ + +/* Integration test register offset */ +#define XSMCPSS_IT_OFFSET 0xE00U + +/* ID configuration register offset */ +#define XSMCPSS_ID_PERIP_0_OFFSET 0xFE0U +#define XSMCPSS_ID_PERIP_1_OFFSET 0xFE4U +#define XSMCPSS_ID_PERIP_2_OFFSET 0xFE8U +#define XSMCPSS_ID_PERIP_3_OFFSET 0xFECU +#define XSMCPSS_ID_PCELL_0_OFFSET 0xFF0U +#define XSMCPSS_ID_PCELL_1_OFFSET 0xFF4U +#define XSMCPSS_ID_PCELL_2_OFFSET 0xFF8U +#define XSMCPSS_ID_PCELL_3_OFFSET 0xFFCU + +/************************** Variable Definitions *****************************/ + +/************************** Function Prototypes ******************************/ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SMC_H */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/translation_table.S b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/translation_table.S new file mode 100644 index 0000000..418ded8 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/translation_table.S @@ -0,0 +1,226 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* @file translation_table.s +* +* @addtogroup a9_boot_code +* @{ +*

translation_table.S

+* translation_table.S contains a static page table required by MMU for +* cortex-A9. This translation table is flat mapped (input address = output +* address) with default memory attributes defined for zynq architecture. It +* utilizes short descriptor translation table format with each section defining +* 1MB of memory. +* +* The overview of translation table memory attributes is described below. +* +*| | Memory Range | Definition in Translation Table | +*|-----------------------|-------------------------|-----------------------------------| +*| DDR | 0x00000000 - 0x3FFFFFFF | Normal write-back Cacheable | +*| PL | 0x40000000 - 0xBFFFFFFF | Strongly Ordered | +*| Reserved | 0xC0000000 - 0xDFFFFFFF | Unassigned | +*| Memory mapped devices | 0xE0000000 - 0xE02FFFFF | Device Memory | +*| Reserved | 0xE0300000 - 0xE0FFFFFF | Unassigned | +*| NAND, NOR | 0xE1000000 - 0xE3FFFFFF | Device memory | +*| SRAM | 0xE4000000 - 0xE5FFFFFF | Normal write-back Cacheable | +*| Reserved | 0xE6000000 - 0xF7FFFFFF | Unassigned | +*| AMBA APB Peripherals | 0xF8000000 - 0xF8FFFFFF | Device Memory | +*| Reserved | 0xF9000000 - 0xFBFFFFFF | Unassigned | +*| Linear QSPI - XIP | 0xFC000000 - 0xFDFFFFFF | Normal write-through cacheable | +*| Reserved | 0xFE000000 - 0xFFEFFFFF | Unassigned | +*| OCM | 0xFFF00000 - 0xFFFFFFFF | Normal inner write-back cacheable | +* +* @note +* +* For region 0x00000000 - 0x3FFFFFFF, a system where DDR is less than 1GB, +* region after DDR and before PL is marked as undefined/reserved in translation +* table. In 0xF8000000 - 0xF8FFFFFF, 0xF8000C00 - 0xF8000FFF, 0xF8010000 - +* 0xF88FFFFF and 0xF8F03000 to 0xF8FFFFFF are reserved but due to granual size +* of 1MB, it is not possible to define separate regions for them. For region +* 0xFFF00000 - 0xFFFFFFFF, 0xFFF00000 to 0xFFFB0000 is reserved but due to 1MB +* granual size, it is not possible to define separate region for it +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- ---------------------------------------------------
+* 1.00a ecm  10/20/09 Initial version
+* 3.04a sdm  01/13/12 Updated MMU table to mark DDR memory as Shareable
+* 3.07a sgd  07/05/2012 Configuring device address spaces as shareable device
+*		       instead of strongly-ordered.
+* 3.07a asa  07/17/2012 Changed the property of the ".mmu_tbl" section.
+* 4.2	pkp  09/02/2014 added entries for 0xfe000000 to 0xffefffff as reserved
+*			and  0xe0000000 - 0xe1ffffff is broken down into
+*			0xe0000000 - 0xe02fffff (memory mapped devides)
+*			0xe0300000 - 0xe0ffffff (reserved) and
+*			0xe1000000 - 0xe1ffffff (NAND)
+* 5.2	pkp  06/08/2015 put a check for XPAR_PS7_DDR_0_S_AXI_BASEADDR to confirm
+*			if DDR is present or not and accordingly generate the
+*			translation table
+* 6.1	pkp  07/11/2016 Corrected comments for memory attributes
+* 6.8   mus  07/12/2018 Mark DDR memory as inner cacheable, if BSP is built
+*			with the USE_AMP flag.
+* 
+* +* +******************************************************************************/ +#include "xparameters.h" + .globl MMUTable + + .section .mmu_tbl,"a" + +MMUTable: + /* Each table entry occupies one 32-bit word and there are + * 4096 entries, so the entire table takes up 16KB. + * Each entry covers a 1MB section. + */ +.set SECT, 0 + +#ifdef XPAR_PS7_DDR_0_S_AXI_BASEADDR +.set DDR_START, XPAR_PS7_DDR_0_S_AXI_BASEADDR +.set DDR_END, XPAR_PS7_DDR_0_S_AXI_HIGHADDR +.set DDR_SIZE, (DDR_END - DDR_START)+1 +.set DDR_REG, DDR_SIZE/0x100000 +#else +.set DDR_REG, 0 +#endif + +.set UNDEF_REG, 0x3FF - DDR_REG + +#ifndef USE_AMP + /*0x00000000 - 0x00100000 (inner and outer cacheable )*/ +.word SECT + 0x15de6 /* S=b1 TEX=b101 AP=b11, Domain=b1111, C=b0, B=b1 */ +#else + /*0x00000000 - 0x00100000 (inner cacheable )*/ +.word SECT + 0x14de6 /* S=b1 TEX=b100 AP=b11, Domain=b1111, C=b0, B=b1 */ +#endif +.set SECT, SECT+0x100000 + +.rept DDR_REG /* (DDR Cacheable) */ +.word SECT + 0x15de6 /* S=b1 TEX=b101 AP=b11, Domain=b1111, C=b0, B=b1 */ +.set SECT, SECT+0x100000 +.endr + +.rept UNDEF_REG /* (unassigned/reserved). + * Generates a translation fault if accessed */ +.word SECT + 0x0 /* S=b0 TEX=b000 AP=b00, Domain=b0, C=b0, B=b0 */ +.set SECT, SECT+0x100000 +.endr + + +.rept 0x0400 /* 0x40000000 - 0x7fffffff (FPGA slave0) */ +.word SECT + 0xc02 /* S=b0 TEX=b000 AP=b11, Domain=b0, C=b0, B=b0 */ +.set SECT, SECT+0x100000 +.endr + +.rept 0x0400 /* 0x80000000 - 0xbfffffff (FPGA slave1) */ +.word SECT + 0xc02 /* S=b0 TEX=b000 AP=b11, Domain=b0, C=b0, B=b0 */ +.set SECT, SECT+0x100000 +.endr + +.rept 0x0200 /* 0xc0000000 - 0xdfffffff (unassigned/reserved). + * Generates a translation fault if accessed */ +.word SECT + 0x0 /* S=b0 TEX=b000 AP=b00, Domain=b0, C=b0, B=b0 */ +.set SECT, SECT+0x100000 +.endr + +.rept 0x003 /* 0xe0000000 - 0xe02fffff (Memory mapped devices) + * UART/USB/IIC/SPI/CAN/GEM/GPIO/QSPI/SD/NAND */ +.word SECT + 0xc06 /* S=b0 TEX=b000 AP=b11, Domain=b0, C=b0, B=b1 */ +.set SECT, SECT+0x100000 +.endr + +.rept 0x0D /* 0xe0300000 - 0xe0ffffff (unassigned/reserved). + * Generates a translation fault if accessed */ +.word SECT + 0x0 /* S=b0 TEX=b000 AP=b00, Domain=b0, C=b0, B=b0 */ +.set SECT, SECT+0x100000 +.endr + +.rept 0x0010 /* 0xe1000000 - 0xe1ffffff (NAND) */ +.word SECT + 0xc06 /* S=b0 TEX=b000 AP=b11, Domain=b0, C=b0, B=b1 */ +.set SECT, SECT+0x100000 +.endr + +.rept 0x0020 /* 0xe2000000 - 0xe3ffffff (NOR) */ +.word SECT + 0xc06 /* S=b0 TEX=b000 AP=b11, Domain=b0, C=b0, B=b1 */ +.set SECT, SECT+0x100000 +.endr + +.rept 0x0020 /* 0xe4000000 - 0xe5ffffff (SRAM) */ +.word SECT + 0xc0e /* S=b0 TEX=b000 AP=b11, Domain=b0, C=b1, B=b1 */ +.set SECT, SECT+0x100000 +.endr + +.rept 0x0120 /* 0xe6000000 - 0xf7ffffff (unassigned/reserved). + * Generates a translation fault if accessed */ +.word SECT + 0x0 /* S=b0 TEX=b000 AP=b00, Domain=b0, C=b0, B=b0 */ +.set SECT, SECT+0x100000 +.endr + +/* 0xf8000c00 to 0xf8000fff, 0xf8010000 to 0xf88fffff and + 0xf8f03000 to 0xf8ffffff are reserved but due to granual size of + 1MB, it is not possible to define separate regions for them */ + +.rept 0x0010 /* 0xf8000000 - 0xf8ffffff (AMBA APB Peripherals) */ + +.word SECT + 0xc06 /* S=b0 TEX=b000 AP=b11, Domain=b0, C=b0, B=b1 */ +.set SECT, SECT+0x100000 +.endr + +.rept 0x0030 /* 0xf9000000 - 0xfbffffff (unassigned/reserved). + * Generates a translation fault if accessed */ +.word SECT + 0x0 /* S=b0 TEX=b000 AP=b00, Domain=b0, C=b0, B=b0 */ +.set SECT, SECT+0x100000 +.endr + +.rept 0x0020 /* 0xfc000000 - 0xfdffffff (Linear QSPI - XIP) */ +.word SECT + 0xc0a /* S=b0 TEX=b000 AP=b11, Domain=b0, C=b1, B=b0 */ +.set SECT, SECT+0x100000 +.endr + +.rept 0x001F /* 0xfe000000 - 0xffefffff (unassigned/reserved). + * Generates a translation fault if accessed */ +.word SECT + 0x0 /* S=b0 TEX=b000 AP=b00, Domain=b0, C=b0, B=b0 */ +.set SECT, SECT+0x100000 +.endr + +/* 0xfff00000 to 0xfffb0000 is reserved but due to granual size of + 1MB, it is not possible to define separate region for it + + 0xfff00000 - 0xffffffff + 256K OCM when mapped to high address space + inner-cacheable */ +.word SECT + 0x4c0e /* S=b0 TEX=b100 AP=b11, Domain=b0, C=b1, B=b1 */ +.set SECT, SECT+0x100000 + +.end +/** +* @} End of "addtogroup a9_boot_code". +*/ \ No newline at end of file diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/unlink.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/unlink.c new file mode 100644 index 0000000..abd0d87 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/unlink.c @@ -0,0 +1,46 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ + +#include +#include "xil_types.h" + +#ifdef __cplusplus +extern "C" { + __attribute__((weak)) sint32 unlink(char8 *path); +} +#endif +/* + * unlink -- since we have no file system, + * we just return an error. + */ +__attribute__((weak)) sint32 unlink(char8 *path) +{ + (void) path; + errno = EIO; + return (-1); +} diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/usleep.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/usleep.c new file mode 100644 index 0000000..0965233 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/usleep.c @@ -0,0 +1,103 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2017 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file usleep.c +* +* This function provides a microsecond delay using the Global Timer register in +* the ARM Cortex A9 MP core. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who      Date     Changes
+* ----- -------- -------- -----------------------------------------------
+* 1.00a ecm/sdm  11/11/09 First release
+* 3.07a sgd      07/05/12 Upadted micro sleep function to make use Global Timer
+* 4.2	pkp		 08/04/14 Removed unimplemented nanosleep routine as it is not
+*						  possible to generate timer in nanosecond due to
+*						  limited cpu frequency
+* 6.0   asa      08/15/16 Updated the usleep signature. Fix for CR#956899.
+* 6.6	srm	 10/18/17 Updated sleep routines to support user configurable
+*			  implementation. Now sleep routines will use Timer
+*                         specified by the user (i.e. Global timer/TTC timer)
+* 
+* +******************************************************************************/ +/***************************** Include Files *********************************/ + +#include "sleep.h" +#include "xtime_l.h" +#include "xparameters.h" +#include "xil_types.h" +#include "xpseudo_asm.h" +#include "xreg_cortexa9.h" + +#if defined (SLEEP_TIMER_BASEADDR) +#include "xil_sleeptimer.h" +#endif + +/**************************** Constant Definitions ************************/ +#if defined (SLEEP_TIMER_BASEADDR) +#define COUNTS_PER_USECOND (SLEEP_TIMER_FREQUENCY / 1000000) +#else +/* Global Timer is always clocked at half of the CPU frequency */ +#define COUNTS_PER_USECOND (XPAR_CPU_CORTEXA9_CORE_CLOCK_FREQ_HZ / (2U*1000000U)) +#endif + +/*****************************************************************************/ +/** +* +* This API gives a delay in microseconds +* +* @param useconds requested +* +* @return 0 if the delay can be achieved, -1 if the requested delay +* is out of range +* +* @note None. +* +****************************************************************************/ +int usleep_A9(unsigned long useconds) +{ +#if defined (SLEEP_TIMER_BASEADDR) + Xil_SleepTTCCommon(useconds, COUNTS_PER_USECOND); +#else + XTime tEnd, tCur; + + XTime_GetTime(&tCur); + tEnd = tCur + (((XTime) useconds) * COUNTS_PER_USECOND); + do + { + XTime_GetTime(&tCur); + } while (tCur < tEnd); +#endif + + return 0; +} diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/vectors.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/vectors.c new file mode 100644 index 0000000..2e23fc9 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/vectors.c @@ -0,0 +1,227 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2016 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* @file vectors.c +* +* This file contains the C level vectors for the ARM Cortex A9 core. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- ---------------------------------------------------
+* 1.00a ecm  10/20/09 Initial version, moved over from bsp area
+* 6.0   mus  27/07/16 Consolidated vectors for a53,a9 and r5 processor
+*                     and added UndefinedException for a53 32 bit and r5
+*                     processor
+* 
+* +* @note +* +* None. +* +******************************************************************************/ +/***************************** Include Files *********************************/ + +#include "xil_exception.h" +#include "vectors.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +typedef struct { + Xil_ExceptionHandler Handler; + void *Data; +} XExc_VectorTableEntry; + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Variable Definitions *****************************/ + +extern XExc_VectorTableEntry XExc_VectorTable[]; + +/************************** Function Prototypes ******************************/ + + +/*****************************************************************************/ +/** +* +* This is the C level wrapper for the FIQ interrupt called from the vectors.s +* file. +* +* @param None. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void FIQInterrupt(void) +{ + XExc_VectorTable[XIL_EXCEPTION_ID_FIQ_INT].Handler(XExc_VectorTable[ + XIL_EXCEPTION_ID_FIQ_INT].Data); +} + +/*****************************************************************************/ +/** +* +* This is the C level wrapper for the IRQ interrupt called from the vectors.s +* file. +* +* @param None. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void IRQInterrupt(void) +{ + XExc_VectorTable[XIL_EXCEPTION_ID_IRQ_INT].Handler(XExc_VectorTable[ + XIL_EXCEPTION_ID_IRQ_INT].Data); +} + +#if !defined (__aarch64__) +/*****************************************************************************/ +/** +* +* This is the C level wrapper for the Undefined exception called from the +* vectors.s file. +* +* @param None. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void UndefinedException(void) +{ + XExc_VectorTable[XIL_EXCEPTION_ID_UNDEFINED_INT].Handler(XExc_VectorTable[ + XIL_EXCEPTION_ID_UNDEFINED_INT].Data); +} + +/*****************************************************************************/ +/** +* +* This is the C level wrapper for the SW Interrupt called from the vectors.s +* file. +* +* @param None. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void SWInterrupt(void) +{ + XExc_VectorTable[XIL_EXCEPTION_ID_SWI_INT].Handler(XExc_VectorTable[ + XIL_EXCEPTION_ID_SWI_INT].Data); +} + +/*****************************************************************************/ +/** +* +* This is the C level wrapper for the DataAbort Interrupt called from the +* vectors.s file. +* +* @param None. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void DataAbortInterrupt(void) +{ + XExc_VectorTable[XIL_EXCEPTION_ID_DATA_ABORT_INT].Handler( + XExc_VectorTable[XIL_EXCEPTION_ID_DATA_ABORT_INT].Data); +} + +/*****************************************************************************/ +/** +* +* This is the C level wrapper for the PrefetchAbort Interrupt called from the +* vectors.s file. +* +* @param None. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void PrefetchAbortInterrupt(void) +{ + XExc_VectorTable[XIL_EXCEPTION_ID_PREFETCH_ABORT_INT].Handler( + XExc_VectorTable[XIL_EXCEPTION_ID_PREFETCH_ABORT_INT].Data); +} +#else + +/*****************************************************************************/ +/** +* +* This is the C level wrapper for the Synchronous Interrupt called from the vectors.s +* file. +* +* @param None. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void SynchronousInterrupt(void) +{ + XExc_VectorTable[XIL_EXCEPTION_ID_SYNC_INT].Handler(XExc_VectorTable[ + XIL_EXCEPTION_ID_SYNC_INT].Data); +} + +/*****************************************************************************/ +/** +* +* This is the C level wrapper for the SError Interrupt called from the +* vectors.s file. +* +* @param None. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void SErrorInterrupt(void) +{ + XExc_VectorTable[XIL_EXCEPTION_ID_SERROR_ABORT_INT].Handler( + XExc_VectorTable[XIL_EXCEPTION_ID_SERROR_ABORT_INT].Data); +} + +#endif diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/vectors.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/vectors.h new file mode 100644 index 0000000..56bacbc --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/vectors.h @@ -0,0 +1,84 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2016 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* @file vectors.h +* +* This file contains the C level vector prototypes for the ARM Cortex A9 core. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- ---------------------------------------------------
+* 1.00a ecm  10/20/10 Initial version, moved over from bsp area
+* 6.0   mus  07/27/16 Consolidated vectors for a9,a53 and r5 processors
+* 
+* +* @note +* +* None. +* +******************************************************************************/ + +#ifndef _VECTORS_H_ +#define _VECTORS_H_ + +/***************************** Include Files *********************************/ + +#include "xil_types.h" +#include "xil_assert.h" + +#ifdef __cplusplus +extern "C" { +#endif +/***************** Macros (Inline Functions) Definitions *********************/ + +/**************************** Type Definitions *******************************/ + +/************************** Constant Definitions *****************************/ + +/************************** Function Prototypes ******************************/ + +void FIQInterrupt(void); +void IRQInterrupt(void); +#if !defined (__aarch64__) +void SWInterrupt(void); +void DataAbortInterrupt(void); +void PrefetchAbortInterrupt(void); +void UndefinedException(void); +#else +void SynchronousInterrupt(void); +void SErrorInterrupt(void); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* protection macro */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/write.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/write.c new file mode 100644 index 0000000..dc10ed7 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/write.c @@ -0,0 +1,117 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ + +/* write.c -- write bytes to an output device. + */ +#ifndef UNDEFINE_FILE_OPS +#include "xil_printf.h" +#include "xparameters.h" + +#ifdef __cplusplus +extern "C" { + __attribute__((weak)) sint32 _write (sint32 fd, char8* buf, sint32 nbytes); +} +#endif + +/* + * write -- write bytes to the serial port. Ignore fd, since + * stdout and stderr are the same. Since we have no filesystem, + * open will only return an error. + */ +__attribute__((weak)) sint32 +write (sint32 fd, char8* buf, sint32 nbytes) + +{ +#ifdef STDOUT_BASEADDRESS + s32 i; + char8* LocalBuf = buf; + + (void)fd; + for (i = 0; i < nbytes; i++) { + if(LocalBuf != NULL) { + LocalBuf += i; + } + if(LocalBuf != NULL) { + if (*LocalBuf == '\n') { + outbyte ('\r'); + } + outbyte (*LocalBuf); + } + if(LocalBuf != NULL) { + LocalBuf -= i; + } + } + return (nbytes); +#else + (void)fd; + (void)buf; + (void)nbytes; + return 0; +#endif +} + +__attribute__((weak)) sint32 +_write (sint32 fd, char8* buf, sint32 nbytes) +{ +#if HYP_GUEST && EL1_NONSECURE && XEN_USE_PV_CONSOLE + sint32 length; + + (void)fd; + (void)nbytes; + length = XPVXenConsole_Write(buf); + return length; +#else +#ifdef STDOUT_BASEADDRESS + s32 i; + char8* LocalBuf = buf; + + (void)fd; + for (i = 0; i < nbytes; i++) { + if(LocalBuf != NULL) { + LocalBuf += i; + } + if(LocalBuf != NULL) { + if (*LocalBuf == '\n') { + outbyte ('\r'); + } + outbyte (*LocalBuf); + } + if(LocalBuf != NULL) { + LocalBuf -= i; + } + } + return (nbytes); +#else + (void)fd; + (void)buf; + (void)nbytes; + return 0; +#endif +#endif +} +#endif diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xbasic_types.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xbasic_types.h new file mode 100644 index 0000000..2d9b245 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xbasic_types.h @@ -0,0 +1,127 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2019 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xbasic_types.h +* +* +* @note Dummy File for backwards compatibility +* + +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date   Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a adk   1/31/14  Added in bsp common folder for backward compatibility
+* 7.0   aru   01/21/19 Modified the typedef of u32,u16,u8
+* 7.0 	aru   02/06/19 Included stdint.h and stddef.h
+* 
+* +******************************************************************************/ + +#ifndef XBASIC_TYPES_H /* prevent circular inclusions */ +#define XBASIC_TYPES_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/** @name Legacy types + * Deprecated legacy types. + * @{ + */ +typedef uint8_t Xuint8; /**< unsigned 8-bit */ +typedef char Xint8; /**< signed 8-bit */ +typedef uint16_t Xuint16; /**< unsigned 16-bit */ +typedef short Xint16; /**< signed 16-bit */ +typedef uint32_t Xuint32; /**< unsigned 32-bit */ +typedef long Xint32; /**< signed 32-bit */ +typedef float Xfloat32; /**< 32-bit floating point */ +typedef double Xfloat64; /**< 64-bit double precision FP */ +typedef unsigned long Xboolean; /**< boolean (XTRUE or XFALSE) */ + +#if !defined __XUINT64__ +typedef struct +{ + Xuint32 Upper; + Xuint32 Lower; +} Xuint64; +#endif + +/** @name New types + * New simple types. + * @{ + */ +#ifndef __KERNEL__ +#ifndef XIL_TYPES_H +typedef Xuint32 u32; +typedef Xuint16 u16; +typedef Xuint8 u8; +#endif +#else +#include +#endif + +#ifndef TRUE +# define TRUE 1U +#endif + +#ifndef FALSE +# define FALSE 0U +#endif + +#ifndef NULL +#define NULL 0U +#endif + +/* + * Xilinx NULL, TRUE and FALSE legacy support. Deprecated. + * Please use NULL, TRUE and FALSE + */ +#define XNULL NULL +#define XTRUE TRUE +#define XFALSE FALSE + +/* + * This file is deprecated and users + * should use xil_types.h and xil_assert.h\n\r + */ +#warning The xbasics_type.h file is deprecated and users should use xil_types.h and xil_assert. +#warning Please refer the Standalone BSP UG647 for further details + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xdebug.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xdebug.h new file mode 100644 index 0000000..b09c02d --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xdebug.h @@ -0,0 +1,40 @@ +#ifndef XDEBUG /* prevent circular inclusions */ +#define XDEBUG /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(DEBUG) && !defined(NDEBUG) + +#ifndef XDEBUG_WARNING +#define XDEBUG_WARNING +#warning DEBUG is enabled +#endif + +int printf(const char *format, ...); + +#define XDBG_DEBUG_ERROR 0x00000001U /* error condition messages */ +#define XDBG_DEBUG_GENERAL 0x00000002U /* general debug messages */ +#define XDBG_DEBUG_ALL 0xFFFFFFFFU /* all debugging data */ + +#define xdbg_current_types (XDBG_DEBUG_GENERAL) + +#define xdbg_stmnt(x) x + +#define xdbg_printf(type, ...) (((type) & xdbg_current_types) ? printf (__VA_ARGS__) : 0) + + +#else /* defined(DEBUG) && !defined(NDEBUG) */ + +#define xdbg_stmnt(x) + +#define xdbg_printf(...) + +#endif /* defined(DEBUG) && !defined(NDEBUG) */ + +#ifdef __cplusplus +} +#endif + +#endif /* XDEBUG */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xenv.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xenv.h new file mode 100644 index 0000000..9c7c4c3 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xenv.h @@ -0,0 +1,183 @@ +/****************************************************************************** +* +* Copyright (C) 2002 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xenv.h +* +* Defines common services that are typically found in a host operating. +* environment. This include file simply includes an OS specific file based +* on the compile-time constant BUILD_ENV_*, where * is the name of the target +* environment. +* +* All services are defined as macros. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00b ch   10/24/02 Added XENV_LINUX
+* 1.00a rmm  04/17/02 First release
+* 
+* +******************************************************************************/ + +#ifndef XENV_H /* prevent circular inclusions */ +#define XENV_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Select which target environment we are operating under + */ + +/* VxWorks target environment */ +#if defined XENV_VXWORKS +#include "xenv_vxworks.h" + +/* Linux target environment */ +#elif defined XENV_LINUX +#include "xenv_linux.h" + +/* Unit test environment */ +#elif defined XENV_UNITTEST +#include "ut_xenv.h" + +/* Integration test environment */ +#elif defined XENV_INTTEST +#include "int_xenv.h" + +/* Standalone environment selected */ +#else +#include "xenv_standalone.h" +#endif + + +/* + * The following comments specify the types and macro wrappers that are + * expected to be defined by the target specific header files + */ + +/**************************** Type Definitions *******************************/ + +/*****************************************************************************/ +/** + * + * XENV_TIME_STAMP + * + * A structure that contains a time stamp used by other time stamp macros + * defined below. This structure is processor dependent. + */ + + +/***************** Macros (Inline Functions) Definitions *********************/ + +/*****************************************************************************/ +/** + * + * XENV_MEM_COPY(void *DestPtr, void *SrcPtr, unsigned Bytes) + * + * Copies a non-overlapping block of memory. + * + * @param DestPtr is the destination address to copy data to. + * @param SrcPtr is the source address to copy data from. + * @param Bytes is the number of bytes to copy. + * + * @return None + */ + +/*****************************************************************************/ +/** + * + * XENV_MEM_FILL(void *DestPtr, char Data, unsigned Bytes) + * + * Fills an area of memory with constant data. + * + * @param DestPtr is the destination address to set. + * @param Data contains the value to set. + * @param Bytes is the number of bytes to set. + * + * @return None + */ +/*****************************************************************************/ +/** + * + * XENV_TIME_STAMP_GET(XTIME_STAMP *StampPtr) + * + * Samples the processor's or external timer's time base counter. + * + * @param StampPtr is the storage for the retrieved time stamp. + * + * @return None + */ + +/*****************************************************************************/ +/** + * + * XENV_TIME_STAMP_DELTA_US(XTIME_STAMP *Stamp1Ptr, XTIME_STAMP* Stamp2Ptr) + * + * Computes the delta between the two time stamps. + * + * @param Stamp1Ptr - First sampled time stamp. + * @param Stamp1Ptr - Sedond sampled time stamp. + * + * @return An unsigned int value with units of microseconds. + */ + +/*****************************************************************************/ +/** + * + * XENV_TIME_STAMP_DELTA_MS(XTIME_STAMP *Stamp1Ptr, XTIME_STAMP* Stamp2Ptr) + * + * Computes the delta between the two time stamps. + * + * @param Stamp1Ptr - First sampled time stamp. + * @param Stamp1Ptr - Sedond sampled time stamp. + * + * @return An unsigned int value with units of milliseconds. + */ + +/*****************************************************************************//** + * + * XENV_USLEEP(unsigned delay) + * + * Delay the specified number of microseconds. + * + * @param delay is the number of microseconds to delay. + * + * @return None + */ + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xenv_standalone.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xenv_standalone.h new file mode 100644 index 0000000..ef905af --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xenv_standalone.h @@ -0,0 +1,364 @@ +/****************************************************************************** +* +* Copyright (C) 2002 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xenv_standalone.h +* +* Defines common services specified by xenv.h. +* +* @note +* This file is not intended to be included directly by driver code. +* Instead, the generic xenv.h file is intended to be included by driver +* code. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a wgr  02/28/07 Added cache handling macros.
+* 1.00a wgr  02/27/07 Simplified code. Deprecated old-style macro names.
+* 1.00a rmm  01/24/06 Implemented XENV_USLEEP. Assume implementation is being
+*                     used under Xilinx standalone BSP.
+* 1.00a xd   11/03/04 Improved support for doxygen.
+* 1.00a rmm  03/21/02 First release
+* 1.00a wgr  03/22/07 Converted to new coding style.
+* 1.00a rpm  06/29/07 Added udelay macro for standalone
+* 1.00a xd   07/19/07 Included xparameters.h as XPAR_ constants are referred
+*                     to in MICROBLAZE section
+* 1.00a ecm  09/19/08 updated for v7.20 of Microblaze, new functionality
+*
+* 
+* +* +******************************************************************************/ + +#ifndef XENV_STANDALONE_H +#define XENV_STANDALONE_H + +#include "xil_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ +/****************************************************************************** + * + * Get the processor dependent includes + * + ******************************************************************************/ + +#include + +#if defined __MICROBLAZE__ +# include "mb_interface.h" +# include "xparameters.h" /* XPAR constants used below in MB section */ + +#elif defined __PPC__ +# include "sleep.h" +# include "xcache_l.h" /* also include xcache_l.h for caching macros */ +#endif + +/****************************************************************************** + * + * MEMCPY / MEMSET related macros. + * + * The following are straight forward implementations of memset and memcpy. + * + * NOTE: memcpy may not work if source and target memory area are overlapping. + * + ******************************************************************************/ +/*****************************************************************************/ +/** + * + * Copies a non-overlapping block of memory. + * + * @param DestPtr + * Destination address to copy data to. + * + * @param SrcPtr + * Source address to copy data from. + * + * @param Bytes + * Number of bytes to copy. + * + * @return None. + * + * @note + * The use of XENV_MEM_COPY is deprecated. Use memcpy() instead. + * + * @note + * This implemention MAY BREAK work if source and target memory + * area are overlapping. + * + *****************************************************************************/ + +#define XENV_MEM_COPY(DestPtr, SrcPtr, Bytes) \ + memcpy((void *) DestPtr, (const void *) SrcPtr, (size_t) Bytes) + + + +/*****************************************************************************/ +/** + * + * Fills an area of memory with constant data. + * + * @param DestPtr + * Destination address to copy data to. + * + * @param Data + * Value to set. + * + * @param Bytes + * Number of bytes to copy. + * + * @return None. + * + * @note + * The use of XENV_MEM_FILL is deprecated. Use memset() instead. + * + *****************************************************************************/ + +#define XENV_MEM_FILL(DestPtr, Data, Bytes) \ + memset((void *) DestPtr, (s32) Data, (size_t) Bytes) + + + +/****************************************************************************** + * + * TIME related macros + * + ******************************************************************************/ + +/** + * A structure that contains a time stamp used by other time stamp macros + * defined below. This structure is processor dependent. + */ +typedef s32 XENV_TIME_STAMP; + +/*****************************************************************************/ +/** + * + * Time is derived from the 64 bit PPC timebase register + * + * @param StampPtr is the storage for the retrieved time stamp. + * + * @return None. + * + * @note + * + * Signature: void XENV_TIME_STAMP_GET(XTIME_STAMP *StampPtr) + *

+ * This macro must be implemented by the user. + * + *****************************************************************************/ +#define XENV_TIME_STAMP_GET(StampPtr) + +/*****************************************************************************/ +/** + * + * This macro is not yet implemented and always returns 0. + * + * @param Stamp1Ptr is the first sampled time stamp. + * @param Stamp2Ptr is the second sampled time stamp. + * + * @return 0 + * + * @note + * + * This macro must be implemented by the user. + * + *****************************************************************************/ +#define XENV_TIME_STAMP_DELTA_US(Stamp1Ptr, Stamp2Ptr) (0) + +/*****************************************************************************/ +/** + * + * This macro is not yet implemented and always returns 0. + * + * @param Stamp1Ptr is the first sampled time stamp. + * @param Stamp2Ptr is the second sampled time stamp. + * + * @return 0 + * + * @note + * + * This macro must be implemented by the user. + * + *****************************************************************************/ +#define XENV_TIME_STAMP_DELTA_MS(Stamp1Ptr, Stamp2Ptr) (0) + +/*****************************************************************************/ +/** + * XENV_USLEEP(unsigned delay) + * + * Delay the specified number of microseconds. Not implemented without OS + * support. + * + * @param delay + * Number of microseconds to delay. + * + * @return None. + * + *****************************************************************************/ + +#ifdef __PPC__ +#define XENV_USLEEP(delay) usleep(delay) +#define udelay(delay) usleep(delay) +#else +#define XENV_USLEEP(delay) +#define udelay(delay) +#endif + + +/****************************************************************************** + * + * CACHE handling macros / mappings + * + ******************************************************************************/ +/****************************************************************************** + * + * Processor independent macros + * + ******************************************************************************/ + +#define XCACHE_ENABLE_CACHE() \ + { XCACHE_ENABLE_DCACHE(); XCACHE_ENABLE_ICACHE(); } + +#define XCACHE_DISABLE_CACHE() \ + { XCACHE_DISABLE_DCACHE(); XCACHE_DISABLE_ICACHE(); } + + +/****************************************************************************** + * + * MicroBlaze case + * + * NOTE: Currently the following macros will only work on systems that contain + * only ONE MicroBlaze processor. Also, the macros will only be enabled if the + * system is built using a xparameters.h file. + * + ******************************************************************************/ + +#if defined __MICROBLAZE__ + +/* Check if MicroBlaze data cache was built into the core. + */ +#if (XPAR_MICROBLAZE_USE_DCACHE == 1) +# define XCACHE_ENABLE_DCACHE() microblaze_enable_dcache() +# define XCACHE_DISABLE_DCACHE() microblaze_disable_dcache() +# define XCACHE_INVALIDATE_DCACHE() microblaze_invalidate_dcache() + +# define XCACHE_INVALIDATE_DCACHE_RANGE(Addr, Len) \ + microblaze_invalidate_dcache_range((s32)(Addr), (s32)(Len)) + +#if (XPAR_MICROBLAZE_DCACHE_USE_WRITEBACK == 1) +# define XCACHE_FLUSH_DCACHE() microblaze_flush_dcache() +# define XCACHE_FLUSH_DCACHE_RANGE(Addr, Len) \ + microblaze_flush_dcache_range((s32)(Addr), (s32)(Len)) +#else +# define XCACHE_FLUSH_DCACHE() microblaze_invalidate_dcache() +# define XCACHE_FLUSH_DCACHE_RANGE(Addr, Len) \ + microblaze_invalidate_dcache_range((s32)(Addr), (s32)(Len)) +#endif /*XPAR_MICROBLAZE_DCACHE_USE_WRITEBACK*/ + +#else +# define XCACHE_ENABLE_DCACHE() +# define XCACHE_DISABLE_DCACHE() +# define XCACHE_INVALIDATE_DCACHE_RANGE(Addr, Len) +# define XCACHE_FLUSH_DCACHE_RANGE(Addr, Len) +#endif /*XPAR_MICROBLAZE_USE_DCACHE*/ + + +/* Check if MicroBlaze instruction cache was built into the core. + */ +#if (XPAR_MICROBLAZE_USE_ICACHE == 1) +# define XCACHE_ENABLE_ICACHE() microblaze_enable_icache() +# define XCACHE_DISABLE_ICACHE() microblaze_disable_icache() + +# define XCACHE_INVALIDATE_ICACHE() microblaze_invalidate_icache() + +# define XCACHE_INVALIDATE_ICACHE_RANGE(Addr, Len) \ + microblaze_invalidate_icache_range((s32)(Addr), (s32)(Len)) + +#else +# define XCACHE_ENABLE_ICACHE() +# define XCACHE_DISABLE_ICACHE() +#endif /*XPAR_MICROBLAZE_USE_ICACHE*/ + + +/****************************************************************************** + * + * PowerPC case + * + * Note that the XCACHE_ENABLE_xxx functions are hardcoded to enable a + * specific memory region (0x80000001). Each bit (0-30) in the regions + * bitmask stands for 128MB of memory. Bit 31 stands for the upper 2GB + * range. + * + * regions --> cached address range + * ------------|-------------------------------------------------- + * 0x80000000 | [0, 0x7FFFFFF] + * 0x00000001 | [0xF8000000, 0xFFFFFFFF] + * 0x80000001 | [0, 0x7FFFFFF],[0xF8000000, 0xFFFFFFFF] + * + ******************************************************************************/ + +#elif defined __PPC__ + +#define XCACHE_ENABLE_DCACHE() XCache_EnableDCache(0x80000001) +#define XCACHE_DISABLE_DCACHE() XCache_DisableDCache() +#define XCACHE_ENABLE_ICACHE() XCache_EnableICache(0x80000001) +#define XCACHE_DISABLE_ICACHE() XCache_DisableICache() + +#define XCACHE_INVALIDATE_DCACHE_RANGE(Addr, Len) \ + XCache_InvalidateDCacheRange((u32)(Addr), (u32)(Len)) + +#define XCACHE_FLUSH_DCACHE_RANGE(Addr, Len) \ + XCache_FlushDCacheRange((u32)(Addr), (u32)(Len)) + +#define XCACHE_INVALIDATE_ICACHE() XCache_InvalidateICache() + + +/****************************************************************************** + * + * Unknown processor / architecture + * + ******************************************************************************/ + +#else +/* #error "Unknown processor / architecture. Must be MicroBlaze or PowerPC." */ +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /* #ifndef XENV_STANDALONE_H */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil-crt0.S b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil-crt0.S new file mode 100644 index 0000000..8ea3a09 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil-crt0.S @@ -0,0 +1,155 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2017 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* @file xil-crt0.S +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- ---------------------------------------------------
+* 1.00a ecm  10/20/09 Initial version
+* 3.05a sdm  02/02/12 Added code for profiling
+* 3.06a sgd  05/16/12 Added global constructors and cleanup code
+*                     Uart initialization based on compiler flag
+* 3.07a sgd  07/05/12 Updated with reset and start Global Timer
+* 3.07a sgd  10/19/12 SMC NOR and SRAM initialization with build option
+* 4.2	pkp  08/04/14 Removed PEEP board related code which contained
+*		      initialization of uart smc nor and sram
+* 5.3	pkp  10/07/15 Added support for OpenAMP by not initializing global
+*		      timer when USE_AMP flag is defined
+* 6.6   srm  10/18/17 Added timer configuration using XTime_StartTTCTimer API.
+*		      Now the TTC instance as specified by the user will be
+*		      started.
+* 
+* +* @note +* +* None. +* +******************************************************************************/ +#include "bspconfig.h" + + .file "xil-crt0.S" + .section ".got2","aw" + .align 2 + + .text +.Lsbss_start: + .long __sbss_start + +.Lsbss_end: + .long __sbss_end + +.Lbss_start: + .long __bss_start + +.Lbss_end: + .long __bss_end + +.Lstack: + .long __stack + + + .globl _start +_start: + bl __cpu_init /* Initialize the CPU first (BSP provides this) */ + + mov r0, #0 + + /* clear sbss */ + ldr r1,.Lsbss_start /* calculate beginning of the SBSS */ + ldr r2,.Lsbss_end /* calculate end of the SBSS */ + +.Lloop_sbss: + cmp r1,r2 + bge .Lenclsbss /* If no SBSS, no clearing required */ + str r0, [r1], #4 + b .Lloop_sbss + +.Lenclsbss: + /* clear bss */ + ldr r1,.Lbss_start /* calculate beginning of the BSS */ + ldr r2,.Lbss_end /* calculate end of the BSS */ + +.Lloop_bss: + cmp r1,r2 + bge .Lenclbss /* If no BSS, no clearing required */ + str r0, [r1], #4 + b .Lloop_bss + +.Lenclbss: + + /* set stack pointer */ + ldr r13,.Lstack /* stack address */ + + /* Reset and start Global Timer */ + mov r0, #0x0 + mov r1, #0x0 + + /* Reset and start Triple Timer Counter */ + #if defined SLEEP_TIMER_BASEADDR + bl XTime_StartTTCTimer + #endif + +#if USE_AMP != 1 + bl XTime_SetTime +#endif + +#ifdef PROFILING /* defined in Makefile */ + /* Setup profiling stuff */ + bl _profile_init +#endif /* PROFILING */ + + /* run global constructors */ + bl __libc_init_array + + /* make sure argc and argv are valid */ + mov r0, #0 + mov r1, #0 + + /* Let her rip */ + bl main + + /* Cleanup global constructors */ + bl __libc_fini_array + +#ifdef PROFILING + /* Cleanup profiling stuff */ + bl _profile_clean +#endif /* PROFILING */ + + /* All done */ + bl exit + +.Lexit: /* should never get here */ + b .Lexit + +.Lstart: + .size _start,.Lstart-_start diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_assert.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_assert.c new file mode 100644 index 0000000..f6ec066 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_assert.c @@ -0,0 +1,143 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2016 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xil_assert.c +* +* This file contains basic assert related functions for Xilinx software IP. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date   Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a hbm  07/14/09 Initial release
+* 6.0   kvn  05/31/16 Make Xil_AsserWait a global variable
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xil_types.h" +#include "xil_assert.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Variable Definitions *****************************/ + +/** + * This variable allows testing to be done easier with asserts. An assert + * sets this variable such that a driver can evaluate this variable + * to determine if an assert occurred. + */ +u32 Xil_AssertStatus; + +/** + * This variable allows the assert functionality to be changed for testing + * such that it does not wait infinitely. Use the debugger to disable the + * waiting during testing of asserts. + */ +s32 Xil_AssertWait = 1; + +/* The callback function to be invoked when an assert is taken */ +static Xil_AssertCallback Xil_AssertCallbackRoutine = NULL; + +/************************** Function Prototypes ******************************/ + +/*****************************************************************************/ +/** +* +* @brief Implement assert. Currently, it calls a user-defined callback +* function if one has been set. Then, it potentially enters an +* infinite loop depending on the value of the Xil_AssertWait +* variable. +* +* @param file: filename of the source +* @param line: linenumber within File +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void Xil_Assert(const char8 *File, s32 Line) +{ + /* if the callback has been set then invoke it */ + if (Xil_AssertCallbackRoutine != 0) { + (*Xil_AssertCallbackRoutine)(File, Line); + } + + /* if specified, wait indefinitely such that the assert will show up + * in testing + */ + while (Xil_AssertWait != 0) { + } +} + +/*****************************************************************************/ +/** +* +* @brief Set up a callback function to be invoked when an assert occurs. +* If a callback is already installed, then it will be replaced. +* +* @param routine: callback to be invoked when an assert is taken +* +* @return None. +* +* @note This function has no effect if NDEBUG is set +* +******************************************************************************/ +void Xil_AssertSetCallback(Xil_AssertCallback Routine) +{ + Xil_AssertCallbackRoutine = Routine; +} + +/*****************************************************************************/ +/** +* +* @brief Null handler function. This follows the XInterruptHandler +* signature for interrupt handlers. It can be used to assign a null +* handler (a stub) to an interrupt controller vector table. +* +* @param NullParameter: arbitrary void pointer and not used. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XNullHandler(void *NullParameter) +{ + (void) NullParameter; +} diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_assert.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_assert.h new file mode 100644 index 0000000..917de31 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_assert.h @@ -0,0 +1,191 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xil_assert.h +* +* @addtogroup common_assert_apis Assert APIs and Macros +* +* The xil_assert.h file contains assert related functions and macros. +* Assert APIs/Macros specifies that a application program satisfies certain +* conditions at particular points in its execution. These function can be +* used by application programs to ensure that, application code is satisfying +* certain conditions. +* +* @{ +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date   Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a hbm  07/14/09 First release
+* 6.0   kvn  05/31/16 Make Xil_AsserWait a global variable
+* 
+* +******************************************************************************/ + +#ifndef XIL_ASSERT_H /* prevent circular inclusions */ +#define XIL_ASSERT_H /* by using protection macros */ + +#include "xil_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/***************************** Include Files *********************************/ + + +/************************** Constant Definitions *****************************/ + +#define XIL_ASSERT_NONE 0U +#define XIL_ASSERT_OCCURRED 1U +#define XNULL NULL + +extern u32 Xil_AssertStatus; +extern s32 Xil_AssertWait; +extern void Xil_Assert(const char8 *File, s32 Line); +void XNullHandler(void *NullParameter); + +/** + * This data type defines a callback to be invoked when an + * assert occurs. The callback is invoked only when asserts are enabled + */ +typedef void (*Xil_AssertCallback) (const char8 *File, s32 Line); + +/***************** Macros (Inline Functions) Definitions *********************/ + +#ifndef NDEBUG + +/*****************************************************************************/ +/** +* @brief This assert macro is to be used for void functions. This in +* conjunction with the Xil_AssertWait boolean can be used to +* accomodate tests so that asserts which fail allow execution to +* continue. +* +* @param Expression: expression to be evaluated. If it evaluates to +* false, the assert occurs. +* +* @return Returns void unless the Xil_AssertWait variable is true, in which +* case no return is made and an infinite loop is entered. +* +******************************************************************************/ +#define Xil_AssertVoid(Expression) \ +{ \ + if (Expression) { \ + Xil_AssertStatus = XIL_ASSERT_NONE; \ + } else { \ + Xil_Assert(__FILE__, __LINE__); \ + Xil_AssertStatus = XIL_ASSERT_OCCURRED; \ + return; \ + } \ +} + +/*****************************************************************************/ +/** +* @brief This assert macro is to be used for functions that do return a +* value. This in conjunction with the Xil_AssertWait boolean can be +* used to accomodate tests so that asserts which fail allow execution +* to continue. +* +* @param Expression: expression to be evaluated. If it evaluates to false, +* the assert occurs. +* +* @return Returns 0 unless the Xil_AssertWait variable is true, in which +* case no return is made and an infinite loop is entered. +* +******************************************************************************/ +#define Xil_AssertNonvoid(Expression) \ +{ \ + if (Expression) { \ + Xil_AssertStatus = XIL_ASSERT_NONE; \ + } else { \ + Xil_Assert(__FILE__, __LINE__); \ + Xil_AssertStatus = XIL_ASSERT_OCCURRED; \ + return 0; \ + } \ +} + +/*****************************************************************************/ +/** +* @brief Always assert. This assert macro is to be used for void functions. +* Use for instances where an assert should always occur. +* +* @return Returns void unless the Xil_AssertWait variable is true, in which +* case no return is made and an infinite loop is entered. +* +******************************************************************************/ +#define Xil_AssertVoidAlways() \ +{ \ + Xil_Assert(__FILE__, __LINE__); \ + Xil_AssertStatus = XIL_ASSERT_OCCURRED; \ + return; \ +} + +/*****************************************************************************/ +/** +* @brief Always assert. This assert macro is to be used for functions that +* do return a value. Use for instances where an assert should always +* occur. +* +* @return Returns void unless the Xil_AssertWait variable is true, in which +* case no return is made and an infinite loop is entered. +* +******************************************************************************/ +#define Xil_AssertNonvoidAlways() \ +{ \ + Xil_Assert(__FILE__, __LINE__); \ + Xil_AssertStatus = XIL_ASSERT_OCCURRED; \ + return 0; \ +} + + +#else + +#define Xil_AssertVoid(Expression) +#define Xil_AssertVoidAlways() +#define Xil_AssertNonvoid(Expression) +#define Xil_AssertNonvoidAlways() + +#endif + +/************************** Function Prototypes ******************************/ + +void Xil_AssertSetCallback(Xil_AssertCallback Routine); + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** +* @} End of "addtogroup common_assert_apis". +*/ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_cache.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_cache.c new file mode 100644 index 0000000..536800f --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_cache.c @@ -0,0 +1,1637 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xil_cache.c +* +* Contains required functions for the ARM cache functionality. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver    Who Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a  ecm 01/29/10 First release
+* 1.00a  ecm 06/24/10 Moved the L1 and L2 specific function prototypes
+*		      		  to xil_cache_mach.h to give access to sophisticated users
+* 3.02a  sdm 04/07/11 Updated Flush/InvalidateRange APIs to flush/invalidate
+*		      		  L1 and L2 caches in a single loop and used dsb, L2 sync
+*		      		  at the end of the loop.
+* 3.04a  sdm 01/02/12 Remove redundant dsb/dmb instructions in cache maintenance
+*		      		  APIs.
+* 3.07a  asa 07/16/12 Corrected the L1 and L2 cache invalidation order.
+* 3.07a  sgd 09/18/12 Corrected the L2 cache enable and disable sequence.
+* 3.10a  srt 04/18/13 Implemented ARM Erratas. Please refer to file
+*		      		  'xil_errata.h' for errata description
+* 3.10a  asa 05/13/13 Modified cache disable APIs. The L2 cache disable
+*			  		  operation was being done with L1 Data cache disabled. This is
+*			  		  fixed so that L2 cache disable operation happens independent of
+*			  		  L1 cache disable operation. This fixes CR #706464.
+*			  		  Changes are done to do a L2 cache sync (poll reg7_?cache_?sync).
+*			  		  This is done to fix the CR #700542.
+* 3.11a  asa 09/23/13 Modified the Xil_DCacheFlushRange and
+*			 		  Xil_DCacheInvalidateRange to fix potential issues. Fixed other
+*			 		  relevant cache APIs to disable and enable back the interrupts.
+*			 		  This fixes CR #663885.
+* 3.11a  asa 09/28/13 Made changes for L2 cache sync operation. It is found
+*			 		  out that for L2 cache flush/clean/invalidation by cache lines
+*			 		  does not need a cache sync as these are atomic nature. Similarly
+*			 		  figured out that for complete L2 cache flush/invalidation by way
+*			 		  we need to wait for some more time in a loop till the status
+*			 		  shows that the cache operation is completed.
+* 4.00	 pkp 24/01/14 Modified Xil_DCacheInvalidateRange to fix the bug. Few
+*			 		  cache lines were missed to invalidate when unaligned address
+*			 		  invalidation was accommodated. That fixes CR #766768.
+*			 		  Also in Xil_L1DCacheInvalidate, while invalidating all L1D cache
+*			 		  stack memory which contains return address was invalidated. So
+*			 		  stack memory was flushed first and then L1D cache is invalidated.
+*			 		  This is done to fix CR #763829
+* 4.01   asa 05/09/14 Made changes in cortexa9/xil_cache.c to fix CR# 798230.
+* 4.02	 pkp 06/27/14 Added notes to Xil_L1DCacheInvalidateRange function for
+*					  explanation of CR#785243
+* 5.00   kvn 12/15/14 Xil_L2CacheInvalidate was modified to fix CR# 838835. L2 Cache
+*					  has stack memory which has return address. Before invalidating
+*					  cache, stack memory was flushed first and L2 Cache is invalidated.
+* 5.01	 pkp 05/12/15 Xil_DCacheInvalidateRange and Xil_DCacheFlushRange is modified
+*					  to remove unnecessary dsb in the APIs. Instead of using dsb
+*					  for L2 Cache, L2CacheSync has been used for each L2 cache line
+*					  and single dsb has been used for L1 cache. Also L2CacheSync is
+*					  added into Xil_L2CacheInvalidateRange API. Xil_L1DCacheInvalidate
+*					  and Xil_L2CacheInvalidate APIs are modified to flush the complete
+*					  stack instead of just System Stack
+* 5.03	 pkp 10/07/15 L2 Cache functionalities are avoided for the OpenAMP slave
+*					  application(when USE_AMP flag is defined for BSP) as master CPU
+*					  would be utilizing L2 cache for its operation
+* 6.6    mus 12/07/17 Errata 753970 is not applicable for the PL130 cache controller
+*                     version r0p2, which is present in zynq. So,removed the handling
+*                     related to same.It fixes CR#989132.
+* 6.6    asa 16/01/18 Changes made in Xil_L1DCacheInvalidate and Xil_L2CacheInvalidate
+*					  routines to ensure the stack data flushed only when the respective
+*					  caches are enabled. This fixes CR-992023.
+*
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xil_cache.h" +#include "xil_cache_l.h" +#include "xil_io.h" +#include "xpseudo_asm.h" +#include "xparameters.h" +#include "xreg_cortexa9.h" +#include "xl2cc.h" +#include "xil_errata.h" +#include "xil_exception.h" + +/************************** Function Prototypes ******************************/ + +/************************** Variable Definitions *****************************/ + +#define IRQ_FIQ_MASK 0xC0U /* Mask IRQ and FIQ interrupts in cpsr */ + +#ifdef __GNUC__ + extern s32 _stack_end; + extern s32 __undef_stack; +#endif + +#ifndef USE_AMP +/**************************************************************************** +* +* Access L2 Debug Control Register. +* +* @param Value, value to be written to Debug Control Register. +* +* @return None. +* +* @note None. +* +****************************************************************************/ +#ifdef __GNUC__ +static inline void Xil_L2WriteDebugCtrl(u32 Value) +#else +static void Xil_L2WriteDebugCtrl(u32 Value) +#endif +{ +#if defined(CONFIG_PL310_ERRATA_588369) || defined(CONFIG_PL310_ERRATA_727915) + Xil_Out32(XPS_L2CC_BASEADDR + XPS_L2CC_DEBUG_CTRL_OFFSET, Value); +#else + (void)(Value); +#endif +} + +/**************************************************************************** +* +* Perform L2 Cache Sync Operation. +* +* @param None. +* +* @return None. +* +* @note None. +* +****************************************************************************/ +#ifdef __GNUC__ +static inline void Xil_L2CacheSync(void) +#else +static void Xil_L2CacheSync(void) +#endif +{ + Xil_Out32(XPS_L2CC_BASEADDR + XPS_L2CC_CACHE_SYNC_OFFSET, 0x0U); +} +#endif +/****************************************************************************/ +/** +* @brief Enable the Data cache. +* +* @param None. +* +* @return None. +* +* @note None. +* +****************************************************************************/ +void Xil_DCacheEnable(void) +{ + Xil_L1DCacheEnable(); +#ifndef USE_AMP + Xil_L2CacheEnable(); +#endif +} + +/****************************************************************************/ +/** +* @brief Disable the Data cache. +* +* @param None. +* +* @return None. +* +* @note None. +* +****************************************************************************/ +void Xil_DCacheDisable(void) +{ +#ifndef USE_AMP + Xil_L2CacheDisable(); +#endif + Xil_L1DCacheDisable(); +} + +/****************************************************************************/ +/** +* @brief Invalidate the entire Data cache. +* +* @param None. +* +* @return None. +* +* @note None. +* +****************************************************************************/ +void Xil_DCacheInvalidate(void) +{ + u32 currmask; + + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); +#ifndef USE_AMP + Xil_L2CacheInvalidate(); +#endif + Xil_L1DCacheInvalidate(); + + mtcpsr(currmask); +} + +/*****************************************************************************/ +/** +* @brief Invalidate a Data cache line. If the byte specified by the address +* (adr) is cached by the Data cache, the cacheline containing that +* byte is invalidated. If the cacheline is modified (dirty), the +* modified contents are lost and are NOT written to the system memory +* before the line is invalidated. +* +* @param adr: 32bit address of the data to be flushed. +* +* @return None. +* +* @note The bottom 4 bits are set to 0, forced by architecture. +* +****************************************************************************/ +void Xil_DCacheInvalidateLine(u32 adr) +{ + u32 currmask; + + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); +#ifndef USE_AMP + Xil_L2CacheInvalidateLine(adr); +#endif + Xil_L1DCacheInvalidateLine(adr); + + mtcpsr(currmask); +} + + +/*****************************************************************************/ +/** +* @brief Invalidate the Data cache for the given address range. +* If the bytes specified by the address range are cached by the Data +* cache, the cachelines containing those bytes are invalidated. If +* the cachelines are modified (dirty), the modified contents are lost +* and NOT written to the system memory before the lines are +* invalidated. +* +* In this function, if start address or end address is not aligned to +* cache-line, particular cache-line containing unaligned start or end +* address is flush first and then invalidated the others as +* invalidating the same unaligned cache line may result into loss of +* data. This issue raises few possibilities. +* +* If the address to be invalidated is not cache-line aligned, the +* following choices are available: +* 1. Invalidate the cache line when required and do not bother much +* for the side effects. Though it sounds good, it can result in +* hard-to-debug issues. The problem is, if some other variable are +* allocated in the same cache line and had been recently updated +* (in cache), the invalidation would result in loss of data. +* 2. Flush the cache line first. This will ensure that if any other +* variable present in the same cache line and updated recently are +* flushed out to memory. Then it can safely be invalidated. Again it +* sounds good, but this can result in issues. For example, when the +* invalidation happens in a typical ISR (after a DMA transfer has +* updated the memory), then flushing the cache line means, loosing +* data that were updated recently before the ISR got invoked. +* +* Linux prefers the second one. To have uniform implementation +* (across standalone and Linux), the second option is implemented. +* This being the case, follwoing needs to be taken care of: +* 1. Whenever possible, the addresses must be cache line aligned. +* Please nore that, not just start address, even the end address must +* be cache line aligned. If that is taken care of, this will always +* work. +* 2. Avoid situations where invalidation has to be done after the +* data is updated by peripheral/DMA directly into the memory. It is +* not tough to achieve (may be a bit risky). The common use case to +* do invalidation is when a DMA happens. Generally for such use +* cases, buffers can be allocated first and then start the DMA. The +* practice that needs to be followed here is, immediately after +* buffer allocation and before starting the DMA, do the invalidation. +* With this approach, invalidation need not to be done after the DMA +* transfer is over. +* +* This is going to always work if done carefully. +* However, the concern is, there is no guarantee that invalidate has +* not needed to be done after DMA is complete. For example, because +* of some reasons if the first cache line or last cache line +* (assuming the buffer in question comprises of multiple cache lines) +* are brought into cache (between the time it is invalidated and DMA +* completes) because of some speculative prefetching or reading data +* for a variable present in the same cache line, then we will have to +* invalidate the cache after DMA is complete. +* +* +* @param adr: 32bit start address of the range to be invalidated. +* @param len: Length of the range to be invalidated in bytes. +* +* @return None. +* +* @note None. +* +****************************************************************************/ +void Xil_DCacheInvalidateRange(INTPTR adr, u32 len) +{ + const u32 cacheline = 32U; + u32 end; + u32 tempadr = adr; + u32 tempend; + u32 currmask; + volatile u32 *L2CCOffset = (volatile u32 *)(XPS_L2CC_BASEADDR + + XPS_L2CC_CACHE_INVLD_PA_OFFSET); + + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + + if (len != 0U) { + end = tempadr + len; + tempend = end; + /* Select L1 Data cache in CSSR */ + mtcp(XREG_CP15_CACHE_SIZE_SEL, 0U); + + if ((tempadr & (cacheline-1U)) != 0U) { + tempadr &= (~(cacheline - 1U)); + + Xil_L1DCacheFlushLine(tempadr); +#ifndef USE_AMP + /* Disable Write-back and line fills */ + Xil_L2WriteDebugCtrl(0x3U); + Xil_L2CacheFlushLine(tempadr); + /* Enable Write-back and line fills */ + Xil_L2WriteDebugCtrl(0x0U); + Xil_L2CacheSync(); +#endif + tempadr += cacheline; + } + if ((tempend & (cacheline-1U)) != 0U) { + tempend &= (~(cacheline - 1U)); + + Xil_L1DCacheFlushLine(tempend); +#ifndef USE_AMP + /* Disable Write-back and line fills */ + Xil_L2WriteDebugCtrl(0x3U); + Xil_L2CacheFlushLine(tempend); + /* Enable Write-back and line fills */ + Xil_L2WriteDebugCtrl(0x0U); + Xil_L2CacheSync(); +#endif + } + + while (tempadr < tempend) { +#ifndef USE_AMP + /* Invalidate L2 cache line */ + *L2CCOffset = tempadr; + Xil_L2CacheSync(); +#endif + + /* Invalidate L1 Data cache line */ +#if defined (__GNUC__) || defined (__ICCARM__) + asm_cp15_inval_dc_line_mva_poc(tempadr); +#else + { volatile register u32 Reg + __asm(XREG_CP15_INVAL_DC_LINE_MVA_POC); + Reg = tempadr; } +#endif + tempadr += cacheline; + } + } + + dsb(); + mtcpsr(currmask); +} + +/****************************************************************************/ +/** +* @brief Flush the entire Data cache. +* +* @param None. +* +* @return None. +* +* @note None. +* +****************************************************************************/ +void Xil_DCacheFlush(void) +{ + u32 currmask; + + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + Xil_L1DCacheFlush(); +#ifndef USE_AMP + Xil_L2CacheFlush(); +#endif + mtcpsr(currmask); +} + + +/****************************************************************************/ +/** +* @brief Flush a Data cache line. If the byte specified by the address (adr) +* is cached by the Data cache, the cacheline containing that byte is +* invalidated. If the cacheline is modified (dirty), the entire +* contents of the cacheline are written to system memory before the +* line is invalidated. +* +* @param adr: 32bit address of the data to be flushed. +* +* @return None. +* +* @note The bottom 4 bits are set to 0, forced by architecture. +* +****************************************************************************/ +void Xil_DCacheFlushLine(u32 adr) +{ + u32 currmask; + + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + Xil_L1DCacheFlushLine(adr); +#ifndef USE_AMP + /* Disable Write-back and line fills */ + Xil_L2WriteDebugCtrl(0x3U); + + Xil_L2CacheFlushLine(adr); + + /* Enable Write-back and line fills */ + Xil_L2WriteDebugCtrl(0x0U); + Xil_L2CacheSync(); +#endif + mtcpsr(currmask); +} + +/****************************************************************************/ +/** +* @brief Flush the Data cache for the given address range. +* If the bytes specified by the address range are cached by the +* data cache, the cachelines containing those bytes are invalidated. +* If the cachelines are modified (dirty), they are written to the +* system memory before the lines are invalidated. +* +* @param adr: 32bit start address of the range to be flushed. +* @param len: Length of the range to be flushed in bytes. +* +* @return None. +* +* @note None. +* +****************************************************************************/ +void Xil_DCacheFlushRange(INTPTR adr, u32 len) +{ + u32 LocalAddr = adr; + const u32 cacheline = 32U; + u32 end; + u32 currmask; + volatile u32 *L2CCOffset = (volatile u32 *)(XPS_L2CC_BASEADDR + + XPS_L2CC_CACHE_INV_CLN_PA_OFFSET); + + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + + if (len != 0U) { + /* Back the starting address up to the start of a cache line + * perform cache operations until adr+len + */ + end = LocalAddr + len; + LocalAddr &= ~(cacheline - 1U); + + while (LocalAddr < end) { + + /* Flush L1 Data cache line */ +#if defined (__GNUC__) || defined (__ICCARM__) + asm_cp15_clean_inval_dc_line_mva_poc(LocalAddr); +#else + { volatile register u32 Reg + __asm(XREG_CP15_CLEAN_INVAL_DC_LINE_MVA_POC); + Reg = LocalAddr; } +#endif +#ifndef USE_AMP + /* Flush L2 cache line */ + *L2CCOffset = LocalAddr; + Xil_L2CacheSync(); +#endif + LocalAddr += cacheline; + } + } + dsb(); + mtcpsr(currmask); +} +/****************************************************************************/ +/** +* @brief Store a Data cache line. If the byte specified by the address (adr) +* is cached by the Data cache and the cacheline is modified (dirty), +* the entire contents of the cacheline are written to system memory. +* After the store completes, the cacheline is marked as unmodified +* (not dirty). +* +* @param adr: 32bit address of the data to be stored. +* +* @return None. +* +* @note The bottom 4 bits are set to 0, forced by architecture. +* +****************************************************************************/ +void Xil_DCacheStoreLine(u32 adr) +{ + u32 currmask; + + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + + Xil_L1DCacheStoreLine(adr); +#ifndef USE_AMP + Xil_L2CacheStoreLine(adr); +#endif + mtcpsr(currmask); +} + +/***************************************************************************/ +/** +* @brief Enable the instruction cache. +* +* @param None. +* +* @return None. +* +* @note None. +* +****************************************************************************/ +void Xil_ICacheEnable(void) +{ + Xil_L1ICacheEnable(); +#ifndef USE_AMP + Xil_L2CacheEnable(); +#endif +} + +/***************************************************************************/ +/** +* @brief Disable the instruction cache. +* +* @param None. +* +* @return None. +* +* @note None. +* +****************************************************************************/ +void Xil_ICacheDisable(void) +{ +#ifndef USE_AMP + Xil_L2CacheDisable(); +#endif + Xil_L1ICacheDisable(); +} + + +/****************************************************************************/ +/** +* @brief Invalidate the entire instruction cache. +* +* @param None. +* +* @return None. +* +* @note None. +* +****************************************************************************/ +void Xil_ICacheInvalidate(void) +{ + u32 currmask; + + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); +#ifndef USE_AMP + Xil_L2CacheInvalidate(); +#endif + Xil_L1ICacheInvalidate(); + + mtcpsr(currmask); +} + +/****************************************************************************/ +/** +* @brief Invalidate an instruction cache line. If the instruction specified +* by the address is cached by the instruction cache, the cacheline +* containing that instruction is invalidated. +* +* @param adr: 32bit address of the instruction to be invalidated. +* +* @return None. +* +* @note The bottom 4 bits are set to 0, forced by architecture. +* +****************************************************************************/ +void Xil_ICacheInvalidateLine(u32 adr) +{ + u32 currmask; + + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); +#ifndef USE_AMP + Xil_L2CacheInvalidateLine(adr); +#endif + Xil_L1ICacheInvalidateLine(adr); + mtcpsr(currmask); +} + +/****************************************************************************/ +/** +* @brief Invalidate the instruction cache for the given address range. +* If the instructions specified by the address range are cached by +* the instrunction cache, the cachelines containing those +* instructions are invalidated. +* +* @param adr: 32bit start address of the range to be invalidated. +* @param len: Length of the range to be invalidated in bytes. +* +* @return None. +* +* @note None. +* +****************************************************************************/ +void Xil_ICacheInvalidateRange(INTPTR adr, u32 len) +{ + u32 LocalAddr = adr; + const u32 cacheline = 32U; + u32 end; + volatile u32 *L2CCOffset = (volatile u32 *)(XPS_L2CC_BASEADDR + + XPS_L2CC_CACHE_INVLD_PA_OFFSET); + + u32 currmask; + + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + if (len != 0U) { + /* Back the starting address up to the start of a cache line + * perform cache operations until adr+len + */ + end = LocalAddr + len; + LocalAddr = LocalAddr & ~(cacheline - 1U); + + /* Select cache L0 I-cache in CSSR */ + mtcp(XREG_CP15_CACHE_SIZE_SEL, 1U); + + while (LocalAddr < end) { +#ifndef USE_AMP + /* Invalidate L2 cache line */ + *L2CCOffset = LocalAddr; + dsb(); +#endif + + /* Invalidate L1 I-cache line */ +#if defined (__GNUC__) || defined (__ICCARM__) + asm_cp15_inval_ic_line_mva_pou(LocalAddr); +#else + { volatile register u32 Reg + __asm(XREG_CP15_INVAL_IC_LINE_MVA_POU); + Reg = LocalAddr; } +#endif + + LocalAddr += cacheline; + } + } + + /* Wait for L1 and L2 invalidate to complete */ + dsb(); + mtcpsr(currmask); +} + +/****************************************************************************/ +/** +* @brief Enable the level 1 Data cache. +* +* @param None. +* +* @return None. +* +* @note None. +* +****************************************************************************/ +void Xil_L1DCacheEnable(void) +{ + register u32 CtrlReg; + + /* enable caches only if they are disabled */ +#ifdef __GNUC__ + CtrlReg = mfcp(XREG_CP15_SYS_CONTROL); +#elif defined (__ICCARM__) + mfcp(XREG_CP15_SYS_CONTROL, CtrlReg); +#else + { volatile register u32 Reg __asm(XREG_CP15_SYS_CONTROL); + CtrlReg = Reg; } +#endif + if ((CtrlReg & (XREG_CP15_CONTROL_C_BIT)) != 0U) { + return; + } + + /* clean and invalidate the Data cache */ + Xil_L1DCacheInvalidate(); + + /* enable the Data cache */ + CtrlReg |= (XREG_CP15_CONTROL_C_BIT); + + mtcp(XREG_CP15_SYS_CONTROL, CtrlReg); +} + +/***************************************************************************/ +/** +* @brief Disable the level 1 Data cache. +* +* @param None. +* +* @return None. +* +* @note None. +* +****************************************************************************/ +void Xil_L1DCacheDisable(void) +{ + register u32 CtrlReg; + + /* clean and invalidate the Data cache */ + Xil_L1DCacheFlush(); + +#ifdef __GNUC__ + /* disable the Data cache */ + CtrlReg = mfcp(XREG_CP15_SYS_CONTROL); +#elif defined (__ICCARM__) + mfcp(XREG_CP15_SYS_CONTROL, CtrlReg); +#else + { volatile register u32 Reg __asm(XREG_CP15_SYS_CONTROL); + CtrlReg = Reg; } +#endif + + CtrlReg &= ~(XREG_CP15_CONTROL_C_BIT); + + mtcp(XREG_CP15_SYS_CONTROL, CtrlReg); +} + +/****************************************************************************/ +/** +* @brief Invalidate the level 1 Data cache. +* +* @param None. +* +* @return None. +* +* @note In Cortex A9, there is no cp instruction for invalidating +* the whole D-cache. This function invalidates each line by +* set/way. +* +****************************************************************************/ +void Xil_L1DCacheInvalidate(void) +{ + register u32 CsidReg, C7Reg; + u32 CacheSize, LineSize, NumWays; + u32 Way, WayIndex, Set, SetIndex, NumSet; + u32 currmask; + +#ifdef __GNUC__ + u32 stack_start,stack_end,stack_size; + register u32 CtrlReg; +#endif + + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + +#ifdef __GNUC__ + stack_end = (u32)&_stack_end; + stack_start = (u32)&__undef_stack; + stack_size=stack_start-stack_end; + + /* Check for the cache status. If cache is enabled, then only + * flush stack memory to save return address. If cache is disabled, + * dont flush anything as it might result in flushing stale date into + * memory which is undesirable. + * */ + CtrlReg = mfcp(XREG_CP15_SYS_CONTROL); + if ((CtrlReg & (XREG_CP15_CONTROL_C_BIT)) != 0U) { + Xil_DCacheFlushRange(stack_end, stack_size); + } +#endif + + /* Select cache level 0 and D cache in CSSR */ + mtcp(XREG_CP15_CACHE_SIZE_SEL, 0U); + +#ifdef __GNUC__ + CsidReg = mfcp(XREG_CP15_CACHE_SIZE_ID); +#elif defined (__ICCARM__) + mfcp(XREG_CP15_CACHE_SIZE_ID, CsidReg); +#else + { volatile register u32 Reg __asm(XREG_CP15_CACHE_SIZE_ID); + CsidReg = Reg; } +#endif + /* Determine Cache Size */ + CacheSize = (CsidReg >> 13U) & 0x1FFU; + CacheSize +=1U; + CacheSize *=128U; /* to get number of bytes */ + + /* Number of Ways */ + NumWays = (CsidReg & 0x3ffU) >> 3U; + NumWays += 1U; + + /* Get the cacheline size, way size, index size from csidr */ + LineSize = (CsidReg & 0x07U) + 4U; + + NumSet = CacheSize/NumWays; + NumSet /= (0x00000001U << LineSize); + + Way = 0U; + Set = 0U; + + /* Invalidate all the cachelines */ + for (WayIndex =0U; WayIndex < NumWays; WayIndex++) { + for (SetIndex =0U; SetIndex < NumSet; SetIndex++) { + C7Reg = Way | Set; + + /* Invalidate by Set/Way */ +#if defined (__GNUC__) || defined (__ICCARM__) + asm_cp15_inval_dc_line_sw(C7Reg); +#else + /*mtcp(XREG_CP15_INVAL_DC_LINE_SW, C7Reg), */ + { volatile register u32 Reg + __asm(XREG_CP15_INVAL_DC_LINE_SW); + Reg = C7Reg; } +#endif + Set += (0x00000001U << LineSize); + } + Set=0U; + Way += 0x40000000U; + } + + /* Wait for L1 invalidate to complete */ + dsb(); + mtcpsr(currmask); +} + +/****************************************************************************/ +/** +* @brief Invalidate a level 1 Data cache line. If the byte specified by the +* address (Addr) is cached by the Data cache, the cacheline +* containing that byte is invalidated. If the cacheline is modified +* (dirty), the modified contents are lost and are NOT written to +* system memory before the line is invalidated. +* +* @param adr: 32bit address of the data to be invalidated. +* +* @return None. +* +* @note The bottom 5 bits are set to 0, forced by architecture. +* +****************************************************************************/ +void Xil_L1DCacheInvalidateLine(u32 adr) +{ + mtcp(XREG_CP15_CACHE_SIZE_SEL, 0U); + mtcp(XREG_CP15_INVAL_DC_LINE_MVA_POC, (adr & (~0x1FU))); + + /* Wait for L1 invalidate to complete */ + dsb(); +} + +/****************************************************************************/ +/** +* @brief Invalidate the level 1 Data cache for the given address range. +* If the bytes specified by the address range are cached by the Data +* cache, the cachelines containing those bytes are invalidated. If the +* cachelines are modified (dirty), the modified contents are lost and +* NOT written to the system memory before the lines are invalidated. +* +* @param adr: 32bit start address of the range to be invalidated. +* @param len: Length of the range to be invalidated in bytes. +* +* @return None. +* +* @note None. +* +****************************************************************************/ +void Xil_L1DCacheInvalidateRange(u32 adr, u32 len) +{ + u32 LocalAddr = adr; + const u32 cacheline = 32U; + u32 end; + u32 currmask; + + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + + if (len != 0U) { + /* Back the starting address up to the start of a cache line + * perform cache operations until adr+len + */ + end = LocalAddr + len; + LocalAddr = LocalAddr & ~(cacheline - 1U); + + /* Select cache L0 D-cache in CSSR */ + mtcp(XREG_CP15_CACHE_SIZE_SEL, 0); + + while (LocalAddr < end) { + +#if defined (__GNUC__) || defined (__ICCARM__) + asm_cp15_inval_dc_line_mva_poc(LocalAddr); +#else + { volatile register u32 Reg + __asm(XREG_CP15_INVAL_DC_LINE_MVA_POC); + Reg = LocalAddr; } +#endif + LocalAddr += cacheline; + } + } + + /* Wait for L1 invalidate to complete */ + dsb(); + mtcpsr(currmask); +} + +/****************************************************************************/ +/** +* @brief Flush the level 1 Data cache. +* +* @param None. +* +* @return None. +* +* @note In Cortex A9, there is no cp instruction for flushing +* the whole D-cache. Need to flush each line. +* +****************************************************************************/ +void Xil_L1DCacheFlush(void) +{ + register u32 CsidReg, C7Reg; + u32 CacheSize, LineSize, NumWays; + u32 Way; + u32 WayIndex, Set, SetIndex, NumSet; + u32 currmask; + + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + + /* Select cache level 0 and D cache in CSSR */ + mtcp(XREG_CP15_CACHE_SIZE_SEL, 0); + +#ifdef __GNUC__ + CsidReg = mfcp(XREG_CP15_CACHE_SIZE_ID); +#elif defined (__ICCARM__) + mfcp(XREG_CP15_CACHE_SIZE_ID, CsidReg); +#else + { volatile register u32 Reg __asm(XREG_CP15_CACHE_SIZE_ID); + CsidReg = Reg; } +#endif + + /* Determine Cache Size */ + + CacheSize = (CsidReg >> 13U) & 0x1FFU; + CacheSize +=1U; + CacheSize *=128U; /* to get number of bytes */ + + /* Number of Ways */ + NumWays = (CsidReg & 0x3ffU) >> 3U; + NumWays += 1U; + + /* Get the cacheline size, way size, index size from csidr */ + LineSize = (CsidReg & 0x07U) + 4U; + + NumSet = CacheSize/NumWays; + NumSet /= (0x00000001U << LineSize); + + Way = 0U; + Set = 0U; + + /* Invalidate all the cachelines */ + for (WayIndex =0U; WayIndex < NumWays; WayIndex++) { + for (SetIndex =0U; SetIndex < NumSet; SetIndex++) { + C7Reg = Way | Set; + /* Flush by Set/Way */ + +#if defined (__GNUC__) || defined (__ICCARM__) + asm_cp15_clean_inval_dc_line_sw(C7Reg); +#else + { volatile register u32 Reg + __asm(XREG_CP15_CLEAN_INVAL_DC_LINE_SW); + Reg = C7Reg; } +#endif + Set += (0x00000001U << LineSize); + } + Set = 0U; + Way += 0x40000000U; + } + + /* Wait for L1 flush to complete */ + dsb(); + mtcpsr(currmask); +} + +/****************************************************************************/ +/** +* @brief Flush a level 1 Data cache line. If the byte specified by the +* address (adr) is cached by the Data cache, the cacheline containing +* that byte is invalidated. If the cacheline is modified (dirty), the +* entire contents of the cacheline are written to system memory +* before the line is invalidated. +* +* @param adr: 32bit address of the data to be flushed. +* +* @return None. +* +* @note The bottom 5 bits are set to 0, forced by architecture. +* +****************************************************************************/ +void Xil_L1DCacheFlushLine(u32 adr) +{ + mtcp(XREG_CP15_CACHE_SIZE_SEL, 0U); + mtcp(XREG_CP15_CLEAN_INVAL_DC_LINE_MVA_POC, (adr & (~0x1FU))); + + /* Wait for L1 flush to complete */ + dsb(); +} + +/****************************************************************************/ +/** +* @brief Flush the level 1 Data cache for the given address range. +* If the bytes specified by the address range are cached by the Data +* cache, the cacheline containing those bytes are invalidated. If the +* cachelines are modified (dirty), they are written to system memory +* before the lines are invalidated. +* +* @param adr: 32bit start address of the range to be flushed. +* @param len: Length of the range to be flushed in bytes. +* +* @return None. +* +* @note None. +* +****************************************************************************/ +void Xil_L1DCacheFlushRange(u32 adr, u32 len) +{ + u32 LocalAddr = adr; + const u32 cacheline = 32U; + u32 end; + u32 currmask; + + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + + if (len != 0U) { + /* Back the starting address up to the start of a cache line + * perform cache operations until adr+len + */ + end = LocalAddr + len; + LocalAddr = LocalAddr & ~(cacheline - 1U); + + /* Select cache L0 D-cache in CSSR */ + mtcp(XREG_CP15_CACHE_SIZE_SEL, 0U); + + while (LocalAddr < end) { + +#if defined (__GNUC__) || defined (__ICCARM__) + asm_cp15_clean_inval_dc_line_mva_poc(LocalAddr); +#else + { volatile register u32 Reg + __asm(XREG_CP15_CLEAN_INVAL_DC_LINE_MVA_POC); + Reg = LocalAddr; } +#endif + LocalAddr += cacheline; + } + } + + /* Wait for L1 flush to complete */ + dsb(); + mtcpsr(currmask); +} + +/****************************************************************************/ +/** +* @brief Store a level 1 Data cache line. If the byte specified by the +* address (adr) is cached by the Data cache and the cacheline is +* modified (dirty), the entire contents of the cacheline are written +* to system memory. After the store completes, the cacheline is +* marked as unmodified (not dirty). +* +* @param Address to be stored. +* +* @return None. +* +* @note The bottom 5 bits are set to 0, forced by architecture. +* +****************************************************************************/ +void Xil_L1DCacheStoreLine(u32 adr) +{ + mtcp(XREG_CP15_CACHE_SIZE_SEL, 0U); + mtcp(XREG_CP15_CLEAN_DC_LINE_MVA_POC, (adr & (~0x1FU))); + + /* Wait for L1 store to complete */ + dsb(); +} + + +/****************************************************************************/ +/** +* @brief Enable the level 1 instruction cache. +* +* @param None. +* +* @return None. +* +* @note None. +* +****************************************************************************/ +void Xil_L1ICacheEnable(void) +{ + register u32 CtrlReg; + + /* enable caches only if they are disabled */ +#ifdef __GNUC__ + CtrlReg = mfcp(XREG_CP15_SYS_CONTROL); +#elif defined (__ICCARM__) + mfcp(XREG_CP15_SYS_CONTROL, CtrlReg); +#else + { volatile register u32 Reg __asm(XREG_CP15_SYS_CONTROL); + CtrlReg = Reg; } +#endif + if ((CtrlReg & (XREG_CP15_CONTROL_I_BIT)) != 0U) { + return; + } + + /* invalidate the instruction cache */ + mtcp(XREG_CP15_INVAL_IC_POU, 0U); + + /* enable the instruction cache */ + CtrlReg |= (XREG_CP15_CONTROL_I_BIT); + + mtcp(XREG_CP15_SYS_CONTROL, CtrlReg); +} + +/****************************************************************************/ +/** +* @brief Disable level 1 the instruction cache. +* +* @param None. +* +* @return None. +* +* @note None. +* +****************************************************************************/ +void Xil_L1ICacheDisable(void) +{ + register u32 CtrlReg; + + dsb(); + + /* invalidate the instruction cache */ + mtcp(XREG_CP15_INVAL_IC_POU, 0U); + + /* disable the instruction cache */ +#ifdef __GNUC__ + CtrlReg = mfcp(XREG_CP15_SYS_CONTROL); +#elif defined (__ICCARM__) + mfcp(XREG_CP15_SYS_CONTROL, CtrlReg); +#else + { volatile register u32 Reg __asm(XREG_CP15_SYS_CONTROL); + CtrlReg = Reg; } +#endif + CtrlReg &= ~(XREG_CP15_CONTROL_I_BIT); + + mtcp(XREG_CP15_SYS_CONTROL, CtrlReg); +} + +/****************************************************************************/ +/** +* @brief Invalidate the entire level 1 instruction cache. +* +* @param None. +* +* @return None. +* +* @note None. +* +****************************************************************************/ +void Xil_L1ICacheInvalidate(void) +{ + mtcp(XREG_CP15_CACHE_SIZE_SEL, 1U); + /* invalidate the instruction cache */ + mtcp(XREG_CP15_INVAL_IC_POU, 0U); + + /* Wait for L1 invalidate to complete */ + dsb(); +} + +/****************************************************************************/ +/** +* @brief Invalidate a level 1 instruction cache line. If the instruction +* specified by the address is cached by the instruction cache, the +* cacheline containing that instruction is invalidated. +* +* @param adr: 32bit address of the instruction to be invalidated. +* +* @return None. +* +* @note The bottom 5 bits are set to 0, forced by architecture. +* +****************************************************************************/ +void Xil_L1ICacheInvalidateLine(u32 adr) +{ + mtcp(XREG_CP15_CACHE_SIZE_SEL, 1U); + mtcp(XREG_CP15_INVAL_IC_LINE_MVA_POU, (adr & (~0x1FU))); + + /* Wait for L1 invalidate to complete */ + dsb(); +} + +/****************************************************************************/ +/** +* @brief Invalidate the level 1 instruction cache for the given address +* range. If the instrucions specified by the address range are cached +* by the instruction cache, the cacheline containing those bytes are +* invalidated. +* +* @param adr: 32bit start address of the range to be invalidated. +* @param len: Length of the range to be invalidated in bytes. +* +* @return None. +* +* @note None. +* +****************************************************************************/ +void Xil_L1ICacheInvalidateRange(u32 adr, u32 len) +{ + u32 LocalAddr = adr; + const u32 cacheline = 32U; + u32 end; + u32 currmask; + + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + + if (len != 0U) { + /* Back the starting address up to the start of a cache line + * perform cache operations until adr+len + */ + end = LocalAddr + len; + LocalAddr = LocalAddr & ~(cacheline - 1U); + + /* Select cache L0 I-cache in CSSR */ + mtcp(XREG_CP15_CACHE_SIZE_SEL, 1U); + + while (LocalAddr < end) { + +#if defined (__GNUC__) || defined (__ICCARM__) + asm_cp15_inval_ic_line_mva_pou(LocalAddr); +#else + { volatile register u32 Reg + __asm(XREG_CP15_INVAL_IC_LINE_MVA_POU); + Reg = LocalAddr; } +#endif + LocalAddr += cacheline; + } + } + + /* Wait for L1 invalidate to complete */ + dsb(); + mtcpsr(currmask); +} + +#ifndef USE_AMP +/****************************************************************************/ +/** +* @brief Enable the L2 cache. +* +* @param None. +* +* @return None. +* +* @note None. +* +****************************************************************************/ +void Xil_L2CacheEnable(void) +{ + register u32 L2CCReg; + + L2CCReg = Xil_In32(XPS_L2CC_BASEADDR + XPS_L2CC_CNTRL_OFFSET); + + /* only enable if L2CC is currently disabled */ + if ((L2CCReg & 0x01U) == 0U) { + /* set up the way size and latencies */ + L2CCReg = Xil_In32(XPS_L2CC_BASEADDR + + XPS_L2CC_AUX_CNTRL_OFFSET); + L2CCReg &= XPS_L2CC_AUX_REG_ZERO_MASK; + L2CCReg |= XPS_L2CC_AUX_REG_DEFAULT_MASK; + Xil_Out32(XPS_L2CC_BASEADDR + XPS_L2CC_AUX_CNTRL_OFFSET, + L2CCReg); + Xil_Out32(XPS_L2CC_BASEADDR + XPS_L2CC_TAG_RAM_CNTRL_OFFSET, + XPS_L2CC_TAG_RAM_DEFAULT_MASK); + Xil_Out32(XPS_L2CC_BASEADDR + XPS_L2CC_DATA_RAM_CNTRL_OFFSET, + XPS_L2CC_DATA_RAM_DEFAULT_MASK); + + /* Clear the pending interrupts */ + L2CCReg = Xil_In32(XPS_L2CC_BASEADDR + + XPS_L2CC_ISR_OFFSET); + Xil_Out32(XPS_L2CC_BASEADDR + XPS_L2CC_IAR_OFFSET, L2CCReg); + + Xil_L2CacheInvalidate(); + /* Enable the L2CC */ + L2CCReg = Xil_In32(XPS_L2CC_BASEADDR + + XPS_L2CC_CNTRL_OFFSET); + Xil_Out32(XPS_L2CC_BASEADDR + XPS_L2CC_CNTRL_OFFSET, + (L2CCReg | (0x01U))); + + Xil_L2CacheSync(); + /* synchronize the processor */ + dsb(); + + } +} + +/****************************************************************************/ +/** +* @brief Disable the L2 cache. +* +* @param None. +* +* @return None. +* +* @note None. +* +****************************************************************************/ +void Xil_L2CacheDisable(void) +{ + register u32 L2CCReg; + + L2CCReg = Xil_In32(XPS_L2CC_BASEADDR + XPS_L2CC_CNTRL_OFFSET); + + if((L2CCReg & 0x1U) != 0U) { + + /* Clean and Invalidate L2 Cache */ + Xil_L2CacheFlush(); + + /* Disable the L2CC */ + L2CCReg = Xil_In32(XPS_L2CC_BASEADDR + XPS_L2CC_CNTRL_OFFSET); + Xil_Out32(XPS_L2CC_BASEADDR + XPS_L2CC_CNTRL_OFFSET, + (L2CCReg & (~0x01U))); + /* Wait for the cache operations to complete */ + + dsb(); + } +} + +/*****************************************************************************/ +/** +* @brief Invalidate the entire level 2 cache. +* +* @param None. +* +* @return None. +* +* @note None. +* +****************************************************************************/ +void Xil_L2CacheInvalidate(void) +{ + #ifdef __GNUC__ + u32 stack_start,stack_end,stack_size; + register u32 L2CCReg; + stack_end = (u32)&_stack_end; + stack_start = (u32)&__undef_stack; + stack_size=stack_start-stack_end; + + /* Check for the cache status. If cache is enabled, then only + * flush stack memory to save return address. If cache is disabled, + * dont flush anything as it might result in flushing stale date into + * memory which is undesirable. + */ + L2CCReg = Xil_In32(XPS_L2CC_BASEADDR + XPS_L2CC_CNTRL_OFFSET); + if ((L2CCReg & 0x01U) != 0U) { + /*Flush stack memory to save return address*/ + Xil_DCacheFlushRange(stack_end, stack_size); + } + + #endif + u32 ResultDCache; + /* Invalidate the caches */ + Xil_Out32(XPS_L2CC_BASEADDR + XPS_L2CC_CACHE_INVLD_WAY_OFFSET, + 0x0000FFFFU); + ResultDCache = Xil_In32(XPS_L2CC_BASEADDR + XPS_L2CC_CACHE_INVLD_WAY_OFFSET) + & 0x0000FFFFU; + while(ResultDCache != (u32)0U) { + ResultDCache = Xil_In32(XPS_L2CC_BASEADDR + XPS_L2CC_CACHE_INVLD_WAY_OFFSET) + & 0x0000FFFFU; + } + + /* Wait for the invalidate to complete */ + Xil_L2CacheSync(); + + /* synchronize the processor */ + dsb(); +} + +/*****************************************************************************/ +/** +* @brief Invalidate a level 2 cache line. If the byte specified by the +* address (adr) is cached by the Data cache, the cacheline containing +* that byte is invalidated. If the cacheline is modified (dirty), +* the modified contents are lost and are NOT written to system memory +* before the line is invalidated. +* +* @param adr: 32bit address of the data/instruction to be invalidated. +* +* @return None. +* +* @note The bottom 4 bits are set to 0, forced by architecture. +* +****************************************************************************/ +void Xil_L2CacheInvalidateLine(u32 adr) +{ + Xil_Out32(XPS_L2CC_BASEADDR + XPS_L2CC_CACHE_INVLD_PA_OFFSET, (u32)adr); + /* synchronize the processor */ + dsb(); +} + +/****************************************************************************/ +/** +* @brief Invalidate the level 2 cache for the given address range. +* If the bytes specified by the address range are cached by the L2 +* cache, the cacheline containing those bytes are invalidated. If the +* cachelines are modified (dirty), the modified contents are lost and +* are NOT written to system memory before the lines are invalidated. +* +* @param adr: 32bit start address of the range to be invalidated. +* @param len: Length of the range to be invalidated in bytes. +* +* @return None. +* +* @note None. +* +****************************************************************************/ +void Xil_L2CacheInvalidateRange(u32 adr, u32 len) +{ + u32 LocalAddr = adr; + const u32 cacheline = 32U; + u32 end; + volatile u32 *L2CCOffset = (volatile u32 *)(XPS_L2CC_BASEADDR + + XPS_L2CC_CACHE_INVLD_PA_OFFSET); + + u32 currmask; + + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + + if (len != 0U) { + /* Back the starting address up to the start of a cache line + * perform cache operations until adr+len + */ + end = LocalAddr + len; + LocalAddr = LocalAddr & ~(cacheline - 1U); + + /* Disable Write-back and line fills */ + Xil_L2WriteDebugCtrl(0x3U); + + while (LocalAddr < end) { + *L2CCOffset = LocalAddr; + Xil_L2CacheSync(); + LocalAddr += cacheline; + } + + /* Enable Write-back and line fills */ + Xil_L2WriteDebugCtrl(0x0U); + } + + /* synchronize the processor */ + dsb(); + mtcpsr(currmask); +} + +/****************************************************************************/ +/** +* @brief Flush the entire level 2 cache. +* +* @param None. +* +* @return None. +* +* @note None. +* +****************************************************************************/ +void Xil_L2CacheFlush(void) +{ + u32 ResultL2Cache; + + /* Flush the caches */ + + /* Disable Write-back and line fills */ + Xil_L2WriteDebugCtrl(0x3U); + + Xil_Out32(XPS_L2CC_BASEADDR + XPS_L2CC_CACHE_INV_CLN_WAY_OFFSET, + 0x0000FFFFU); + ResultL2Cache = Xil_In32(XPS_L2CC_BASEADDR + XPS_L2CC_CACHE_INV_CLN_WAY_OFFSET) + & 0x0000FFFFU; + + while(ResultL2Cache != (u32)0U) { + ResultL2Cache = Xil_In32(XPS_L2CC_BASEADDR + XPS_L2CC_CACHE_INV_CLN_WAY_OFFSET) + & 0x0000FFFFU; + } + + Xil_L2CacheSync(); + /* Enable Write-back and line fills */ + Xil_L2WriteDebugCtrl(0x0U); + + /* synchronize the processor */ + dsb(); +} + +/****************************************************************************/ +/** +* @brief Flush a level 2 cache line. If the byte specified by the address +* (adr) is cached by the L2 cache, the cacheline containing that +* byte is invalidated. If the cacheline is modified (dirty), the +* entire contents of the cacheline are written to system memory +* before the line is invalidated. +* +* @param adr: 32bit address of the data/instruction to be flushed. +* +* @return None. +* +* @note The bottom 4 bits are set to 0, forced by architecture. +* +****************************************************************************/ +void Xil_L2CacheFlushLine(u32 adr) +{ +#ifdef CONFIG_PL310_ERRATA_588369 + Xil_Out32(XPS_L2CC_BASEADDR + XPS_L2CC_CACHE_CLEAN_PA_OFFSET, adr); + Xil_Out32(XPS_L2CC_BASEADDR + XPS_L2CC_CACHE_INVLD_PA_OFFSET, adr); +#else + Xil_Out32(XPS_L2CC_BASEADDR + XPS_L2CC_CACHE_INV_CLN_PA_OFFSET, adr); +#endif + /* synchronize the processor */ + dsb(); +} + +/****************************************************************************/ +/** +* @brief Flush the level 2 cache for the given address range. +* If the bytes specified by the address range are cached by the L2 +* cache, the cacheline containing those bytes are invalidated. If the +* cachelines are modified (dirty), they are written to the system +* memory before the lines are invalidated. +* +* @param adr: 32bit start address of the range to be flushed. +* @param len: Length of the range to be flushed in bytes. +* +* @return None. +* +* @note None. +* +****************************************************************************/ +void Xil_L2CacheFlushRange(u32 adr, u32 len) +{ + u32 LocalAddr = adr; + const u32 cacheline = 32U; + u32 end; + volatile u32 *L2CCOffset = (volatile u32 *)(XPS_L2CC_BASEADDR + + XPS_L2CC_CACHE_INV_CLN_PA_OFFSET); + + u32 currmask; + + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + if (len != 0U) { + /* Back the starting address up to the start of a cache line + * perform cache operations until adr+len + */ + end = LocalAddr + len; + LocalAddr = LocalAddr & ~(cacheline - 1U); + + /* Disable Write-back and line fills */ + Xil_L2WriteDebugCtrl(0x3U); + + while (LocalAddr < end) { + *L2CCOffset = LocalAddr; + Xil_L2CacheSync(); + LocalAddr += cacheline; + } + + /* Enable Write-back and line fills */ + Xil_L2WriteDebugCtrl(0x0U); + } + /* synchronize the processor */ + dsb(); + mtcpsr(currmask); +} + +/****************************************************************************/ +/** +* @brief Store a level 2 cache line. If the byte specified by the address +* (adr) is cached by the L2 cache and the cacheline is modified +* (dirty), the entire contents of the cacheline are written to +* system memory. After the store completes, the cacheline is marked +* as unmodified (not dirty). +* +* @param adr: 32bit address of the data/instruction to be stored. +* +* @return None. +* +* @note The bottom 4 bits are set to 0, forced by architecture. +* +****************************************************************************/ +void Xil_L2CacheStoreLine(u32 adr) +{ + Xil_Out32(XPS_L2CC_BASEADDR + XPS_L2CC_CACHE_CLEAN_PA_OFFSET, adr); + /* synchronize the processor */ + dsb(); +} +#endif diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_cache.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_cache.h new file mode 100644 index 0000000..ce6fcf4 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_cache.h @@ -0,0 +1,118 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xil_cache.h +* +* @addtogroup a9_cache_apis Cortex A9 Processor Cache Functions +* +* Cache functions provide access to cache related operations such as flush +* and invalidate for instruction and data caches. It gives option to perform +* the cache operations on a single cacheline, a range of memory and an entire +* cache. +* +* @{ +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a ecm  01/29/10 First release
+* 3.04a sdm  01/02/12 Remove redundant dsb/dmb instructions in cache maintenance
+*		      APIs.
+* 6.8   aru  09/06/18 Removed compilation warnings for ARMCC toolchain.
+* 
+* +******************************************************************************/ +#ifndef XIL_CACHE_H +#define XIL_CACHE_H + +#include "xil_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __GNUC__ + +#define asm_cp15_inval_dc_line_mva_poc(param) __asm__ __volatile__("mcr " \ + XREG_CP15_INVAL_DC_LINE_MVA_POC :: "r" (param)); + +#define asm_cp15_clean_inval_dc_line_mva_poc(param) __asm__ __volatile__("mcr " \ + XREG_CP15_CLEAN_INVAL_DC_LINE_MVA_POC :: "r" (param)); + +#define asm_cp15_inval_ic_line_mva_pou(param) __asm__ __volatile__("mcr " \ + XREG_CP15_INVAL_IC_LINE_MVA_POU :: "r" (param)); + +#define asm_cp15_inval_dc_line_sw(param) __asm__ __volatile__("mcr " \ + XREG_CP15_INVAL_DC_LINE_SW :: "r" (param)); + +#define asm_cp15_clean_inval_dc_line_sw(param) __asm__ __volatile__("mcr " \ + XREG_CP15_CLEAN_INVAL_DC_LINE_SW :: "r" (param)); + +#elif defined (__ICCARM__) + +#define asm_cp15_inval_dc_line_mva_poc(param) __asm volatile ("mcr " \ + XREG_CP15_INVAL_DC_LINE_MVA_POC :: "r" (param)); + +#define asm_cp15_clean_inval_dc_line_mva_poc(param) __asm volatile ("mcr " \ + XREG_CP15_CLEAN_INVAL_DC_LINE_MVA_POC :: "r" (param)); + +#define asm_cp15_inval_ic_line_mva_pou(param) __asm volatile ("mcr " \ + XREG_CP15_INVAL_IC_LINE_MVA_POU :: "r" (param)); + +#define asm_cp15_inval_dc_line_sw(param) __asm volatile ("mcr " \ + XREG_CP15_INVAL_DC_LINE_SW :: "r" (param)); + +#define asm_cp15_clean_inval_dc_line_sw(param) __asm volatile ("mcr " \ + XREG_CP15_CLEAN_INVAL_DC_LINE_SW :: "r" (param)); + +#endif + +void Xil_DCacheEnable(void); +void Xil_DCacheDisable(void); +void Xil_DCacheInvalidate(void); +void Xil_DCacheInvalidateRange(INTPTR adr, u32 len); +void Xil_DCacheFlush(void); +void Xil_DCacheFlushRange(INTPTR adr, u32 len); + +void Xil_ICacheEnable(void); +void Xil_ICacheDisable(void); +void Xil_ICacheInvalidate(void); +void Xil_ICacheInvalidateRange(INTPTR adr, u32 len); + +#ifdef __cplusplus +} +#endif + +#endif +/** +* @} End of "addtogroup a9_cache_apis". +*/ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_cache_l.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_cache_l.h new file mode 100644 index 0000000..b6ff809 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_cache_l.h @@ -0,0 +1,97 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xil_cache_l.h +* +* Contains L1 and L2 specific functions for the ARM cache functionality +* used by xcache.c. This functionality is being made available here for +* more sophisticated users. +* +* @addtogroup a9_cache_apis +* @{ +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a ecm  01/24/10 First release
+* 6.8   aru  09/06/18 Removed compilation warnings for ARMCC toolchain.
+* 
+* +******************************************************************************/ +#ifndef XIL_CACHE_MACH_H +#define XIL_CACHE_MACH_H + +#include "xil_types.h" +#ifdef __cplusplus +extern "C" { +#endif + +/************************** Function Prototypes ******************************/ + +void Xil_DCacheInvalidateLine(u32 adr); +void Xil_DCacheFlushLine(u32 adr); +void Xil_DCacheStoreLine(u32 adr); +void Xil_ICacheInvalidateLine(u32 adr); + +void Xil_L1DCacheEnable(void); +void Xil_L1DCacheDisable(void); +void Xil_L1DCacheInvalidate(void); +void Xil_L1DCacheInvalidateLine(u32 adr); +void Xil_L1DCacheInvalidateRange(u32 adr, u32 len); +void Xil_L1DCacheFlush(void); +void Xil_L1DCacheFlushLine(u32 adr); +void Xil_L1DCacheFlushRange(u32 adr, u32 len); +void Xil_L1DCacheStoreLine(u32 adr); + +void Xil_L1ICacheEnable(void); +void Xil_L1ICacheDisable(void); +void Xil_L1ICacheInvalidate(void); +void Xil_L1ICacheInvalidateLine(u32 adr); +void Xil_L1ICacheInvalidateRange(u32 adr, u32 len); + +void Xil_L2CacheEnable(void); +void Xil_L2CacheDisable(void); +void Xil_L2CacheInvalidate(void); +void Xil_L2CacheInvalidateLine(u32 adr); +void Xil_L2CacheInvalidateRange(u32 adr, u32 len); +void Xil_L2CacheFlush(void); +void Xil_L2CacheFlushLine(u32 adr); +void Xil_L2CacheFlushRange(u32 adr, u32 len); +void Xil_L2CacheStoreLine(u32 adr); + +#ifdef __cplusplus +} +#endif + +#endif +/** +* @} End of "addtogroup a9_cache_apis". +*/ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_cache_vxworks.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_cache_vxworks.h new file mode 100644 index 0000000..7e2a7d9 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_cache_vxworks.h @@ -0,0 +1,89 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xil_cache_vxworks.h +* +* Contains the cache related functions for VxWorks that is wrapped by +* xil_cache. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date	 Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a hbm  12/11/09 Initial release
+*
+* 
+* +* @note +* +******************************************************************************/ + +#ifndef XIL_CACHE_VXWORKS_H +#define XIL_CACHE_VXWORKS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "vxWorks.h" +#include "vxLib.h" +#include "sysLibExtra.h" +#include "cacheLib.h" + +#if (CPU_FAMILY==PPC) + +#define Xil_DCacheEnable() cacheEnable(DATA_CACHE) + +#define Xil_DCacheDisable() cacheDisable(DATA_CACHE) + +#define Xil_DCacheInvalidateRange(Addr, Len) \ + cacheInvalidate(DATA_CACHE, (void *)(Addr), (Len)) + +#define Xil_DCacheFlushRange(Addr, Len) \ + cacheFlush(DATA_CACHE, (void *)(Addr), (Len)) + +#define Xil_ICacheEnable() cacheEnable(INSTRUCTION_CACHE) + +#define Xil_ICacheDisable() cacheDisable(INSTRUCTION_CACHE) + +#define Xil_ICacheInvalidateRange(Addr, Len) \ + cacheInvalidate(INSTRUCTION_CACHE, (void *)(Addr), (Len)) + + +#else +#error "Unknown processor / architecture. Must be PPC for VxWorks." +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_errata.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_errata.h new file mode 100644 index 0000000..c839b63 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_errata.h @@ -0,0 +1,127 @@ +/****************************************************************************** +* +* Copyright (C) 2013 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xil_errata.h +* +* @addtogroup a9_errata Cortex A9 Processor and pl310 Errata Support +* @{ +* Various ARM errata are handled in the standalone BSP. The implementation for +* errata handling follows ARM guidelines and is based on the open source Linux +* support for these errata. +* +* @note +* The errata handling is enabled by default. To disable handling of all the +* errata globally, un-define the macro ENABLE_ARM_ERRATA in xil_errata.h. To +* disable errata on a per-erratum basis, un-define relevant macros in +* xil_errata.h. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a srt  04/18/13 First release
+* 6.6   mus  12/07/17 Removed errata 753970, It fixes CR#989132.
+* 
+* +******************************************************************************/ +#ifndef XIL_ERRATA_H +#define XIL_ERRATA_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @name errata_definitions + * + * The errata conditions handled in the standalone BSP are listed below + * @{ + */ + +#define ENABLE_ARM_ERRATA 1 + +#ifdef ENABLE_ARM_ERRATA + +/** + * Errata No: 742230 + * Description: DMB operation may be faulty + */ +#define CONFIG_ARM_ERRATA_742230 1 + +/** + * Errata No: 743622 + * Description: Faulty hazard checking in the Store Buffer may lead + * to data corruption. + */ +#define CONFIG_ARM_ERRATA_743622 1 + +/** + * Errata No: 775420 + * Description: A data cache maintenance operation which aborts, + * might lead to deadlock + */ +#define CONFIG_ARM_ERRATA_775420 1 + +/** + * Errata No: 794073 + * Description: Speculative instruction fetches with MMU disabled + * might not comply with architectural requirements + */ +#define CONFIG_ARM_ERRATA_794073 1 + + +/** PL310 L2 Cache Errata */ + +/** + * Errata No: 588369 + * Description: Clean & Invalidate maintenance operations do not + * invalidate clean lines + */ +#define CONFIG_PL310_ERRATA_588369 1 + +/** + * Errata No: 727915 + * Description: Background Clean and Invalidate by Way operation + * can cause data corruption + */ +#define CONFIG_PL310_ERRATA_727915 1 + +/*@}*/ +#endif /* ENABLE_ARM_ERRATA */ + +#ifdef __cplusplus +} +#endif + +#endif /* XIL_ERRATA_H */ +/** +* @} End of "addtogroup a9_errata". +*/ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_exception.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_exception.c new file mode 100644 index 0000000..16facac --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_exception.c @@ -0,0 +1,379 @@ +/****************************************************************************** +* +* Copyright (C) 2015 - 2019 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xil_exception.c +* +* This file contains low-level driver functions for the Cortex A53,A9,R5 exception +* Handler. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who      Date     Changes
+* ----- -------- -------- -----------------------------------------------
+* 5.2	pkp  	 28/05/15 First release
+* 6.0   mus      27/07/16 Consolidated exceptions for a53,a9 and r5
+*                         processors and added Xil_UndefinedExceptionHandler
+*                         for a53 32 bit and r5 as well.
+* 6.4   mus      08/06/17 Updated debug prints to replace %x with the %lx, to
+*                         fix the warnings.
+* 6.7   mna      26/04/18 Add an API to obtain a corresponding
+*                         Xil_ExceptionHandler entry from XExc_VectorTable.
+* 6.7  asa       18/05/18 Fix bugs in the API Xil_GetExceptionRegisterHandler.
+* 7.0  mus       07/03/19 Tweak Xil_ExceptionRegisterHandler and
+*                         Xil_GetExceptionRegisterHandler to support legacy
+*                         examples for Cortexa72 EL3 exception level.
+*
+* 
+* +*****************************************************************************/ + +/***************************** Include Files ********************************/ + +#include "xil_types.h" +#include "xil_assert.h" +#include "xil_exception.h" +#include "xpseudo_asm.h" +#include "xdebug.h" +/************************** Constant Definitions ****************************/ + +/**************************** Type Definitions ******************************/ + +typedef struct { + Xil_ExceptionHandler Handler; + void *Data; +} XExc_VectorTableEntry; + +/***************** Macros (Inline Functions) Definitions ********************/ + +/************************** Function Prototypes *****************************/ +static void Xil_ExceptionNullHandler(void *Data); +/************************** Variable Definitions *****************************/ +/* + * Exception vector table to store handlers for each exception vector. + */ +#if defined (__aarch64__) +XExc_VectorTableEntry XExc_VectorTable[XIL_EXCEPTION_ID_LAST + 1] = +{ + {Xil_ExceptionNullHandler, NULL}, + {Xil_SyncAbortHandler, NULL}, + {Xil_ExceptionNullHandler, NULL}, + {Xil_ExceptionNullHandler, NULL}, + {Xil_SErrorAbortHandler, NULL}, + +}; +#else +XExc_VectorTableEntry XExc_VectorTable[XIL_EXCEPTION_ID_LAST + 1] = +{ + {Xil_ExceptionNullHandler, NULL}, + {Xil_UndefinedExceptionHandler, NULL}, + {Xil_ExceptionNullHandler, NULL}, + {Xil_PrefetchAbortHandler, NULL}, + {Xil_DataAbortHandler, NULL}, + {Xil_ExceptionNullHandler, NULL}, + {Xil_ExceptionNullHandler, NULL}, +}; +#endif +#if !defined (__aarch64__) +u32 DataAbortAddr; /* Address of instruction causing data abort */ +u32 PrefetchAbortAddr; /* Address of instruction causing prefetch abort */ +u32 UndefinedExceptionAddr; /* Address of instruction causing Undefined + exception */ +#endif + +/*****************************************************************************/ + +/****************************************************************************/ +/** +* +* This function is a stub Handler that is the default Handler that gets called +* if the application has not setup a Handler for a specific exception. The +* function interface has to match the interface specified for a Handler even +* though none of the arguments are used. +* +* @param Data is unused by this function. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +static void Xil_ExceptionNullHandler(void *Data) +{ + (void) Data; +DieLoop: goto DieLoop; +} + +/****************************************************************************/ +/** +* @brief The function is a common API used to initialize exception handlers +* across all supported arm processors. For ARM Cortex-A53, Cortex-R5, +* and Cortex-A9, the exception handlers are being initialized +* statically and this function does not do anything. +* However, it is still present to take care of backward compatibility +* issues (in earlier versions of BSPs, this API was being used to +* initialize exception handlers). +* +* @param None. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void Xil_ExceptionInit(void) +{ + return; +} + +/*****************************************************************************/ +/** +* @brief Register a handler for a specific exception. This handler is being +* called when the processor encounters the specified exception. +* +* @param exception_id contains the ID of the exception source and should +* be in the range of 0 to XIL_EXCEPTION_ID_LAST. +* See xil_exception.h for further information. +* @param Handler to the Handler for that exception. +* @param Data is a reference to Data that will be passed to the +* Handler when it gets called. +* +* @return None. +* +* @note None. +* +****************************************************************************/ +void Xil_ExceptionRegisterHandler(u32 Exception_id, + Xil_ExceptionHandler Handler, + void *Data) +{ +#if defined (versal) && !defined(ARMR5) && EL3 +/* + * Cortexa72 processor in versal is coupled with GIC-500, and GIC-500 supports + * only FIQ at EL3. Hence, tweaking this API to always act on FIQ, + * ignoring argument passed by user. + */ + Exception_id = XIL_EXCEPTION_ID_FIQ_INT; +#endif + XExc_VectorTable[Exception_id].Handler = Handler; + XExc_VectorTable[Exception_id].Data = Data; +} + +/*****************************************************************************/ +/** +* @brief Get a handler for a specific exception. This handler is being +* called when the processor encounters the specified exception. +* +* @param exception_id contains the ID of the exception source and should +* be in the range of 0 to XIL_EXCEPTION_ID_LAST. +* See xil_exception.h for further information. +* @param Handler to the Handler for that exception. +* @param Data is a reference to Data that will be passed to the +* Handler when it gets called. +* +* @return None. +* +* @note None. +* +****************************************************************************/ +void Xil_GetExceptionRegisterHandler(u32 Exception_id, + Xil_ExceptionHandler *Handler, + void **Data) +{ +#if defined (versal) && !defined(ARMR5) && EL3 +/* + * Cortexa72 processor in versal is coupled with GIC-500, and GIC-500 supports + * only FIQ at EL3. Hence, tweaking this API to always act on FIQ, + * ignoring argument passed by user. + */ + Exception_id = XIL_EXCEPTION_ID_FIQ_INT; +#endif + + *Handler = XExc_VectorTable[Exception_id].Handler; + *Data = XExc_VectorTable[Exception_id].Data; +} + +/*****************************************************************************/ +/** +* +* @brief Removes the Handler for a specific exception Id. The stub Handler +* is then registered for this exception Id. +* +* @param exception_id contains the ID of the exception source and should +* be in the range of 0 to XIL_EXCEPTION_ID_LAST. +* See xil_exception.h for further information. +* +* @return None. +* +* @note None. +* +****************************************************************************/ +void Xil_ExceptionRemoveHandler(u32 Exception_id) +{ + Xil_ExceptionRegisterHandler(Exception_id, + Xil_ExceptionNullHandler, + NULL); +} + +#if defined (__aarch64__) +/*****************************************************************************/ +/** +* +* Default Synchronous abort handler which prints a debug message on console if +* Debug flag is enabled +* +* @param None +* +* @return None. +* +* @note None. +* +****************************************************************************/ + +void Xil_SyncAbortHandler(void *CallBackRef){ + (void) CallBackRef; + xdbg_printf(XDBG_DEBUG_ERROR, "Synchronous abort \n"); + while(1) { + ; + } +} + +/*****************************************************************************/ +/** +* +* Default SError abort handler which prints a debug message on console if +* Debug flag is enabled +* +* @param None +* +* @return None. +* +* @note None. +* +****************************************************************************/ +void Xil_SErrorAbortHandler(void *CallBackRef){ + (void) CallBackRef; + xdbg_printf(XDBG_DEBUG_ERROR, "Synchronous abort \n"); + while(1) { + ; + } +} +#else +/*****************************************************************************/ +/* +* +* Default Data abort handler which prints data fault status register through +* which information about data fault can be acquired +* +* @param None +* +* @return None. +* +* @note None. +* +****************************************************************************/ + +void Xil_DataAbortHandler(void *CallBackRef){ + (void) CallBackRef; +#ifdef DEBUG + u32 FaultStatus; + + xdbg_printf(XDBG_DEBUG_ERROR, "Data abort \n"); + #ifdef __GNUC__ + FaultStatus = mfcp(XREG_CP15_DATA_FAULT_STATUS); + #elif defined (__ICCARM__) + mfcp(XREG_CP15_DATA_FAULT_STATUS,FaultStatus); + #else + { volatile register u32 Reg __asm(XREG_CP15_DATA_FAULT_STATUS); + FaultStatus = Reg; } + #endif + xdbg_printf(XDBG_DEBUG_GENERAL, "Data abort with Data Fault Status Register %lx\n",FaultStatus); + xdbg_printf(XDBG_DEBUG_GENERAL, "Address of Instruction causing Data abort %lx\n",DataAbortAddr); +#endif + while(1) { + ; + } +} + +/*****************************************************************************/ +/* +* +* Default Prefetch abort handler which prints prefetch fault status register through +* which information about instruction prefetch fault can be acquired +* +* @param None +* +* @return None. +* +* @note None. +* +****************************************************************************/ +void Xil_PrefetchAbortHandler(void *CallBackRef){ + (void) CallBackRef; +#ifdef DEBUG + u32 FaultStatus; + + xdbg_printf(XDBG_DEBUG_ERROR, "Prefetch abort \n"); + #ifdef __GNUC__ + FaultStatus = mfcp(XREG_CP15_INST_FAULT_STATUS); + #elif defined (__ICCARM__) + mfcp(XREG_CP15_INST_FAULT_STATUS,FaultStatus); + #else + { volatile register u32 Reg __asm(XREG_CP15_INST_FAULT_STATUS); + FaultStatus = Reg; } + #endif + xdbg_printf(XDBG_DEBUG_GENERAL, "Prefetch abort with Instruction Fault Status Register %lx\n",FaultStatus); + xdbg_printf(XDBG_DEBUG_GENERAL, "Address of Instruction causing Prefetch abort %lx\n",PrefetchAbortAddr); +#endif + while(1) { + ; + } +} +/*****************************************************************************/ +/* +* +* Default undefined exception handler which prints address of the undefined +* instruction if debug prints are enabled +* +* @param None +* +* @return None. +* +* @note None. +* +****************************************************************************/ +void Xil_UndefinedExceptionHandler(void *CallBackRef){ + (void) CallBackRef; + xdbg_printf(XDBG_DEBUG_GENERAL, "Address of the undefined instruction %lx\n",UndefinedExceptionAddr); + while(1) { + ; + } +} +#endif diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_exception.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_exception.h new file mode 100644 index 0000000..807f310 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_exception.h @@ -0,0 +1,285 @@ +/****************************************************************************** +* +* Copyright (C) 2015 - 2016 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xil_exception.h +* +* This header file contains ARM Cortex A53,A9,R5 specific exception related APIs. +* For exception related functions that can be used across all Xilinx supported +* processors, please use xil_exception.h. +* +* @addtogroup arm_exception_apis ARM Processor Exception Handling +* @{ +* ARM processors specific exception related APIs for cortex A53,A9 and R5 can +* utilized for enabling/disabling IRQ, registering/removing handler for +* exceptions or initializing exception vector table with null handler. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who      Date     Changes
+* ----- -------- -------- -----------------------------------------------
+* 5.2	pkp  	 28/05/15 First release
+* 6.0   mus      27/07/16 Consolidated file for a53,a9 and r5 processors
+* 6.7   mna      26/04/18 Add API Xil_GetExceptionRegisterHandler.
+* 6.7   asa      18/05/18 Update signature of API Xil_GetExceptionRegisterHandler.
+* 7.0   mus      01/03/19 Tweak Xil_ExceptionEnableMask and
+*                         Xil_ExceptionDisableMask macros to support legacy
+*                         examples for Cortexa72 EL3 exception level.
+* 
+* +******************************************************************************/ + +#ifndef XIL_EXCEPTION_H /* prevent circular inclusions */ +#define XIL_EXCEPTION_H /* by using protection macros */ + +/***************************** Include Files ********************************/ + +#include "xil_types.h" +#include "xpseudo_asm.h" +#include "bspconfig.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/************************** Constant Definitions ****************************/ + +#define XIL_EXCEPTION_FIQ XREG_CPSR_FIQ_ENABLE +#define XIL_EXCEPTION_IRQ XREG_CPSR_IRQ_ENABLE +#define XIL_EXCEPTION_ALL (XREG_CPSR_FIQ_ENABLE | XREG_CPSR_IRQ_ENABLE) + +#define XIL_EXCEPTION_ID_FIRST 0U +#if defined (__aarch64__) +#define XIL_EXCEPTION_ID_SYNC_INT 1U +#define XIL_EXCEPTION_ID_IRQ_INT 2U +#define XIL_EXCEPTION_ID_FIQ_INT 3U +#define XIL_EXCEPTION_ID_SERROR_ABORT_INT 4U +#define XIL_EXCEPTION_ID_LAST 5U +#else +#define XIL_EXCEPTION_ID_RESET 0U +#define XIL_EXCEPTION_ID_UNDEFINED_INT 1U +#define XIL_EXCEPTION_ID_SWI_INT 2U +#define XIL_EXCEPTION_ID_PREFETCH_ABORT_INT 3U +#define XIL_EXCEPTION_ID_DATA_ABORT_INT 4U +#define XIL_EXCEPTION_ID_IRQ_INT 5U +#define XIL_EXCEPTION_ID_FIQ_INT 6U +#define XIL_EXCEPTION_ID_LAST 6U +#endif + +/* + * XIL_EXCEPTION_ID_INT is defined for all Xilinx processors. + */ +#if defined (versal) && !defined(ARMR5) && EL3 +#define XIL_EXCEPTION_ID_INT XIL_EXCEPTION_ID_FIQ_INT +#else +#define XIL_EXCEPTION_ID_INT XIL_EXCEPTION_ID_IRQ_INT +#endif + +/**************************** Type Definitions ******************************/ + +/** + * This typedef is the exception handler function. + */ +typedef void (*Xil_ExceptionHandler)(void *data); +typedef void (*Xil_InterruptHandler)(void *data); + +/***************** Macros (Inline Functions) Definitions ********************/ + +/****************************************************************************/ +/** +* @brief Enable Exceptions. +* +* @param Mask: Value for enabling the exceptions. +* +* @return None. +* +* @note If bit is 0, exception is enabled. +* C-Style signature: void Xil_ExceptionEnableMask(Mask) +* +******************************************************************************/ +#if defined (versal) && !defined(ARMR5) && EL3 +/* + * Cortexa72 processor in versal is coupled with GIC-500, and GIC-500 supports + * only FIQ at EL3. Hence, tweaking this macro to always enable FIQ + * ignoring argument passed by user. + */ +#define Xil_ExceptionEnableMask(Mask) \ + mtcpsr(mfcpsr() & ~ ((XIL_EXCEPTION_FIQ) & XIL_EXCEPTION_ALL)) +#elif defined (__GNUC__) || defined (__ICCARM__) +#define Xil_ExceptionEnableMask(Mask) \ + mtcpsr(mfcpsr() & ~ ((Mask) & XIL_EXCEPTION_ALL)) +#else +#define Xil_ExceptionEnableMask(Mask) \ + { \ + register u32 Reg __asm("cpsr"); \ + mtcpsr((Reg) & (~((Mask) & XIL_EXCEPTION_ALL))); \ + } +#endif +/****************************************************************************/ +/** +* @brief Enable the IRQ exception. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +#if defined (versal) && !defined(ARMR5) && EL3 +#define Xil_ExceptionEnable() \ + Xil_ExceptionEnableMask(XIL_EXCEPTION_FIQ) +#else +#define Xil_ExceptionEnable() \ + Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ) +#endif + +/****************************************************************************/ +/** +* @brief Disable Exceptions. +* +* @param Mask: Value for disabling the exceptions. +* +* @return None. +* +* @note If bit is 1, exception is disabled. +* C-Style signature: Xil_ExceptionDisableMask(Mask) +* +******************************************************************************/ +#if defined (versal) && !defined(ARMR5) && EL3 +/* + * Cortexa72 processor in versal is coupled with GIC-500, and GIC-500 supports + * only FIQ at EL3. Hence, tweaking this macro to always disable FIQ + * ignoring argument passed by user. + */ +#define Xil_ExceptionDisableMask(Mask) \ + mtcpsr(mfcpsr() | ((XIL_EXCEPTION_FIQ) & XIL_EXCEPTION_ALL)) +#elif defined (__GNUC__) || defined (__ICCARM__) +#define Xil_ExceptionDisableMask(Mask) \ + mtcpsr(mfcpsr() | ((Mask) & XIL_EXCEPTION_ALL)) +#else +#define Xil_ExceptionDisableMask(Mask) \ + { \ + register u32 Reg __asm("cpsr"); \ + mtcpsr((Reg) | ((Mask) & XIL_EXCEPTION_ALL)); \ + } +#endif +/****************************************************************************/ +/** +* Disable the IRQ exception. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +#define Xil_ExceptionDisable() \ + Xil_ExceptionDisableMask(XIL_EXCEPTION_IRQ) + +#if !defined (__aarch64__) && !defined (ARMA53_32) +/****************************************************************************/ +/** +* @brief Enable nested interrupts by clearing the I and F bits in CPSR. This +* API is defined for cortex-a9 and cortex-r5. +* +* @return None. +* +* @note This macro is supposed to be used from interrupt handlers. In the +* interrupt handler the interrupts are disabled by default (I and F +* are 1). To allow nesting of interrupts, this macro should be +* used. It clears the I and F bits by changing the ARM mode to +* system mode. Once these bits are cleared and provided the +* preemption of interrupt conditions are met in the GIC, nesting of +* interrupts will start happening. +* Caution: This macro must be used with caution. Before calling this +* macro, the user must ensure that the source of the current IRQ +* is appropriately cleared. Otherwise, as soon as we clear the I and +* F bits, there can be an infinite loop of interrupts with an +* eventual crash (all the stack space getting consumed). +******************************************************************************/ +#define Xil_EnableNestedInterrupts() \ + __asm__ __volatile__ ("stmfd sp!, {lr}"); \ + __asm__ __volatile__ ("mrs lr, spsr"); \ + __asm__ __volatile__ ("stmfd sp!, {lr}"); \ + __asm__ __volatile__ ("msr cpsr_c, #0x1F"); \ + __asm__ __volatile__ ("stmfd sp!, {lr}"); + +/****************************************************************************/ +/** +* @brief Disable the nested interrupts by setting the I and F bits. This API +* is defined for cortex-a9 and cortex-r5. +* +* @return None. +* +* @note This macro is meant to be called in the interrupt service routines. +* This macro cannot be used independently. It can only be used when +* nesting of interrupts have been enabled by using the macro +* Xil_EnableNestedInterrupts(). In a typical flow, the user first +* calls the Xil_EnableNestedInterrupts in the ISR at the appropriate +* point. The user then must call this macro before exiting the interrupt +* service routine. This macro puts the ARM back in IRQ/FIQ mode and +* hence sets back the I and F bits. +******************************************************************************/ +#define Xil_DisableNestedInterrupts() \ + __asm__ __volatile__ ("ldmfd sp!, {lr}"); \ + __asm__ __volatile__ ("msr cpsr_c, #0x92"); \ + __asm__ __volatile__ ("ldmfd sp!, {lr}"); \ + __asm__ __volatile__ ("msr spsr_cxsf, lr"); \ + __asm__ __volatile__ ("ldmfd sp!, {lr}"); \ + +#endif +/************************** Variable Definitions ****************************/ + +/************************** Function Prototypes *****************************/ + +extern void Xil_ExceptionRegisterHandler(u32 Exception_id, + Xil_ExceptionHandler Handler, + void *Data); + +extern void Xil_ExceptionRemoveHandler(u32 Exception_id); +extern void Xil_GetExceptionRegisterHandler(u32 Exception_id, + Xil_ExceptionHandler *Handler, void **Data); + +extern void Xil_ExceptionInit(void); +#if defined (__aarch64__) +void Xil_SyncAbortHandler(void *CallBackRef); +void Xil_SErrorAbortHandler(void *CallBackRef); +#else +extern void Xil_DataAbortHandler(void *CallBackRef); +extern void Xil_PrefetchAbortHandler(void *CallBackRef); +extern void Xil_UndefinedExceptionHandler(void *CallBackRef); +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* XIL_EXCEPTION_H */ +/** +* @} End of "addtogroup arm_exception_apis". +*/ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_hal.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_hal.h new file mode 100644 index 0000000..e8971c9 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_hal.h @@ -0,0 +1,65 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xil_hal.h +* +* Contains all the HAL header files. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date	 Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a hbm  07/28/09 Initial release
+*
+* 
+* +* @note +* +******************************************************************************/ + +#ifndef XIL_HAL_H +#define XIL_HAL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "xil_cache.h" +#include "xil_io.h" +#include "xil_assert.h" +#include "xil_exception.h" +#include "xil_types.h" + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_io.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_io.c new file mode 100644 index 0000000..6ed1559 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_io.c @@ -0,0 +1,98 @@ +/****************************************************************************** +* +* Copyright (C) 2014 - 2016 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xil_io.c +* +* Contains I/O functions for memory-mapped or non-memory-mapped I/O +* architectures. +* +* @note +* +* This file contains architecture-dependent code. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who      Date     Changes
+* ----- -------- -------- -----------------------------------------------
+* 5.00 	pkp  	 05/29/14 First release
+* 
+******************************************************************************/ + + +/***************************** Include Files *********************************/ +#include "xil_io.h" +#include "xil_types.h" +#include "xil_assert.h" + +/*****************************************************************************/ +/** +* +* @brief Perform a 16-bit endian converion. +* +* @param Data: 16 bit value to be converted +* +* @return 16 bit Data with converted endianess +* +******************************************************************************/ +u16 Xil_EndianSwap16(u16 Data) +{ + return (u16) (((Data & 0xFF00U) >> 8U) | ((Data & 0x00FFU) << 8U)); +} + +/*****************************************************************************/ +/** +* +* @brief Perform a 32-bit endian converion. +* +* @param Data: 32 bit value to be converted +* +* @return 32 bit data with converted endianess +* +******************************************************************************/ +u32 Xil_EndianSwap32(u32 Data) +{ + u16 LoWord; + u16 HiWord; + + /* get each of the half words from the 32 bit word */ + + LoWord = (u16) (Data & 0x0000FFFFU); + HiWord = (u16) ((Data & 0xFFFF0000U) >> 16U); + + /* byte swap each of the 16 bit half words */ + + LoWord = (((LoWord & 0xFF00U) >> 8U) | ((LoWord & 0x00FFU) << 8U)); + HiWord = (((HiWord & 0xFF00U) >> 8U) | ((HiWord & 0x00FFU) << 8U)); + + /* swap the half words before returning the value */ + + return ((((u32)LoWord) << (u32)16U) | (u32)HiWord); +} diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_io.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_io.h new file mode 100644 index 0000000..00207cf --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_io.h @@ -0,0 +1,341 @@ +/****************************************************************************** +* +* Copyright (C) 2014 - 2016 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xil_io.h +* +* @addtogroup common_io_interfacing_apis Register IO interfacing APIs +* +* The xil_io.h file contains the interface for the general I/O component, which +* encapsulates the Input/Output functions for the processors that do not +* require any special I/O handling. +* +* @{ +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who      Date     Changes
+* ----- -------- -------- -----------------------------------------------
+* 5.00 	pkp  	 05/29/14 First release
+* 6.00  mus      08/19/16 Remove checking of __LITTLE_ENDIAN__ flag for
+*                         ARM processors
+* 
+******************************************************************************/ + +#ifndef XIL_IO_H /* prevent circular inclusions */ +#define XIL_IO_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +#include "xil_types.h" +#include "xil_printf.h" + +#if defined (__MICROBLAZE__) +#include "mb_interface.h" +#else +#include "xpseudo_asm.h" +#endif + +/************************** Function Prototypes ******************************/ +u16 Xil_EndianSwap16(u16 Data); +u32 Xil_EndianSwap32(u32 Data); +#ifdef ENABLE_SAFETY +extern u32 XStl_RegUpdate(u32 RegAddr, u32 RegVal); +#endif + +/***************** Macros (Inline Functions) Definitions *********************/ +#if defined __GNUC__ +#if defined (__MICROBLAZE__) +# define INST_SYNC mbar(0) +# define DATA_SYNC mbar(1) +# else +# define SYNCHRONIZE_IO dmb() +# define INST_SYNC isb() +# define DATA_SYNC dsb() +# endif +#else +# define SYNCHRONIZE_IO +# define INST_SYNC +# define DATA_SYNC +# define INST_SYNC +# define DATA_SYNC +#endif + +#if defined (__GNUC__) || defined (__ICCARM__) || defined (__MICROBLAZE__) +#define INLINE inline +#else +#define INLINE __inline +#endif + +/*****************************************************************************/ +/** +* +* @brief Performs an input operation for a memory location by reading +* from the specified address and returning the 8 bit Value read from +* that address. +* +* @param Addr: contains the address to perform the input operation +* +* @return The 8 bit Value read from the specified input address. + +* +******************************************************************************/ +static INLINE u8 Xil_In8(UINTPTR Addr) +{ + return *(volatile u8 *) Addr; +} + +/*****************************************************************************/ +/** +* +* @brief Performs an input operation for a memory location by reading from +* the specified address and returning the 16 bit Value read from that +* address. +* +* @param Addr: contains the address to perform the input operation +* +* @return The 16 bit Value read from the specified input address. +* +******************************************************************************/ +static INLINE u16 Xil_In16(UINTPTR Addr) +{ + return *(volatile u16 *) Addr; +} + +/*****************************************************************************/ +/** +* +* @brief Performs an input operation for a memory location by +* reading from the specified address and returning the 32 bit Value +* read from that address. +* +* @param Addr: contains the address to perform the input operation +* +* @return The 32 bit Value read from the specified input address. +* +******************************************************************************/ +static INLINE u32 Xil_In32(UINTPTR Addr) +{ + return *(volatile u32 *) Addr; +} + +/*****************************************************************************/ +/** +* +* @brief Performs an input operation for a memory location by reading the +* 64 bit Value read from that address. +* +* +* @param Addr: contains the address to perform the input operation +* +* @return The 64 bit Value read from the specified input address. +* +******************************************************************************/ +static INLINE u64 Xil_In64(UINTPTR Addr) +{ + return *(volatile u64 *) Addr; +} + +/*****************************************************************************/ +/** +* +* @brief Performs an output operation for an memory location by +* writing the 8 bit Value to the the specified address. +* +* @param Addr: contains the address to perform the output operation +* @param Value: contains the 8 bit Value to be written at the specified +* address. +* +* @return None. +* +******************************************************************************/ +static INLINE void Xil_Out8(UINTPTR Addr, u8 Value) +{ + volatile u8 *LocalAddr = (volatile u8 *)Addr; + *LocalAddr = Value; +} + +/*****************************************************************************/ +/** +* +* @brief Performs an output operation for a memory location by writing the +* 16 bit Value to the the specified address. +* +* @param Addr contains the address to perform the output operation +* @param Value contains the Value to be written at the specified address. +* +* @return None. +* +******************************************************************************/ +static INLINE void Xil_Out16(UINTPTR Addr, u16 Value) +{ + volatile u16 *LocalAddr = (volatile u16 *)Addr; + *LocalAddr = Value; +} + +/*****************************************************************************/ +/** +* +* @brief Performs an output operation for a memory location by writing the +* 32 bit Value to the the specified address. +* +* @param Addr contains the address to perform the output operation +* @param Value contains the 32 bit Value to be written at the specified +* address. +* +* @return None. +* +******************************************************************************/ +static INLINE void Xil_Out32(UINTPTR Addr, u32 Value) +{ +#ifndef ENABLE_SAFETY + volatile u32 *LocalAddr = (volatile u32 *)Addr; + *LocalAddr = Value; +#else + XStl_RegUpdate(Addr, Value); +#endif +} + +/*****************************************************************************/ +/** +* +* @brief Performs an output operation for a memory location by writing the +* 64 bit Value to the the specified address. +* +* @param Addr contains the address to perform the output operation +* @param Value contains 64 bit Value to be written at the specified address. +* +* @return None. +* +******************************************************************************/ +static INLINE void Xil_Out64(UINTPTR Addr, u64 Value) +{ + volatile u64 *LocalAddr = (volatile u64 *)Addr; + *LocalAddr = Value; +} + +#if defined (__MICROBLAZE__) +#ifdef __LITTLE_ENDIAN__ +# define Xil_In16LE Xil_In16 +# define Xil_In32LE Xil_In32 +# define Xil_Out16LE Xil_Out16 +# define Xil_Out32LE Xil_Out32 +# define Xil_Htons Xil_EndianSwap16 +# define Xil_Htonl Xil_EndianSwap32 +# define Xil_Ntohs Xil_EndianSwap16 +# define Xil_Ntohl Xil_EndianSwap32 +# else +# define Xil_In16BE Xil_In16 +# define Xil_In32BE Xil_In32 +# define Xil_Out16BE Xil_Out16 +# define Xil_Out32BE Xil_Out32 +# define Xil_Htons(Data) (Data) +# define Xil_Htonl(Data) (Data) +# define Xil_Ntohs(Data) (Data) +# define Xil_Ntohl(Data) (Data) +#endif +#else +# define Xil_In16LE Xil_In16 +# define Xil_In32LE Xil_In32 +# define Xil_Out16LE Xil_Out16 +# define Xil_Out32LE Xil_Out32 +# define Xil_Htons Xil_EndianSwap16 +# define Xil_Htonl Xil_EndianSwap32 +# define Xil_Ntohs Xil_EndianSwap16 +# define Xil_Ntohl Xil_EndianSwap32 +#endif + +#if defined (__MICROBLAZE__) +#ifdef __LITTLE_ENDIAN__ +static INLINE u16 Xil_In16BE(UINTPTR Addr) +#else +static INLINE u16 Xil_In16LE(UINTPTR Addr) +#endif +#else +static INLINE u16 Xil_In16BE(UINTPTR Addr) +#endif +{ + u16 value = Xil_In16(Addr); + return Xil_EndianSwap16(value); +} + +#if defined (__MICROBLAZE__) +#ifdef __LITTLE_ENDIAN__ +static INLINE u32 Xil_In32BE(UINTPTR Addr) +#else +static INLINE u32 Xil_In32LE(UINTPTR Addr) +#endif +#else +static INLINE u32 Xil_In32BE(UINTPTR Addr) +#endif +{ + u32 value = Xil_In32(Addr); + return Xil_EndianSwap32(value); +} + +#if defined (__MICROBLAZE__) +#ifdef __LITTLE_ENDIAN__ +static INLINE void Xil_Out16BE(UINTPTR Addr, u16 Value) +#else +static INLINE void Xil_Out16LE(UINTPTR Addr, u16 Value) +#endif +#else +static INLINE void Xil_Out16BE(UINTPTR Addr, u16 Value) +#endif +{ + Value = Xil_EndianSwap16(Value); + Xil_Out16(Addr, Value); +} + +#if defined (__MICROBLAZE__) +#ifdef __LITTLE_ENDIAN__ +static INLINE void Xil_Out32BE(UINTPTR Addr, u32 Value) +#else +static INLINE void Xil_Out32LE(UINTPTR Addr, u32 Value) +#endif +#else +static INLINE void Xil_Out32BE(UINTPTR Addr, u32 Value) +#endif +{ + Value = Xil_EndianSwap32(Value); + Xil_Out32(Addr, Value); +} + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** +* @} End of "addtogroup common_io_interfacing_apis". +*/ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_macroback.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_macroback.h new file mode 100644 index 0000000..b245c18 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_macroback.h @@ -0,0 +1,1056 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ + +/*********************************************************************/ +/** + * @file xil_macroback.h + * + * This header file is meant to bring back the removed _m macros. + * This header file must be included last. + * The following macros are not defined here due to the driver change: + * XGpio_mSetDataDirection + * XGpio_mGetDataReg + * XGpio_mSetDataReg + * XIIC_RESET + * XIIC_CLEAR_STATS + * XSpi_mReset + * XSysAce_mSetCfgAddr + * XSysAce_mIsCfgDone + * XTft_mSetPixel + * XTft_mGetPixel + * XWdtTb_mEnableWdt + * XWdtTb_mDisbleWdt + * XWdtTb_mRestartWdt + * XWdtTb_mGetTimebaseReg + * XWdtTb_mHasReset + * + * Please refer the corresonding driver document for replacement. + * + *********************************************************************/ + +#ifndef XIL_MACROBACK_H +#define XIL_MACROBACK_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*********************************************************************/ +/** + * Macros for Driver XCan + * + *********************************************************************/ +#ifndef XCan_mReadReg +#define XCan_mReadReg XCan_ReadReg +#endif + +#ifndef XCan_mWriteReg +#define XCan_mWriteReg XCan_WriteReg +#endif + +#ifndef XCan_mIsTxDone +#define XCan_mIsTxDone XCan_IsTxDone +#endif + +#ifndef XCan_mIsTxFifoFull +#define XCan_mIsTxFifoFull XCan_IsTxFifoFull +#endif + +#ifndef XCan_mIsHighPriorityBufFull +#define XCan_mIsHighPriorityBufFull XCan_IsHighPriorityBufFull +#endif + +#ifndef XCan_mIsRxEmpty +#define XCan_mIsRxEmpty XCan_IsRxEmpty +#endif + +#ifndef XCan_mIsAcceptFilterBusy +#define XCan_mIsAcceptFilterBusy XCan_IsAcceptFilterBusy +#endif + +#ifndef XCan_mCreateIdValue +#define XCan_mCreateIdValue XCan_CreateIdValue +#endif + +#ifndef XCan_mCreateDlcValue +#define XCan_mCreateDlcValue XCan_CreateDlcValue +#endif + +/*********************************************************************/ +/** + * Macros for Driver XDmaCentral + * + *********************************************************************/ +#ifndef XDmaCentral_mWriteReg +#define XDmaCentral_mWriteReg XDmaCentral_WriteReg +#endif + +#ifndef XDmaCentral_mReadReg +#define XDmaCentral_mReadReg XDmaCentral_ReadReg +#endif + +/*********************************************************************/ +/** + * Macros for Driver XDsAdc + * + *********************************************************************/ +#ifndef XDsAdc_mWriteReg +#define XDsAdc_mWriteReg XDsAdc_WriteReg +#endif + +#ifndef XDsAdc_mReadReg +#define XDsAdc_mReadReg XDsAdc_ReadReg +#endif + +#ifndef XDsAdc_mIsEmpty +#define XDsAdc_mIsEmpty XDsAdc_IsEmpty +#endif + +#ifndef XDsAdc_mSetFstmReg +#define XDsAdc_mSetFstmReg XDsAdc_SetFstmReg +#endif + +#ifndef XDsAdc_mGetFstmReg +#define XDsAdc_mGetFstmReg XDsAdc_GetFstmReg +#endif + +#ifndef XDsAdc_mEnableConversion +#define XDsAdc_mEnableConversion XDsAdc_EnableConversion +#endif + +#ifndef XDsAdc_mDisableConversion +#define XDsAdc_mDisableConversion XDsAdc_DisableConversion +#endif + +#ifndef XDsAdc_mGetFifoOccyReg +#define XDsAdc_mGetFifoOccyReg XDsAdc_GetFifoOccyReg +#endif + +/*********************************************************************/ +/** + * Macros for Driver XDsDac + * + *********************************************************************/ +#ifndef XDsDac_mWriteReg +#define XDsDac_mWriteReg XDsDac_WriteReg +#endif + +#ifndef XDsDac_mReadReg +#define XDsDac_mReadReg XDsDac_ReadReg +#endif + +#ifndef XDsDac_mIsEmpty +#define XDsDac_mIsEmpty XDsDac_IsEmpty +#endif + +#ifndef XDsDac_mFifoIsFull +#define XDsDac_mFifoIsFull XDsDac_FifoIsFull +#endif + +#ifndef XDsDac_mGetVacancy +#define XDsDac_mGetVacancy XDsDac_GetVacancy +#endif + +/*********************************************************************/ +/** + * Macros for Driver XEmacLite + * + *********************************************************************/ +#ifndef XEmacLite_mReadReg +#define XEmacLite_mReadReg XEmacLite_ReadReg +#endif + +#ifndef XEmacLite_mWriteReg +#define XEmacLite_mWriteReg XEmacLite_WriteReg +#endif + +#ifndef XEmacLite_mGetTxStatus +#define XEmacLite_mGetTxStatus XEmacLite_GetTxStatus +#endif + +#ifndef XEmacLite_mSetTxStatus +#define XEmacLite_mSetTxStatus XEmacLite_SetTxStatus +#endif + +#ifndef XEmacLite_mGetRxStatus +#define XEmacLite_mGetRxStatus XEmacLite_GetRxStatus +#endif + +#ifndef XEmacLite_mSetRxStatus +#define XEmacLite_mSetRxStatus XEmacLite_SetRxStatus +#endif + +#ifndef XEmacLite_mIsTxDone +#define XEmacLite_mIsTxDone XEmacLite_IsTxDone +#endif + +#ifndef XEmacLite_mIsRxEmpty +#define XEmacLite_mIsRxEmpty XEmacLite_IsRxEmpty +#endif + +#ifndef XEmacLite_mNextTransmitAddr +#define XEmacLite_mNextTransmitAddr XEmacLite_NextTransmitAddr +#endif + +#ifndef XEmacLite_mNextReceiveAddr +#define XEmacLite_mNextReceiveAddr XEmacLite_NextReceiveAddr +#endif + +#ifndef XEmacLite_mIsMdioConfigured +#define XEmacLite_mIsMdioConfigured XEmacLite_IsMdioConfigured +#endif + +#ifndef XEmacLite_mIsLoopbackConfigured +#define XEmacLite_mIsLoopbackConfigured XEmacLite_IsLoopbackConfigured +#endif + +#ifndef XEmacLite_mGetReceiveDataLength +#define XEmacLite_mGetReceiveDataLength XEmacLite_GetReceiveDataLength +#endif + +#ifndef XEmacLite_mGetTxActive +#define XEmacLite_mGetTxActive XEmacLite_GetTxActive +#endif + +#ifndef XEmacLite_mSetTxActive +#define XEmacLite_mSetTxActive XEmacLite_SetTxActive +#endif + +/*********************************************************************/ +/** + * Macros for Driver XGpio + * + *********************************************************************/ +#ifndef XGpio_mWriteReg +#define XGpio_mWriteReg XGpio_WriteReg +#endif + +#ifndef XGpio_mReadReg +#define XGpio_mReadReg XGpio_ReadReg +#endif + +/*********************************************************************/ +/** + * Macros for Driver XHwIcap + * + *********************************************************************/ +#ifndef XHwIcap_mFifoWrite +#define XHwIcap_mFifoWrite XHwIcap_FifoWrite +#endif + +#ifndef XHwIcap_mFifoRead +#define XHwIcap_mFifoRead XHwIcap_FifoRead +#endif + +#ifndef XHwIcap_mSetSizeReg +#define XHwIcap_mSetSizeReg XHwIcap_SetSizeReg +#endif + +#ifndef XHwIcap_mGetControlReg +#define XHwIcap_mGetControlReg XHwIcap_GetControlReg +#endif + +#ifndef XHwIcap_mStartConfig +#define XHwIcap_mStartConfig XHwIcap_StartConfig +#endif + +#ifndef XHwIcap_mStartReadBack +#define XHwIcap_mStartReadBack XHwIcap_StartReadBack +#endif + +#ifndef XHwIcap_mGetStatusReg +#define XHwIcap_mGetStatusReg XHwIcap_GetStatusReg +#endif + +#ifndef XHwIcap_mIsTransferDone +#define XHwIcap_mIsTransferDone XHwIcap_IsTransferDone +#endif + +#ifndef XHwIcap_mIsDeviceBusy +#define XHwIcap_mIsDeviceBusy XHwIcap_IsDeviceBusy +#endif + +#ifndef XHwIcap_mIntrGlobalEnable +#define XHwIcap_mIntrGlobalEnable XHwIcap_IntrGlobalEnable +#endif + +#ifndef XHwIcap_mIntrGlobalDisable +#define XHwIcap_mIntrGlobalDisable XHwIcap_IntrGlobalDisable +#endif + +#ifndef XHwIcap_mIntrGetStatus +#define XHwIcap_mIntrGetStatus XHwIcap_IntrGetStatus +#endif + +#ifndef XHwIcap_mIntrDisable +#define XHwIcap_mIntrDisable XHwIcap_IntrDisable +#endif + +#ifndef XHwIcap_mIntrEnable +#define XHwIcap_mIntrEnable XHwIcap_IntrEnable +#endif + +#ifndef XHwIcap_mIntrGetEnabled +#define XHwIcap_mIntrGetEnabled XHwIcap_IntrGetEnabled +#endif + +#ifndef XHwIcap_mIntrClear +#define XHwIcap_mIntrClear XHwIcap_IntrClear +#endif + +#ifndef XHwIcap_mGetWrFifoVacancy +#define XHwIcap_mGetWrFifoVacancy XHwIcap_GetWrFifoVacancy +#endif + +#ifndef XHwIcap_mGetRdFifoOccupancy +#define XHwIcap_mGetRdFifoOccupancy XHwIcap_GetRdFifoOccupancy +#endif + +#ifndef XHwIcap_mSliceX2Col +#define XHwIcap_mSliceX2Col XHwIcap_SliceX2Col +#endif + +#ifndef XHwIcap_mSliceY2Row +#define XHwIcap_mSliceY2Row XHwIcap_SliceY2Row +#endif + +#ifndef XHwIcap_mSliceXY2Slice +#define XHwIcap_mSliceXY2Slice XHwIcap_SliceXY2Slice +#endif + +#ifndef XHwIcap_mReadReg +#define XHwIcap_mReadReg XHwIcap_ReadReg +#endif + +#ifndef XHwIcap_mWriteReg +#define XHwIcap_mWriteReg XHwIcap_WriteReg +#endif + +/*********************************************************************/ +/** + * Macros for Driver XIic + * + *********************************************************************/ +#ifndef XIic_mReadReg +#define XIic_mReadReg XIic_ReadReg +#endif + +#ifndef XIic_mWriteReg +#define XIic_mWriteReg XIic_WriteReg +#endif + +#ifndef XIic_mEnterCriticalRegion +#define XIic_mEnterCriticalRegion XIic_IntrGlobalDisable +#endif + +#ifndef XIic_mExitCriticalRegion +#define XIic_mExitCriticalRegion XIic_IntrGlobalEnable +#endif + +#ifndef XIIC_GINTR_DISABLE +#define XIIC_GINTR_DISABLE XIic_IntrGlobalDisable +#endif + +#ifndef XIIC_GINTR_ENABLE +#define XIIC_GINTR_ENABLE XIic_IntrGlobalEnable +#endif + +#ifndef XIIC_IS_GINTR_ENABLED +#define XIIC_IS_GINTR_ENABLED XIic_IsIntrGlobalEnabled +#endif + +#ifndef XIIC_WRITE_IISR +#define XIIC_WRITE_IISR XIic_WriteIisr +#endif + +#ifndef XIIC_READ_IISR +#define XIIC_READ_IISR XIic_ReadIisr +#endif + +#ifndef XIIC_WRITE_IIER +#define XIIC_WRITE_IIER XIic_WriteIier +#endif + +#ifndef XIic_mClearIisr +#define XIic_mClearIisr XIic_ClearIisr +#endif + +#ifndef XIic_mSend7BitAddress +#define XIic_mSend7BitAddress XIic_Send7BitAddress +#endif + +#ifndef XIic_mDynSend7BitAddress +#define XIic_mDynSend7BitAddress XIic_DynSend7BitAddress +#endif + +#ifndef XIic_mDynSendStartStopAddress +#define XIic_mDynSendStartStopAddress XIic_DynSendStartStopAddress +#endif + +#ifndef XIic_mDynSendStop +#define XIic_mDynSendStop XIic_DynSendStop +#endif + +#ifndef XIic_mSend10BitAddrByte1 +#define XIic_mSend10BitAddrByte1 XIic_Send10BitAddrByte1 +#endif + +#ifndef XIic_mSend10BitAddrByte2 +#define XIic_mSend10BitAddrByte2 XIic_Send10BitAddrByte2 +#endif + +#ifndef XIic_mSend7BitAddr +#define XIic_mSend7BitAddr XIic_Send7BitAddr +#endif + +#ifndef XIic_mDisableIntr +#define XIic_mDisableIntr XIic_DisableIntr +#endif + +#ifndef XIic_mEnableIntr +#define XIic_mEnableIntr XIic_EnableIntr +#endif + +#ifndef XIic_mClearIntr +#define XIic_mClearIntr XIic_ClearIntr +#endif + +#ifndef XIic_mClearEnableIntr +#define XIic_mClearEnableIntr XIic_ClearEnableIntr +#endif + +#ifndef XIic_mFlushRxFifo +#define XIic_mFlushRxFifo XIic_FlushRxFifo +#endif + +#ifndef XIic_mFlushTxFifo +#define XIic_mFlushTxFifo XIic_FlushTxFifo +#endif + +#ifndef XIic_mReadRecvByte +#define XIic_mReadRecvByte XIic_ReadRecvByte +#endif + +#ifndef XIic_mWriteSendByte +#define XIic_mWriteSendByte XIic_WriteSendByte +#endif + +#ifndef XIic_mSetControlRegister +#define XIic_mSetControlRegister XIic_SetControlRegister +#endif + +/*********************************************************************/ +/** + * Macros for Driver XIntc + * + *********************************************************************/ +#ifndef XIntc_mMasterEnable +#define XIntc_mMasterEnable XIntc_MasterEnable +#endif + +#ifndef XIntc_mMasterDisable +#define XIntc_mMasterDisable XIntc_MasterDisable +#endif + +#ifndef XIntc_mEnableIntr +#define XIntc_mEnableIntr XIntc_EnableIntr +#endif + +#ifndef XIntc_mDisableIntr +#define XIntc_mDisableIntr XIntc_DisableIntr +#endif + +#ifndef XIntc_mAckIntr +#define XIntc_mAckIntr XIntc_AckIntr +#endif + +#ifndef XIntc_mGetIntrStatus +#define XIntc_mGetIntrStatus XIntc_GetIntrStatus +#endif + +/*********************************************************************/ +/** + * Macros for Driver XLlDma + * + *********************************************************************/ +#ifndef XLlDma_mBdRead +#define XLlDma_mBdRead XLlDma_BdRead +#endif + +#ifndef XLlDma_mBdWrite +#define XLlDma_mBdWrite XLlDma_BdWrite +#endif + +#ifndef XLlDma_mWriteReg +#define XLlDma_mWriteReg XLlDma_WriteReg +#endif + +#ifndef XLlDma_mReadReg +#define XLlDma_mReadReg XLlDma_ReadReg +#endif + +#ifndef XLlDma_mBdClear +#define XLlDma_mBdClear XLlDma_BdClear +#endif + +#ifndef XLlDma_mBdSetStsCtrl +#define XLlDma_mBdSetStsCtrl XLlDma_BdSetStsCtrl +#endif + +#ifndef XLlDma_mBdGetStsCtrl +#define XLlDma_mBdGetStsCtrl XLlDma_BdGetStsCtrl +#endif + +#ifndef XLlDma_mBdSetLength +#define XLlDma_mBdSetLength XLlDma_BdSetLength +#endif + +#ifndef XLlDma_mBdGetLength +#define XLlDma_mBdGetLength XLlDma_BdGetLength +#endif + +#ifndef XLlDma_mBdSetId +#define XLlDma_mBdSetId XLlDma_BdSetId +#endif + +#ifndef XLlDma_mBdGetId +#define XLlDma_mBdGetId XLlDma_BdGetId +#endif + +#ifndef XLlDma_mBdSetBufAddr +#define XLlDma_mBdSetBufAddr XLlDma_BdSetBufAddr +#endif + +#ifndef XLlDma_mBdGetBufAddr +#define XLlDma_mBdGetBufAddr XLlDma_BdGetBufAddr +#endif + +#ifndef XLlDma_mBdGetLength +#define XLlDma_mBdGetLength XLlDma_BdGetLength +#endif + +#ifndef XLlDma_mGetTxRing +#define XLlDma_mGetTxRing XLlDma_GetTxRing +#endif + +#ifndef XLlDma_mGetRxRing +#define XLlDma_mGetRxRing XLlDma_GetRxRing +#endif + +#ifndef XLlDma_mGetCr +#define XLlDma_mGetCr XLlDma_GetCr +#endif + +#ifndef XLlDma_mSetCr +#define XLlDma_mSetCr XLlDma_SetCr +#endif + +#ifndef XLlDma_mBdRingCntCalc +#define XLlDma_mBdRingCntCalc XLlDma_BdRingCntCalc +#endif + +#ifndef XLlDma_mBdRingMemCalc +#define XLlDma_mBdRingMemCalc XLlDma_BdRingMemCalc +#endif + +#ifndef XLlDma_mBdRingGetCnt +#define XLlDma_mBdRingGetCnt XLlDma_BdRingGetCnt +#endif + +#ifndef XLlDma_mBdRingGetFreeCnt +#define XLlDma_mBdRingGetFreeCnt XLlDma_BdRingGetFreeCnt +#endif + +#ifndef XLlDma_mBdRingSnapShotCurrBd +#define XLlDma_mBdRingSnapShotCurrBd XLlDma_BdRingSnapShotCurrBd +#endif + +#ifndef XLlDma_mBdRingNext +#define XLlDma_mBdRingNext XLlDma_BdRingNext +#endif + +#ifndef XLlDma_mBdRingPrev +#define XLlDma_mBdRingPrev XLlDma_BdRingPrev +#endif + +#ifndef XLlDma_mBdRingGetSr +#define XLlDma_mBdRingGetSr XLlDma_BdRingGetSr +#endif + +#ifndef XLlDma_mBdRingSetSr +#define XLlDma_mBdRingSetSr XLlDma_BdRingSetSr +#endif + +#ifndef XLlDma_mBdRingGetCr +#define XLlDma_mBdRingGetCr XLlDma_BdRingGetCr +#endif + +#ifndef XLlDma_mBdRingSetCr +#define XLlDma_mBdRingSetCr XLlDma_BdRingSetCr +#endif + +#ifndef XLlDma_mBdRingBusy +#define XLlDma_mBdRingBusy XLlDma_BdRingBusy +#endif + +#ifndef XLlDma_mBdRingIntEnable +#define XLlDma_mBdRingIntEnable XLlDma_BdRingIntEnable +#endif + +#ifndef XLlDma_mBdRingIntDisable +#define XLlDma_mBdRingIntDisable XLlDma_BdRingIntDisable +#endif + +#ifndef XLlDma_mBdRingIntGetEnabled +#define XLlDma_mBdRingIntGetEnabled XLlDma_BdRingIntGetEnabled +#endif + +#ifndef XLlDma_mBdRingGetIrq +#define XLlDma_mBdRingGetIrq XLlDma_BdRingGetIrq +#endif + +#ifndef XLlDma_mBdRingAckIrq +#define XLlDma_mBdRingAckIrq XLlDma_BdRingAckIrq +#endif + +/*********************************************************************/ +/** + * Macros for Driver XMbox + * + *********************************************************************/ +#ifndef XMbox_mWriteReg +#define XMbox_mWriteReg XMbox_WriteReg +#endif + +#ifndef XMbox_mReadReg +#define XMbox_mReadReg XMbox_ReadReg +#endif + +#ifndef XMbox_mWriteMBox +#define XMbox_mWriteMBox XMbox_WriteMBox +#endif + +#ifndef XMbox_mReadMBox +#define XMbox_mReadMBox XMbox_ReadMBox +#endif + +#ifndef XMbox_mFSLReadMBox +#define XMbox_mFSLReadMBox XMbox_FSLReadMBox +#endif + +#ifndef XMbox_mFSLWriteMBox +#define XMbox_mFSLWriteMBox XMbox_FSLWriteMBox +#endif + +#ifndef XMbox_mFSLIsEmpty +#define XMbox_mFSLIsEmpty XMbox_FSLIsEmpty +#endif + +#ifndef XMbox_mFSLIsFull +#define XMbox_mFSLIsFull XMbox_FSLIsFull +#endif + +#ifndef XMbox_mIsEmpty +#define XMbox_mIsEmpty XMbox_IsEmptyHw +#endif + +#ifndef XMbox_mIsFull +#define XMbox_mIsFull XMbox_IsFullHw +#endif + +/*********************************************************************/ +/** + * Macros for Driver XMpmc + * + *********************************************************************/ +#ifndef XMpmc_mReadReg +#define XMpmc_mReadReg XMpmc_ReadReg +#endif + +#ifndef XMpmc_mWriteReg +#define XMpmc_mWriteReg XMpmc_WriteReg +#endif + +/*********************************************************************/ +/** + * Macros for Driver XMutex + * + *********************************************************************/ +#ifndef XMutex_mWriteReg +#define XMutex_mWriteReg XMutex_WriteReg +#endif + +#ifndef XMutex_mReadReg +#define XMutex_mReadReg XMutex_ReadReg +#endif + +/*********************************************************************/ +/** + * Macros for Driver XPcie + * + *********************************************************************/ +#ifndef XPcie_mReadReg +#define XPcie_mReadReg XPcie_ReadReg +#endif + +#ifndef XPcie_mWriteReg +#define XPcie_mWriteReg XPcie_WriteReg +#endif + +/*********************************************************************/ +/** + * Macros for Driver XSpi + * + *********************************************************************/ +#ifndef XSpi_mIntrGlobalEnable +#define XSpi_mIntrGlobalEnable XSpi_IntrGlobalEnable +#endif + +#ifndef XSpi_mIntrGlobalDisable +#define XSpi_mIntrGlobalDisable XSpi_IntrGlobalDisable +#endif + +#ifndef XSpi_mIsIntrGlobalEnabled +#define XSpi_mIsIntrGlobalEnabled XSpi_IsIntrGlobalEnabled +#endif + +#ifndef XSpi_mIntrGetStatus +#define XSpi_mIntrGetStatus XSpi_IntrGetStatus +#endif + +#ifndef XSpi_mIntrClear +#define XSpi_mIntrClear XSpi_IntrClear +#endif + +#ifndef XSpi_mIntrEnable +#define XSpi_mIntrEnable XSpi_IntrEnable +#endif + +#ifndef XSpi_mIntrDisable +#define XSpi_mIntrDisable XSpi_IntrDisable +#endif + +#ifndef XSpi_mIntrGetEnabled +#define XSpi_mIntrGetEnabled XSpi_IntrGetEnabled +#endif + +#ifndef XSpi_mSetControlReg +#define XSpi_mSetControlReg XSpi_SetControlReg +#endif + +#ifndef XSpi_mGetControlReg +#define XSpi_mGetControlReg XSpi_GetControlReg +#endif + +#ifndef XSpi_mGetStatusReg +#define XSpi_mGetStatusReg XSpi_GetStatusReg +#endif + +#ifndef XSpi_mSetSlaveSelectReg +#define XSpi_mSetSlaveSelectReg XSpi_SetSlaveSelectReg +#endif + +#ifndef XSpi_mGetSlaveSelectReg +#define XSpi_mGetSlaveSelectReg XSpi_GetSlaveSelectReg +#endif + +#ifndef XSpi_mEnable +#define XSpi_mEnable XSpi_Enable +#endif + +#ifndef XSpi_mDisable +#define XSpi_mDisable XSpi_Disable +#endif + +/*********************************************************************/ +/** + * Macros for Driver XSysAce + * + *********************************************************************/ +#ifndef XSysAce_mGetControlReg +#define XSysAce_mGetControlReg XSysAce_GetControlReg +#endif + +#ifndef XSysAce_mSetControlReg +#define XSysAce_mSetControlReg XSysAce_SetControlReg +#endif + +#ifndef XSysAce_mOrControlReg +#define XSysAce_mOrControlReg XSysAce_OrControlReg +#endif + +#ifndef XSysAce_mAndControlReg +#define XSysAce_mAndControlReg XSysAce_AndControlReg +#endif + +#ifndef XSysAce_mGetErrorReg +#define XSysAce_mGetErrorReg XSysAce_GetErrorReg +#endif + +#ifndef XSysAce_mGetStatusReg +#define XSysAce_mGetStatusReg XSysAce_GetStatusReg +#endif + +#ifndef XSysAce_mWaitForLock +#define XSysAce_mWaitForLock XSysAce_WaitForLock +#endif + +#ifndef XSysAce_mEnableIntr +#define XSysAce_mEnableIntr XSysAce_EnableIntr +#endif + +#ifndef XSysAce_mDisableIntr +#define XSysAce_mDisableIntr XSysAce_DisableIntr +#endif + +#ifndef XSysAce_mIsReadyForCmd +#define XSysAce_mIsReadyForCmd XSysAce_IsReadyForCmd +#endif + +#ifndef XSysAce_mIsMpuLocked +#define XSysAce_mIsMpuLocked XSysAce_IsMpuLocked +#endif + +#ifndef XSysAce_mIsIntrEnabled +#define XSysAce_mIsIntrEnabled XSysAce_IsIntrEnabled +#endif + +/*********************************************************************/ +/** + * Macros for Driver XSysMon + * + *********************************************************************/ +#ifndef XSysMon_mIsEventSamplingModeSet +#define XSysMon_mIsEventSamplingModeSet XSysMon_IsEventSamplingModeSet +#endif + +#ifndef XSysMon_mIsDrpBusy +#define XSysMon_mIsDrpBusy XSysMon_IsDrpBusy +#endif + +#ifndef XSysMon_mIsDrpLocked +#define XSysMon_mIsDrpLocked XSysMon_IsDrpLocked +#endif + +#ifndef XSysMon_mRawToTemperature +#define XSysMon_mRawToTemperature XSysMon_RawToTemperature +#endif + +#ifndef XSysMon_mRawToVoltage +#define XSysMon_mRawToVoltage XSysMon_RawToVoltage +#endif + +#ifndef XSysMon_mTemperatureToRaw +#define XSysMon_mTemperatureToRaw XSysMon_TemperatureToRaw +#endif + +#ifndef XSysMon_mVoltageToRaw +#define XSysMon_mVoltageToRaw XSysMon_VoltageToRaw +#endif + +#ifndef XSysMon_mReadReg +#define XSysMon_mReadReg XSysMon_ReadReg +#endif + +#ifndef XSysMon_mWriteReg +#define XSysMon_mWriteReg XSysMon_WriteReg +#endif + +/*********************************************************************/ +/** + * Macros for Driver XTmrCtr + * + *********************************************************************/ +#ifndef XTimerCtr_mReadReg +#define XTimerCtr_mReadReg XTimerCtr_ReadReg +#endif + +#ifndef XTmrCtr_mWriteReg +#define XTmrCtr_mWriteReg XTmrCtr_WriteReg +#endif + +#ifndef XTmrCtr_mSetControlStatusReg +#define XTmrCtr_mSetControlStatusReg XTmrCtr_SetControlStatusReg +#endif + +#ifndef XTmrCtr_mGetControlStatusReg +#define XTmrCtr_mGetControlStatusReg XTmrCtr_GetControlStatusReg +#endif + +#ifndef XTmrCtr_mGetTimerCounterReg +#define XTmrCtr_mGetTimerCounterReg XTmrCtr_GetTimerCounterReg +#endif + +#ifndef XTmrCtr_mSetLoadReg +#define XTmrCtr_mSetLoadReg XTmrCtr_SetLoadReg +#endif + +#ifndef XTmrCtr_mGetLoadReg +#define XTmrCtr_mGetLoadReg XTmrCtr_GetLoadReg +#endif + +#ifndef XTmrCtr_mEnable +#define XTmrCtr_mEnable XTmrCtr_Enable +#endif + +#ifndef XTmrCtr_mDisable +#define XTmrCtr_mDisable XTmrCtr_Disable +#endif + +#ifndef XTmrCtr_mEnableIntr +#define XTmrCtr_mEnableIntr XTmrCtr_EnableIntr +#endif + +#ifndef XTmrCtr_mDisableIntr +#define XTmrCtr_mDisableIntr XTmrCtr_DisableIntr +#endif + +#ifndef XTmrCtr_mLoadTimerCounterReg +#define XTmrCtr_mLoadTimerCounterReg XTmrCtr_LoadTimerCounterReg +#endif + +#ifndef XTmrCtr_mHasEventOccurred +#define XTmrCtr_mHasEventOccurred XTmrCtr_HasEventOccurred +#endif + +/*********************************************************************/ +/** + * Macros for Driver XUartLite + * + *********************************************************************/ +#ifndef XUartLite_mUpdateStats +#define XUartLite_mUpdateStats XUartLite_UpdateStats +#endif + +#ifndef XUartLite_mWriteReg +#define XUartLite_mWriteReg XUartLite_WriteReg +#endif + +#ifndef XUartLite_mReadReg +#define XUartLite_mReadReg XUartLite_ReadReg +#endif + +#ifndef XUartLite_mClearStats +#define XUartLite_mClearStats XUartLite_ClearStats +#endif + +#ifndef XUartLite_mSetControlReg +#define XUartLite_mSetControlReg XUartLite_SetControlReg +#endif + +#ifndef XUartLite_mGetStatusReg +#define XUartLite_mGetStatusReg XUartLite_GetStatusReg +#endif + +#ifndef XUartLite_mIsReceiveEmpty +#define XUartLite_mIsReceiveEmpty XUartLite_IsReceiveEmpty +#endif + +#ifndef XUartLite_mIsTransmitFull +#define XUartLite_mIsTransmitFull XUartLite_IsTransmitFull +#endif + +#ifndef XUartLite_mIsIntrEnabled +#define XUartLite_mIsIntrEnabled XUartLite_IsIntrEnabled +#endif + +#ifndef XUartLite_mEnableIntr +#define XUartLite_mEnableIntr XUartLite_EnableIntr +#endif + +#ifndef XUartLite_mDisableIntr +#define XUartLite_mDisableIntr XUartLite_DisableIntr +#endif + +/*********************************************************************/ +/** + * Macros for Driver XUartNs550 + * + *********************************************************************/ +#ifndef XUartNs550_mUpdateStats +#define XUartNs550_mUpdateStats XUartNs550_UpdateStats +#endif + +#ifndef XUartNs550_mReadReg +#define XUartNs550_mReadReg XUartNs550_ReadReg +#endif + +#ifndef XUartNs550_mWriteReg +#define XUartNs550_mWriteReg XUartNs550_WriteReg +#endif + +#ifndef XUartNs550_mClearStats +#define XUartNs550_mClearStats XUartNs550_ClearStats +#endif + +#ifndef XUartNs550_mGetLineStatusReg +#define XUartNs550_mGetLineStatusReg XUartNs550_GetLineStatusReg +#endif + +#ifndef XUartNs550_mGetLineControlReg +#define XUartNs550_mGetLineControlReg XUartNs550_GetLineControlReg +#endif + +#ifndef XUartNs550_mSetLineControlReg +#define XUartNs550_mSetLineControlReg XUartNs550_SetLineControlReg +#endif + +#ifndef XUartNs550_mEnableIntr +#define XUartNs550_mEnableIntr XUartNs550_EnableIntr +#endif + +#ifndef XUartNs550_mDisableIntr +#define XUartNs550_mDisableIntr XUartNs550_DisableIntr +#endif + +#ifndef XUartNs550_mIsReceiveData +#define XUartNs550_mIsReceiveData XUartNs550_IsReceiveData +#endif + +#ifndef XUartNs550_mIsTransmitEmpty +#define XUartNs550_mIsTransmitEmpty XUartNs550_IsTransmitEmpty +#endif + +/*********************************************************************/ +/** + * Macros for Driver XUsb + * + *********************************************************************/ +#ifndef XUsb_mReadReg +#define XUsb_mReadReg XUsb_ReadReg +#endif + +#ifndef XUsb_mWriteReg +#define XUsb_mWriteReg XUsb_WriteReg +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_mem.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_mem.c new file mode 100644 index 0000000..e089bb5 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_mem.c @@ -0,0 +1,85 @@ +/******************************************************************************/ +/** +* Copyright (C) 2015 - 2016 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* @file xil_mem.c +* +* This file contains xil mem copy function to use in case of word aligned +* data copies. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who      Date     Changes
+* ----- -------- -------- -----------------------------------------------
+* 6.1   nsk      11/07/16 First release.
+*
+* 
+* +*****************************************************************************/ + +/***************************** Include Files ********************************/ + +#include "xil_types.h" + +/***************** Inline Functions Definitions ********************/ +/*****************************************************************************/ +/** +* @brief This function copies memory from once location to other. +* +* @param dst: pointer pointing to destination memory +* +* @param src: pointer pointing to source memory +* +* @param cnt: 32 bit length of bytes to be copied +* +*****************************************************************************/ +void Xil_MemCpy(void* dst, const void* src, u32 cnt) +{ + char *d = (char*)(void *)dst; + const char *s = src; + + while (cnt >= sizeof (int)) { + *(int*)d = *(int*)s; + d += sizeof (int); + s += sizeof (int); + cnt -= sizeof (int); + } + while (cnt >= sizeof (u16)) { + *(u16*)d = *(u16*)s; + d += sizeof (u16); + s += sizeof (u16); + cnt -= sizeof (u16); + } + while ((cnt) > 0U){ + *d = *s; + d += 1U; + s += 1U; + cnt -= 1U; + } +} diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_mem.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_mem.h new file mode 100644 index 0000000..9aae942 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_mem.h @@ -0,0 +1,68 @@ +/******************************************************************************/ +/** +* Copyright (C) 2015 - 2019 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* @file xil_mem.h +* +* @addtogroup common_mem_operation_api Customized APIs for Memory Operations +* +* The xil_mem.h file contains prototype for functions related +* to memory operations. These APIs are applicable for all processors supported +* by Xilinx. +* +* @{ +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who      Date     Changes
+* ----- -------- -------- -----------------------------------------------
+* 6.1   nsk      11/07/16 First release.
+* 7.0   mus      01/07/19 Add cpp extern macro
+*
+* 
+* +*****************************************************************************/ +#ifndef XIL_MEM_H /* prevent circular inclusions */ +#define XIL_MEM_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/************************** Function Prototypes *****************************/ + +void Xil_MemCpy(void* dst, const void* src, u32 cnt); + +#ifdef __cplusplus +} +#endif + +#endif /* XIL_MEM_H */ +/** +* @} End of "addtogroup common_mem_operation_api". +*/ \ No newline at end of file diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_misc_psreset_api.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_misc_psreset_api.c new file mode 100644 index 0000000..77d6fc1 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_misc_psreset_api.c @@ -0,0 +1,520 @@ +/****************************************************************************** +* +* Copyright (C) 2013 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xil_misc_reset.c +* +* This file contains the implementation of the reset sequence for various +* zynq ps devices like DDR,OCM,Slcr,Ethernet,Usb.. controllers. The reset +* sequence provided to the interfaces is based on the provision in +* slcr reset functional blcok. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date   Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00b kpc   03/07/13 First release
+* 5.4	pkp	  09/11/15 Change the description for XOcm_Remap function
+* 
+* +******************************************************************************/ + + +/***************************** Include Files *********************************/ +#include "xil_misc_psreset_api.h" + +/************************** Constant Definitions *****************************/ + + +/**************************** Type Definitions *******************************/ + + +/***************** Macros (Inline Functions) Definitions *********************/ + + +/************************** Function Prototypes ******************************/ + + +/*****************************************************************************/ +/** +* This function contains the implementation for ddr reset. +* +* @param N/A. +* +* @return N/A. +* +* @note None. +* +******************************************************************************/ +void XDdr_ResetHw(void) +{ + u32 RegVal; + + /* Unlock the slcr register access lock */ + Xil_Out32(XSLCR_UNLOCK_ADDR, XSLCR_UNLOCK_CODE); + /* Assert and deassert the ddr softreset bit */ + RegVal = Xil_In32(XDDRC_CTRL_BASEADDR); + RegVal &= (u32)(~XDDRPS_CTRL_RESET_MASK); + Xil_Out32(XDDRC_CTRL_BASEADDR,RegVal); + RegVal |= ((u32)XDDRPS_CTRL_RESET_MASK); + Xil_Out32(XDDRC_CTRL_BASEADDR,RegVal); + +} + +/*****************************************************************************/ +/** +* This function contains the implementation for remapping the ocm memory region +* to postbootrom state. +* +* @param N/A. +* +* @return N/A. +* +* @note None. +* +******************************************************************************/ +void XOcm_Remap(void) +{ + u32 RegVal; + + /* Unlock the slcr register access lock */ + Xil_Out32(XSLCR_UNLOCK_ADDR, XSLCR_UNLOCK_CODE); + /* Map the ocm region to postbootrom state */ + RegVal = Xil_In32(XSLCR_OCM_CFG_ADDR); + RegVal = (RegVal & (u32)(~XSLCR_OCM_CFG_HIADDR_MASK)) | (u32)XSLCR_OCM_CFG_RESETVAL; + Xil_Out32(XSLCR_OCM_CFG_ADDR, RegVal); +} + +/*****************************************************************************/ +/** +* This function contains the implementation for SMC reset sequence +* +* @param BaseAddress of the interface +* +* @return N/A. +* +* @note None. +* +******************************************************************************/ +void XSmc_ResetHw(u32 BaseAddress) +{ + u32 RegVal; + + /* Clear the interuupts */ + RegVal = Xil_In32(BaseAddress + XSMC_MEMC_CLR_CONFIG_OFFSET); + RegVal = RegVal | (u32)XSMC_MEMC_CLR_CONFIG_MASK; + Xil_Out32(BaseAddress + XSMC_MEMC_CLR_CONFIG_OFFSET, RegVal); + /* Clear the idle counter registers */ + Xil_Out32(BaseAddress + XSMC_REFRESH_PERIOD_0_OFFSET, 0x0U); + Xil_Out32(BaseAddress + XSMC_REFRESH_PERIOD_1_OFFSET, 0x0U); + /* Update the ecc registers with reset values */ + Xil_Out32(BaseAddress + XSMC_ECC_MEMCFG1_OFFSET, + XSMC_ECC_MEMCFG1_RESET_VAL); + Xil_Out32(BaseAddress + XSMC_ECC_MEMCMD1_OFFSET, + XSMC_ECC_MEMCMD1_RESET_VAL); + Xil_Out32(BaseAddress + XSMC_ECC_MEMCMD2_OFFSET, + XSMC_ECC_MEMCMD2_RESET_VAL); + +} + +/*****************************************************************************/ +/** +* This function contains the implementation for updating the slcr mio registers +* with reset values +* @param N/A. +* +* @return N/A. +* +* @note None. +* +******************************************************************************/ +void XSlcr_MioWriteResetValues(void) +{ + u32 i; + + /* Unlock the slcr register access lock */ + Xil_Out32(XSLCR_UNLOCK_ADDR, XSLCR_UNLOCK_CODE); + /* Update all the MIO registers with reset values */ + for (i=0U; i<=1U;i++) + { + Xil_Out32((XSLCR_MIO_PIN_00_ADDR + (i * 4U)), + XSLCR_MIO_PIN_00_RESET_VAL); + } + for (; i<=8U;i++) + { + Xil_Out32((XSLCR_MIO_PIN_00_ADDR + (i * 4U)), + XSLCR_MIO_PIN_02_RESET_VAL); + } + for (; i<=53U ;i++) + { + Xil_Out32((XSLCR_MIO_PIN_00_ADDR + (i * 4U)), + XSLCR_MIO_PIN_00_RESET_VAL); + } + + +} + +/*****************************************************************************/ +/** +* This function contains the implementation for updating the slcr pll registers +* with reset values +* @param N/A. +* +* @return N/A. +* +* @note None. +* +******************************************************************************/ +void XSlcr_PllWriteResetValues(void) +{ + + /* Unlock the slcr register access lock */ + Xil_Out32(XSLCR_UNLOCK_ADDR, XSLCR_UNLOCK_CODE); + + /* update the pll control registers with reset values */ + Xil_Out32(XSLCR_IO_PLL_CTRL_ADDR, XSLCR_IO_PLL_CTRL_RESET_VAL); + Xil_Out32(XSLCR_ARM_PLL_CTRL_ADDR, XSLCR_ARM_PLL_CTRL_RESET_VAL); + Xil_Out32(XSLCR_DDR_PLL_CTRL_ADDR, XSLCR_DDR_PLL_CTRL_RESET_VAL); + /* update the pll config registers with reset values */ + Xil_Out32(XSLCR_IO_PLL_CFG_ADDR, XSLCR_IO_PLL_CFG_RESET_VAL); + Xil_Out32(XSLCR_ARM_PLL_CFG_ADDR, XSLCR_ARM_PLL_CFG_RESET_VAL); + Xil_Out32(XSLCR_DDR_PLL_CFG_ADDR, XSLCR_DDR_PLL_CFG_RESET_VAL); + /* update the clock control registers with reset values */ + Xil_Out32(XSLCR_ARM_CLK_CTRL_ADDR, XSLCR_ARM_CLK_CTRL_RESET_VAL); + Xil_Out32(XSLCR_DDR_CLK_CTRL_ADDR, XSLCR_DDR_CLK_CTRL_RESET_VAL); +} + +/*****************************************************************************/ +/** +* This function contains the implementation for disabling the level shifters +* +* @param N/A. +* +* @return N/A. +* +* @note None. +* +******************************************************************************/ +void XSlcr_DisableLevelShifters(void) +{ + u32 RegVal; + /* Unlock the slcr register access lock */ + Xil_Out32(XSLCR_UNLOCK_ADDR, XSLCR_UNLOCK_CODE); + /* Disable the level shifters */ + RegVal = Xil_In32(XSLCR_LVL_SHFTR_EN_ADDR); + RegVal = RegVal & (u32)(~XSLCR_LVL_SHFTR_EN_MASK); + Xil_Out32(XSLCR_LVL_SHFTR_EN_ADDR, RegVal); + +} +/*****************************************************************************/ +/** +* This function contains the implementation for OCM software reset from the +* slcr +* +* @param N/A. +* +* @return N/A. +* +* @note None. +* +******************************************************************************/ +void XSlcr_OcmReset(void) +{ + u32 RegVal; + /* Unlock the slcr register access lock */ + Xil_Out32(XSLCR_UNLOCK_ADDR, XSLCR_UNLOCK_CODE); + /* Assert the reset */ + RegVal = Xil_In32(XSLCR_OCM_RST_CTRL_ADDR); + RegVal = RegVal | ((u32)XSLCR_OCM_RST_CTRL_VAL); + Xil_Out32(XSLCR_OCM_RST_CTRL_ADDR, RegVal); + /* Release the reset */ + RegVal = Xil_In32(XSLCR_OCM_RST_CTRL_ADDR); + RegVal = RegVal & (u32)(~XSLCR_OCM_RST_CTRL_VAL); + Xil_Out32(XSLCR_OCM_RST_CTRL_ADDR, RegVal); +} + +/*****************************************************************************/ +/** +* This function contains the implementation for Ethernet software reset from +* the slcr +* @param N/A. +* +* @return N/A. +* +* @note None. +* +******************************************************************************/ +void XSlcr_EmacPsReset(void) +{ + u32 RegVal; + /* Unlock the slcr register access lock */ + Xil_Out32(XSLCR_UNLOCK_ADDR, XSLCR_UNLOCK_CODE); + /* Assert the reset */ + RegVal = Xil_In32(XSLCR_GEM_RST_CTRL_ADDR); + RegVal = RegVal | ((u32)XSLCR_GEM_RST_CTRL_VAL); + Xil_Out32(XSLCR_GEM_RST_CTRL_ADDR, RegVal); + /* Release the reset */ + RegVal = Xil_In32(XSLCR_GEM_RST_CTRL_ADDR); + RegVal = RegVal & (u32)(~XSLCR_GEM_RST_CTRL_VAL); + Xil_Out32(XSLCR_GEM_RST_CTRL_ADDR, RegVal); +} + +/*****************************************************************************/ +/** +* This function contains the implementation for USB software reset from the +* slcr +* +* @param N/A. +* +* @return N/A. +* +* @note None. +* +******************************************************************************/ +void XSlcr_UsbPsReset(void) +{ + u32 RegVal; + /* Unlock the slcr register access lock */ + Xil_Out32(XSLCR_UNLOCK_ADDR, XSLCR_UNLOCK_CODE); + /* Assert the reset */ + RegVal = Xil_In32(XSLCR_USB_RST_CTRL_ADDR); + RegVal = RegVal | ((u32)XSLCR_USB_RST_CTRL_VAL); + Xil_Out32(XSLCR_USB_RST_CTRL_ADDR, RegVal); + /* Release the reset */ + RegVal = Xil_In32(XSLCR_USB_RST_CTRL_ADDR); + RegVal = RegVal & (u32)(~XSLCR_USB_RST_CTRL_VAL); + Xil_Out32(XSLCR_USB_RST_CTRL_ADDR, RegVal); +} +/*****************************************************************************/ +/** +* This function contains the implementation for QSPI software reset from the +* slcr +* +* @param N/A. +* +* @return N/A. +* +* @note None. +* +******************************************************************************/ +void XSlcr_QspiPsReset(void) +{ + u32 RegVal; + /* Unlock the slcr register access lock */ + Xil_Out32(XSLCR_UNLOCK_ADDR, XSLCR_UNLOCK_CODE); + /* Assert the reset */ + RegVal = Xil_In32(XSLCR_LQSPI_RST_CTRL_ADDR); + RegVal = RegVal | ((u32)XSLCR_QSPI_RST_CTRL_VAL); + Xil_Out32(XSLCR_LQSPI_RST_CTRL_ADDR, RegVal); + /* Release the reset */ + RegVal = Xil_In32(XSLCR_LQSPI_RST_CTRL_ADDR); + RegVal = RegVal & (u32)(~XSLCR_QSPI_RST_CTRL_VAL); + Xil_Out32(XSLCR_LQSPI_RST_CTRL_ADDR, RegVal); +} +/*****************************************************************************/ +/** +* This function contains the implementation for SPI software reset from the +* slcr +* +* @param N/A. +* +* @return N/A. +* +* @note None. +* +******************************************************************************/ +void XSlcr_SpiPsReset(void) +{ + u32 RegVal; + /* Unlock the slcr register access lock */ + Xil_Out32(XSLCR_UNLOCK_ADDR, XSLCR_UNLOCK_CODE); + /* Assert the reset */ + RegVal = Xil_In32(XSLCR_SPI_RST_CTRL_ADDR); + RegVal = RegVal | ((u32)XSLCR_SPI_RST_CTRL_VAL); + Xil_Out32(XSLCR_SPI_RST_CTRL_ADDR, RegVal); + /* Release the reset */ + RegVal = Xil_In32(XSLCR_SPI_RST_CTRL_ADDR); + RegVal = RegVal & (u32)(~XSLCR_SPI_RST_CTRL_VAL); + Xil_Out32(XSLCR_SPI_RST_CTRL_ADDR, RegVal); +} +/*****************************************************************************/ +/** +* This function contains the implementation for i2c software reset from the slcr +* +* @param N/A. +* +* @return N/A. +* +* @note None. +* +******************************************************************************/ +void XSlcr_I2cPsReset(void) +{ + u32 RegVal; + /* Unlock the slcr register access lock */ + Xil_Out32(XSLCR_UNLOCK_ADDR, XSLCR_UNLOCK_CODE); + /* Assert the reset */ + RegVal = Xil_In32(XSLCR_I2C_RST_CTRL_ADDR); + RegVal = RegVal | ((u32)XSLCR_I2C_RST_CTRL_VAL); + Xil_Out32(XSLCR_I2C_RST_CTRL_ADDR, RegVal); + /* Release the reset */ + RegVal = Xil_In32(XSLCR_I2C_RST_CTRL_ADDR); + RegVal = RegVal & (u32)(~XSLCR_I2C_RST_CTRL_VAL); + Xil_Out32(XSLCR_I2C_RST_CTRL_ADDR, RegVal); +} +/*****************************************************************************/ +/** +* This function contains the implementation for UART software reset from the +* slcr +* +* @param N/A. +* +* @return N/A. +* +* @note None. +* +******************************************************************************/ +void XSlcr_UartPsReset(void) +{ + u32 RegVal; + /* Unlock the slcr register access lock */ + Xil_Out32(XSLCR_UNLOCK_ADDR, XSLCR_UNLOCK_CODE); + /* Assert the reset */ + RegVal = Xil_In32(XSLCR_UART_RST_CTRL_ADDR); + RegVal = RegVal | ((u32)XSLCR_UART_RST_CTRL_VAL); + Xil_Out32(XSLCR_UART_RST_CTRL_ADDR, RegVal); + /* Release the reset */ + RegVal = Xil_In32(XSLCR_UART_RST_CTRL_ADDR); + RegVal = RegVal & (u32)(~XSLCR_UART_RST_CTRL_VAL); + Xil_Out32(XSLCR_UART_RST_CTRL_ADDR, RegVal); +} +/*****************************************************************************/ +/** +* This function contains the implementation for CAN software reset from slcr +* registers +* +* @param N/A. +* +* @return N/A. +* +* @note None. +* +******************************************************************************/ +void XSlcr_CanPsReset(void) +{ + u32 RegVal; + /* Unlock the slcr register access lock */ + Xil_Out32(XSLCR_UNLOCK_ADDR, XSLCR_UNLOCK_CODE); + /* Assert the reset */ + RegVal = Xil_In32(XSLCR_CAN_RST_CTRL_ADDR); + RegVal = RegVal | ((u32)XSLCR_CAN_RST_CTRL_VAL); + Xil_Out32(XSLCR_CAN_RST_CTRL_ADDR, RegVal); + /* Release the reset */ + RegVal = Xil_In32(XSLCR_CAN_RST_CTRL_ADDR); + RegVal = RegVal & (u32)(~XSLCR_CAN_RST_CTRL_VAL); + Xil_Out32(XSLCR_CAN_RST_CTRL_ADDR, RegVal); +} +/*****************************************************************************/ +/** +* This function contains the implementation for SMC software reset from the slcr +* +* @param N/A. +* +* @return N/A. +* +* @note None. +* +******************************************************************************/ +void XSlcr_SmcPsReset(void) +{ + u32 RegVal; + /* Unlock the slcr register access lock */ + Xil_Out32(XSLCR_UNLOCK_ADDR, XSLCR_UNLOCK_CODE); + /* Assert the reset */ + RegVal = Xil_In32(XSLCR_SMC_RST_CTRL_ADDR); + RegVal = RegVal | ((u32)XSLCR_SMC_RST_CTRL_VAL); + Xil_Out32(XSLCR_SMC_RST_CTRL_ADDR, RegVal); + /* Release the reset */ + RegVal = Xil_In32(XSLCR_SMC_RST_CTRL_ADDR); + RegVal = RegVal & (u32)(~XSLCR_SMC_RST_CTRL_VAL); + Xil_Out32(XSLCR_SMC_RST_CTRL_ADDR, RegVal); +} +/*****************************************************************************/ +/** +* This function contains the implementation for DMA controller software reset +* from the slcr +* +* @param N/A. +* +* @return N/A. +* +* @note None. +* +******************************************************************************/ +void XSlcr_DmaPsReset(void) +{ + u32 RegVal; + /* Unlock the slcr register access lock */ + Xil_Out32(XSLCR_UNLOCK_ADDR, XSLCR_UNLOCK_CODE); + /* Assert the reset */ + RegVal = Xil_In32(XSLCR_DMAC_RST_CTRL_ADDR); + RegVal = RegVal | ((u32)XSLCR_DMAC_RST_CTRL_VAL); + Xil_Out32(XSLCR_DMAC_RST_CTRL_ADDR, RegVal); + /* Release the reset */ + RegVal = Xil_In32(XSLCR_DMAC_RST_CTRL_ADDR); + RegVal = RegVal & (u32)(~XSLCR_DMAC_RST_CTRL_VAL); + Xil_Out32(XSLCR_DMAC_RST_CTRL_ADDR, RegVal); +} +/*****************************************************************************/ +/** +* This function contains the implementation for Gpio AMBA software reset from +* the slcr +* +* @param N/A. +* +* @return N/A. +* +* @note None. +* +******************************************************************************/ +void XSlcr_GpioPsReset(void) +{ + u32 RegVal; + /* Unlock the slcr register access lock */ + Xil_Out32(XSLCR_UNLOCK_ADDR, XSLCR_UNLOCK_CODE); + /* Assert the reset */ + RegVal = Xil_In32(XSLCR_GPIO_RST_CTRL_ADDR); + RegVal = RegVal | ((u32)XSLCR_GPIO_RST_CTRL_VAL); + Xil_Out32(XSLCR_GPIO_RST_CTRL_ADDR, RegVal); + /* Release the reset */ + RegVal = Xil_In32(XSLCR_GPIO_RST_CTRL_ADDR); + RegVal = RegVal & (u32)(~XSLCR_GPIO_RST_CTRL_VAL); + Xil_Out32(XSLCR_GPIO_RST_CTRL_ADDR, RegVal); +} diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_misc_psreset_api.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_misc_psreset_api.h new file mode 100644 index 0000000..3a26175 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_misc_psreset_api.h @@ -0,0 +1,273 @@ +/****************************************************************************** +* +* Copyright (C) 2013 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* @file xil_misc_psreset_api.h +* +* This file contains the various register defintions and function prototypes for +* implementing the reset functionality of zynq ps devices +* +* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ---- -------- ------------------------------------------------------- +* 1.00b kpc 03/07/13 First release. +* +* +******************************************************************************/ + +#ifndef XIL_MISC_RESET_H /* prevent circular inclusions */ +#define XIL_MISC_RESET_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/***************************** Include Files *********************************/ +#include "xil_types.h" +#include "xil_io.h" + +/************************** Constant Definitions *****************************/ +#define XDDRC_CTRL_BASEADDR 0xF8006000U +#define XSLCR_BASEADDR 0xF8000000U +/**< OCM configuration register */ +#define XSLCR_OCM_CFG_ADDR (XSLCR_BASEADDR + 0x00000910U) +/**< SLCR unlock register */ +#define XSLCR_UNLOCK_ADDR (XSLCR_BASEADDR + 0x00000008U) +/**< SLCR GEM0 rx clock control register */ +#define XSLCR_GEM0_RCLK_CTRL_ADDR (XSLCR_BASEADDR + 0x00000138U) +/**< SLCR GEM1 rx clock control register */ +#define XSLCR_GEM1_RCLK_CTRL_ADDR (XSLCR_BASEADDR + 0x0000013CU) +/**< SLCR GEM0 clock control register */ +#define XSLCR_GEM0_CLK_CTRL_ADDR (XSLCR_BASEADDR + 0x00000140U) +/**< SLCR GEM1 clock control register */ +#define XSLCR_GEM1_CLK_CTRL_ADDR (XSLCR_BASEADDR + 0x00000144U) +/**< SLCR SMC clock control register */ +#define XSLCR_SMC_CLK_CTRL_ADDR (XSLCR_BASEADDR + 0x00000148U) +/**< SLCR GEM reset control register */ +#define XSLCR_GEM_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x00000214U) +/**< SLCR USB0 clock control register */ +#define XSLCR_USB0_CLK_CTRL_ADDR (XSLCR_BASEADDR + 0x00000130U) +/**< SLCR USB1 clock control register */ +#define XSLCR_USB1_CLK_CTRL_ADDR (XSLCR_BASEADDR + 0x00000134U) +/**< SLCR USB1 reset control register */ +#define XSLCR_USB_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x00000210U) +/**< SLCR SMC reset control register */ +#define XSLCR_SMC_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x00000234U) +/**< SLCR Level shifter enable register */ +#define XSLCR_LVL_SHFTR_EN_ADDR (XSLCR_BASEADDR + 0x00000900U) +/**< SLCR ARM pll control register */ +#define XSLCR_ARM_PLL_CTRL_ADDR (XSLCR_BASEADDR + 0x00000100U) +/**< SLCR DDR pll control register */ +#define XSLCR_DDR_PLL_CTRL_ADDR (XSLCR_BASEADDR + 0x00000104U) +/**< SLCR IO pll control register */ +#define XSLCR_IO_PLL_CTRL_ADDR (XSLCR_BASEADDR + 0x00000108U) +/**< SLCR ARM pll configuration register */ +#define XSLCR_ARM_PLL_CFG_ADDR (XSLCR_BASEADDR + 0x00000110U) +/**< SLCR DDR pll configuration register */ +#define XSLCR_DDR_PLL_CFG_ADDR (XSLCR_BASEADDR + 0x00000114U) +/**< SLCR IO pll configuration register */ +#define XSLCR_IO_PLL_CFG_ADDR (XSLCR_BASEADDR + 0x00000118U) +/**< SLCR ARM clock control register */ +#define XSLCR_ARM_CLK_CTRL_ADDR (XSLCR_BASEADDR + 0x00000120U) +/**< SLCR DDR clock control register */ +#define XSLCR_DDR_CLK_CTRL_ADDR (XSLCR_BASEADDR + 0x00000124U) +/**< SLCR MIO pin address register */ +#define XSLCR_MIO_PIN_00_ADDR (XSLCR_BASEADDR + 0x00000700U) +/**< SLCR DMAC reset control address register */ +#define XSLCR_DMAC_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x0000020CU) +/**< SLCR USB reset control address register */ +/*#define XSLCR_USB_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x00000210U)*/ +/**< SLCR GEM reset control address register */ +/*#define XSLCR_GEM_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x00000214U)*/ +/**< SLCR SDIO reset control address register */ +#define XSLCR_SDIO_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x00000218U) +/**< SLCR SPI reset control address register */ +#define XSLCR_SPI_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x0000021CU) +/**< SLCR CAN reset control address register */ +#define XSLCR_CAN_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x00000220U) +/**< SLCR I2C reset control address register */ +#define XSLCR_I2C_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x00000224U) +/**< SLCR UART reset control address register */ +#define XSLCR_UART_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x00000228U) +/**< SLCR GPIO reset control address register */ +#define XSLCR_GPIO_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x0000022CU) +/**< SLCR LQSPI reset control address register */ +#define XSLCR_LQSPI_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x00000230U) +/**< SLCR SMC reset control address register */ +/*#define XSLCR_SMC_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x00000234U)*/ +/**< SLCR OCM reset control address register */ +#define XSLCR_OCM_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x00000238U) + +/**< SMC mem controller clear config register */ +#define XSMC_MEMC_CLR_CONFIG_OFFSET 0x0000000CU +/**< SMC idlecount configuration register */ +#define XSMC_REFRESH_PERIOD_0_OFFSET 0x00000020U +#define XSMC_REFRESH_PERIOD_1_OFFSET 0x00000024U +/**< SMC ECC configuration register */ +#define XSMC_ECC_MEMCFG1_OFFSET 0x00000404U +/**< SMC ECC command 1 register */ +#define XSMC_ECC_MEMCMD1_OFFSET 0x00000404U +/**< SMC ECC command 2 register */ +#define XSMC_ECC_MEMCMD2_OFFSET 0x00000404U + +/**< SLCR unlock code */ +#define XSLCR_UNLOCK_CODE 0x0000DF0DU + +/**< SMC mem clear configuration mask */ +#define XSMC_MEMC_CLR_CONFIG_MASK 0x000005FU +/**< SMC ECC memconfig 1 reset value */ +#define XSMC_ECC_MEMCFG1_RESET_VAL 0x0000043U +/**< SMC ECC memcommand 1 reset value */ +#define XSMC_ECC_MEMCMD1_RESET_VAL 0x01300080U +/**< SMC ECC memcommand 2 reset value */ +#define XSMC_ECC_MEMCMD2_RESET_VAL 0x01E00585U + +/**< DDR controller reset bit mask */ +#define XDDRPS_CTRL_RESET_MASK 0x00000001U +/**< SLCR OCM configuration reset value*/ +#define XSLCR_OCM_CFG_RESETVAL 0x00000008U +/**< SLCR OCM bank selection mask*/ +#define XSLCR_OCM_CFG_HIADDR_MASK 0x0000000FU +/**< SLCR level shifter enable mask*/ +#define XSLCR_LVL_SHFTR_EN_MASK 0x0000000FU + +/**< SLCR PLL register reset values */ +#define XSLCR_ARM_PLL_CTRL_RESET_VAL 0x0001A008U +#define XSLCR_DDR_PLL_CTRL_RESET_VAL 0x0001A008U +#define XSLCR_IO_PLL_CTRL_RESET_VAL 0x0001A008U +#define XSLCR_ARM_PLL_CFG_RESET_VAL 0x00177EA0U +#define XSLCR_DDR_PLL_CFG_RESET_VAL 0x00177EA0U +#define XSLCR_IO_PLL_CFG_RESET_VAL 0x00177EA0U +#define XSLCR_ARM_CLK_CTRL_RESET_VAL 0x1F000400U +#define XSLCR_DDR_CLK_CTRL_RESET_VAL 0x18400003U + +/**< SLCR MIO register default values */ +#define XSLCR_MIO_PIN_00_RESET_VAL 0x00001601U +#define XSLCR_MIO_PIN_02_RESET_VAL 0x00000601U + +/**< SLCR Reset control registers default values */ +#define XSLCR_DMAC_RST_CTRL_VAL 0x00000001U +#define XSLCR_GEM_RST_CTRL_VAL 0x000000F3U +#define XSLCR_USB_RST_CTRL_VAL 0x00000003U +#define XSLCR_I2C_RST_CTRL_VAL 0x00000003U +#define XSLCR_SPI_RST_CTRL_VAL 0x0000000FU +#define XSLCR_UART_RST_CTRL_VAL 0x0000000FU +#define XSLCR_QSPI_RST_CTRL_VAL 0x00000003U +#define XSLCR_GPIO_RST_CTRL_VAL 0x00000001U +#define XSLCR_SMC_RST_CTRL_VAL 0x00000003U +#define XSLCR_OCM_RST_CTRL_VAL 0x00000001U +#define XSLCR_SDIO_RST_CTRL_VAL 0x00000033U +#define XSLCR_CAN_RST_CTRL_VAL 0x00000003U +/**************************** Type Definitions *******************************/ + +/* the following data type is used to hold a null terminated version string + * consisting of the following format, "X.YYX" + */ + + +/***************** Macros (Inline Functions) Definitions *********************/ + + +/************************** Function Prototypes ******************************/ +/* + * Performs reset operation to the ddr interface + */ +void XDdr_ResetHw(void); +/* + * Map the ocm region to post bootrom state + */ +void XOcm_Remap(void); +/* + * Performs the smc interface reset + */ +void XSmc_ResetHw(u32 BaseAddress); +/* + * updates the MIO registers with reset values + */ +void XSlcr_MioWriteResetValues(void); +/* + * updates the PLL and clock registers with reset values + */ +void XSlcr_PllWriteResetValues(void); +/* + * Disables the level shifters + */ +void XSlcr_DisableLevelShifters(void); +/* + * provides softreset to the GPIO interface + */ +void XSlcr_GpioPsReset(void); +/* + * provides softreset to the DMA interface + */ +void XSlcr_DmaPsReset(void); +/* + * provides softreset to the SMC interface + */ +void XSlcr_SmcPsReset(void); +/* + * provides softreset to the CAN interface + */ +void XSlcr_CanPsReset(void); +/* + * provides softreset to the Uart interface + */ +void XSlcr_UartPsReset(void); +/* + * provides softreset to the I2C interface + */ +void XSlcr_I2cPsReset(void); +/* + * provides softreset to the SPI interface + */ +void XSlcr_SpiPsReset(void); +/* + * provides softreset to the QSPI interface + */ +void XSlcr_QspiPsReset(void); +/* + * provides softreset to the USB interface + */ +void XSlcr_UsbPsReset(void); +/* + * provides softreset to the GEM interface + */ +void XSlcr_EmacPsReset(void); +/* + * provides softreset to the OCM interface + */ +void XSlcr_OcmReset(void); + + +#ifdef __cplusplus +} +#endif + +#endif /* XIL_MISC_RESET_H */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_mmu.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_mmu.c new file mode 100644 index 0000000..ef5bbfe --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_mmu.c @@ -0,0 +1,227 @@ +/****************************************************************************** +* +* Copyright (C) 2012 - 2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* @file xil_mmu.c +* +* This file provides APIs for enabling/disabling MMU and setting the memory +* attributes for sections, in the MMU translation table. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- ---------------------------------------------------
+* 1.00a sdm  01/12/12 Initial version
+* 3.05a asa  03/10/12 Modified the Xil_EnableMMU to invalidate the caches
+*		      before enabling back.
+* 3.05a asa  04/15/12 Modified the Xil_SetTlbAttributes routine so that
+*		      translation table and branch predictor arrays are
+*		      invalidated, D-cache flushed before the attribute
+*		      change is applied. This is done so that the user
+*		      need not call Xil_DisableMMU before calling
+*		      Xil_SetTlbAttributes.
+* 3.10a  srt 04/18/13 Implemented ARM Erratas. Please refer to file
+*		      'xil_errata.h' for errata description
+* 3.11a  asa 09/23/13 Modified Xil_SetTlbAttributes to flush the complete
+*			 D cache after the translation table update. Removed the
+*			 redundant TLB invalidation in the same API at the beginning.
+* 6.8   aru  09/06/18 Removed compilation warnings for ARMCC toolchain.
+*                     It fixes CR#1008309.
+* 
+* +* @note +* +* None. +* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xil_cache.h" +#include "xpseudo_asm.h" +#include "xil_types.h" +#include "xil_mmu.h" +#include "xil_errata.h" + +/***************** Macros (Inline Functions) Definitions *********************/ + +/**************************** Type Definitions *******************************/ + +/************************** Constant Definitions *****************************/ +#define ARM_AR_MEM_TTB_SECT_SIZE 1024*1024 +#define ARM_AR_MEM_TTB_SECT_SIZE_MASK (~(ARM_AR_MEM_TTB_SECT_SIZE-1UL)) +/************************** Variable Definitions *****************************/ + +extern u32 MMUTable; + +/************************** Function Prototypes ******************************/ + +/*****************************************************************************/ +/** +* @brief This function sets the memory attributes for a section covering 1MB +* of memory in the translation table. +* +* @param Addr: 32-bit address for which memory attributes need to be set. +* @param attrib: Attribute for the given memory region. xil_mmu.h contains +* definitions of commonly used memory attributes which can be +* utilized for this function. +* +* +* @return None. +* +* @note The MMU or D-cache does not need to be disabled before changing a +* translation table entry. +* +******************************************************************************/ +void Xil_SetTlbAttributes(INTPTR Addr, u32 attrib) +{ + u32 *ptr; + u32 section; + + section = Addr / 0x100000U; + ptr = &MMUTable; + ptr += section; + if(ptr != NULL) { + *ptr = (Addr & 0xFFF00000U) | attrib; + } + + Xil_DCacheFlush(); + + mtcp(XREG_CP15_INVAL_UTLB_UNLOCKED, 0U); + /* Invalidate all branch predictors */ + mtcp(XREG_CP15_INVAL_BRANCH_ARRAY, 0U); + + dsb(); /* ensure completion of the BP and TLB invalidation */ + isb(); /* synchronize context on this processor */ +} + +/*****************************************************************************/ +/** +* @brief Enable MMU for cortex A9 processor. This function invalidates the +* instruction and data caches, and then enables MMU. +* +* @param None. +* @return None. +* +******************************************************************************/ +void Xil_EnableMMU(void) +{ + u32 Reg; + Xil_DCacheInvalidate(); + Xil_ICacheInvalidate(); + +#ifdef __GNUC__ + Reg = mfcp(XREG_CP15_SYS_CONTROL); +#elif defined (__ICCARM__) + mfcp(XREG_CP15_SYS_CONTROL, Reg); +#else + { volatile register u32 Cp15Reg __asm(XREG_CP15_SYS_CONTROL); + Reg = Cp15Reg; } +#endif + Reg |= (u32)0x05U; + mtcp(XREG_CP15_SYS_CONTROL, Reg); + + dsb(); + isb(); +} + +/*****************************************************************************/ +/** +* @brief Disable MMU for Cortex A9 processors. This function invalidates +* the TLBs, Branch Predictor Array and flushed the D Caches before +* disabling the MMU. +* +* @param None. +* +* @return None. +* +* @note When the MMU is disabled, all the memory accesses are treated as +* strongly ordered. +******************************************************************************/ +void Xil_DisableMMU(void) +{ + u32 Reg; + + mtcp(XREG_CP15_INVAL_UTLB_UNLOCKED, 0U); + mtcp(XREG_CP15_INVAL_BRANCH_ARRAY, 0U); + Xil_DCacheFlush(); + +#ifdef __GNUC__ + Reg = mfcp(XREG_CP15_SYS_CONTROL); +#elif defined (__ICCARM__) + mfcp(XREG_CP15_SYS_CONTROL, Reg); +#else + { volatile register u32 Cp15Reg __asm(XREG_CP15_SYS_CONTROL); + Reg = Cp15Reg; } +#endif + Reg &= (u32)(~0x05U); +#ifdef CONFIG_ARM_ERRATA_794073 + /* Disable Branch Prediction */ + Reg &= (u32)(~0x800U); +#endif + mtcp(XREG_CP15_SYS_CONTROL, Reg); +} + +/*****************************************************************************/ +/** +* @brief Memory mapping for Cortex A9 processor. +* +* @param PhysAddr is physical address. +* @param size is size of region. +* @param flags is flags used to set translation table. +* +* @return Pointer to virtual address. +* +* @note: Previously this was implemented in libmetal. Move to embeddedsw as this +* functionality is specific to A9 processor. +* +******************************************************************************/ +void* Xil_MemMap(UINTPTR PhysAddr, size_t size, u32 flags) +{ + u32 Sectionoffset; + u32 Ttbaddr; + + if (!flags) + return (void*)PhysAddr; + + /* Ensure alignement on a section boundary */ + PhysAddr &= ARM_AR_MEM_TTB_SECT_SIZE_MASK; + + /* Loop through entire region of memory (one MMU section at a time). + Each section requires a TTB entry. */ + for (Sectionoffset = 0; Sectionoffset < size; + Sectionoffset += ARM_AR_MEM_TTB_SECT_SIZE) { + /* Calculate translation table entry for this memory section */ + Ttbaddr = (PhysAddr + Sectionoffset); + + /* Write translation table entry value to entry address */ + Xil_SetTlbAttributes(Ttbaddr, flags); + } + return (void*)PhysAddr; +} diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_mmu.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_mmu.h new file mode 100644 index 0000000..3b63c0b --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_mmu.h @@ -0,0 +1,106 @@ +/****************************************************************************** +* +* Copyright (C) 2012 - 2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* @file xil_mmu.h +* +* @addtogroup a9_mmu_apis Cortex A9 Processor MMU Functions +* +* MMU functions equip users to enable MMU, disable MMU and modify default +* memory attributes of MMU table as per the need. +* +* @{ +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- ---------------------------------------------------
+* 1.00a sdm  01/12/12 Initial version
+* 4.2	pkp	 07/21/14 Included xil_types.h file which contains definition for
+*					  u32 which resolves issue of CR#805869
+* 5.4	pkp	 23/11/15 Added attribute definitions for Xil_SetTlbAttributes API
+* 6.8   aru  09/06/18 Removed compilation warnings for ARMCC toolchain.
+* 
+* +* +******************************************************************************/ + +#ifndef XIL_MMU_H +#define XIL_MMU_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/***************************** Include Files *********************************/ + +#include "xil_types.h" + +/***************** Macros (Inline Functions) Definitions *********************/ + +/**************************** Type Definitions *******************************/ + +/************************** Constant Definitions *****************************/ + +/* Memory type */ +#define NORM_NONCACHE 0x11DE2 /* Normal Non-cacheable */ +#define STRONG_ORDERED 0xC02 /* Strongly ordered */ +#define DEVICE_MEMORY 0xC06 /* Device memory */ +#define RESERVED 0x0 /* reserved memory */ + +/* Normal write-through cacheable shareable */ +#define NORM_WT_CACHE 0x16DEA + +/* Normal write back cacheable shareable */ +#define NORM_WB_CACHE 0x15DE6 + +/* shareability attribute */ +#define SHAREABLE (0x1 << 16) +#define NON_SHAREABLE (~(0x1 << 16)) + +/* Execution type */ +#define EXECUTE_NEVER ((0x1 << 4) | (0x1 << 0)) + +/************************** Variable Definitions *****************************/ + +/************************** Function Prototypes ******************************/ + +void Xil_SetTlbAttributes(INTPTR Addr, u32 attrib); +void Xil_EnableMMU(void); +void Xil_DisableMMU(void); +void* Xil_MemMap(UINTPTR PhysAddr, size_t size, u32 flags); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* XIL_MMU_H */ +/** +* @} End of "addtogroup a9_mmu_apis". +*/ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_printf.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_printf.c new file mode 100644 index 0000000..3113269 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_printf.c @@ -0,0 +1,443 @@ +/*---------------------------------------------------*/ +/* Modified from : */ +/* Public Domain version of printf */ +/* Rud Merriam, Compsult, Inc. Houston, Tx. */ +/* For Embedded Systems Programming, 1991 */ +/* */ +/*---------------------------------------------------*/ +#include "xil_printf.h" +#include "xil_types.h" +#include "xil_assert.h" +#include +#include +#include + +static void padding( const s32 l_flag,const struct params_s *par); +static void outs(const charptr lp, struct params_s *par); +static s32 getnum( charptr* linep); + +typedef struct params_s { + s32 len; + s32 num1; + s32 num2; + char8 pad_character; + s32 do_padding; + s32 left_flag; + s32 unsigned_flag; +} params_t; + + +/*---------------------------------------------------*/ +/* The purpose of this routine is to output data the */ +/* same as the standard printf function without the */ +/* overhead most run-time libraries involve. Usually */ +/* the printf brings in many kilobytes of code and */ +/* that is unacceptable in most embedded systems. */ +/*---------------------------------------------------*/ + + +/*---------------------------------------------------*/ +/* */ +/* This routine puts pad characters into the output */ +/* buffer. */ +/* */ +static void padding( const s32 l_flag, const struct params_s *par) +{ + s32 i; + + if ((par->do_padding != 0) && (l_flag != 0) && (par->len < par->num1)) { + i=(par->len); + for (; i<(par->num1); i++) { +#ifdef STDOUT_BASEADDRESS + outbyte( par->pad_character); +#endif + } + } +} + +/*---------------------------------------------------*/ +/* */ +/* This routine moves a string to the output buffer */ +/* as directed by the padding and positioning flags. */ +/* */ +static void outs(const charptr lp, struct params_s *par) +{ + charptr LocalPtr; + LocalPtr = lp; + /* pad on left if needed */ + if(LocalPtr != NULL) { + par->len = (s32)strlen( LocalPtr); + } + padding( !(par->left_flag), par); + + /* Move string to the buffer */ + while (((*LocalPtr) != (char8)0) && ((par->num2) != 0)) { + (par->num2)--; +#ifdef STDOUT_BASEADDRESS + outbyte(*LocalPtr); +#endif + LocalPtr += 1; +} + + /* Pad on right if needed */ + /* CR 439175 - elided next stmt. Seemed bogus. */ + /* par->len = strlen( lp) */ + padding( par->left_flag, par); +} + +/*---------------------------------------------------*/ +/* */ +/* This routine moves a number to the output buffer */ +/* as directed by the padding and positioning flags. */ +/* */ + +static void outnum( const s32 n, const s32 base, struct params_s *par) +{ + s32 negative; + s32 i; + char8 outbuf[32]; + const char8 digits[] = "0123456789ABCDEF"; + u32 num; + for(i = 0; i<32; i++) { + outbuf[i] = '0'; + } + + /* Check if number is negative */ + if ((par->unsigned_flag == 0) && (base == 10) && (n < 0L)) { + negative = 1; + num =(-(n)); + } + else{ + num = n; + negative = 0; + } + + /* Build number (backwards) in outbuf */ + i = 0; + do { + outbuf[i] = digits[(num % base)]; + i++; + num /= base; + } while (num > 0); + + if (negative != 0) { + outbuf[i] = '-'; + i++; + } + + outbuf[i] = '\0'; + i--; + + /* Move the converted number to the buffer and */ + /* add in the padding where needed. */ + par->len = (s32)strlen(outbuf); + padding( !(par->left_flag), par); + while (&outbuf[i] >= outbuf) { +#ifdef STDOUT_BASEADDRESS + outbyte( outbuf[i] ); +#endif + i--; +} + padding( par->left_flag, par); +} +/*---------------------------------------------------*/ +/* */ +/* This routine moves a 64-bit number to the output */ +/* buffer as directed by the padding and positioning */ +/* flags. */ +/* */ +#if defined (__aarch64__) || defined (__arch64__) +static void outnum1( const s64 n, const s32 base, params_t *par) +{ + s32 negative; + s32 i; + char8 outbuf[64]; + const char8 digits[] = "0123456789ABCDEF"; + u64 num; + for(i = 0; i<64; i++) { + outbuf[i] = '0'; + } + + /* Check if number is negative */ + if ((par->unsigned_flag == 0) && (base == 10) && (n < 0L)) { + negative = 1; + num =(-(n)); + } + else{ + num = (n); + negative = 0; + } + + /* Build number (backwards) in outbuf */ + i = 0; + do { + outbuf[i] = digits[(num % base)]; + i++; + num /= base; + } while (num > 0); + + if (negative != 0) { + outbuf[i] = '-'; + i++; + } + + outbuf[i] = '\0'; + i--; + + /* Move the converted number to the buffer and */ + /* add in the padding where needed. */ + par->len = (s32)strlen(outbuf); + padding( !(par->left_flag), par); + while (&outbuf[i] >= outbuf) { + outbyte( outbuf[i] ); + i--; +} + padding( par->left_flag, par); +} +#endif +/*---------------------------------------------------*/ +/* */ +/* This routine gets a number from the format */ +/* string. */ +/* */ +static s32 getnum( charptr* linep) +{ + s32 n; + s32 ResultIsDigit = 0; + charptr cptr; + n = 0; + cptr = *linep; + if(cptr != NULL){ + ResultIsDigit = isdigit(((s32)*cptr)); + } + while (ResultIsDigit != 0) { + if(cptr != NULL){ + n = ((n*10) + (((s32)*cptr) - (s32)'0')); + cptr += 1; + if(cptr != NULL){ + ResultIsDigit = isdigit(((s32)*cptr)); + } + } + ResultIsDigit = isdigit(((s32)*cptr)); + } + *linep = ((charptr )(cptr)); + return(n); +} + +/*---------------------------------------------------*/ +/* */ +/* This routine operates just like a printf/sprintf */ +/* routine. It outputs a set of data under the */ +/* control of a formatting string. Not all of the */ +/* standard C format control are supported. The ones */ +/* provided are primarily those needed for embedded */ +/* systems work. Primarily the floating point */ +/* routines are omitted. Other formats could be */ +/* added easily by following the examples shown for */ +/* the supported formats. */ +/* */ + +/* void esp_printf( const func_ptr f_ptr, + const charptr ctrl1, ...) */ +#if defined (__aarch64__) && HYP_GUEST && EL1_NONSECURE && XEN_USE_PV_CONSOLE +void xil_printf( const char8 *ctrl1, ...){ + XPVXenConsole_Printf(ctrl1); +} +#else +void xil_printf( const char8 *ctrl1, ...) +{ + s32 Check; +#if defined (__aarch64__) || defined (__arch64__) + s32 long_flag; +#endif + s32 dot_flag; + + params_t par; + + char8 ch; + va_list argp; + char8 *ctrl = (char8 *)ctrl1; + + va_start( argp, ctrl1); + + while ((ctrl != NULL) && (*ctrl != (char8)0)) { + + /* move format string chars to buffer until a */ + /* format control is found. */ + if (*ctrl != '%') { +#ifdef STDOUT_BASEADDRESS + outbyte(*ctrl); +#endif + ctrl += 1; + continue; + } + + /* initialize all the flags for this format. */ + dot_flag = 0; +#if defined (__aarch64__) || defined (__arch64__) + long_flag = 0; +#endif + par.unsigned_flag = 0; + par.left_flag = 0; + par.do_padding = 0; + par.pad_character = ' '; + par.num2=32767; + par.num1=0; + par.len=0; + + try_next: + if(ctrl != NULL) { + ctrl += 1; + } + if(ctrl != NULL) { + ch = *ctrl; + } + else { + ch = *ctrl; + } + + if (isdigit((s32)ch) != 0) { + if (dot_flag != 0) { + par.num2 = getnum(&ctrl); + } + else { + if (ch == '0') { + par.pad_character = '0'; + } + if(ctrl != NULL) { + par.num1 = getnum(&ctrl); + } + par.do_padding = 1; + } + if(ctrl != NULL) { + ctrl -= 1; + } + goto try_next; + } + + switch (tolower((s32)ch)) { + case '%': +#ifdef STDOUT_BASEADDRESS + outbyte( '%'); +#endif + Check = 1; + break; + + case '-': + par.left_flag = 1; + Check = 0; + break; + + case '.': + dot_flag = 1; + Check = 0; + break; + + case 'l': + #if defined (__aarch64__) || defined (__arch64__) + long_flag = 1; + #endif + Check = 0; + break; + + case 'u': + par.unsigned_flag = 1; + /* fall through */ + case 'i': + case 'd': + #if defined (__aarch64__) || defined (__arch64__) + if (long_flag != 0){ + outnum1((s64)va_arg(argp, s64), 10L, &par); + } + else { + outnum( va_arg(argp, s32), 10L, &par); + } + #else + outnum( va_arg(argp, s32), 10L, &par); + #endif + Check = 1; + break; + case 'p': + #if defined (__aarch64__) || defined (__arch64__) + par.unsigned_flag = 1; + outnum1((s64)va_arg(argp, s64), 16L, &par); + Check = 1; + break; + #endif + case 'X': + case 'x': + par.unsigned_flag = 1; + #if defined (__aarch64__) || defined (__arch64__) + if (long_flag != 0) { + outnum1((s64)va_arg(argp, s64), 16L, &par); + } + else { + outnum((s32)va_arg(argp, s32), 16L, &par); + } + #else + outnum((s32)va_arg(argp, s32), 16L, &par); + #endif + Check = 1; + break; + + case 's': + outs( va_arg( argp, char *), &par); + Check = 1; + break; + + case 'c': +#ifdef STDOUT_BASEADDRESS + outbyte( va_arg( argp, s32)); +#endif + Check = 1; + break; + + case '\\': + switch (*ctrl) { + case 'a': +#ifdef STDOUT_BASEADDRESS + outbyte( ((char8)0x07)); +#endif + break; + case 'h': +#ifdef STDOUT_BASEADDRESS + outbyte( ((char8)0x08)); +#endif + break; + case 'r': +#ifdef STDOUT_BASEADDRESS + outbyte( ((char8)0x0D)); +#endif + break; + case 'n': +#ifdef STDOUT_BASEADDRESS + outbyte( ((char8)0x0D)); + outbyte( ((char8)0x0A)); +#endif + break; + default: +#ifdef STDOUT_BASEADDRESS + outbyte( *ctrl); +#endif + break; + } + ctrl += 1; + Check = 0; + break; + + default: + Check = 1; + break; + } + if(Check == 1) { + if(ctrl != NULL) { + ctrl += 1; + } + continue; + } + goto try_next; + } + va_end( argp); +} +#endif +/*---------------------------------------------------*/ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_printf.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_printf.h new file mode 100644 index 0000000..a0177fc --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_printf.h @@ -0,0 +1,48 @@ + #ifndef XIL_PRINTF_H + #define XIL_PRINTF_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include "xil_types.h" +#include "xparameters.h" +#include "bspconfig.h" +#if defined (__aarch64__) && HYP_GUEST && EL1_NONSECURE && XEN_USE_PV_CONSOLE +#include "xen_console.h" +#endif + +/*----------------------------------------------------*/ +/* Use the following parameter passing structure to */ +/* make xil_printf re-entrant. */ +/*----------------------------------------------------*/ + +struct params_s; + + +/*---------------------------------------------------*/ +/* The purpose of this routine is to output data the */ +/* same as the standard printf function without the */ +/* overhead most run-time libraries involve. Usually */ +/* the printf brings in many kilobytes of code and */ +/* that is unacceptable in most embedded systems. */ +/*---------------------------------------------------*/ + +typedef char8* charptr; +typedef s32 (*func_ptr)(int c); + +/* */ + +void xil_printf( const char8 *ctrl1, ...); +void print( const char8 *ptr); +extern void outbyte (char8 c); +extern char8 inbyte(void); + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_sleepcommon.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_sleepcommon.c new file mode 100644 index 0000000..cb28204 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_sleepcommon.c @@ -0,0 +1,102 @@ +/****************************************************************************** +* +* Copyright (C) 2017 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +*@file xil_sleepcommon.c +* +* This file contains the sleep API's +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who      Date     Changes
+* ----- -------- -------- -----------------------------------------------
+* 6.6 	srm  	 11/02/17 First release
+* 
+******************************************************************************/ + + +/***************************** Include Files *********************************/ +#include "xil_io.h" +#include "sleep.h" + +/**************************** Constant Definitions *************************/ + + +/*****************************************************************************/ +/** +* +* This API gives delay in sec +* +* @param seconds - delay time in seconds +* +* @return none +* +* @note none +* +*****************************************************************************/ + void sleep(unsigned int seconds) + { +#if defined (ARMR5) + sleep_R5(seconds); +#elif defined (__aarch64__) || defined (ARMA53_32) + sleep_A53(seconds); +#elif defined (__MICROBLAZE__) + sleep_MB(seconds); +#else + sleep_A9(seconds); +#endif + + } + +/****************************************************************************/ +/** +* +* This API gives delay in usec +* +* @param useconds - delay time in useconds +* +* @return none +* +* @note none +* +*****************************************************************************/ + void usleep(unsigned long useconds) + { +#if defined (ARMR5) + usleep_R5(useconds); +#elif defined (__aarch64__) || defined (ARMA53_32) + usleep_A53(useconds); +#elif defined (__MICROBLAZE__) + usleep_MB(useconds); +#else + usleep_A9(useconds); +#endif + + } diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_sleeptimer.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_sleeptimer.c new file mode 100644 index 0000000..316efd5 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_sleeptimer.c @@ -0,0 +1,162 @@ +/****************************************************************************** +* +* Copyright (C) 2017 - 2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ + +/*****************************************************************************/ +/** +* +* @file xil_sleeptimer.c +* +* This file provides the common helper routines for the sleep API's +* +*
+* MODIFICATION HISTORY :
+*
+* Ver   Who  Date	 Changes
+* ----- ---- -------- -------------------------------------------------------
+* 6.6	srm  10/18/17 First Release.
+* 6.6   srm  04/20/18 Fixed compilation warning in Xil_SleepTTCCommon API
+*
+* 
+*****************************************************************************/ + +/**************************** Include Files ********************************/ + +#include "xil_io.h" +#include "xil_sleeptimer.h" +#include "xtime_l.h" + +/**************************** Constant Definitions *************************/ + + +/* Function definitions are applicable only when TTC3 is present*/ +#if defined (SLEEP_TIMER_BASEADDR) +/****************************************************************************/ +/** +* +* This is a helper function used by sleep/usleep APIs to +* have delay in sec/usec +* +* @param delay - delay time in seconds/micro seconds +* +* @param frequency - Number of counts per second/micro second +* +* @return none +* +* @note none +* +*****************************************************************************/ +void Xil_SleepTTCCommon(u32 delay, u64 frequency) +{ + u64 tEnd = 0U; + u64 tCur = 0U; + XCntrVal TimeHighVal = 0U; + XCntrVal TimeLowVal1 = 0U; + XCntrVal TimeLowVal2 = 0U; + + TimeLowVal1 = XSleep_ReadCounterVal(SLEEP_TIMER_BASEADDR + + XSLEEP_TIMER_TTC_COUNT_VALUE_OFFSET); + tEnd = (u64)TimeLowVal1 + ((u64)(delay) * frequency); + do + { + TimeLowVal2 = XSleep_ReadCounterVal(SLEEP_TIMER_BASEADDR + + XSLEEP_TIMER_TTC_COUNT_VALUE_OFFSET); + if (TimeLowVal2 < TimeLowVal1) { + TimeHighVal++; + } + TimeLowVal1 = TimeLowVal2; + tCur = (((u64) TimeHighVal) << XSLEEP_TIMER_REG_SHIFT) | + (u64)TimeLowVal2; + }while (tCur < tEnd); +} + + +/*****************************************************************************/ +/** +* +* This API starts the Triple Timer Counter +* +* @param none +* +* @return none +* +* @note none +* +*****************************************************************************/ +void XTime_StartTTCTimer() +{ + u32 TimerPrescalar; + u32 TimerCntrl; + +#if (defined (__aarch64__) && EL3==1) || defined (ARMR5) || defined (ARMA53_32) + u32 LpdRst; + +#if defined (versal) + u32 RstAddr = CRL_TTC_RST; + u32 RstMask = CRL_TTC_BASE_RST_MASK << XSLEEP_TTC_INSTANCE; +#else + u32 RstAddr = RST_LPD_IOU2; + u32 RstMask = RST_LPD_IOU2_TTC_BASE_RESET_MASK << XSLEEP_TTC_INSTANCE; +#endif + /* check if the timer is reset */ + LpdRst = XSleep_ReadCounterVal(RstAddr); + if ((LpdRst & RstMask) != 0 ) { + LpdRst = LpdRst & (~RstMask); + Xil_Out32(RstAddr, LpdRst); + } else { +#endif + TimerCntrl = XSleep_ReadCounterVal(SLEEP_TIMER_BASEADDR + + XSLEEP_TIMER_TTC_CNT_CNTRL_OFFSET); + /* check if Timer is disabled */ + if ((TimerCntrl & XSLEEP_TIMER_TTC_CNT_CNTRL_DIS_MASK) == 0) { + TimerPrescalar = XSleep_ReadCounterVal(SLEEP_TIMER_BASEADDR + + XSLEEP_TIMER_TTC_CLK_CNTRL_OFFSET); + /* check if Timer is configured with proper functionalty for sleep */ + if ((TimerPrescalar & XSLEEP_TIMER_TTC_CLK_CNTRL_PS_EN_MASK) == 0) + return; + } +#if (defined (__aarch64__) && EL3==1) || defined (ARMR5) || defined (ARMA53_32) + } +#endif + /* Disable the timer to configure */ + TimerCntrl = XSleep_ReadCounterVal(SLEEP_TIMER_BASEADDR + + XSLEEP_TIMER_TTC_CNT_CNTRL_OFFSET); + TimerCntrl = TimerCntrl | XSLEEP_TIMER_TTC_CNT_CNTRL_DIS_MASK; + Xil_Out32(SLEEP_TIMER_BASEADDR + XSLEEP_TIMER_TTC_CNT_CNTRL_OFFSET, + TimerCntrl); + /* Disable the prescalar */ + TimerPrescalar = XSleep_ReadCounterVal(SLEEP_TIMER_BASEADDR + + XSLEEP_TIMER_TTC_CLK_CNTRL_OFFSET); + TimerPrescalar = TimerPrescalar & (~XSLEEP_TIMER_TTC_CLK_CNTRL_PS_EN_MASK); + Xil_Out32(SLEEP_TIMER_BASEADDR + XSLEEP_TIMER_TTC_CLK_CNTRL_OFFSET, + TimerPrescalar); + /* Enable the Timer */ + TimerCntrl = TimerCntrl & (~XSLEEP_TIMER_TTC_CNT_CNTRL_DIS_MASK); + Xil_Out32(SLEEP_TIMER_BASEADDR + XSLEEP_TIMER_TTC_CNT_CNTRL_OFFSET, + TimerCntrl); +} +#endif diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_sleeptimer.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_sleeptimer.h new file mode 100644 index 0000000..08f64ba --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_sleeptimer.h @@ -0,0 +1,128 @@ +/****************************************************************************** +* +* Copyright (C) 2017 - 2019 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xil_sleeptimer.h +* +* This header file contains ARM Cortex A53,A9,R5 specific sleep related APIs. +* For sleep related functions that can be used across all Xilinx supported +* processors, please use xil_sleeptimer.h. +* +* +*
+* MODIFICATION HISTORY :
+*
+* Ver   Who  Date	 Changes
+* ----- ---- -------- -------------------------------------------------------
+* 6.6	srm  10/18/17 First Release.
+* 7.0   mus  01/07/19 Add cpp extern macro
+*
+* 
+*****************************************************************************/ + +#ifndef XIL_SLEEPTIMER_H /* prevent circular inclusions */ +#define XIL_SLEEPTIMER_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/**************************** Include Files ********************************/ + +#include "xil_io.h" +#include "xparameters.h" +#include "bspconfig.h" + +/************************** Constant Definitions *****************************/ + +#if defined (ARMR5) || (__aarch64__) || (ARMA53_32) +#define XSLEEP_TIMER_REG_SHIFT 32U +#define XSleep_ReadCounterVal Xil_In32 +#define XCntrVal u32 +#else +#define XSLEEP_TIMER_REG_SHIFT 16U +#define XSleep_ReadCounterVal Xil_In16 +#define XCntrVal u16 +#endif + +#if defined(ARMR5) || (defined (__aarch64__) && EL3==1) || defined (ARMA53_32) +#if defined (versal) +#define CRL_TTC_RST 0xFF5E0344U +#define CRL_TTC_BASE_RST_MASK 0x1U +#else +#define RST_LPD_IOU2 0xFF5E0238U +#define RST_LPD_IOU2_TTC_BASE_RESET_MASK 0x00000800U +#endif +#endif + +#if defined (SLEEP_TIMER_BASEADDR) +/** @name Register Map +* +* Register offsets from the base address of the TTC device +* +* @{ +*/ + #define XSLEEP_TIMER_TTC_CLK_CNTRL_OFFSET 0x00000000U + /**< Clock Control Register */ + #define XSLEEP_TIMER_TTC_CNT_CNTRL_OFFSET 0x0000000CU + /**< Counter Control Register*/ + #define XSLEEP_TIMER_TTC_COUNT_VALUE_OFFSET 0x00000018U + /**< Current Counter Value */ +/* @} */ +/** @name Clock Control Register +* Clock Control Register definitions of TTC +* @{ +*/ + #define XSLEEP_TIMER_TTC_CLK_CNTRL_PS_EN_MASK 0x00000001U + /**< Prescale enable */ +/* @} */ +/** @name Counter Control Register +* Counter Control Register definitions of TTC +* @{ +*/ +#define XSLEEP_TIMER_TTC_CNT_CNTRL_DIS_MASK 0x00000001U + /**< Disable the counter */ +#define XSLEEP_TIMER_TTC_CNT_CNTRL_RST_MASK 0x00000010U + /**< Reset counter */ +/* @} */ + +/**************************** Type Definitions *******************************/ + +/************************** Function Prototypes ******************************/ + +void Xil_SleepTTCCommon(u32 delay, u64 frequency); +void XTime_StartTTCTimer(); + +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* XIL_SLEEPTIMER_H */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_testcache.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_testcache.c new file mode 100644 index 0000000..6ea52a8 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_testcache.c @@ -0,0 +1,367 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xil_testcache.c +* +* Contains utility functions to test cache. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date	 Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a hbm  07/28/09 Initial release
+* 4.1   asa  05/09/14 Ensured that the address uses for cache test is aligned
+*				      cache line.
+* 
+* +* @note +* This file contain functions that all operate on HAL. +* +******************************************************************************/ +#ifdef __ARM__ +#include "xil_cache.h" +#include "xil_testcache.h" +#include "xil_types.h" +#include "xpseudo_asm.h" +#ifdef __aarch64__ +#include "xreg_cortexa53.h" +#else +#include "xreg_cortexr5.h" +#endif + +#include "xil_types.h" + +extern void xil_printf(const char8 *ctrl1, ...); + +#define DATA_LENGTH 128 + +#ifdef __aarch64__ +static INTPTR Data[DATA_LENGTH] __attribute__ ((aligned(64))); +#else +static INTPTR Data[DATA_LENGTH] __attribute__ ((aligned(32))); +#endif + + +/*****************************************************************************/ +/** +* +* @brief Perform DCache range related API test such as Xil_DCacheFlushRange +* and Xil_DCacheInvalidateRange. This test function writes a constant +* value to the Data array, flushes the range, writes a new value, then +* invalidates the corresponding range. +* @param None +* +* @return +* - -1 is returned for a failure +* - 0 is returned for a pass +* +*****************************************************************************/ +s32 Xil_TestDCacheRange(void) +{ + s32 Index; + s32 Status = 0; + u32 CtrlReg; + INTPTR Value; + + xil_printf("-- Cache Range Test --\n\r"); + + for (Index = 0; Index < DATA_LENGTH; Index++) + Data[Index] = 0xA0A00505; + + xil_printf(" initialize Data done:\r\n"); + + Xil_DCacheFlushRange((INTPTR)Data, DATA_LENGTH * sizeof(INTPTR)); + + xil_printf(" flush range done\r\n"); + + dsb(); + #ifdef __aarch64__ + CtrlReg = mfcp(SCTLR_EL3); + CtrlReg &= ~(XREG_CONTROL_DCACHE_BIT); + mtcp(SCTLR_EL3,CtrlReg); + #else + CtrlReg = mfcp(XREG_CP15_SYS_CONTROL); + CtrlReg &= ~(XREG_CP15_CONTROL_C_BIT); + mtcp(XREG_CP15_SYS_CONTROL, CtrlReg); + #endif + dsb(); + + Status = 0; + + for (Index = 0; Index < DATA_LENGTH; Index++) { + Value = Data[Index]; + if (Value != 0xA0A00505) { + Status = -1; + xil_printf("Data[%d] = %x\r\n", Index, Value); + break; + } + } + + if (!Status) { + xil_printf(" Flush worked\r\n"); + } + else { + xil_printf("Error: flush dcache range not working\r\n"); + } + dsb(); + #ifdef __aarch64__ + CtrlReg = mfcp(SCTLR_EL3); + CtrlReg |= (XREG_CONTROL_DCACHE_BIT); + mtcp(SCTLR_EL3,CtrlReg); + #else + CtrlReg = mfcp(XREG_CP15_SYS_CONTROL); + CtrlReg |= (XREG_CP15_CONTROL_C_BIT); + mtcp(XREG_CP15_SYS_CONTROL, CtrlReg); + #endif + dsb(); + for (Index = 0; Index < DATA_LENGTH; Index++) + Data[Index] = 0xA0A0C505; + + + + Xil_DCacheFlushRange((INTPTR)Data, DATA_LENGTH * sizeof(INTPTR)); + + for (Index = 0; Index < DATA_LENGTH; Index++) + Data[Index] = Index + 3; + + Xil_DCacheInvalidateRange((INTPTR)Data, DATA_LENGTH * sizeof(INTPTR)); + + xil_printf(" invalidate dcache range done\r\n"); + dsb(); + #ifdef __aarch64__ + CtrlReg = mfcp(SCTLR_EL3); + CtrlReg &= ~(XREG_CONTROL_DCACHE_BIT); + mtcp(SCTLR_EL3,CtrlReg); + #else + CtrlReg = mfcp(XREG_CP15_SYS_CONTROL); + CtrlReg &= ~(XREG_CP15_CONTROL_C_BIT); + mtcp(XREG_CP15_SYS_CONTROL, CtrlReg); + #endif + dsb(); + for (Index = 0; Index < DATA_LENGTH; Index++) + Data[Index] = 0xA0A0A05; + dsb(); + #ifdef __aarch64__ + CtrlReg = mfcp(SCTLR_EL3); + CtrlReg |= (XREG_CONTROL_DCACHE_BIT); + mtcp(SCTLR_EL3,CtrlReg); + #else + CtrlReg = mfcp(XREG_CP15_SYS_CONTROL); + CtrlReg |= (XREG_CP15_CONTROL_C_BIT); + mtcp(XREG_CP15_SYS_CONTROL, CtrlReg); + #endif + dsb(); + + Status = 0; + + for (Index = 0; Index < DATA_LENGTH; Index++) { + Value = Data[Index]; + if (Value != 0xA0A0A05) { + Status = -1; + xil_printf("Data[%d] = %x\r\n", Index, Value); + break; + } + } + + + if (!Status) { + xil_printf(" Invalidate worked\r\n"); + } + else { + xil_printf("Error: Invalidate dcache range not working\r\n"); + } + xil_printf("-- Cache Range Test Complete --\r\n"); + return Status; + +} + +/*****************************************************************************/ +/** +* @brief Perform DCache all related API test such as Xil_DCacheFlush and +* Xil_DCacheInvalidate. This test function writes a constant value +* to the Data array, flushes the DCache, writes a new value, +* then invalidates the DCache. +* +* @return +* - 0 is returned for a pass +* - -1 is returned for a failure +*****************************************************************************/ +s32 Xil_TestDCacheAll(void) +{ + s32 Index; + s32 Status; + INTPTR Value; + u32 CtrlReg; + + xil_printf("-- Cache All Test --\n\r"); + + for (Index = 0; Index < DATA_LENGTH; Index++) + Data[Index] = 0x50500A0A; + xil_printf(" initialize Data done:\r\n"); + + Xil_DCacheFlush(); + xil_printf(" flush all done\r\n"); + dsb(); + #ifdef __aarch64__ + CtrlReg = mfcp(SCTLR_EL3); + CtrlReg &= ~(XREG_CONTROL_DCACHE_BIT); + mtcp(SCTLR_EL3,CtrlReg); + #else + CtrlReg = mfcp(XREG_CP15_SYS_CONTROL); + CtrlReg &= ~(XREG_CP15_CONTROL_C_BIT); + mtcp(XREG_CP15_SYS_CONTROL, CtrlReg); + #endif + dsb(); + Status = 0; + + for (Index = 0; Index < DATA_LENGTH; Index++) { + Value = Data[Index]; + + if (Value != 0x50500A0A) { + Status = -1; + xil_printf("Data[%d] = %x\r\n", Index, Value); + break; + } + } + + if (!Status) { + xil_printf(" Flush all worked\r\n"); + } + else { + xil_printf("Error: Flush dcache all not working\r\n"); + } + dsb(); + #ifdef __aarch64__ + CtrlReg = mfcp(SCTLR_EL3); + CtrlReg |= (XREG_CONTROL_DCACHE_BIT); + mtcp(SCTLR_EL3,CtrlReg); + #else + CtrlReg = mfcp(XREG_CP15_SYS_CONTROL); + CtrlReg |= (XREG_CP15_CONTROL_C_BIT); + mtcp(XREG_CP15_SYS_CONTROL, CtrlReg); + #endif + dsb(); + for (Index = 0; Index < DATA_LENGTH; Index++) + Data[Index] = 0x505FFA0A; + + Xil_DCacheFlush(); + + + for (Index = 0; Index < DATA_LENGTH; Index++) + Data[Index] = Index + 3; + + Xil_DCacheInvalidate(); + + xil_printf(" invalidate all done\r\n"); + dsb(); + #ifdef __aarch64__ + CtrlReg = mfcp(SCTLR_EL3); + CtrlReg &= ~(XREG_CONTROL_DCACHE_BIT); + mtcp(SCTLR_EL3,CtrlReg); + #else + CtrlReg = mfcp(XREG_CP15_SYS_CONTROL); + CtrlReg &= ~(XREG_CP15_CONTROL_C_BIT); + mtcp(XREG_CP15_SYS_CONTROL, CtrlReg); + #endif + dsb(); + for (Index = 0; Index < DATA_LENGTH; Index++) + Data[Index] = 0x50CFA0A; + dsb(); + #ifdef __aarch64__ + CtrlReg = mfcp(SCTLR_EL3); + CtrlReg |= (XREG_CONTROL_DCACHE_BIT); + mtcp(SCTLR_EL3,CtrlReg); + #else + CtrlReg = mfcp(XREG_CP15_SYS_CONTROL); + CtrlReg |= (XREG_CP15_CONTROL_C_BIT); + mtcp(XREG_CP15_SYS_CONTROL, CtrlReg); + #endif + dsb(); + Status = 0; + + for (Index = 0; Index < DATA_LENGTH; Index++) { + Value = Data[Index]; + if (Value != 0x50CFA0A) { + Status = -1; + xil_printf("Data[%d] = %x\r\n", Index, Value); + break; + } + } + + if (!Status) { + xil_printf(" Invalidate all worked\r\n"); + } + else { + xil_printf("Error: Invalidate dcache all not working\r\n"); + } + + xil_printf("-- DCache all Test Complete --\n\r"); + + return Status; +} + +/*****************************************************************************/ +/** +* @brief Perform Xil_ICacheInvalidateRange() on a few function pointers. +* +* @return +* - 0 is returned for a pass +* @note +* The function will hang if it fails. +*****************************************************************************/ +s32 Xil_TestICacheRange(void) +{ + + Xil_ICacheInvalidateRange((INTPTR)Xil_TestICacheRange, 1024); + Xil_ICacheInvalidateRange((INTPTR)Xil_TestDCacheRange, 1024); + Xil_ICacheInvalidateRange((INTPTR)Xil_TestDCacheAll, 1024); + + xil_printf("-- Invalidate icache range done --\r\n"); + + return 0; +} + +/*****************************************************************************/ +/** +* @brief Perform Xil_ICacheInvalidate() on a few function pointers. +* +* @return +* - 0 is returned for a pass +* @note +* The function will hang if it fails. +*****************************************************************************/ +s32 Xil_TestICacheAll(void) +{ + Xil_ICacheInvalidate(); + xil_printf("-- Invalidate icache all done --\r\n"); + return 0; +} +#endif diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_testcache.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_testcache.h new file mode 100644 index 0000000..8289ca9 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_testcache.h @@ -0,0 +1,67 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xil_testcache.h +* +* @addtogroup common_test_utils +*

Cache test

+* The xil_testcache.h file contains utility functions to test cache. +* +* @{ +*
+* Ver    Who    Date    Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a hbm  07/29/09 First release
+* 
+* +******************************************************************************/ + +#ifndef XIL_TESTCACHE_H /* prevent circular inclusions */ +#define XIL_TESTCACHE_H /* by using protection macros */ + +#include "xil_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern s32 Xil_TestDCacheRange(void); +extern s32 Xil_TestDCacheAll(void); +extern s32 Xil_TestICacheRange(void); +extern s32 Xil_TestICacheAll(void); + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** +* @} End of "addtogroup common_test_utils". +*/ \ No newline at end of file diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_testio.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_testio.c new file mode 100644 index 0000000..9a13a64 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_testio.c @@ -0,0 +1,295 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xil_testio.c +* +* Contains the memory test utility functions. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver    Who    Date    Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a hbm  08/25/09 First release
+* 
+* +*****************************************************************************/ + +/***************************** Include Files ********************************/ +#include "xil_testio.h" +#include "xil_assert.h" +#include "xil_io.h" + +/************************** Constant Definitions ****************************/ +/************************** Function Prototypes *****************************/ + + + +/** + * + * Endian swap a 16-bit word. + * @param Data is the 16-bit word to be swapped. + * @return The endian swapped value. + * + */ +static u16 Swap16(u16 Data) +{ + return ((Data >> 8U) & 0x00FFU) | ((Data << 8U) & 0xFF00U); +} + +/** + * + * Endian swap a 32-bit word. + * @param Data is the 32-bit word to be swapped. + * @return The endian swapped value. + * + */ +static u32 Swap32(u32 Data) +{ + u16 Lo16; + u16 Hi16; + + u16 Swap16Lo; + u16 Swap16Hi; + + Hi16 = (u16)((Data >> 16U) & 0x0000FFFFU); + Lo16 = (u16)(Data & 0x0000FFFFU); + + Swap16Lo = Swap16(Lo16); + Swap16Hi = Swap16(Hi16); + + return (((u32)(Swap16Lo)) << 16U) | ((u32)Swap16Hi); +} + +/*****************************************************************************/ +/** +* +* @brief Perform a destructive 8-bit wide register IO test where the +* register is accessed using Xil_Out8 and Xil_In8, and comparing +* the written values by reading them back. +* +* @param Addr: a pointer to the region of memory to be tested. +* @param Length: Length of the block. +* @param Value: constant used for writting the memory. +* +* @return +* - -1 is returned for a failure +* - 0 is returned for a pass +* +*****************************************************************************/ + +s32 Xil_TestIO8(u8 *Addr, s32 Length, u8 Value) +{ + u8 ValueIn; + s32 Index; + s32 Status = 0; + + for (Index = 0; Index < Length; Index++) { + Xil_Out8((INTPTR)Addr, Value); + + ValueIn = Xil_In8((INTPTR)Addr); + + if ((Value != ValueIn) && (Status == 0)) { + Status = -1; + break; + } + } + return Status; + +} + +/*****************************************************************************/ +/** +* +* @brief Perform a destructive 16-bit wide register IO test. Each location +* is tested by sequentially writing a 16-bit wide register, reading +* the register, and comparing value. This function tests three kinds +* of register IO functions, normal register IO, little-endian register +* IO, and big-endian register IO. When testing little/big-endian IO, +* the function performs the following sequence, Xil_Out16LE/Xil_Out16BE, +* Xil_In16, Compare In-Out values, Xil_Out16, Xil_In16LE/Xil_In16BE, +* Compare In-Out values. Whether to swap the read-in value before +* comparing is controlled by the 5th argument. +* +* @param Addr: a pointer to the region of memory to be tested. +* @param Length: Length of the block. +* @param Value: constant used for writting the memory. +* @param Kind: Type of test. Acceptable values are: +* XIL_TESTIO_DEFAULT, XIL_TESTIO_LE, XIL_TESTIO_BE. +* @param Swap: indicates whether to byte swap the read-in value. +* +* @return +* - -1 is returned for a failure +* - 0 is returned for a pass +* +*****************************************************************************/ + +s32 Xil_TestIO16(u16 *Addr, s32 Length, u16 Value, s32 Kind, s32 Swap) +{ + u16 *TempAddr16; + u16 ValueIn = 0U; + s32 Index; + TempAddr16 = Addr; + Xil_AssertNonvoid(TempAddr16 != NULL); + + for (Index = 0; Index < Length; Index++) { + switch (Kind) { + case XIL_TESTIO_LE: + Xil_Out16LE((INTPTR)TempAddr16, Value); + break; + case XIL_TESTIO_BE: + Xil_Out16BE((INTPTR)TempAddr16, Value); + break; + default: + Xil_Out16((INTPTR)TempAddr16, Value); + break; + } + + ValueIn = Xil_In16((INTPTR)TempAddr16); + + if ((Kind != 0) && (Swap != 0)) { + ValueIn = Swap16(ValueIn); + } + + if (Value != ValueIn) { + return -1; + } + + /* second round */ + Xil_Out16((INTPTR)TempAddr16, Value); + + switch (Kind) { + case XIL_TESTIO_LE: + ValueIn = Xil_In16LE((INTPTR)TempAddr16); + break; + case XIL_TESTIO_BE: + ValueIn = Xil_In16BE((INTPTR)TempAddr16); + break; + default: + ValueIn = Xil_In16((INTPTR)TempAddr16); + break; + } + + + if ((Kind != 0) && (Swap != 0)) { + ValueIn = Swap16(ValueIn); + } + + if (Value != ValueIn) { + return -1; + } + TempAddr16 += sizeof(u16); + } + return 0; +} + + +/*****************************************************************************/ +/** +* +* @brief Perform a destructive 32-bit wide register IO test. Each location +* is tested by sequentially writing a 32-bit wide regsiter, reading +* the register, and comparing value. This function tests three kinds +* of register IO functions, normal register IO, little-endian register IO, +* and big-endian register IO. When testing little/big-endian IO, +* the function perform the following sequence, Xil_Out32LE/ +* Xil_Out32BE, Xil_In32, Compare, Xil_Out32, Xil_In32LE/Xil_In32BE, Compare. +* Whether to swap the read-in value *before comparing is controlled +* by the 5th argument. +* @param Addr: a pointer to the region of memory to be tested. +* @param Length: Length of the block. +* @param Value: constant used for writting the memory. +* @param Kind: type of test. Acceptable values are: +* XIL_TESTIO_DEFAULT, XIL_TESTIO_LE, XIL_TESTIO_BE. +* @param Swap: indicates whether to byte swap the read-in value. +* +* @return +* - -1 is returned for a failure +* - 0 is returned for a pass +* +*****************************************************************************/ +s32 Xil_TestIO32(u32 *Addr, s32 Length, u32 Value, s32 Kind, s32 Swap) +{ + u32 *TempAddr; + u32 ValueIn = 0U; + s32 Index; + TempAddr = Addr; + Xil_AssertNonvoid(TempAddr != NULL); + + for (Index = 0; Index < Length; Index++) { + switch (Kind) { + case XIL_TESTIO_LE: + Xil_Out32LE((INTPTR)TempAddr, Value); + break; + case XIL_TESTIO_BE: + Xil_Out32BE((INTPTR)TempAddr, Value); + break; + default: + Xil_Out32((INTPTR)TempAddr, Value); + break; + } + + ValueIn = Xil_In32((INTPTR)TempAddr); + + if ((Kind != 0) && (Swap != 0)) { + ValueIn = Swap32(ValueIn); + } + + if (Value != ValueIn) { + return -1; + } + + /* second round */ + Xil_Out32((INTPTR)TempAddr, Value); + + + switch (Kind) { + case XIL_TESTIO_LE: + ValueIn = Xil_In32LE((INTPTR)TempAddr); + break; + case XIL_TESTIO_BE: + ValueIn = Xil_In32BE((INTPTR)TempAddr); + break; + default: + ValueIn = Xil_In32((INTPTR)TempAddr); + break; + } + + if ((Kind != 0) && (Swap != 0)) { + ValueIn = Swap32(ValueIn); + } + + if (Value != ValueIn) { + return -1; + } + TempAddr += sizeof(u32); + } + return 0; +} diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_testio.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_testio.h new file mode 100644 index 0000000..6f0fc1c --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_testio.h @@ -0,0 +1,90 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xil_testio.h +* +* @addtogroup common_test_utils Test Utilities +*

I/O test

+* The xil_testio.h file contains utility functions to test endian related memory +* IO functions. +* +* A subset of the memory tests can be selected or all of the tests can be run +* in order. If there is an error detected by a subtest, the test stops and the +* failure code is returned. Further tests are not run even if all of the tests +* are selected. +* +* @{ +*
+* MODIFICATION HISTORY:
+*
+* Ver    Who    Date    Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00 hbm  08/05/09 First release
+* 
+* +******************************************************************************/ + +#ifndef XIL_TESTIO_H /* prevent circular inclusions */ +#define XIL_TESTIO_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ +#include "xil_types.h" + +/************************** Constant Definitions *****************************/ + + +#define XIL_TESTIO_DEFAULT 0 +#define XIL_TESTIO_LE 1 +#define XIL_TESTIO_BE 2 + +/**************************** Type Definitions *******************************/ + + +/***************** Macros (Inline Functions) Definitions *********************/ + + +/************************** Function Prototypes ******************************/ + +extern s32 Xil_TestIO8(u8 *Addr, s32 Length, u8 Value); +extern s32 Xil_TestIO16(u16 *Addr, s32 Length, u16 Value, s32 Kind, s32 Swap); +extern s32 Xil_TestIO32(u32 *Addr, s32 Length, u32 Value, s32 Kind, s32 Swap); + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** +* @} End of "addtogroup common_test_utils". +*/ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_testmem.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_testmem.c new file mode 100644 index 0000000..b7eb68b --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_testmem.c @@ -0,0 +1,864 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xil_testmem.c +* +* Contains the memory test utility functions. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver    Who    Date    Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a hbm  08/25/09 First release
+* 
+* +*****************************************************************************/ + +/***************************** Include Files ********************************/ +#include "xil_testmem.h" +#include "xil_io.h" +#include "xil_assert.h" + +/************************** Constant Definitions ****************************/ +/************************** Function Prototypes *****************************/ + +static u32 RotateLeft(u32 Input, u8 Width); + +/* define ROTATE_RIGHT to give access to this functionality */ +/* #define ROTATE_RIGHT */ +#ifdef ROTATE_RIGHT +static u32 RotateRight(u32 Input, u8 Width); +#endif /* ROTATE_RIGHT */ + + +/*****************************************************************************/ +/** +* +* @brief Perform a destructive 32-bit wide memory test. +* +* @param Addr: pointer to the region of memory to be tested. +* @param Words: length of the block. +* @param Pattern: constant used for the constant pattern test, if 0, +* 0xDEADBEEF is used. +* @param Subtest: test type selected. See xil_testmem.h for possible +* values. +* +* @return +* - 0 is returned for a pass +* - 1 is returned for a failure +* +* @note +* Used for spaces where the address range of the region is smaller than +* the data width. If the memory range is greater than 2 ** Width, +* the patterns used in XIL_TESTMEM_WALKONES and XIL_TESTMEM_WALKZEROS will +* repeat on a boundry of a power of two making it more difficult to detect +* addressing errors. The XIL_TESTMEM_INCREMENT and XIL_TESTMEM_INVERSEADDR +* tests suffer the same problem. Ideally, if large blocks of memory are to be +* tested, break them up into smaller regions of memory to allow the test +* patterns used not to repeat over the region tested. +* +*****************************************************************************/ +s32 Xil_TestMem32(u32 *Addr, u32 Words, u32 Pattern, u8 Subtest) +{ + u32 I; + u32 j; + u32 Val; + u32 FirtVal; + u32 WordMem32; + s32 Status = 0; + + Xil_AssertNonvoid(Words != (u32)0); + Xil_AssertNonvoid(Subtest <= (u8)XIL_TESTMEM_MAXTEST); + Xil_AssertNonvoid(Addr != NULL); + + /* + * variable initialization + */ + Val = XIL_TESTMEM_INIT_VALUE; + FirtVal = XIL_TESTMEM_INIT_VALUE; + + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_INCREMENT)) { + /* + * Fill the memory with incrementing + * values starting from 'FirtVal' + */ + for (I = 0U; I < Words; I++) { + *(Addr+I) = Val; + Val++; + } + + /* + * Restore the reference 'Val' to the + * initial value + */ + Val = FirtVal; + + /* + * Check every word within the words + * of tested memory and compare it + * with the incrementing reference + * Val + */ + + for (I = 0U; I < Words; I++) { + WordMem32 = *(Addr+I); + + if (WordMem32 != Val) { + Status = -1; + goto End_Label; + } + + Val++; + } + } + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_WALKONES)) { + /* + * set up to cycle through all possible initial + * test Patterns for walking ones test + */ + + for (j = 0U; j < (u32)32; j++) { + /* + * Generate an initial value for walking ones test + * to test for bad data bits + */ + + Val = (1U << j); + + /* + * START walking ones test + * Write a one to each data bit indifferent locations + */ + + for (I = 0U; I < (u32)32; I++) { + /* write memory location */ + *(Addr+I) = Val; + Val = (u32) RotateLeft(Val, 32U); + } + + /* + * Restore the reference 'val' to the + * initial value + */ + Val = 1U << j; + + /* Read the values from each location that was + * written */ + for (I = 0U; I < (u32)32; I++) { + /* read memory location */ + + WordMem32 = *(Addr+I); + + if (WordMem32 != Val) { + Status = -1; + goto End_Label; + } + + Val = (u32)RotateLeft(Val, 32U); + } + } + } + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_WALKZEROS)) { + /* + * set up to cycle through all possible + * initial test Patterns for walking zeros test + */ + + for (j = 0U; j < (u32)32; j++) { + + /* + * Generate an initial value for walking ones test + * to test for bad data bits + */ + + Val = ~(1U << j); + + /* + * START walking zeros test + * Write a one to each data bit indifferent locations + */ + + for (I = 0U; I < (u32)32; I++) { + /* write memory location */ + *(Addr+I) = Val; + Val = ~((u32)RotateLeft(~Val, 32U)); + } + + /* + * Restore the reference 'Val' to the + * initial value + */ + + Val = ~(1U << j); + + /* Read the values from each location that was + * written */ + for (I = 0U; I < (u32)32; I++) { + /* read memory location */ + WordMem32 = *(Addr+I); + if (WordMem32 != Val) { + Status = -1; + goto End_Label; + } + Val = ~((u32)RotateLeft(~Val, 32U)); + } + + } + } + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_INVERSEADDR)) { + /* Fill the memory with inverse of address */ + for (I = 0U; I < Words; I++) { + /* write memory location */ + Val = (u32) (~((INTPTR) (&Addr[I]))); + *(Addr+I) = Val; + } + + /* + * Check every word within the words + * of tested memory + */ + + for (I = 0U; I < Words; I++) { + /* Read the location */ + WordMem32 = *(Addr+I); + Val = (u32) (~((INTPTR) (&Addr[I]))); + + if ((WordMem32 ^ Val) != 0x00000000U) { + Status = -1; + goto End_Label; + } + } + } + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_FIXEDPATTERN)) { + /* + * Generate an initial value for + * memory testing + */ + + if (Pattern == (u32)0) { + Val = 0xDEADBEEFU; + } + else { + Val = Pattern; + } + + /* + * Fill the memory with fixed Pattern + */ + + for (I = 0U; I < Words; I++) { + /* write memory location */ + *(Addr+I) = Val; + } + + /* + * Check every word within the words + * of tested memory and compare it + * with the fixed Pattern + */ + + for (I = 0U; I < Words; I++) { + + /* read memory location */ + + WordMem32 = *(Addr+I); + if (WordMem32 != Val) { + Status = -1; + goto End_Label; + } + } + } + +End_Label: + return Status; +} + +/*****************************************************************************/ +/** +* +* @brief Perform a destructive 16-bit wide memory test. +* +* @param Addr: pointer to the region of memory to be tested. +* @param Words: length of the block. +* @param Pattern: constant used for the constant Pattern test, if 0, +* 0xDEADBEEF is used. +* @param Subtest: type of test selected. See xil_testmem.h for possible +* values. +* +* @return +* +* - -1 is returned for a failure +* - 0 is returned for a pass +* +* @note +* Used for spaces where the address range of the region is smaller than +* the data width. If the memory range is greater than 2 ** Width, +* the patterns used in XIL_TESTMEM_WALKONES and XIL_TESTMEM_WALKZEROS will +* repeat on a boundry of a power of two making it more difficult to detect +* addressing errors. The XIL_TESTMEM_INCREMENT and XIL_TESTMEM_INVERSEADDR +* tests suffer the same problem. Ideally, if large blocks of memory are to be +* tested, break them up into smaller regions of memory to allow the test +* patterns used not to repeat over the region tested. +* +*****************************************************************************/ +s32 Xil_TestMem16(u16 *Addr, u32 Words, u16 Pattern, u8 Subtest) +{ + u32 I; + u32 j; + u16 Val; + u16 FirtVal; + u16 WordMem16; + s32 Status = 0; + + Xil_AssertNonvoid(Words != (u32)0); + Xil_AssertNonvoid(Subtest <= XIL_TESTMEM_MAXTEST); + Xil_AssertNonvoid(Addr != NULL); + + /* + * variable initialization + */ + Val = XIL_TESTMEM_INIT_VALUE; + FirtVal = XIL_TESTMEM_INIT_VALUE; + + /* + * selectthe proper Subtest(s) + */ + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_INCREMENT)) { + /* + * Fill the memory with incrementing + * values starting from 'FirtVal' + */ + for (I = 0U; I < Words; I++) { + /* write memory location */ + *(Addr+I) = Val; + Val++; + } + /* + * Restore the reference 'Val' to the + * initial value + */ + Val = FirtVal; + + /* + * Check every word within the words + * of tested memory and compare it + * with the incrementing reference val + */ + + for (I = 0U; I < Words; I++) { + /* read memory location */ + WordMem16 = *(Addr+I); + if (WordMem16 != Val) { + Status = -1; + goto End_Label; + } + Val++; + } + } + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_WALKONES)) { + /* + * set up to cycle through all possible initial test + * Patterns for walking ones test + */ + + for (j = 0U; j < (u32)16; j++) { + /* + * Generate an initial value for walking ones test + * to test for bad data bits + */ + + Val = (u16)((u32)1 << j); + /* + * START walking ones test + * Write a one to each data bit indifferent locations + */ + + for (I = 0U; I < (u32)16; I++) { + /* write memory location */ + *(Addr+I) = Val; + Val = (u16)RotateLeft(Val, 16U); + } + /* + * Restore the reference 'Val' to the + * initial value + */ + Val = (u16)((u32)1 << j); + /* Read the values from each location that was written */ + for (I = 0U; I < (u32)16; I++) { + /* read memory location */ + WordMem16 = *(Addr+I); + if (WordMem16 != Val) { + Status = -1; + goto End_Label; + } + Val = (u16)RotateLeft(Val, 16U); + } + } + } + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_WALKZEROS)) { + /* + * set up to cycle through all possible initial + * test Patterns for walking zeros test + */ + + for (j = 0U; j < (u32)16; j++) { + /* + * Generate an initial value for walking ones + * test to test for bad + * data bits + */ + + Val = ~(1U << j); + /* + * START walking zeros test + * Write a one to each data bit indifferent locations + */ + + for (I = 0U; I < (u32)16; I++) { + /* write memory location */ + *(Addr+I) = Val; + Val = ~((u16)RotateLeft(~Val, 16U)); + } + /* + * Restore the reference 'Val' to the + * initial value + */ + Val = ~(1U << j); + /* Read the values from each location that was written */ + for (I = 0U; I < (u32)16; I++) { + /* read memory location */ + WordMem16 = *(Addr+I); + if (WordMem16 != Val) { + Status = -1; + goto End_Label; + } + Val = ~((u16)RotateLeft(~Val, 16U)); + } + + } + } + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_INVERSEADDR)) { + /* Fill the memory with inverse of address */ + for (I = 0U; I < Words; I++) { + /* write memory location */ + Val = (u16) (~((INTPTR)(&Addr[I]))); + *(Addr+I) = Val; + } + /* + * Check every word within the words + * of tested memory + */ + + for (I = 0U; I < Words; I++) { + /* read memory location */ + WordMem16 = *(Addr+I); + Val = (u16) (~((INTPTR) (&Addr[I]))); + if ((WordMem16 ^ Val) != 0x0000U) { + Status = -1; + goto End_Label; + } + } + } + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_FIXEDPATTERN)) { + /* + * Generate an initial value for + * memory testing + */ + if (Pattern == (u16)0) { + Val = 0xDEADU; + } + else { + Val = Pattern; + } + + /* + * Fill the memory with fixed pattern + */ + + for (I = 0U; I < Words; I++) { + /* write memory location */ + *(Addr+I) = Val; + } + + /* + * Check every word within the words + * of tested memory and compare it + * with the fixed pattern + */ + + for (I = 0U; I < Words; I++) { + /* read memory location */ + WordMem16 = *(Addr+I); + if (WordMem16 != Val) { + Status = -1; + goto End_Label; + } + } + } + +End_Label: + return Status; +} + + +/*****************************************************************************/ +/** +* +* @brief Perform a destructive 8-bit wide memory test. +* +* @param Addr: pointer to the region of memory to be tested. +* @param Words: length of the block. +* @param Pattern: constant used for the constant pattern test, if 0, +* 0xDEADBEEF is used. +* @param Subtest: type of test selected. See xil_testmem.h for possible +* values. +* +* @return +* - -1 is returned for a failure +* - 0 is returned for a pass +* +* @note +* Used for spaces where the address range of the region is smaller than +* the data width. If the memory range is greater than 2 ** Width, +* the patterns used in XIL_TESTMEM_WALKONES and XIL_TESTMEM_WALKZEROS will +* repeat on a boundry of a power of two making it more difficult to detect +* addressing errors. The XIL_TESTMEM_INCREMENT and XIL_TESTMEM_INVERSEADDR +* tests suffer the same problem. Ideally, if large blocks of memory are to be +* tested, break them up into smaller regions of memory to allow the test +* patterns used not to repeat over the region tested. +* +*****************************************************************************/ +s32 Xil_TestMem8(u8 *Addr, u32 Words, u8 Pattern, u8 Subtest) +{ + u32 I; + u32 j; + u8 Val; + u8 FirtVal; + u8 WordMem8; + s32 Status = 0; + + Xil_AssertNonvoid(Words != (u32)0); + Xil_AssertNonvoid(Subtest <= XIL_TESTMEM_MAXTEST); + Xil_AssertNonvoid(Addr != NULL); + + /* + * variable initialization + */ + Val = XIL_TESTMEM_INIT_VALUE; + FirtVal = XIL_TESTMEM_INIT_VALUE; + + /* + * select the proper Subtest(s) + */ + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_INCREMENT)) { + /* + * Fill the memory with incrementing + * values starting from 'FirtVal' + */ + for (I = 0U; I < Words; I++) { + /* write memory location */ + *(Addr+I) = Val; + Val++; + } + /* + * Restore the reference 'Val' to the + * initial value + */ + Val = FirtVal; + /* + * Check every word within the words + * of tested memory and compare it + * with the incrementing reference + * Val + */ + + for (I = 0U; I < Words; I++) { + /* read memory location */ + WordMem8 = *(Addr+I); + if (WordMem8 != Val) { + Status = -1; + goto End_Label; + } + Val++; + } + } + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_WALKONES)) { + /* + * set up to cycle through all possible initial + * test Patterns for walking ones test + */ + + for (j = 0U; j < (u32)8; j++) { + /* + * Generate an initial value for walking ones test + * to test for bad data bits + */ + Val = (u8)((u32)1 << j); + /* + * START walking ones test + * Write a one to each data bit indifferent locations + */ + for (I = 0U; I < (u32)8; I++) { + /* write memory location */ + *(Addr+I) = Val; + Val = (u8)RotateLeft(Val, 8U); + } + /* + * Restore the reference 'Val' to the + * initial value + */ + Val = (u8)((u32)1 << j); + /* Read the values from each location that was written */ + for (I = 0U; I < (u32)8; I++) { + /* read memory location */ + WordMem8 = *(Addr+I); + if (WordMem8 != Val) { + Status = -1; + goto End_Label; + } + Val = (u8)RotateLeft(Val, 8U); + } + } + } + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_WALKZEROS)) { + /* + * set up to cycle through all possible initial test + * Patterns for walking zeros test + */ + + for (j = 0U; j < (u32)8; j++) { + /* + * Generate an initial value for walking ones test to test + * for bad data bits + */ + Val = ~(1U << j); + /* + * START walking zeros test + * Write a one to each data bit indifferent locations + */ + for (I = 0U; I < (u32)8; I++) { + /* write memory location */ + *(Addr+I) = Val; + Val = ~((u8)RotateLeft(~Val, 8U)); + } + /* + * Restore the reference 'Val' to the + * initial value + */ + Val = ~(1U << j); + /* Read the values from each location that was written */ + for (I = 0U; I < (u32)8; I++) { + /* read memory location */ + WordMem8 = *(Addr+I); + if (WordMem8 != Val) { + Status = -1; + goto End_Label; + } + + Val = ~((u8)RotateLeft(~Val, 8U)); + } + } + } + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_INVERSEADDR)) { + /* Fill the memory with inverse of address */ + for (I = 0U; I < Words; I++) { + /* write memory location */ + Val = (u8) (~((INTPTR) (&Addr[I]))); + *(Addr+I) = Val; + } + + /* + * Check every word within the words + * of tested memory + */ + + for (I = 0U; I < Words; I++) { + /* read memory location */ + WordMem8 = *(Addr+I); + Val = (u8) (~((INTPTR) (&Addr[I]))); + if ((WordMem8 ^ Val) != 0x00U) { + Status = -1; + goto End_Label; + } + } + } + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_FIXEDPATTERN)) { + /* + * Generate an initial value for + * memory testing + */ + + if (Pattern == (u8)0) { + Val = 0xA5U; + } + else { + Val = Pattern; + } + /* + * Fill the memory with fixed Pattern + */ + for (I = 0U; I < Words; I++) { + /* write memory location */ + *(Addr+I) = Val; + } + /* + * Check every word within the words + * of tested memory and compare it + * with the fixed Pattern + */ + + for (I = 0U; I < Words; I++) { + /* read memory location */ + WordMem8 = *(Addr+I); + if (WordMem8 != Val) { + Status = -1; + goto End_Label; + } + } + } + +End_Label: + return Status; +} + + +/*****************************************************************************/ +/** +* +* @brief Rotates the provided value to the left one bit position +* +* @param Input is value to be rotated to the left +* @param Width is the number of bits in the input data +* +* @return +* The resulting unsigned long value of the rotate left +* +* +*****************************************************************************/ +static u32 RotateLeft(u32 Input, u8 Width) +{ + u32 Msb; + u32 ReturnVal; + u32 WidthMask; + u32 MsbMask; + u32 LocalInput = Input; + + /* + * set up the WidthMask and the MsbMask + */ + + MsbMask = 1U << (Width - 1U); + + WidthMask = (MsbMask << (u32)1) - (u32)1; + + /* + * set the Width of the Input to the correct width + */ + + LocalInput = LocalInput & WidthMask; + + Msb = LocalInput & MsbMask; + + ReturnVal = LocalInput << 1U; + + if (Msb != 0x00000000U) { + ReturnVal = ReturnVal | (u32)0x00000001; + } + + ReturnVal = ReturnVal & WidthMask; + + return ReturnVal; + +} + +#ifdef ROTATE_RIGHT +/*****************************************************************************/ +/** +* +* @brief Rotates the provided value to the right one bit position +* +* @param Input: value to be rotated to the right +* @param Width: number of bits in the input data +* +* @return +* The resulting u32 value of the rotate right +* +*****************************************************************************/ +static u32 RotateRight(u32 Input, u8 Width) +{ + u32 Lsb; + u32 ReturnVal; + u32 WidthMask; + u32 MsbMask; + u32 LocalInput = Input; + /* + * set up the WidthMask and the MsbMask + */ + + MsbMask = 1U << (Width - 1U); + + WidthMask = (MsbMask << 1U) - 1U; + + /* + * set the width of the input to the correct width + */ + + LocalInput = LocalInput & WidthMask; + + ReturnVal = LocalInput >> 1U; + + Lsb = LocalInput & 0x00000001U; + + if (Lsb != 0x00000000U) { + ReturnVal = ReturnVal | MsbMask; + } + + ReturnVal = ReturnVal & WidthMask; + + return ReturnVal; + +} +#endif /* ROTATE_RIGHT */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_testmem.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_testmem.h new file mode 100644 index 0000000..ecce6b7 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_testmem.h @@ -0,0 +1,154 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xil_testmem.h +* @addtogroup common_test_utils +* +*

Memory test

+* +* The xil_testmem.h file contains utility functions to test memory. +* A subset of the memory tests can be selected or all of the tests can be run +* in order. If there is an error detected by a subtest, the test stops and the +* failure code is returned. Further tests are not run even if all of the tests +* are selected. +* Following list describes the supported memory tests: +* +* - XIL_TESTMEM_ALLMEMTESTS: This test runs all of the subtests. +* +* - XIL_TESTMEM_INCREMENT: This test +* starts at 'XIL_TESTMEM_INIT_VALUE' and uses the incrementing value as the +* test value for memory. +* +* - XIL_TESTMEM_WALKONES: Also known as the Walking ones test. This test +* uses a walking '1' as the test value for memory. +* @code +* location 1 = 0x00000001 +* location 2 = 0x00000002 +* ... +* @endcode +* +* - XIL_TESTMEM_WALKZEROS: Also known as the Walking zero's test. +* This test uses the inverse value of the walking ones test +* as the test value for memory. +* @code +* location 1 = 0xFFFFFFFE +* location 2 = 0xFFFFFFFD +* ... +*@endcode +* +* - XIL_TESTMEM_INVERSEADDR: Also known as the inverse address test. +* This test uses the inverse of the address of the location under test +* as the test value for memory. +* +* - XIL_TESTMEM_FIXEDPATTERN: Also known as the fixed pattern test. +* This test uses the provided patters as the test value for memory. +* If zero is provided as the pattern the test uses '0xDEADBEEF". +* +* @warning +* The tests are DESTRUCTIVE. Run before any initialized memory spaces +* have been set up. +* The address provided to the memory tests is not checked for +* validity except for the NULL case. It is possible to provide a code-space +* pointer for this test to start with and ultimately destroy executable code +* causing random failures. +* +* @note +* Used for spaces where the address range of the region is smaller than +* the data width. If the memory range is greater than 2 ** width, +* the patterns used in XIL_TESTMEM_WALKONES and XIL_TESTMEM_WALKZEROS will +* repeat on a boundry of a power of two making it more difficult to detect +* addressing errors. The XIL_TESTMEM_INCREMENT and XIL_TESTMEM_INVERSEADDR +* tests suffer the same problem. Ideally, if large blocks of memory are to be +* tested, break them up into smaller regions of memory to allow the test +* patterns used not to repeat over the region tested. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver    Who    Date    Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a hbm  08/25/09 First release
+* 
+* +******************************************************************************/ + +#ifndef XIL_TESTMEM_H /* prevent circular inclusions */ +#define XIL_TESTMEM_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ +#include "xil_types.h" + +/************************** Constant Definitions *****************************/ + + +/**************************** Type Definitions *******************************/ + +/* xutil_memtest defines */ + +#define XIL_TESTMEM_INIT_VALUE 1U + +/** @name Memory subtests + * @{ + */ +/** + * See the detailed description of the subtests in the file description. + */ +#define XIL_TESTMEM_ALLMEMTESTS 0x00U +#define XIL_TESTMEM_INCREMENT 0x01U +#define XIL_TESTMEM_WALKONES 0x02U +#define XIL_TESTMEM_WALKZEROS 0x03U +#define XIL_TESTMEM_INVERSEADDR 0x04U +#define XIL_TESTMEM_FIXEDPATTERN 0x05U +#define XIL_TESTMEM_MAXTEST XIL_TESTMEM_FIXEDPATTERN +/* @} */ + +/***************** Macros (Inline Functions) Definitions *********************/ + + +/************************** Function Prototypes ******************************/ + +/* xutil_testmem prototypes */ + +extern s32 Xil_TestMem32(u32 *Addr, u32 Words, u32 Pattern, u8 Subtest); +extern s32 Xil_TestMem16(u16 *Addr, u32 Words, u16 Pattern, u8 Subtest); +extern s32 Xil_TestMem8(u8 *Addr, u32 Words, u8 Pattern, u8 Subtest); + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** +* @} End of "addtogroup common_test_utils". +*/ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_types.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_types.h new file mode 100644 index 0000000..625ff8c --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_types.h @@ -0,0 +1,214 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2019 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xil_types.h +* +* @addtogroup common_types Basic Data types for Xilinx® Software IP +* +* The xil_types.h file contains basic types for Xilinx software IP. These data types +* are applicable for all processors supported by Xilinx. +* @{ +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date   Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a hbm  07/14/09 First release
+* 3.03a sdm  05/30/11 Added Xuint64 typedef and XUINT64_MSW/XUINT64_LSW macros
+* 5.00 	pkp  05/29/14 Made changes for 64 bit architecture
+*	srt  07/14/14 Use standard definitions from stdint.h and stddef.h
+*		      Define LONG and ULONG datatypes and mask values
+* 7.00  mus  01/07/19 Add cpp extern macro
+* 
+* +******************************************************************************/ + +#ifndef XIL_TYPES_H /* prevent circular inclusions */ +#define XIL_TYPES_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/************************** Constant Definitions *****************************/ + +#ifndef TRUE +# define TRUE 1U +#endif + +#ifndef FALSE +# define FALSE 0U +#endif + +#ifndef NULL +#define NULL 0U +#endif + +#define XIL_COMPONENT_IS_READY 0x11111111U /**< In device drivers, This macro will be + assigend to "IsReady" member of driver + instance to indicate that driver + instance is initialized and ready to use. */ +#define XIL_COMPONENT_IS_STARTED 0x22222222U /**< In device drivers, This macro will be assigend to + "IsStarted" member of driver instance + to indicate that driver instance is + started and it can be enabled. */ + +/* @name New types + * New simple types. + * @{ + */ +#ifndef __KERNEL__ +#ifndef XBASIC_TYPES_H +/* + * guarded against xbasic_types.h. + */ +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +/** @}*/ +#define __XUINT64__ +typedef struct +{ + u32 Upper; + u32 Lower; +} Xuint64; + + +/*****************************************************************************/ +/** +* @brief Return the most significant half of the 64 bit data type. +* +* @param x is the 64 bit word. +* +* @return The upper 32 bits of the 64 bit word. +* +******************************************************************************/ +#define XUINT64_MSW(x) ((x).Upper) + +/*****************************************************************************/ +/** +* @brief Return the least significant half of the 64 bit data type. +* +* @param x is the 64 bit word. +* +* @return The lower 32 bits of the 64 bit word. +* +******************************************************************************/ +#define XUINT64_LSW(x) ((x).Lower) + +#endif /* XBASIC_TYPES_H */ + +/* + * xbasic_types.h does not typedef s* or u64 + */ +/** @{ */ +typedef char char8; +typedef int8_t s8; +typedef int16_t s16; +typedef int32_t s32; +typedef int64_t s64; +typedef uint64_t u64; +typedef int sint32; + +typedef intptr_t INTPTR; +typedef uintptr_t UINTPTR; +typedef ptrdiff_t PTRDIFF; +/** @}*/ +#if !defined(LONG) || !defined(ULONG) +typedef long LONG; +typedef unsigned long ULONG; +#endif + +#define ULONG64_HI_MASK 0xFFFFFFFF00000000U +#define ULONG64_LO_MASK ~ULONG64_HI_MASK + +#else +#include +#endif + +/** @{ */ +/** + * This data type defines an interrupt handler for a device. + * The argument points to the instance of the component + */ +typedef void (*XInterruptHandler) (void *InstancePtr); + +/** + * This data type defines an exception handler for a processor. + * The argument points to the instance of the component + */ +typedef void (*XExceptionHandler) (void *InstancePtr); + +/** + * @brief Returns 32-63 bits of a number. + * @param n : Number being accessed. + * @return Bits 32-63 of number. + * + * @note A basic shift-right of a 64- or 32-bit quantity. + * Use this to suppress the "right shift count >= width of type" + * warning when that quantity is 32-bits. + */ +#define UPPER_32_BITS(n) ((u32)(((n) >> 16) >> 16)) + +/** + * @brief Returns 0-31 bits of a number + * @param n : Number being accessed. + * @return Bits 0-31 of number + */ +#define LOWER_32_BITS(n) ((u32)(n)) + + + + +/************************** Constant Definitions *****************************/ + +#ifndef TRUE +#define TRUE 1U +#endif + +#ifndef FALSE +#define FALSE 0U +#endif + +#ifndef NULL +#define NULL 0U +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** +* @} End of "addtogroup common_types". +*/ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_util.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_util.c new file mode 100644 index 0000000..d9282ca --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_util.c @@ -0,0 +1,175 @@ +/******************************************************************************/ +/** +* Copyright (C) 2019 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* @file xil_util.c +* +* This file contains xil utility functions +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who      Date     Changes
+* ----- -------- -------- -----------------------------------------------
+* 6.4   mmd      04/21/19 First release.
+*
+* 
+* +*****************************************************************************/ + +/***************************** Include Files ********************************/ +#include "xil_types.h" +#include "xil_io.h" +#include "xstatus.h" + +/************************** Constant Definitions ****************************/ +#define MAX_NIBBLES 8U + +/************************** Function Prototypes *****************************/ +/****************************************************************************/ +/** + * Converts the char into the equivalent nibble. + * Ex: 'a' -> 0xa, 'A' -> 0xa, '9'->0x9 + * + * @param InChar is input character. It has to be between 0-9,a-f,A-F + * @param Num is the output nibble. + * + * @return + * - XST_SUCCESS no errors occured. + * - ERROR when input parameters are not valid + * + * @note None. + * + *****************************************************************************/ + +u32 Xil_ConvertCharToNibble(u8 InChar, u8 *Num) +{ + u32 Status; + + /* Convert the char to nibble */ + if ((InChar >= (u8)'0') && (InChar <= (u8)'9')) { + *Num = InChar - (u8)'0'; + Status = XST_SUCCESS; + } + else if ((InChar >= (u8)'a') && (InChar <= (u8)'f')) { + *Num = InChar - (u8)'a' + 10U; + Status = XST_SUCCESS; + } + else if ((InChar >= (u8)'A') && (InChar <= (u8)'F')) { + *Num = InChar - (u8)'A' + 10U; + Status = XST_SUCCESS; + } + else { + Status = XST_FAILURE; + } + + return Status; +} + +/****************************************************************************/ +/* + * Converts the string into the equivalent Hex buffer. + * Ex: "abc123" -> {0xab, 0xc1, 0x23} + * + * @param Str is a Input String. Will support the lower and upper + * case values. Value should be between 0-9, a-f and A-F + * + * @param Buf is Output buffer. + * @param Len of the input string. Should have even values + * + * @return + * - XST_SUCCESS no errors occured. + * - ERROR when input parameters are not valid + * - an error when input buffer has invalid values + * + * @note None. + * + *****************************************************************************/ +u32 Xil_ConvertStringToHex(const char *Str, u32 *buf, u8 Len) +{ + u32 Status = XST_FAILURE; + u8 ConvertedLen = 0U, index = 0U; + u8 Nibble[MAX_NIBBLES] = {0U}; + u8 i; + + while (ConvertedLen < Len) { + /* Convert char to nibble */ + for (i = 0U; i < MAX_NIBBLES; i++) { + Status = Xil_ConvertCharToNibble( + Str[ConvertedLen], &Nibble[i]); + ConvertedLen = ConvertedLen +1U; + if (Status != XST_SUCCESS) { + /* Error converting char to nibble */ + goto END; + } + } + + buf[index] = ((Nibble[0] << (u8)28U )| (Nibble[1] << (u8)24U) | + (Nibble[2] << (u8)20U) | (Nibble[3] << (u8)16U) | + (Nibble[4] << (u8)12U) | (Nibble[5] << (u8)8U)| + (Nibble[6] << (u8)4U) | (u32)Nibble[7]); + index++; + } +END: + return Status; +} + +/****************************************************************************/ +/* + * Waits for the event + * + * @param RegAddr Address of register to be checked for event(s) occurance + * @param EventMask Mask indicating event(s) to be checked + * @param Event Specific event(s) value to be checked + * @param Timeout Free counter decremented on each event(s) check and + * declared timeout when reaches 0 + * + * @return + * - XST_SUCCESS On occurance of the event(s). + * - XST_FAILURE Event did not occur before counter reaches 0 + * + * @note None. + * + *****************************************************************************/ +u32 Xil_WaitForEvent(u32 RegAddr, u32 EventMask, u32 Event, u32 Timeout) +{ + u32 RegVal; + u32 PollCount = Timeout; + u32 Status = XST_FAILURE; + + while(PollCount > 0) { + RegVal = Xil_In32(RegAddr) & EventMask; + if (RegVal == Event) { + Status = XST_SUCCESS; + break; + } + PollCount--; + } + + return Status; +} diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_util.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_util.h new file mode 100644 index 0000000..194c425 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_util.h @@ -0,0 +1,57 @@ +/******************************************************************************/ +/** +* Copyright (C) 2019 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* @file xil_util.h +* +* This file contains xil utility functions declaration +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who      Date     Changes
+* ----- -------- -------- -----------------------------------------------
+* 6.4   mmd      04/21/19 First release.
+*
+* 
+* +*****************************************************************************/ + +#ifndef XIL_UTIL_H_ +#define XIL_UTIL_H_ + +/* Converts input character to nibble */ +u32 Xil_ConvertCharToNibble(u8 InChar, u8 *Num); + +/* Conver input hex string to array of 32-bits integers */ +u32 Xil_ConvertStringToHex(const char *Str, u32 *buf, u8 Len); + +/* Waits for specified event */ +u32 Xil_WaitForEvent(u32 RegAddr, u32 EventMask, u32 Event, u32 Timeout); + +#endif /* XIL_UTIL_H_ */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xl2cc.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xl2cc.h new file mode 100644 index 0000000..22373c1 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xl2cc.h @@ -0,0 +1,168 @@ +/****************************************************************************** +* +* Copyright (C) 2011 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* @file xl2cc.h +* +* This file contains the address definitions for the PL310 Level-2 Cache +* Controller. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- ---------------------------------------------------
+* 1.00a sdm  02/01/10 Initial version
+* 3.10a srt 04/18/13 Implemented ARM Erratas. Please refer to file
+*		      'xil_errata.h' for errata description
+* 
+* +* @note +* +* None. +* +******************************************************************************/ + +#ifndef _XL2CC_H_ +#define _XL2CC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/************************** Constant Definitions *****************************/ +/* L2CC Register Offsets */ +#define XPS_L2CC_ID_OFFSET 0x0000U +#define XPS_L2CC_TYPE_OFFSET 0x0004U +#define XPS_L2CC_CNTRL_OFFSET 0x0100U +#define XPS_L2CC_AUX_CNTRL_OFFSET 0x0104U +#define XPS_L2CC_TAG_RAM_CNTRL_OFFSET 0x0108U +#define XPS_L2CC_DATA_RAM_CNTRL_OFFSET 0x010CU + +#define XPS_L2CC_EVNT_CNTRL_OFFSET 0x0200U +#define XPS_L2CC_EVNT_CNT1_CTRL_OFFSET 0x0204U +#define XPS_L2CC_EVNT_CNT0_CTRL_OFFSET 0x0208U +#define XPS_L2CC_EVNT_CNT1_VAL_OFFSET 0x020CU +#define XPS_L2CC_EVNT_CNT0_VAL_OFFSET 0x0210U + +#define XPS_L2CC_IER_OFFSET 0x0214U /* Interrupt Mask */ +#define XPS_L2CC_IPR_OFFSET 0x0218U /* Masked interrupt status */ +#define XPS_L2CC_ISR_OFFSET 0x021CU /* Raw Interrupt Status */ +#define XPS_L2CC_IAR_OFFSET 0x0220U /* Interrupt Clear */ + +#define XPS_L2CC_CACHE_SYNC_OFFSET 0x0730U /* Cache Sync */ +#define XPS_L2CC_DUMMY_CACHE_SYNC_OFFSET 0x0740U /* Dummy Register for Cache Sync */ +#define XPS_L2CC_CACHE_INVLD_PA_OFFSET 0x0770U /* Cache Invalid by PA */ +#define XPS_L2CC_CACHE_INVLD_WAY_OFFSET 0x077CU /* Cache Invalid by Way */ +#define XPS_L2CC_CACHE_CLEAN_PA_OFFSET 0x07B0U /* Cache Clean by PA */ +#define XPS_L2CC_CACHE_CLEAN_INDX_OFFSET 0x07B8U /* Cache Clean by Index */ +#define XPS_L2CC_CACHE_CLEAN_WAY_OFFSET 0x07BCU /* Cache Clean by Way */ +#define XPS_L2CC_CACHE_INV_CLN_PA_OFFSET 0x07F0U /* Cache Invalidate and Clean by PA */ +#define XPS_L2CC_CACHE_INV_CLN_INDX_OFFSET 0x07F8U /* Cache Invalidate and Clean by Index */ +#define XPS_L2CC_CACHE_INV_CLN_WAY_OFFSET 0x07FCU /* Cache Invalidate and Clean by Way */ + +#define XPS_L2CC_CACHE_DLCKDWN_0_WAY_OFFSET 0x0900U /* Cache Data Lockdown 0 by Way */ +#define XPS_L2CC_CACHE_ILCKDWN_0_WAY_OFFSET 0x0904U /* Cache Instruction Lockdown 0 by Way */ +#define XPS_L2CC_CACHE_DLCKDWN_1_WAY_OFFSET 0x0908U /* Cache Data Lockdown 1 by Way */ +#define XPS_L2CC_CACHE_ILCKDWN_1_WAY_OFFSET 0x090CU /* Cache Instruction Lockdown 1 by Way */ +#define XPS_L2CC_CACHE_DLCKDWN_2_WAY_OFFSET 0x0910U /* Cache Data Lockdown 2 by Way */ +#define XPS_L2CC_CACHE_ILCKDWN_2_WAY_OFFSET 0x0914U /* Cache Instruction Lockdown 2 by Way */ +#define XPS_L2CC_CACHE_DLCKDWN_3_WAY_OFFSET 0x0918U /* Cache Data Lockdown 3 by Way */ +#define XPS_L2CC_CACHE_ILCKDWN_3_WAY_OFFSET 0x091CU /* Cache Instruction Lockdown 3 by Way */ +#define XPS_L2CC_CACHE_DLCKDWN_4_WAY_OFFSET 0x0920U /* Cache Data Lockdown 4 by Way */ +#define XPS_L2CC_CACHE_ILCKDWN_4_WAY_OFFSET 0x0924U /* Cache Instruction Lockdown 4 by Way */ +#define XPS_L2CC_CACHE_DLCKDWN_5_WAY_OFFSET 0x0928U /* Cache Data Lockdown 5 by Way */ +#define XPS_L2CC_CACHE_ILCKDWN_5_WAY_OFFSET 0x092CU /* Cache Instruction Lockdown 5 by Way */ +#define XPS_L2CC_CACHE_DLCKDWN_6_WAY_OFFSET 0x0930U /* Cache Data Lockdown 6 by Way */ +#define XPS_L2CC_CACHE_ILCKDWN_6_WAY_OFFSET 0x0934U /* Cache Instruction Lockdown 6 by Way */ +#define XPS_L2CC_CACHE_DLCKDWN_7_WAY_OFFSET 0x0938U /* Cache Data Lockdown 7 by Way */ +#define XPS_L2CC_CACHE_ILCKDWN_7_WAY_OFFSET 0x093CU /* Cache Instruction Lockdown 7 by Way */ + +#define XPS_L2CC_CACHE_LCKDWN_LINE_ENABLE_OFFSET 0x0950U /* Cache Lockdown Line Enable */ +#define XPS_L2CC_CACHE_UUNLOCK_ALL_WAY_OFFSET 0x0954U /* Cache Unlock All Lines by Way */ + +#define XPS_L2CC_ADDR_FILTER_START_OFFSET 0x0C00U /* Start of address filtering */ +#define XPS_L2CC_ADDR_FILTER_END_OFFSET 0x0C04U /* Start of address filtering */ + +#define XPS_L2CC_DEBUG_CTRL_OFFSET 0x0F40U /* Debug Control Register */ + +/* XPS_L2CC_CNTRL_OFFSET bit masks */ +#define XPS_L2CC_ENABLE_MASK 0x00000001U /* enables the L2CC */ + +/* XPS_L2CC_AUX_CNTRL_OFFSET bit masks */ +#define XPS_L2CC_AUX_EBRESPE_MASK 0x40000000U /* Early BRESP Enable */ +#define XPS_L2CC_AUX_IPFE_MASK 0x20000000U /* Instruction Prefetch Enable */ +#define XPS_L2CC_AUX_DPFE_MASK 0x10000000U /* Data Prefetch Enable */ +#define XPS_L2CC_AUX_NSIC_MASK 0x08000000U /* Non-secure interrupt access control */ +#define XPS_L2CC_AUX_NSLE_MASK 0x04000000U /* Non-secure lockdown enable */ +#define XPS_L2CC_AUX_CRP_MASK 0x02000000U /* Cache replacement policy */ +#define XPS_L2CC_AUX_FWE_MASK 0x01800000U /* Force write allocate */ +#define XPS_L2CC_AUX_SAOE_MASK 0x00400000U /* Shared attribute override enable */ +#define XPS_L2CC_AUX_PE_MASK 0x00200000U /* Parity enable */ +#define XPS_L2CC_AUX_EMBE_MASK 0x00100000U /* Event monitor bus enable */ +#define XPS_L2CC_AUX_WAY_SIZE_MASK 0x000E0000U /* Way-size */ +#define XPS_L2CC_AUX_ASSOC_MASK 0x00010000U /* Associativity */ +#define XPS_L2CC_AUX_SAIE_MASK 0x00002000U /* Shared attribute invalidate enable */ +#define XPS_L2CC_AUX_EXCL_CACHE_MASK 0x00001000U /* Exclusive cache configuration */ +#define XPS_L2CC_AUX_SBDLE_MASK 0x00000800U /* Store buffer device limitation Enable */ +#define XPS_L2CC_AUX_HPSODRE_MASK 0x00000400U /* High Priority for SO and Dev Reads Enable */ +#define XPS_L2CC_AUX_FLZE_MASK 0x00000001U /* Full line of zero enable */ + +#define XPS_L2CC_AUX_REG_DEFAULT_MASK 0x72360000U /* Enable all prefetching, */ + /* Cache replacement policy, Parity enable, */ + /* Event monitor bus enable and Way Size (64 KB) */ +#define XPS_L2CC_AUX_REG_ZERO_MASK 0xFFF1FFFFU /* */ + +#define XPS_L2CC_TAG_RAM_DEFAULT_MASK 0x00000111U /* latency for TAG RAM */ +#define XPS_L2CC_DATA_RAM_DEFAULT_MASK 0x00000121U /* latency for DATA RAM */ + +/* Interrupt bit masks */ +#define XPS_L2CC_IXR_DECERR_MASK 0x00000100U /* DECERR from L3 */ +#define XPS_L2CC_IXR_SLVERR_MASK 0x00000080U /* SLVERR from L3 */ +#define XPS_L2CC_IXR_ERRRD_MASK 0x00000040U /* Error on L2 data RAM (Read) */ +#define XPS_L2CC_IXR_ERRRT_MASK 0x00000020U /* Error on L2 tag RAM (Read) */ +#define XPS_L2CC_IXR_ERRWD_MASK 0x00000010U /* Error on L2 data RAM (Write) */ +#define XPS_L2CC_IXR_ERRWT_MASK 0x00000008U /* Error on L2 tag RAM (Write) */ +#define XPS_L2CC_IXR_PARRD_MASK 0x00000004U /* Parity Error on L2 data RAM (Read) */ +#define XPS_L2CC_IXR_PARRT_MASK 0x00000002U /* Parity Error on L2 tag RAM (Read) */ +#define XPS_L2CC_IXR_ECNTR_MASK 0x00000001U /* Event Counter1/0 Overflow Increment */ + +/* Address filtering mask and enable bit */ +#define XPS_L2CC_ADDR_FILTER_VALID_MASK 0xFFF00000U /* Address filtering valid bits*/ +#define XPS_L2CC_ADDR_FILTER_ENABLE_MASK 0x00000001U /* Address filtering enable bit*/ + +/* Debug control bits */ +#define XPS_L2CC_DEBUG_SPIDEN_MASK 0x00000004U /* Debug SPIDEN bit */ +#define XPS_L2CC_DEBUG_DWB_MASK 0x00000002U /* Debug DWB bit, forces write through */ +#define XPS_L2CC_DEBUG_DCL_MASK 0x00000002U /* Debug DCL bit, disables cache line fill */ + +#ifdef __cplusplus +} +#endif + +#endif /* protection macro */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xl2cc_counter.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xl2cc_counter.c new file mode 100644 index 0000000..465be05 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xl2cc_counter.c @@ -0,0 +1,165 @@ +/****************************************************************************** +* +* Copyright (C) 2011 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xl2cc_counter.c +* +* This file contains APIs for configuring and controlling the event counters +* in PL310 L2 cache controller. For more information about the event counters, +* see xl2cc_counter.h. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a sdm  07/11/11 First release
+* 3.07a asa  08/30/12 Updated for CR 675636 to provide the L2 Base Address
+*		      inside the APIs
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include +#include "xparameters_ps.h" +#include "xl2cc_counter.h" +#include "xl2cc.h" + +/************************** Constant Definitions ****************************/ + +/**************************** Type Definitions ******************************/ + +/***************** Macros (Inline Functions) Definitions ********************/ + +/************************** Variable Definitions *****************************/ + +/************************** Function Prototypes ******************************/ + +void XL2cc_EventCtrReset(void); + +/******************************************************************************/ + +/****************************************************************************/ +/** +* +* @brief This function initializes the event counters in L2 Cache controller +* with a set of event codes specified by the user. +* +* @param Event0: Event code for counter 0. +* @param Event1: Event code for counter 1. +* +* @return None. +* +* @note The definitions for event codes XL2CC_* can be found in +* xl2cc_counter.h. +* +*****************************************************************************/ +void XL2cc_EventCtrInit(s32 Event0, s32 Event1) +{ + + /* Write event code into cnt1 cfg reg */ + *((volatile u32*)(XPS_L2CC_BASEADDR + XPS_L2CC_EVNT_CNT1_CTRL_OFFSET)) = (((u32)Event1) << 2); + + /* Write event code into cnt0 cfg reg */ + *((volatile u32*)(XPS_L2CC_BASEADDR + XPS_L2CC_EVNT_CNT0_CTRL_OFFSET)) = (((u32)Event0) << 2); + + /* Reset counters */ + XL2cc_EventCtrReset(); +} + + +/****************************************************************************/ +/** +* +* @brief This function starts the event counters in L2 Cache controller. +* +* @param None. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XL2cc_EventCtrStart(void) +{ + u32 *LocalPtr; + LocalPtr = (u32 *)(XPS_L2CC_BASEADDR + XPS_L2CC_EVNT_CNTRL_OFFSET); + XL2cc_EventCtrReset(); + + /* Enable counter */ + /* *((volatile u32*)((void *)(XPS_L2CC_BASEADDR + XPS_L2CC_EVNT_CNTRL_OFFSET))) = 1 */ + *LocalPtr = (u32)1; +} + +/****************************************************************************/ +/** +* +* @brief This function disables the event counters in L2 Cache controller, +* saves the counter values and resets the counters. +* +* @param EveCtr0: Output parameter which is used to return the value +* in event counter 0. +* EveCtr1: Output parameter which is used to return the value +* in event counter 1. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XL2cc_EventCtrStop(u32 *EveCtr0, u32 *EveCtr1) +{ + /* Disable counter */ + *((volatile u32*) (XPS_L2CC_BASEADDR + XPS_L2CC_EVNT_CNTRL_OFFSET)) = 0U; + + /* Save counter values */ + *EveCtr1 = *((volatile u32*)(XPS_L2CC_BASEADDR + XPS_L2CC_EVNT_CNT1_VAL_OFFSET)); + *EveCtr0 = *((volatile u32*)(XPS_L2CC_BASEADDR + XPS_L2CC_EVNT_CNT0_VAL_OFFSET)); + + XL2cc_EventCtrReset(); +} + +/****************************************************************************/ +/** +* +* @brief This function resets the event counters in L2 Cache controller. +* +* @param None. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XL2cc_EventCtrReset(void) +{ + *((volatile u32*)(XPS_L2CC_BASEADDR + XPS_L2CC_EVNT_CNTRL_OFFSET)) = 0x6U; +} diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xl2cc_counter.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xl2cc_counter.h new file mode 100644 index 0000000..b8d768f --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xl2cc_counter.h @@ -0,0 +1,110 @@ +/****************************************************************************** +* +* Copyright (C) 2011 - 2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xl2cc_counter.h +* +* @addtogroup l2_event_counter_apis PL310 L2 Event Counters Functions +* +* xl2cc_counter.h contains APIs for configuring and controlling the event +* counters in PL310 L2 cache controller. +* PL310 has two event counters which can be used to count variety of events +* like DRHIT, DRREQ, DWHIT, DWREQ, etc. xl2cc_counter.h contains definitions +* for different configurations which can be used for the event counters to +* count a set of events. +* +* +* @{ +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a sdm  07/11/11 First release
+* 3.07a asa  08/30/12 Updated for CR 675636 to provide the L2 Base Address
+*		      inside the APIs
+* 6.8   aru  09/06/18 Removed compilation warnings for ARMCC toolchain.
+* 
+* +******************************************************************************/ + +#ifndef L2CCCOUNTER_H /* prevent circular inclusions */ +#define L2CCCOUNTER_H /* by using protection macros */ + +/***************************** Include Files ********************************/ + +#include "xpseudo_asm.h" +#include "xil_types.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/************************** Constant Definitions ****************************/ + +/* + * The following constants define the event codes for the event counters. + */ +#define XL2CC_CO 0x1 +#define XL2CC_DRHIT 0x2 +#define XL2CC_DRREQ 0x3 +#define XL2CC_DWHIT 0x4 +#define XL2CC_DWREQ 0x5 +#define XL2CC_DWTREQ 0x6 +#define XL2CC_IRHIT 0x7 +#define XL2CC_IRREQ 0x8 +#define XL2CC_WA 0x9 +#define XL2CC_IPFALLOC 0xa +#define XL2CC_EPFHIT 0xb +#define XL2CC_EPFALLOC 0xc +#define XL2CC_SRRCVD 0xd +#define XL2CC_SRCONF 0xe +#define XL2CC_EPFRCVD 0xf + +/**************************** Type Definitions ******************************/ + +/***************** Macros (Inline Functions) Definitions ********************/ + +/************************** Variable Definitions ****************************/ + +/************************** Function Prototypes *****************************/ + +void XL2cc_EventCtrInit(s32 Event0, s32 Event1); +void XL2cc_EventCtrStart(void); +void XL2cc_EventCtrStop(u32 *EveCtr0, u32 *EveCtr1); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* L2CCCOUNTER_H */ +/** +* @} End of "addtogroup l2_event_counter_apis". +*/ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xparameters_ps.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xparameters_ps.h new file mode 100644 index 0000000..2a6a0e0 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xparameters_ps.h @@ -0,0 +1,334 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2017 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* @file xparameters_ps.h +* +* This file contains the address definitions for the hard peripherals +* attached to the ARM Cortex A9 core. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who     Date     Changes
+* ----- ------- -------- ---------------------------------------------------
+* 1.00a ecm/sdm 02/01/10 Initial version
+* 3.04a sdm     02/02/12 Removed some of the defines as they are being generated through
+*                        driver tcl
+* 5.0	pkp		01/16/15 Added interrupt ID definition of ttc for TEST APP
+* 6.6   srm     10/18/17 Added ARMA9 macro to identify CortexA9
+*
+* 
+* +* @note +* +* None. +* +******************************************************************************/ + +#ifndef _XPARAMETERS_PS_H_ +#define _XPARAMETERS_PS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/**************************** Include Files *******************************/ + + +/************************** Constant Definitions *****************************/ + +/* + * This block contains constant declarations for the peripherals + * within the hardblock + */ + +/* Canonical definitions for DDR MEMORY */ +#define XPAR_DDR_MEM_BASEADDR 0x00000000U +#define XPAR_DDR_MEM_HIGHADDR 0x3FFFFFFFU + +/* Canonical definitions for Interrupts */ +#define XPAR_XUARTPS_0_INTR XPS_UART0_INT_ID +#define XPAR_XUARTPS_1_INTR XPS_UART1_INT_ID +#define XPAR_XUSBPS_0_INTR XPS_USB0_INT_ID +#define XPAR_XUSBPS_1_INTR XPS_USB1_INT_ID +#define XPAR_XIICPS_0_INTR XPS_I2C0_INT_ID +#define XPAR_XIICPS_1_INTR XPS_I2C1_INT_ID +#define XPAR_XSPIPS_0_INTR XPS_SPI0_INT_ID +#define XPAR_XSPIPS_1_INTR XPS_SPI1_INT_ID +#define XPAR_XCANPS_0_INTR XPS_CAN0_INT_ID +#define XPAR_XCANPS_1_INTR XPS_CAN1_INT_ID +#define XPAR_XGPIOPS_0_INTR XPS_GPIO_INT_ID +#define XPAR_XEMACPS_0_INTR XPS_GEM0_INT_ID +#define XPAR_XEMACPS_0_WAKE_INTR XPS_GEM0_WAKE_INT_ID +#define XPAR_XEMACPS_1_INTR XPS_GEM1_INT_ID +#define XPAR_XEMACPS_1_WAKE_INTR XPS_GEM1_WAKE_INT_ID +#define XPAR_XSDIOPS_0_INTR XPS_SDIO0_INT_ID +#define XPAR_XQSPIPS_0_INTR XPS_QSPI_INT_ID +#define XPAR_XSDIOPS_1_INTR XPS_SDIO1_INT_ID +#define XPAR_XWDTPS_0_INTR XPS_WDT_INT_ID +#define XPAR_XDCFG_0_INTR XPS_DVC_INT_ID +#define XPAR_SCUTIMER_INTR XPS_SCU_TMR_INT_ID +#define XPAR_SCUWDT_INTR XPS_SCU_WDT_INT_ID +#define XPAR_XTTCPS_0_INTR XPS_TTC0_0_INT_ID +#define XPAR_XTTCPS_1_INTR XPS_TTC0_1_INT_ID +#define XPAR_XTTCPS_2_INTR XPS_TTC0_2_INT_ID +#define XPAR_XTTCPS_3_INTR XPS_TTC1_0_INT_ID +#define XPAR_XTTCPS_4_INTR XPS_TTC1_1_INT_ID +#define XPAR_XTTCPS_5_INTR XPS_TTC1_2_INT_ID +#define XPAR_XDMAPS_0_FAULT_INTR XPS_DMA0_ABORT_INT_ID +#define XPAR_XDMAPS_0_DONE_INTR_0 XPS_DMA0_INT_ID +#define XPAR_XDMAPS_0_DONE_INTR_1 XPS_DMA1_INT_ID +#define XPAR_XDMAPS_0_DONE_INTR_2 XPS_DMA2_INT_ID +#define XPAR_XDMAPS_0_DONE_INTR_3 XPS_DMA3_INT_ID +#define XPAR_XDMAPS_0_DONE_INTR_4 XPS_DMA4_INT_ID +#define XPAR_XDMAPS_0_DONE_INTR_5 XPS_DMA5_INT_ID +#define XPAR_XDMAPS_0_DONE_INTR_6 XPS_DMA6_INT_ID +#define XPAR_XDMAPS_0_DONE_INTR_7 XPS_DMA7_INT_ID + + +#define XPAR_XQSPIPS_0_LINEAR_BASEADDR XPS_QSPI_LINEAR_BASEADDR +#define XPAR_XPARPORTPS_CTRL_BASEADDR XPS_PARPORT_CRTL_BASEADDR + + + +/* Canonical definitions for DMAC */ + + +/* Canonical definitions for WDT */ + +/* Canonical definitions for SLCR */ +#define XPAR_XSLCR_NUM_INSTANCES 1U +#define XPAR_XSLCR_0_DEVICE_ID 0U +#define XPAR_XSLCR_0_BASEADDR XPS_SYS_CTRL_BASEADDR + +/* Canonical definitions for SCU GIC */ +#define XPAR_SCUGIC_NUM_INSTANCES 1U +#define XPAR_SCUGIC_SINGLE_DEVICE_ID 0U +#define XPAR_SCUGIC_CPU_BASEADDR (XPS_SCU_PERIPH_BASE + 0x00000100U) +#define XPAR_SCUGIC_DIST_BASEADDR (XPS_SCU_PERIPH_BASE + 0x00001000U) +#define XPAR_SCUGIC_ACK_BEFORE 0U + +/* Canonical definitions for Global Timer */ +#define XPAR_GLOBAL_TMR_NUM_INSTANCES 1U +#define XPAR_GLOBAL_TMR_DEVICE_ID 0U +#define XPAR_GLOBAL_TMR_BASEADDR (XPS_SCU_PERIPH_BASE + 0x00000200U) +#define XPAR_GLOBAL_TMR_INTR XPS_GLOBAL_TMR_INT_ID + + +/* Xilinx Parallel Flash Library (XilFlash) User Settings */ +#define XPAR_AXI_EMC + + +#define XPAR_CPU_CORTEXA9_CORE_CLOCK_FREQ_HZ XPAR_CPU_CORTEXA9_0_CPU_CLK_FREQ_HZ + + +/* + * This block contains constant declarations for the peripherals + * within the hardblock. These have been put for bacwards compatibilty + */ + +#define XPS_PERIPHERAL_BASEADDR 0xE0000000U +#define XPS_UART0_BASEADDR 0xE0000000U +#define XPS_UART1_BASEADDR 0xE0001000U +#define XPS_USB0_BASEADDR 0xE0002000U +#define XPS_USB1_BASEADDR 0xE0003000U +#define XPS_I2C0_BASEADDR 0xE0004000U +#define XPS_I2C1_BASEADDR 0xE0005000U +#define XPS_SPI0_BASEADDR 0xE0006000U +#define XPS_SPI1_BASEADDR 0xE0007000U +#define XPS_CAN0_BASEADDR 0xE0008000U +#define XPS_CAN1_BASEADDR 0xE0009000U +#define XPS_GPIO_BASEADDR 0xE000A000U +#define XPS_GEM0_BASEADDR 0xE000B000U +#define XPS_GEM1_BASEADDR 0xE000C000U +#define XPS_QSPI_BASEADDR 0xE000D000U +#define XPS_PARPORT_CRTL_BASEADDR 0xE000E000U +#define XPS_SDIO0_BASEADDR 0xE0100000U +#define XPS_SDIO1_BASEADDR 0xE0101000U +#define XPS_IOU_BUS_CFG_BASEADDR 0xE0200000U +#define XPS_NAND_BASEADDR 0xE1000000U +#define XPS_PARPORT0_BASEADDR 0xE2000000U +#define XPS_PARPORT1_BASEADDR 0xE4000000U +#define XPS_QSPI_LINEAR_BASEADDR 0xFC000000U +#define XPS_SYS_CTRL_BASEADDR 0xF8000000U /* AKA SLCR */ +#define XPS_TTC0_BASEADDR 0xF8001000U +#define XPS_TTC1_BASEADDR 0xF8002000U +#define XPS_DMAC0_SEC_BASEADDR 0xF8003000U +#define XPS_DMAC0_NON_SEC_BASEADDR 0xF8004000U +#define XPS_WDT_BASEADDR 0xF8005000U +#define XPS_DDR_CTRL_BASEADDR 0xF8006000U +#define XPS_DEV_CFG_APB_BASEADDR 0xF8007000U +#define XPS_AFI0_BASEADDR 0xF8008000U +#define XPS_AFI1_BASEADDR 0xF8009000U +#define XPS_AFI2_BASEADDR 0xF800A000U +#define XPS_AFI3_BASEADDR 0xF800B000U +#define XPS_OCM_BASEADDR 0xF800C000U +#define XPS_EFUSE_BASEADDR 0xF800D000U +#define XPS_CORESIGHT_BASEADDR 0xF8800000U +#define XPS_TOP_BUS_CFG_BASEADDR 0xF8900000U +#define XPS_SCU_PERIPH_BASE 0xF8F00000U +#define XPS_L2CC_BASEADDR 0xF8F02000U +#define XPS_SAM_RAM_BASEADDR 0xFFFC0000U +#define XPS_FPGA_AXI_S0_BASEADDR 0x40000000U +#define XPS_FPGA_AXI_S1_BASEADDR 0x80000000U +#define XPS_IOU_S_SWITCH_BASEADDR 0xE0000000U +#define XPS_PERIPH_APB_BASEADDR 0xF8000000U + +/* Shared Peripheral Interrupts (SPI) */ +#define XPS_CORE_PARITY0_INT_ID 32U +#define XPS_CORE_PARITY1_INT_ID 33U +#define XPS_L2CC_INT_ID 34U +#define XPS_OCMINTR_INT_ID 35U +#define XPS_ECC_INT_ID 36U +#define XPS_PMU0_INT_ID 37U +#define XPS_PMU1_INT_ID 38U +#define XPS_SYSMON_INT_ID 39U +#define XPS_DVC_INT_ID 40U +#define XPS_WDT_INT_ID 41U +#define XPS_TTC0_0_INT_ID 42U +#define XPS_TTC0_1_INT_ID 43U +#define XPS_TTC0_2_INT_ID 44U +#define XPS_DMA0_ABORT_INT_ID 45U +#define XPS_DMA0_INT_ID 46U +#define XPS_DMA1_INT_ID 47U +#define XPS_DMA2_INT_ID 48U +#define XPS_DMA3_INT_ID 49U +#define XPS_SMC_INT_ID 50U +#define XPS_QSPI_INT_ID 51U +#define XPS_GPIO_INT_ID 52U +#define XPS_USB0_INT_ID 53U +#define XPS_GEM0_INT_ID 54U +#define XPS_GEM0_WAKE_INT_ID 55U +#define XPS_SDIO0_INT_ID 56U +#define XPS_I2C0_INT_ID 57U +#define XPS_SPI0_INT_ID 58U +#define XPS_UART0_INT_ID 59U +#define XPS_CAN0_INT_ID 60U +#define XPS_FPGA0_INT_ID 61U +#define XPS_FPGA1_INT_ID 62U +#define XPS_FPGA2_INT_ID 63U +#define XPS_FPGA3_INT_ID 64U +#define XPS_FPGA4_INT_ID 65U +#define XPS_FPGA5_INT_ID 66U +#define XPS_FPGA6_INT_ID 67U +#define XPS_FPGA7_INT_ID 68U +#define XPS_TTC1_0_INT_ID 69U +#define XPS_TTC1_1_INT_ID 70U +#define XPS_TTC1_2_INT_ID 71U +#define XPS_DMA4_INT_ID 72U +#define XPS_DMA5_INT_ID 73U +#define XPS_DMA6_INT_ID 74U +#define XPS_DMA7_INT_ID 75U +#define XPS_USB1_INT_ID 76U +#define XPS_GEM1_INT_ID 77U +#define XPS_GEM1_WAKE_INT_ID 78U +#define XPS_SDIO1_INT_ID 79U +#define XPS_I2C1_INT_ID 80U +#define XPS_SPI1_INT_ID 81U +#define XPS_UART1_INT_ID 82U +#define XPS_CAN1_INT_ID 83U +#define XPS_FPGA8_INT_ID 84U +#define XPS_FPGA9_INT_ID 85U +#define XPS_FPGA10_INT_ID 86U +#define XPS_FPGA11_INT_ID 87U +#define XPS_FPGA12_INT_ID 88U +#define XPS_FPGA13_INT_ID 89U +#define XPS_FPGA14_INT_ID 90U +#define XPS_FPGA15_INT_ID 91U + +/* Private Peripheral Interrupts (PPI) */ +#define XPS_GLOBAL_TMR_INT_ID 27U /* SCU Global Timer interrupt */ +#define XPS_FIQ_INT_ID 28U /* FIQ from FPGA fabric */ +#define XPS_SCU_TMR_INT_ID 29U /* SCU Private Timer interrupt */ +#define XPS_SCU_WDT_INT_ID 30U /* SCU Private WDT interrupt */ +#define XPS_IRQ_INT_ID 31U /* IRQ from FPGA fabric */ + + +/* REDEFINES for TEST APP */ +/* Definitions for UART */ +#define XPAR_PS7_UART_0_INTR XPS_UART0_INT_ID +#define XPAR_PS7_UART_1_INTR XPS_UART1_INT_ID +#define XPAR_PS7_USB_0_INTR XPS_USB0_INT_ID +#define XPAR_PS7_USB_1_INTR XPS_USB1_INT_ID +#define XPAR_PS7_I2C_0_INTR XPS_I2C0_INT_ID +#define XPAR_PS7_I2C_1_INTR XPS_I2C1_INT_ID +#define XPAR_PS7_SPI_0_INTR XPS_SPI0_INT_ID +#define XPAR_PS7_SPI_1_INTR XPS_SPI1_INT_ID +#define XPAR_PS7_CAN_0_INTR XPS_CAN0_INT_ID +#define XPAR_PS7_CAN_1_INTR XPS_CAN1_INT_ID +#define XPAR_PS7_GPIO_0_INTR XPS_GPIO_INT_ID +#define XPAR_PS7_ETHERNET_0_INTR XPS_GEM0_INT_ID +#define XPAR_PS7_ETHERNET_0_WAKE_INTR XPS_GEM0_WAKE_INT_ID +#define XPAR_PS7_ETHERNET_1_INTR XPS_GEM1_INT_ID +#define XPAR_PS7_ETHERNET_1_WAKE_INTR XPS_GEM1_WAKE_INT_ID +#define XPAR_PS7_QSPI_0_INTR XPS_QSPI_INT_ID +#define XPAR_PS7_WDT_0_INTR XPS_WDT_INT_ID +#define XPAR_PS7_SCUWDT_0_INTR XPS_SCU_WDT_INT_ID +#define XPAR_PS7_SCUTIMER_0_INTR XPS_SCU_TMR_INT_ID +#define XPAR_PS7_XADC_0_INTR XPS_SYSMON_INT_ID +#define XPAR_PS7_TTC_0_INTR XPS_TTC0_0_INT_ID +#define XPAR_PS7_TTC_1_INTR XPS_TTC0_1_INT_ID +#define XPAR_PS7_TTC_2_INTR XPS_TTC0_2_INT_ID +#define XPAR_PS7_TTC_3_INTR XPS_TTC1_0_INT_ID +#define XPAR_PS7_TTC_4_INTR XPS_TTC1_1_INT_ID +#define XPAR_PS7_TTC_5_INTR XPS_TTC1_2_INT_ID + +#define XPAR_XADCPS_INT_ID XPS_SYSMON_INT_ID + +/* For backwards compatibilty */ +#define XPAR_XUARTPS_0_CLOCK_HZ XPAR_XUARTPS_0_UART_CLK_FREQ_HZ +#define XPAR_XUARTPS_1_CLOCK_HZ XPAR_XUARTPS_1_UART_CLK_FREQ_HZ +#define XPAR_XTTCPS_0_CLOCK_HZ XPAR_XTTCPS_0_TTC_CLK_FREQ_HZ +#define XPAR_XTTCPS_1_CLOCK_HZ XPAR_XTTCPS_1_TTC_CLK_FREQ_HZ +#define XPAR_XTTCPS_2_CLOCK_HZ XPAR_XTTCPS_2_TTC_CLK_FREQ_HZ +#define XPAR_XTTCPS_3_CLOCK_HZ XPAR_XTTCPS_3_TTC_CLK_FREQ_HZ +#define XPAR_XTTCPS_4_CLOCK_HZ XPAR_XTTCPS_4_TTC_CLK_FREQ_HZ +#define XPAR_XTTCPS_5_CLOCK_HZ XPAR_XTTCPS_5_TTC_CLK_FREQ_HZ +#define XPAR_XIICPS_0_CLOCK_HZ XPAR_XIICPS_0_I2C_CLK_FREQ_HZ +#define XPAR_XIICPS_1_CLOCK_HZ XPAR_XIICPS_1_I2C_CLK_FREQ_HZ + +#define XPAR_XQSPIPS_0_CLOCK_HZ XPAR_XQSPIPS_0_QSPI_CLK_FREQ_HZ + +#ifdef XPAR_CPU_CORTEXA9_0_CPU_CLK_FREQ_HZ +#define XPAR_CPU_CORTEXA9_CORE_CLOCK_FREQ_HZ XPAR_CPU_CORTEXA9_0_CPU_CLK_FREQ_HZ +#endif + +#ifdef XPAR_CPU_CORTEXA9_1_CPU_CLK_FREQ_HZ +#define XPAR_CPU_CORTEXA9_CORE_CLOCK_FREQ_HZ XPAR_CPU_CORTEXA9_1_CPU_CLK_FREQ_HZ +#endif + +#define XPAR_SCUTIMER_DEVICE_ID 0U +#define XPAR_SCUWDT_DEVICE_ID 0U + + +#ifdef __cplusplus +} +#endif + +#endif /* protection macro */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xplatform_info.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xplatform_info.c new file mode 100644 index 0000000..03b1742 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xplatform_info.c @@ -0,0 +1,162 @@ +/****************************************************************************** +* +* Copyright (C) 2014 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xplatform_info.c +* +* This file contains information about hardware for which the code is built +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date   Changes
+* ----- ---- -------- -------------------------------------------------------
+* 5.00  pkp  12/15/14 Initial release
+* 5.04  pkp  01/12/16 Added platform information support for Cortex-A53 32bit
+*					  mode
+* 6.00  mus  17/08/16 Removed unused variable from XGetPlatform_Info
+* 6.4   ms   05/23/17 Added PSU_PMU macro to support XGetPSVersion_Info
+*                     function for PMUFW.
+*       ms   06/13/17 Added PSU_PMU macro to provide support of
+*                     XGetPlatform_Info function for PMUFW.
+*       mus  08/17/17 Add EL1 NS mode support for
+*                     XGet_Zynq_UltraMp_Platform_info and XGetPSVersion_Info
+*                     APIs.
+* 7.0	aru 03/15/19  Check for versal before aarch64 and armr5
+*		      in XGetPlatform_Info()
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xil_types.h" +#include "xil_io.h" +#include "xplatform_info.h" +#if defined (__aarch64__) +#include "bspconfig.h" +#include "xil_smc.h" +#endif +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Variable Definitions *****************************/ + + +/************************** Function Prototypes ******************************/ + +/*****************************************************************************/ +/** +* +* @brief This API is used to provide information about platform +* +* @param None. +* +* @return The information about platform defined in xplatform_info.h +* +******************************************************************************/ +u32 XGetPlatform_Info() +{ +#if defined (versal) + return XPLAT_versal; +#elif defined (ARMR5) || (__aarch64__) || (ARMA53_32) || (PSU_PMU) + return XPLAT_ZYNQ_ULTRA_MP; +#elif (__microblaze__) + return XPLAT_MICROBLAZE; +#else + return XPLAT_ZYNQ; +#endif +} + +/*****************************************************************************/ +/** +* +* @brief This API is used to provide information about zynq ultrascale MP platform +* +* @param None. +* +* @return The information about zynq ultrascale MP platform defined in +* xplatform_info.h +* +******************************************************************************/ +#if defined (ARMR5) || (__aarch64__) || (ARMA53_32) +u32 XGet_Zynq_UltraMp_Platform_info() +{ +#if EL1_NONSECURE + XSmc_OutVar reg; + /* + * This SMC call will return, + * idcode - upper 32 bits of reg.Arg0 + * version - lower 32 bits of reg.Arg1 + */ + reg = Xil_Smc(GET_CHIPID_SMC_FID,0,0, 0, 0, 0, 0, 0); + return (u32)((reg.Arg1 >> XPLAT_INFO_SHIFT) & XPLAT_INFO_MASK); +#else + u32 reg; + reg = ((Xil_In32(XPLAT_PS_VERSION_ADDRESS) >> XPLAT_INFO_SHIFT ) + & XPLAT_INFO_MASK); + return reg; +#endif +} +#endif + +/*****************************************************************************/ +/** +* +* @brief This API is used to provide information about PS Silicon version +* +* @param None. +* +* @return The information about PS Silicon version. +* +******************************************************************************/ +#if defined (ARMR5) || (__aarch64__) || (ARMA53_32) || (PSU_PMU) +u32 XGetPSVersion_Info() +{ +#if EL1_NONSECURE + /* + * This SMC call will return, + * idcode - upper 32 bits of reg.Arg0 + * version - lower 32 bits of reg.Arg1 + */ + XSmc_OutVar reg; + reg = Xil_Smc(GET_CHIPID_SMC_FID,0,0, 0, 0, 0, 0, 0); + return (u32)((reg.Arg1 & XPS_VERSION_INFO_MASK) >> + XPS_VERSION_INFO_SHIFT); +#else + u32 reg; + reg = (Xil_In32(XPLAT_PS_VERSION_ADDRESS) + & XPS_VERSION_INFO_MASK); + return (reg >> XPS_VERSION_INFO_SHIFT); +#endif +} +#endif diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xplatform_info.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xplatform_info.h new file mode 100644 index 0000000..88851bb --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xplatform_info.h @@ -0,0 +1,120 @@ +/****************************************************************************** +* +* Copyright (C) 2014 - 2017 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xplatform_info.h +* +* @addtogroup common_platform_info APIs to Get Platform Information +* +* The xplatform_info.h file contains definitions for various available Xilinx® +* platforms. Also, it contains prototype of APIs, which can be used to get the +* platform information. +* +* @{ +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date    Changes
+* ----- ---- --------- -------------------------------------------------------
+* 6.4    ms   05/23/17 Added PSU_PMU macro to support XGetPSVersion_Info
+*                      function for PMUFW.
+* 
+* +******************************************************************************/ + +#ifndef XPLATFORM_INFO_H /* prevent circular inclusions */ +#define XPLATFORM_INFO_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +#include "xil_types.h" + +/************************** Constant Definitions *****************************/ +#if defined (versal) +#define XPAR_PMC_TAP_BASEADDR 0xF11A0000U +#define XPAR_PMC_TAP_VERSION_OFFSET 0x00000004U +#define XPLAT_PS_VERSION_ADDRESS (XPAR_PMC_TAP_BASEADDR + \ + XPAR_PMC_TAP_VERSION_OFFSET) +#else +#define XPAR_CSU_BASEADDR 0xFFCA0000U +#define XPAR_CSU_VER_OFFSET 0x00000044U +#define XPLAT_PS_VERSION_ADDRESS (XPAR_CSU_BASEADDR + \ + XPAR_CSU_VER_OFFSET) +#endif +#define XPLAT_ZYNQ_ULTRA_MP_SILICON 0x0 +#define XPLAT_ZYNQ_ULTRA_MP 0x1 +#define XPLAT_ZYNQ_ULTRA_MPVEL 0x2 +#define XPLAT_ZYNQ_ULTRA_MPQEMU 0x3 +#define XPLAT_ZYNQ 0x4 +#define XPLAT_MICROBLAZE 0x5 +#define XPLAT_versal 0x6U + +#define XPS_VERSION_1 0x0 +#define XPS_VERSION_2 0x1 +#define XPLAT_INFO_MASK (0xF) + +#if defined (versal) +#define XPS_VERSION_INFO_MASK 0xFF00U +#define XPS_VERSION_INFO_SHIFT 0x8U +#define XPLAT_INFO_SHIFT 0x18U +#else +#define XPS_VERSION_INFO_MASK (0xF) +#define XPS_VERSION_INFO_SHIFT 0x0U +#define XPLAT_INFO_SHIFT 0xCU +#endif + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + + +u32 XGetPlatform_Info(void); + +#if defined (ARMR5) || (__aarch64__) || (ARMA53_32) || (PSU_PMU) +u32 XGetPSVersion_Info(); +#endif + +#if defined (ARMR5) || (__aarch64__) || (ARMA53_32) +u32 XGet_Zynq_UltraMp_Platform_info(); +#endif +/************************** Function Prototypes ******************************/ + + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** +* @} End of "addtogroup common_platform_info". +*/ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xpm_counter.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xpm_counter.c new file mode 100644 index 0000000..482671e --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xpm_counter.c @@ -0,0 +1,293 @@ +/****************************************************************************** +* +* Copyright (C) 2011 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xpm_counter.c +* +* This file contains APIs for configuring and controlling the Cortex-A9 +* Performance Monitor Events. For more information about the event counters, +* see xpm_counter.h. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a sdm  07/11/11 First release
+* 4.2	pkp	 07/21/14 Corrected reset value of event counter in function
+*					  Xpm_ResetEventCounters to fix CR#796275
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xpm_counter.h" + +/************************** Constant Definitions ****************************/ + +/**************************** Type Definitions ******************************/ + +typedef const u32 PmcrEventCfg32[XPM_CTRCOUNT]; + +/***************** Macros (Inline Functions) Definitions ********************/ + +/************************** Variable Definitions *****************************/ + +/************************** Function Prototypes ******************************/ + +void Xpm_DisableEventCounters(void); +void Xpm_EnableEventCounters (void); +void Xpm_ResetEventCounters (void); + +/******************************************************************************/ + +/****************************************************************************/ +/** +* +* @brief This function disables the Cortex A9 event counters. +* +* @param None. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void Xpm_DisableEventCounters(void) +{ + /* Disable the event counters */ + mtcp(XREG_CP15_COUNT_ENABLE_CLR, 0x3f); +} + +/****************************************************************************/ +/** +* +* @brief This function enables the Cortex A9 event counters. +* +* @param None. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void Xpm_EnableEventCounters(void) +{ + /* Enable the event counters */ + mtcp(XREG_CP15_COUNT_ENABLE_SET, 0x3f); +} + +/****************************************************************************/ +/** +* +* @brief This function resets the Cortex A9 event counters. +* +* @param None. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void Xpm_ResetEventCounters(void) +{ + u32 Reg; +#ifdef __GNUC__ + Reg = mfcp(XREG_CP15_PERF_MONITOR_CTRL); +#elif defined (__ICCARM__) + mfcp(XREG_CP15_PERF_MONITOR_CTRL, Reg); +#else + { register u32 C15Reg __asm(XREG_CP15_PERF_MONITOR_CTRL); + Reg = C15Reg; } +#endif + Reg |= (1U << 1U); /* reset event counters */ + mtcp(XREG_CP15_PERF_MONITOR_CTRL, Reg); + +} + +/****************************************************************************/ +/** +* @brief This function configures the Cortex A9 event counters controller, +* with the event codes, in a configuration selected by the user and +* enables the counters. +* +* @param PmcrCfg: Configuration value based on which the event counters +* are configured. XPM_CNTRCFG* values defined in xpm_counter.h can +* be utilized for setting configuration. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void Xpm_SetEvents(s32 PmcrCfg) +{ + u32 Counter; + static PmcrEventCfg32 PmcrEvents[] = { + { + XPM_EVENT_SOFTINCR, + XPM_EVENT_INSRFETCH_CACHEREFILL, + XPM_EVENT_INSTRFECT_TLBREFILL, + XPM_EVENT_DATA_CACHEREFILL, + XPM_EVENT_DATA_CACHEACCESS, + XPM_EVENT_DATA_TLBREFILL + }, + { + XPM_EVENT_DATA_READS, + XPM_EVENT_DATA_WRITE, + XPM_EVENT_EXCEPTION, + XPM_EVENT_EXCEPRETURN, + XPM_EVENT_CHANGECONTEXT, + XPM_EVENT_SW_CHANGEPC + }, + { + XPM_EVENT_IMMEDBRANCH, + XPM_EVENT_UNALIGNEDACCESS, + XPM_EVENT_BRANCHMISS, + XPM_EVENT_CLOCKCYCLES, + XPM_EVENT_BRANCHPREDICT, + XPM_EVENT_JAVABYTECODE + }, + { + XPM_EVENT_SWJAVABYTECODE, + XPM_EVENT_JAVABACKBRANCH, + XPM_EVENT_COHERLINEMISS, + XPM_EVENT_COHERLINEHIT, + XPM_EVENT_INSTRSTALL, + XPM_EVENT_DATASTALL + }, + { + XPM_EVENT_MAINTLBSTALL, + XPM_EVENT_STREXPASS, + XPM_EVENT_STREXFAIL, + XPM_EVENT_DATAEVICT, + XPM_EVENT_NODISPATCH, + XPM_EVENT_ISSUEEMPTY + }, + { + XPM_EVENT_INSTRRENAME, + XPM_EVENT_PREDICTFUNCRET, + XPM_EVENT_MAINEXEC, + XPM_EVENT_SECEXEC, + XPM_EVENT_LDRSTR, + XPM_EVENT_FLOATRENAME + }, + { + XPM_EVENT_NEONRENAME, + XPM_EVENT_PLDSTALL, + XPM_EVENT_WRITESTALL, + XPM_EVENT_INSTRTLBSTALL, + XPM_EVENT_DATATLBSTALL, + XPM_EVENT_INSTR_uTLBSTALL + }, + { + XPM_EVENT_DATA_uTLBSTALL, + XPM_EVENT_DMB_STALL, + XPM_EVENT_INT_CLKEN, + XPM_EVENT_DE_CLKEN, + XPM_EVENT_INSTRISB, + XPM_EVENT_INSTRDSB + }, + { + XPM_EVENT_INSTRDMB, + XPM_EVENT_EXTINT, + XPM_EVENT_PLE_LRC, + XPM_EVENT_PLE_LRS, + XPM_EVENT_PLE_FLUSH, + XPM_EVENT_PLE_CMPL + }, + { + XPM_EVENT_PLE_OVFL, + XPM_EVENT_PLE_PROG, + XPM_EVENT_PLE_LRC, + XPM_EVENT_PLE_LRS, + XPM_EVENT_PLE_FLUSH, + XPM_EVENT_PLE_CMPL + }, + { + XPM_EVENT_DATASTALL, + XPM_EVENT_INSRFETCH_CACHEREFILL, + XPM_EVENT_INSTRFECT_TLBREFILL, + XPM_EVENT_DATA_CACHEREFILL, + XPM_EVENT_DATA_CACHEACCESS, + XPM_EVENT_DATA_TLBREFILL + }, + }; + const u32 *ptr = PmcrEvents[PmcrCfg]; + + Xpm_DisableEventCounters(); + + for(Counter = 0U; Counter < XPM_CTRCOUNT; Counter++) { + + /* Selecet event counter */ + mtcp(XREG_CP15_EVENT_CNTR_SEL, Counter); + + /* Set the event */ + mtcp(XREG_CP15_EVENT_TYPE_SEL, ptr[Counter]); + } + + Xpm_ResetEventCounters(); + Xpm_EnableEventCounters(); +} + +/****************************************************************************/ +/** +* +* @brief This function disables the event counters and returns the counter +* values. +* +* @param PmCtrValue: Pointer to an array of type u32 PmCtrValue[6]. +* It is an output parameter which is used to return the PM +* counter values. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void Xpm_GetEventCounters(u32 *PmCtrValue) +{ + u32 Counter; + + Xpm_DisableEventCounters(); + + for(Counter = 0U; Counter < XPM_CTRCOUNT; Counter++) { + + mtcp(XREG_CP15_EVENT_CNTR_SEL, Counter); +#ifdef __GNUC__ + PmCtrValue[Counter] = mfcp(XREG_CP15_PERF_MONITOR_COUNT); +#elif defined (__ICCARM__) + mfcp(XREG_CP15_PERF_MONITOR_COUNT, PmCtrValue[Counter]); +#else + { register u32 Cp15Reg __asm(XREG_CP15_PERF_MONITOR_COUNT); + PmCtrValue[Counter] = Cp15Reg; } +#endif + } +} diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xpm_counter.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xpm_counter.h new file mode 100644 index 0000000..39db7d8 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xpm_counter.h @@ -0,0 +1,572 @@ +/****************************************************************************** +* +* Copyright (C) 2011 - 2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xpm_counter.h +* +* @addtogroup a9_event_counter_apis Cortex A9 Event Counters Functions +* +* Cortex A9 event counter functions can be utilized to configure and control +* the Cortex-A9 performance monitor events. +* +* Cortex-A9 performance monitor has six event counters which can be used to +* count a variety of events described in Coretx-A9 TRM. xpm_counter.h defines +* configurations XPM_CNTRCFGx which can be used to program the event counters +* to count a set of events. +* +* @note +* It doesn't handle the Cortex-A9 cycle counter, as the cycle counter is +* being used for time keeping. +* +* @{ +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a sdm  07/11/11 First release
+* 6.8   aru  09/06/18 Removed compilation warnings for ARMCC toolchain.
+* 
+* +******************************************************************************/ + +#ifndef XPMCOUNTER_H /* prevent circular inclusions */ +#define XPMCOUNTER_H /* by using protection macros */ + +/***************************** Include Files ********************************/ + +#include +#include "xpseudo_asm.h" +#include "xil_types.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/************************** Constant Definitions ****************************/ + +/* Number of performance counters */ +#define XPM_CTRCOUNT 6U + +/* The following constants define the Cortex-A9 Performance Monitor Events */ + +/* + * Software increment. The register is incremented only on writes to the + * Software Increment Register + */ +#define XPM_EVENT_SOFTINCR 0x00U + +/* + * Instruction fetch that causes a refill at (at least) the lowest level(s) of + * instruction or unified cache. Includes the speculative linefills in the + * count + */ +#define XPM_EVENT_INSRFETCH_CACHEREFILL 0x01U + +/* + * Instruction fetch that causes a TLB refill at (at least) the lowest level of + * TLB. Includes the speculative requests in the count + */ +#define XPM_EVENT_INSTRFECT_TLBREFILL 0x02U + +/* + * Data read or write operation that causes a refill at (at least) the lowest + * level(s)of data or unified cache. Counts the number of allocations performed + * in the Data Cache due to a read or a write + */ +#define XPM_EVENT_DATA_CACHEREFILL 0x03U + +/* + * Data read or write operation that causes a cache access at (at least) the + * lowest level(s) of data or unified cache. This includes speculative reads + */ +#define XPM_EVENT_DATA_CACHEACCESS 0x04U + +/* + * Data read or write operation that causes a TLB refill at (at least) the + * lowest level of TLB. This does not include micro TLB misses due to PLD, PLI, + * CP15 Cache operation by MVA and CP15 VA to PA operations + */ +#define XPM_EVENT_DATA_TLBREFILL 0x05U + +/* + * Data read architecturally executed. Counts the number of data read + * instructions accepted by the Load Store Unit. This includes counting the + * speculative and aborted LDR/LDM, as well as the reads due to the SWP + * instructions + */ +#define XPM_EVENT_DATA_READS 0x06U + +/* + * Data write architecturally executed. Counts the number of data write + * instructions accepted by the Load Store Unit. This includes counting the + * speculative and aborted STR/STM, as well as the writes due to the SWP + * instructions + */ +#define XPM_EVENT_DATA_WRITE 0x07U + +/* Exception taken. Counts the number of exceptions architecturally taken.*/ +#define XPM_EVENT_EXCEPTION 0x09U + +/* Exception return architecturally executed.*/ +#define XPM_EVENT_EXCEPRETURN 0x0AU + +/* + * Change to ContextID retired. Counts the number of instructions + * architecturally executed writing into the ContextID Register + */ +#define XPM_EVENT_CHANGECONTEXT 0x0BU + +/* + * Software change of PC, except by an exception, architecturally executed. + * Count the number of PC changes architecturally executed, excluding the PC + * changes due to taken exceptions + */ +#define XPM_EVENT_SW_CHANGEPC 0x0CU + +/* + * Immediate branch architecturally executed (taken or not taken). This includes + * the branches which are flushed due to a previous load/store which aborts + * late + */ +#define XPM_EVENT_IMMEDBRANCH 0x0DU + +/* + * Unaligned access architecturally executed. Counts the number of aborted + * unaligned accessed architecturally executed, and the number of not-aborted + * unaligned accesses, including the speculative ones + */ +#define XPM_EVENT_UNALIGNEDACCESS 0x0FU + +/* + * Branch mispredicted/not predicted. Counts the number of mispredicted or + * not-predicted branches executed. This includes the branches which are flushed + * due to a previous load/store which aborts late + */ +#define XPM_EVENT_BRANCHMISS 0x10U + +/* + * Counts clock cycles when the Cortex-A9 processor is not in WFE/WFI. This + * event is not exported on the PMUEVENT bus + */ +#define XPM_EVENT_CLOCKCYCLES 0x11U + +/* + * Branches or other change in program flow that could have been predicted by + * the branch prediction resources of the processor. This includes the branches + * which are flushed due to a previous load/store which aborts late + */ +#define XPM_EVENT_BRANCHPREDICT 0x12U + +/* + * Java bytecode execute. Counts the number of Java bytecodes being decoded, + * including speculative ones + */ +#define XPM_EVENT_JAVABYTECODE 0x40U + +/* + * Software Java bytecode executed. Counts the number of software java bytecodes + * being decoded, including speculative ones + */ +#define XPM_EVENT_SWJAVABYTECODE 0x41U + +/* + * Jazelle backward branches executed. Counts the number of Jazelle taken + * branches being executed. This includes the branches which are flushed due + * to a previous load/store which aborts late + */ +#define XPM_EVENT_JAVABACKBRANCH 0x42U + +/* + * Coherent linefill miss Counts the number of coherent linefill requests + * performed by the Cortex-A9 processor which also miss in all the other + * Cortex-A9 processors, meaning that the request is sent to the external + * memory + */ +#define XPM_EVENT_COHERLINEMISS 0x50U + +/* + * Coherent linefill hit. Counts the number of coherent linefill requests + * performed by the Cortex-A9 processor which hit in another Cortex-A9 + * processor, meaning that the linefill data is fetched directly from the + * relevant Cortex-A9 cache + */ +#define XPM_EVENT_COHERLINEHIT 0x51U + +/* + * Instruction cache dependent stall cycles. Counts the number of cycles where + * the processor is ready to accept new instructions, but does not receive any + * due to the instruction side not being able to provide any and the + * instruction cache is currently performing at least one linefill + */ +#define XPM_EVENT_INSTRSTALL 0x60U + +/* + * Data cache dependent stall cycles. Counts the number of cycles where the core + * has some instructions that it cannot issue to any pipeline, and the Load + * Store unit has at least one pending linefill request, and no pending + */ +#define XPM_EVENT_DATASTALL 0x61U + +/* + * Main TLB miss stall cycles. Counts the number of cycles where the processor + * is stalled waiting for the completion of translation table walks from the + * main TLB. The processor stalls can be due to the instruction side not being + * able to provide the instructions, or to the data side not being able to + * provide the necessary data, due to them waiting for the main TLB translation + * table walk to complete + */ +#define XPM_EVENT_MAINTLBSTALL 0x62U + +/* + * Counts the number of STREX instructions architecturally executed and + * passed + */ +#define XPM_EVENT_STREXPASS 0x63U + +/* + * Counts the number of STREX instructions architecturally executed and + * failed + */ +#define XPM_EVENT_STREXFAIL 0x64U + +/* + * Data eviction. Counts the number of eviction requests due to a linefill in + * the data cache + */ +#define XPM_EVENT_DATAEVICT 0x65U + +/* + * Counts the number of cycles where the issue stage does not dispatch any + * instruction because it is empty or cannot dispatch any instructions + */ +#define XPM_EVENT_NODISPATCH 0x66U + +/* + * Counts the number of cycles where the issue stage is empty + */ +#define XPM_EVENT_ISSUEEMPTY 0x67U + +/* + * Counts the number of instructions going through the Register Renaming stage. + * This number is an approximate number of the total number of instructions + * speculatively executed, and even more approximate of the total number of + * instructions architecturally executed. The approximation depends mainly on + * the branch misprediction rate. + * The renaming stage can handle two instructions in the same cycle so the event + * is two bits long: + * - b00 no instructions renamed + * - b01 one instruction renamed + * - b10 two instructions renamed + */ +#define XPM_EVENT_INSTRRENAME 0x68U + +/* + * Counts the number of procedure returns whose condition codes do not fail, + * excluding all returns from exception. This count includes procedure returns + * which are flushed due to a previous load/store which aborts late. + * Only the following instructions are reported: + * - BX R14 + * - MOV PC LR + * - POP {..,pc} + * - LDR pc,[sp],#offset + * The following instructions are not reported: + * - LDMIA R9!,{..,PC} (ThumbEE state only) + * - LDR PC,[R9],#offset (ThumbEE state only) + * - BX R0 (Rm != R14) + * - MOV PC,R0 (Rm != R14) + * - LDM SP,{...,PC} (writeback not specified) + * - LDR PC,[SP,#offset] (wrong addressing mode) + */ +#define XPM_EVENT_PREDICTFUNCRET 0x6EU + +/* + * Counts the number of instructions being executed in the main execution + * pipeline of the processor, the multiply pipeline and arithmetic logic unit + * pipeline. The counted instructions are still speculative + */ +#define XPM_EVENT_MAINEXEC 0x70U + +/* + * Counts the number of instructions being executed in the processor second + * execution pipeline (ALU). The counted instructions are still speculative + */ +#define XPM_EVENT_SECEXEC 0x71U + +/* + * Counts the number of instructions being executed in the Load/Store unit. The + * counted instructions are still speculative + */ +#define XPM_EVENT_LDRSTR 0x72U + +/* + * Counts the number of Floating-point instructions going through the Register + * Rename stage. Instructions are still speculative in this stage. + *Two floating-point instructions can be renamed in the same cycle so the event + * is two bitslong: + *0b00 no floating-point instruction renamed + *0b01 one floating-point instruction renamed + *0b10 two floating-point instructions renamed + */ +#define XPM_EVENT_FLOATRENAME 0x73U + +/* + * Counts the number of Neon instructions going through the Register Rename + * stage.Instructions are still speculative in this stage. + * Two NEON instructions can be renamed in the same cycle so the event is two + * bits long: + *0b00 no NEON instruction renamed + *0b01 one NEON instruction renamed + *0b10 two NEON instructions renamed + */ +#define XPM_EVENT_NEONRENAME 0x74U + +/* + * Counts the number of cycles where the processor is stalled because PLD slots + * are all full + */ +#define XPM_EVENT_PLDSTALL 0x80U + +/* + * Counts the number of cycles when the processor is stalled and the data side + * is stalled too because it is full and executing writes to the external + * memory + */ +#define XPM_EVENT_WRITESTALL 0x81U + +/* + * Counts the number of stall cycles due to main TLB misses on requests issued + * by the instruction side + */ +#define XPM_EVENT_INSTRTLBSTALL 0x82U + +/* + * Counts the number of stall cycles due to main TLB misses on requests issued + * by the data side + */ +#define XPM_EVENT_DATATLBSTALL 0x83U + +/* + * Counts the number of stall cycles due to micro TLB misses on the instruction + * side. This event does not include main TLB miss stall cycles that are already + * counted in the corresponding main TLB event + */ +#define XPM_EVENT_INSTR_uTLBSTALL 0x84U + +/* + * Counts the number of stall cycles due to micro TLB misses on the data side. + * This event does not include main TLB miss stall cycles that are already + * counted in the corresponding main TLB event + */ +#define XPM_EVENT_DATA_uTLBSTALL 0x85U + +/* + * Counts the number of stall cycles because of the execution of a DMB memory + * barrier. This includes all DMB instructions being executed, even + * speculatively + */ +#define XPM_EVENT_DMB_STALL 0x86U + +/* + * Counts the number of cycles during which the integer core clock is enabled + */ +#define XPM_EVENT_INT_CLKEN 0x8AU + +/* + * Counts the number of cycles during which the Data Engine clock is enabled + */ +#define XPM_EVENT_DE_CLKEN 0x8BU + +/* + * Counts the number of ISB instructions architecturally executed + */ +#define XPM_EVENT_INSTRISB 0x90U + +/* + * Counts the number of DSB instructions architecturally executed + */ +#define XPM_EVENT_INSTRDSB 0x91U + +/* + * Counts the number of DMB instructions speculatively executed + */ +#define XPM_EVENT_INSTRDMB 0x92U + +/* + * Counts the number of external interrupts executed by the processor + */ +#define XPM_EVENT_EXTINT 0x93U + +/* + * PLE cache line request completed + */ +#define XPM_EVENT_PLE_LRC 0xA0U + +/* + * PLE cache line request skipped + */ +#define XPM_EVENT_PLE_LRS 0xA1U + +/* + * PLE FIFO flush + */ +#define XPM_EVENT_PLE_FLUSH 0xA2U + +/* + * PLE request complete + */ +#define XPM_EVENT_PLE_CMPL 0xA3U + +/* + * PLE FIFO overflow + */ +#define XPM_EVENT_PLE_OVFL 0xA4U + +/* + * PLE request programmed + */ +#define XPM_EVENT_PLE_PROG 0xA5U + +/* + * The following constants define the configurations for Cortex-A9 Performance + * Monitor Events. Each configuration configures the event counters for a set + * of events. + * ----------------------------------------------- + * Config PmCtr0... PmCtr5 + * ----------------------------------------------- + * XPM_CNTRCFG1 { XPM_EVENT_SOFTINCR, + * XPM_EVENT_INSRFETCH_CACHEREFILL, + * XPM_EVENT_INSTRFECT_TLBREFILL, + * XPM_EVENT_DATA_CACHEREFILL, + * XPM_EVENT_DATA_CACHEACCESS, + * XPM_EVENT_DATA_TLBREFILL } + * + * XPM_CNTRCFG2 { XPM_EVENT_DATA_READS, + * XPM_EVENT_DATA_WRITE, + * XPM_EVENT_EXCEPTION, + * XPM_EVENT_EXCEPRETURN, + * XPM_EVENT_CHANGECONTEXT, + * XPM_EVENT_SW_CHANGEPC } + * + * XPM_CNTRCFG3 { XPM_EVENT_IMMEDBRANCH, + * XPM_EVENT_UNALIGNEDACCESS, + * XPM_EVENT_BRANCHMISS, + * XPM_EVENT_CLOCKCYCLES, + * XPM_EVENT_BRANCHPREDICT, + * XPM_EVENT_JAVABYTECODE } + * + * XPM_CNTRCFG4 { XPM_EVENT_SWJAVABYTECODE, + * XPM_EVENT_JAVABACKBRANCH, + * XPM_EVENT_COHERLINEMISS, + * XPM_EVENT_COHERLINEHIT, + * XPM_EVENT_INSTRSTALL, + * XPM_EVENT_DATASTALL } + * + * XPM_CNTRCFG5 { XPM_EVENT_MAINTLBSTALL, + * XPM_EVENT_STREXPASS, + * XPM_EVENT_STREXFAIL, + * XPM_EVENT_DATAEVICT, + * XPM_EVENT_NODISPATCH, + * XPM_EVENT_ISSUEEMPTY } + * + * XPM_CNTRCFG6 { XPM_EVENT_INSTRRENAME, + * XPM_EVENT_PREDICTFUNCRET, + * XPM_EVENT_MAINEXEC, + * XPM_EVENT_SECEXEC, + * XPM_EVENT_LDRSTR, + * XPM_EVENT_FLOATRENAME } + * + * XPM_CNTRCFG7 { XPM_EVENT_NEONRENAME, + * XPM_EVENT_PLDSTALL, + * XPM_EVENT_WRITESTALL, + * XPM_EVENT_INSTRTLBSTALL, + * XPM_EVENT_DATATLBSTALL, + * XPM_EVENT_INSTR_uTLBSTALL } + * + * XPM_CNTRCFG8 { XPM_EVENT_DATA_uTLBSTALL, + * XPM_EVENT_DMB_STALL, + * XPM_EVENT_INT_CLKEN, + * XPM_EVENT_DE_CLKEN, + * XPM_EVENT_INSTRISB, + * XPM_EVENT_INSTRDSB } + * + * XPM_CNTRCFG9 { XPM_EVENT_INSTRDMB, + * XPM_EVENT_EXTINT, + * XPM_EVENT_PLE_LRC, + * XPM_EVENT_PLE_LRS, + * XPM_EVENT_PLE_FLUSH, + * XPM_EVENT_PLE_CMPL } + * + * XPM_CNTRCFG10 { XPM_EVENT_PLE_OVFL, + * XPM_EVENT_PLE_PROG, + * XPM_EVENT_PLE_LRC, + * XPM_EVENT_PLE_LRS, + * XPM_EVENT_PLE_FLUSH, + * XPM_EVENT_PLE_CMPL } + * + * XPM_CNTRCFG11 { XPM_EVENT_DATASTALL, + * XPM_EVENT_INSRFETCH_CACHEREFILL, + * XPM_EVENT_INSTRFECT_TLBREFILL, + * XPM_EVENT_DATA_CACHEREFILL, + * XPM_EVENT_DATA_CACHEACCESS, + * XPM_EVENT_DATA_TLBREFILL } + */ +#define XPM_CNTRCFG1 0 +#define XPM_CNTRCFG2 1 +#define XPM_CNTRCFG3 2 +#define XPM_CNTRCFG4 3 +#define XPM_CNTRCFG5 4 +#define XPM_CNTRCFG6 5 +#define XPM_CNTRCFG7 6 +#define XPM_CNTRCFG8 7 +#define XPM_CNTRCFG9 8 +#define XPM_CNTRCFG10 9 +#define XPM_CNTRCFG11 10 + +/**************************** Type Definitions ******************************/ + +/***************** Macros (Inline Functions) Definitions ********************/ + +/************************** Variable Definitions ****************************/ + +/************************** Function Prototypes *****************************/ + +/* Interface fuctions to access perfromance counters from abstraction layer */ +void Xpm_SetEvents(s32 PmcrCfg); +void Xpm_GetEventCounters(u32 *PmCtrValue); + +#ifdef __cplusplus +} +#endif + +#endif +/** +* @} End of "addtogroup a9_event_counter_apis". +*/ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xpseudo_asm.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xpseudo_asm.h new file mode 100644 index 0000000..c7123a0 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xpseudo_asm.h @@ -0,0 +1,82 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xpseudo_asm.h +* +* @addtogroup a9_specific Cortex A9 Processor Specific Include Files +* +* The xpseudo_asm.h includes xreg_cortexa9.h and xpseudo_asm_gcc.h. +* +* The xreg_cortexa9.h file contains definitions for inline assembler code. +* It provides inline definitions for Cortex A9 GPRs, SPRs, MPE registers, +* co-processor registers and Debug registers. +* +* The xpseudo_asm_gcc.h contains the definitions for the most often used inline +* assembler instructions, available as macros. These can be very useful for +* tasks such as setting or getting special purpose registers, synchronization, +* or cache manipulation etc. These inline assembler instructions can be used +* from drivers and user applications written in C. +* +* @{ +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a ecm  10/18/09 First release
+* 3.04a sdm  01/02/12 Remove redundant dsb in mcr instruction.
+* 6.8   aru  09/06/18 Removed compilation warnings for ARMCC toolchain.
+* 
+* +******************************************************************************/ +#ifndef XPSEUDO_ASM_H +#define XPSEUDO_ASM_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "xreg_cortexa9.h" +#ifdef __GNUC__ + #include "xpseudo_asm_gcc.h" +#elif defined (__ICCARM__) + #include "xpseudo_asm_iccarm.h" +#else + #include "xpseudo_asm_rvct.h" +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* XPSEUDO_ASM_H */ +/** +* @} End of "addtogroup a9_specific". +*/ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xpseudo_asm_gcc.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xpseudo_asm_gcc.h new file mode 100644 index 0000000..85b067d --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xpseudo_asm_gcc.h @@ -0,0 +1,252 @@ +/****************************************************************************** +* +* Copyright (C) 2014 - 2016 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xpseudo_asm_gcc.h +* +* This header file contains macros for using inline assembler code. It is +* written specifically for the GNU compiler. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who      Date     Changes
+* ----- -------- -------- -----------------------------------------------
+* 5.00 	pkp		 05/21/14 First release
+* 6.0   mus      07/27/16 Consolidated file for a53,a9 and r5 processors
+* 
+* +******************************************************************************/ + +#ifndef XPSEUDO_ASM_GCC_H /* prevent circular inclusions */ +#define XPSEUDO_ASM_GCC_H /* by using protection macros */ + +/***************************** Include Files ********************************/ + +#include "xil_types.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/************************** Constant Definitions ****************************/ + +/**************************** Type Definitions ******************************/ + +/***************** Macros (Inline Functions) Definitions ********************/ + +/* necessary for pre-processor */ +#define stringify(s) tostring(s) +#define tostring(s) #s + +#if defined (__aarch64__) +/* pseudo assembler instructions */ +#define mfcpsr() ({u32 rval = 0U; \ + asm volatile("mrs %0, DAIF" : "=r" (rval));\ + rval;\ + }) + +#define mtcpsr(v) __asm__ __volatile__ ("msr DAIF, %0" : : "r" (v)) + +#define cpsiei() //__asm__ __volatile__("cpsie i\n") +#define cpsidi() //__asm__ __volatile__("cpsid i\n") + +#define cpsief() //__asm__ __volatile__("cpsie f\n") +#define cpsidf() //__asm__ __volatile__("cpsid f\n") + + + +#define mtgpr(rn, v) /*__asm__ __volatile__(\ + "mov r" stringify(rn) ", %0 \n"\ + : : "r" (v)\ + )*/ + +#define mfgpr(rn) /*({u32 rval; \ + __asm__ __volatile__(\ + "mov %0,r" stringify(rn) "\n"\ + : "=r" (rval)\ + );\ + rval;\ + })*/ + +/* memory synchronization operations */ + +/* Instruction Synchronization Barrier */ +#define isb() __asm__ __volatile__ ("isb sy") + +/* Data Synchronization Barrier */ +#define dsb() __asm__ __volatile__("dsb sy") + +/* Data Memory Barrier */ +#define dmb() __asm__ __volatile__("dmb sy") + + +/* Memory Operations */ +#define ldr(adr) ({u64 rval; \ + __asm__ __volatile__(\ + "ldr %0,[%1]"\ + : "=r" (rval) : "r" (adr)\ + );\ + rval;\ + }) + +#define mfelrel3() ({u64 rval = 0U; \ + asm volatile("mrs %0, ELR_EL3" : "=r" (rval));\ + rval;\ + }) + +#define mtelrel3(v) __asm__ __volatile__ ("msr ELR_EL3, %0" : : "r" (v)) + +#else + +/* pseudo assembler instructions */ +#define mfcpsr() ({u32 rval = 0U; \ + __asm__ __volatile__(\ + "mrs %0, cpsr\n"\ + : "=r" (rval)\ + );\ + rval;\ + }) + +#define mtcpsr(v) __asm__ __volatile__(\ + "msr cpsr,%0\n"\ + : : "r" (v)\ + ) + +#define cpsiei() __asm__ __volatile__("cpsie i\n") +#define cpsidi() __asm__ __volatile__("cpsid i\n") + +#define cpsief() __asm__ __volatile__("cpsie f\n") +#define cpsidf() __asm__ __volatile__("cpsid f\n") + + + +#define mtgpr(rn, v) __asm__ __volatile__(\ + "mov r" stringify(rn) ", %0 \n"\ + : : "r" (v)\ + ) + +#define mfgpr(rn) ({u32 rval; \ + __asm__ __volatile__(\ + "mov %0,r" stringify(rn) "\n"\ + : "=r" (rval)\ + );\ + rval;\ + }) + +/* memory synchronization operations */ + +/* Instruction Synchronization Barrier */ +#define isb() __asm__ __volatile__ ("isb" : : : "memory") + +/* Data Synchronization Barrier */ +#define dsb() __asm__ __volatile__ ("dsb" : : : "memory") + +/* Data Memory Barrier */ +#define dmb() __asm__ __volatile__ ("dmb" : : : "memory") + + +/* Memory Operations */ +#define ldr(adr) ({u32 rval; \ + __asm__ __volatile__(\ + "ldr %0,[%1]"\ + : "=r" (rval) : "r" (adr)\ + );\ + rval;\ + }) + +#endif + +#define ldrb(adr) ({u8 rval; \ + __asm__ __volatile__(\ + "ldrb %0,[%1]"\ + : "=r" (rval) : "r" (adr)\ + );\ + rval;\ + }) + +#define str(adr, val) __asm__ __volatile__(\ + "str %0,[%1]\n"\ + : : "r" (val), "r" (adr)\ + ) + +#define strb(adr, val) __asm__ __volatile__(\ + "strb %0,[%1]\n"\ + : : "r" (val), "r" (adr)\ + ) + +/* Count leading zeroes (clz) */ +#define clz(arg) ({u8 rval; \ + __asm__ __volatile__(\ + "clz %0,%1"\ + : "=r" (rval) : "r" (arg)\ + );\ + rval;\ + }) + +#if defined (__aarch64__) +#define mtcpdc(reg,val) __asm__ __volatile__("dc " #reg ",%0" : : "r" (val)) +#define mtcpic(reg,val) __asm__ __volatile__("ic " #reg ",%0" : : "r" (val)) + +#define mtcpicall(reg) __asm__ __volatile__("ic " #reg) +#define mtcptlbi(reg) __asm__ __volatile__("tlbi " #reg) +#define mtcpat(reg,val) __asm__ __volatile__("at " #reg ",%0" : : "r" (val)) +/* CP15 operations */ +#define mfcp(reg) ({u64 rval = 0U;\ + __asm__ __volatile__("mrs %0, " #reg : "=r" (rval));\ + rval;\ + }) + +#define mtcp(reg,val) __asm__ __volatile__("msr " #reg ",%0" : : "r" (val)) + +#else +/* CP15 operations */ +#define mtcp(rn, v) __asm__ __volatile__(\ + "mcr " rn "\n"\ + : : "r" (v)\ + ); + +#define mfcp(rn) ({u32 rval = 0U; \ + __asm__ __volatile__(\ + "mrc " rn "\n"\ + : "=r" (rval)\ + );\ + rval;\ + }) +#endif + +/************************** Variable Definitions ****************************/ + +/************************** Function Prototypes *****************************/ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* XPSEUDO_ASM_GCC_H */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xreg_cortexa9.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xreg_cortexa9.h new file mode 100644 index 0000000..ad93665 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xreg_cortexa9.h @@ -0,0 +1,587 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xreg_cortexa9.h +* +* This header file contains definitions for using inline assembler code. It is +* written specifically for the GNU, ARMCC compiler. +* +* All of the ARM Cortex A9 GPRs, SPRs, and Debug Registers are defined along +* with the positions of the bits within the registers. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who      Date     Changes
+* ----- -------- -------- -----------------------------------------------
+* 1.00a ecm/sdm  10/20/09 First release
+* 
+* +******************************************************************************/ +#ifndef XREG_CORTEXA9_H +#define XREG_CORTEXA9_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* GPRs */ +#define XREG_GPR0 r0 +#define XREG_GPR1 r1 +#define XREG_GPR2 r2 +#define XREG_GPR3 r3 +#define XREG_GPR4 r4 +#define XREG_GPR5 r5 +#define XREG_GPR6 r6 +#define XREG_GPR7 r7 +#define XREG_GPR8 r8 +#define XREG_GPR9 r9 +#define XREG_GPR10 r10 +#define XREG_GPR11 r11 +#define XREG_GPR12 r12 +#define XREG_GPR13 r13 +#define XREG_GPR14 r14 +#define XREG_GPR15 r15 +#define XREG_CPSR cpsr + +/* Coprocessor number defines */ +#define XREG_CP0 0 +#define XREG_CP1 1 +#define XREG_CP2 2 +#define XREG_CP3 3 +#define XREG_CP4 4 +#define XREG_CP5 5 +#define XREG_CP6 6 +#define XREG_CP7 7 +#define XREG_CP8 8 +#define XREG_CP9 9 +#define XREG_CP10 10 +#define XREG_CP11 11 +#define XREG_CP12 12 +#define XREG_CP13 13 +#define XREG_CP14 14 +#define XREG_CP15 15 + +/* Coprocessor control register defines */ +#define XREG_CR0 cr0 +#define XREG_CR1 cr1 +#define XREG_CR2 cr2 +#define XREG_CR3 cr3 +#define XREG_CR4 cr4 +#define XREG_CR5 cr5 +#define XREG_CR6 cr6 +#define XREG_CR7 cr7 +#define XREG_CR8 cr8 +#define XREG_CR9 cr9 +#define XREG_CR10 cr10 +#define XREG_CR11 cr11 +#define XREG_CR12 cr12 +#define XREG_CR13 cr13 +#define XREG_CR14 cr14 +#define XREG_CR15 cr15 + +/* Current Processor Status Register (CPSR) Bits */ +#define XREG_CPSR_THUMB_MODE 0x20 +#define XREG_CPSR_MODE_BITS 0x1F +#define XREG_CPSR_SYSTEM_MODE 0x1F +#define XREG_CPSR_UNDEFINED_MODE 0x1B +#define XREG_CPSR_DATA_ABORT_MODE 0x17 +#define XREG_CPSR_SVC_MODE 0x13 +#define XREG_CPSR_IRQ_MODE 0x12 +#define XREG_CPSR_FIQ_MODE 0x11 +#define XREG_CPSR_USER_MODE 0x10 + +#define XREG_CPSR_IRQ_ENABLE 0x80 +#define XREG_CPSR_FIQ_ENABLE 0x40 + +#define XREG_CPSR_N_BIT 0x80000000 +#define XREG_CPSR_Z_BIT 0x40000000 +#define XREG_CPSR_C_BIT 0x20000000 +#define XREG_CPSR_V_BIT 0x10000000 + + +/* CP15 defines */ +#if defined (__GNUC__) || defined (__ICCARM__) +/* C0 Register defines */ +#define XREG_CP15_MAIN_ID "p15, 0, %0, c0, c0, 0" +#define XREG_CP15_CACHE_TYPE "p15, 0, %0, c0, c0, 1" +#define XREG_CP15_TCM_TYPE "p15, 0, %0, c0, c0, 2" +#define XREG_CP15_TLB_TYPE "p15, 0, %0, c0, c0, 3" +#define XREG_CP15_MULTI_PROC_AFFINITY "p15, 0, %0, c0, c0, 5" + +#define XREG_CP15_PROC_FEATURE_0 "p15, 0, %0, c0, c1, 0" +#define XREG_CP15_PROC_FEATURE_1 "p15, 0, %0, c0, c1, 1" +#define XREG_CP15_DEBUG_FEATURE_0 "p15, 0, %0, c0, c1, 2" +#define XREG_CP15_MEMORY_FEATURE_0 "p15, 0, %0, c0, c1, 4" +#define XREG_CP15_MEMORY_FEATURE_1 "p15, 0, %0, c0, c1, 5" +#define XREG_CP15_MEMORY_FEATURE_2 "p15, 0, %0, c0, c1, 6" +#define XREG_CP15_MEMORY_FEATURE_3 "p15, 0, %0, c0, c1, 7" + +#define XREG_CP15_INST_FEATURE_0 "p15, 0, %0, c0, c2, 0" +#define XREG_CP15_INST_FEATURE_1 "p15, 0, %0, c0, c2, 1" +#define XREG_CP15_INST_FEATURE_2 "p15, 0, %0, c0, c2, 2" +#define XREG_CP15_INST_FEATURE_3 "p15, 0, %0, c0, c2, 3" +#define XREG_CP15_INST_FEATURE_4 "p15, 0, %0, c0, c2, 4" + +#define XREG_CP15_CACHE_SIZE_ID "p15, 1, %0, c0, c0, 0" +#define XREG_CP15_CACHE_LEVEL_ID "p15, 1, %0, c0, c0, 1" +#define XREG_CP15_AUXILARY_ID "p15, 1, %0, c0, c0, 7" + +#define XREG_CP15_CACHE_SIZE_SEL "p15, 2, %0, c0, c0, 0" + +/* C1 Register Defines */ +#define XREG_CP15_SYS_CONTROL "p15, 0, %0, c1, c0, 0" +#define XREG_CP15_AUX_CONTROL "p15, 0, %0, c1, c0, 1" +#define XREG_CP15_CP_ACCESS_CONTROL "p15, 0, %0, c1, c0, 2" + +#define XREG_CP15_SECURE_CONFIG "p15, 0, %0, c1, c1, 0" +#define XREG_CP15_SECURE_DEBUG_ENABLE "p15, 0, %0, c1, c1, 1" +#define XREG_CP15_NS_ACCESS_CONTROL "p15, 0, %0, c1, c1, 2" +#define XREG_CP15_VIRTUAL_CONTROL "p15, 0, %0, c1, c1, 3" + +#else /* RVCT */ +/* C0 Register defines */ +#define XREG_CP15_MAIN_ID "cp15:0:c0:c0:0" +#define XREG_CP15_CACHE_TYPE "cp15:0:c0:c0:1" +#define XREG_CP15_TCM_TYPE "cp15:0:c0:c0:2" +#define XREG_CP15_TLB_TYPE "cp15:0:c0:c0:3" +#define XREG_CP15_MULTI_PROC_AFFINITY "cp15:0:c0:c0:5" + +#define XREG_CP15_PROC_FEATURE_0 "cp15:0:c0:c1:0" +#define XREG_CP15_PROC_FEATURE_1 "cp15:0:c0:c1:1" +#define XREG_CP15_DEBUG_FEATURE_0 "cp15:0:c0:c1:2" +#define XREG_CP15_MEMORY_FEATURE_0 "cp15:0:c0:c1:4" +#define XREG_CP15_MEMORY_FEATURE_1 "cp15:0:c0:c1:5" +#define XREG_CP15_MEMORY_FEATURE_2 "cp15:0:c0:c1:6" +#define XREG_CP15_MEMORY_FEATURE_3 "cp15:0:c0:c1:7" + +#define XREG_CP15_INST_FEATURE_0 "cp15:0:c0:c2:0" +#define XREG_CP15_INST_FEATURE_1 "cp15:0:c0:c2:1" +#define XREG_CP15_INST_FEATURE_2 "cp15:0:c0:c2:2" +#define XREG_CP15_INST_FEATURE_3 "cp15:0:c0:c2:3" +#define XREG_CP15_INST_FEATURE_4 "cp15:0:c0:c2:4" + +#define XREG_CP15_CACHE_SIZE_ID "cp15:1:c0:c0:0" +#define XREG_CP15_CACHE_LEVEL_ID "cp15:1:c0:c0:1" +#define XREG_CP15_AUXILARY_ID "cp15:1:c0:c0:7" + +#define XREG_CP15_CACHE_SIZE_SEL "cp15:2:c0:c0:0" + +/* C1 Register Defines */ +#define XREG_CP15_SYS_CONTROL "cp15:0:c1:c0:0" +#define XREG_CP15_AUX_CONTROL "cp15:0:c1:c0:1" +#define XREG_CP15_CP_ACCESS_CONTROL "cp15:0:c1:c0:2" + +#define XREG_CP15_SECURE_CONFIG "cp15:0:c1:c1:0" +#define XREG_CP15_SECURE_DEBUG_ENABLE "cp15:0:c1:c1:1" +#define XREG_CP15_NS_ACCESS_CONTROL "cp15:0:c1:c1:2" +#define XREG_CP15_VIRTUAL_CONTROL "cp15:0:c1:c1:3" +#endif + +/* XREG_CP15_CONTROL bit defines */ +#define XREG_CP15_CONTROL_TE_BIT 0x40000000U +#define XREG_CP15_CONTROL_AFE_BIT 0x20000000U +#define XREG_CP15_CONTROL_TRE_BIT 0x10000000U +#define XREG_CP15_CONTROL_NMFI_BIT 0x08000000U +#define XREG_CP15_CONTROL_EE_BIT 0x02000000U +#define XREG_CP15_CONTROL_HA_BIT 0x00020000U +#define XREG_CP15_CONTROL_RR_BIT 0x00004000U +#define XREG_CP15_CONTROL_V_BIT 0x00002000U +#define XREG_CP15_CONTROL_I_BIT 0x00001000U +#define XREG_CP15_CONTROL_Z_BIT 0x00000800U +#define XREG_CP15_CONTROL_SW_BIT 0x00000400U +#define XREG_CP15_CONTROL_B_BIT 0x00000080U +#define XREG_CP15_CONTROL_C_BIT 0x00000004U +#define XREG_CP15_CONTROL_A_BIT 0x00000002U +#define XREG_CP15_CONTROL_M_BIT 0x00000001U + +#if defined (__GNUC__) || defined (__ICCARM__) +/* C2 Register Defines */ +#define XREG_CP15_TTBR0 "p15, 0, %0, c2, c0, 0" +#define XREG_CP15_TTBR1 "p15, 0, %0, c2, c0, 1" +#define XREG_CP15_TTB_CONTROL "p15, 0, %0, c2, c0, 2" + +/* C3 Register Defines */ +#define XREG_CP15_DOMAIN_ACCESS_CTRL "p15, 0, %0, c3, c0, 0" + +/* C4 Register Defines */ +/* Not Used */ + +/* C5 Register Defines */ +#define XREG_CP15_DATA_FAULT_STATUS "p15, 0, %0, c5, c0, 0" +#define XREG_CP15_INST_FAULT_STATUS "p15, 0, %0, c5, c0, 1" + +#define XREG_CP15_AUX_DATA_FAULT_STATUS "p15, 0, %0, c5, c1, 0" +#define XREG_CP15_AUX_INST_FAULT_STATUS "p15, 0, %0, c5, c1, 1" + +/* C6 Register Defines */ +#define XREG_CP15_DATA_FAULT_ADDRESS "p15, 0, %0, c6, c0, 0" +#define XREG_CP15_INST_FAULT_ADDRESS "p15, 0, %0, c6, c0, 2" + +/* C7 Register Defines */ +#define XREG_CP15_NOP "p15, 0, %0, c7, c0, 4" + +#define XREG_CP15_INVAL_IC_POU_IS "p15, 0, %0, c7, c1, 0" +#define XREG_CP15_INVAL_BRANCH_ARRAY_IS "p15, 0, %0, c7, c1, 6" + +#define XREG_CP15_PHYS_ADDR "p15, 0, %0, c7, c4, 0" + +#define XREG_CP15_INVAL_IC_POU "p15, 0, %0, c7, c5, 0" +#define XREG_CP15_INVAL_IC_LINE_MVA_POU "p15, 0, %0, c7, c5, 1" + +/* The CP15 register access below has been deprecated in favor of the new + * isb instruction in Cortex A9. + */ +#define XREG_CP15_INST_SYNC_BARRIER "p15, 0, %0, c7, c5, 4" +#define XREG_CP15_INVAL_BRANCH_ARRAY "p15, 0, %0, c7, c5, 6" + +#define XREG_CP15_INVAL_DC_LINE_MVA_POC "p15, 0, %0, c7, c6, 1" +#define XREG_CP15_INVAL_DC_LINE_SW "p15, 0, %0, c7, c6, 2" + +#define XREG_CP15_VA_TO_PA_CURRENT_0 "p15, 0, %0, c7, c8, 0" +#define XREG_CP15_VA_TO_PA_CURRENT_1 "p15, 0, %0, c7, c8, 1" +#define XREG_CP15_VA_TO_PA_CURRENT_2 "p15, 0, %0, c7, c8, 2" +#define XREG_CP15_VA_TO_PA_CURRENT_3 "p15, 0, %0, c7, c8, 3" + +#define XREG_CP15_VA_TO_PA_OTHER_0 "p15, 0, %0, c7, c8, 4" +#define XREG_CP15_VA_TO_PA_OTHER_1 "p15, 0, %0, c7, c8, 5" +#define XREG_CP15_VA_TO_PA_OTHER_2 "p15, 0, %0, c7, c8, 6" +#define XREG_CP15_VA_TO_PA_OTHER_3 "p15, 0, %0, c7, c8, 7" + +#define XREG_CP15_CLEAN_DC_LINE_MVA_POC "p15, 0, %0, c7, c10, 1" +#define XREG_CP15_CLEAN_DC_LINE_SW "p15, 0, %0, c7, c10, 2" + +/* The next two CP15 register accesses below have been deprecated in favor + * of the new dsb and dmb instructions in Cortex A9. + */ +#define XREG_CP15_DATA_SYNC_BARRIER "p15, 0, %0, c7, c10, 4" +#define XREG_CP15_DATA_MEMORY_BARRIER "p15, 0, %0, c7, c10, 5" + +#define XREG_CP15_CLEAN_DC_LINE_MVA_POU "p15, 0, %0, c7, c11, 1" + +#define XREG_CP15_NOP2 "p15, 0, %0, c7, c13, 1" + +#define XREG_CP15_CLEAN_INVAL_DC_LINE_MVA_POC "p15, 0, %0, c7, c14, 1" +#define XREG_CP15_CLEAN_INVAL_DC_LINE_SW "p15, 0, %0, c7, c14, 2" + +/* C8 Register Defines */ +#define XREG_CP15_INVAL_TLB_IS "p15, 0, %0, c8, c3, 0" +#define XREG_CP15_INVAL_TLB_MVA_IS "p15, 0, %0, c8, c3, 1" +#define XREG_CP15_INVAL_TLB_ASID_IS "p15, 0, %0, c8, c3, 2" +#define XREG_CP15_INVAL_TLB_MVA_ASID_IS "p15, 0, %0, c8, c3, 3" + +#define XREG_CP15_INVAL_ITLB_UNLOCKED "p15, 0, %0, c8, c5, 0" +#define XREG_CP15_INVAL_ITLB_MVA "p15, 0, %0, c8, c5, 1" +#define XREG_CP15_INVAL_ITLB_ASID "p15, 0, %0, c8, c5, 2" + +#define XREG_CP15_INVAL_DTLB_UNLOCKED "p15, 0, %0, c8, c6, 0" +#define XREG_CP15_INVAL_DTLB_MVA "p15, 0, %0, c8, c6, 1" +#define XREG_CP15_INVAL_DTLB_ASID "p15, 0, %0, c8, c6, 2" + +#define XREG_CP15_INVAL_UTLB_UNLOCKED "p15, 0, %0, c8, c7, 0" +#define XREG_CP15_INVAL_UTLB_MVA "p15, 0, %0, c8, c7, 1" +#define XREG_CP15_INVAL_UTLB_ASID "p15, 0, %0, c8, c7, 2" +#define XREG_CP15_INVAL_UTLB_MVA_ASID "p15, 0, %0, c8, c7, 3" + +/* C9 Register Defines */ +#define XREG_CP15_PERF_MONITOR_CTRL "p15, 0, %0, c9, c12, 0" +#define XREG_CP15_COUNT_ENABLE_SET "p15, 0, %0, c9, c12, 1" +#define XREG_CP15_COUNT_ENABLE_CLR "p15, 0, %0, c9, c12, 2" +#define XREG_CP15_V_FLAG_STATUS "p15, 0, %0, c9, c12, 3" +#define XREG_CP15_SW_INC "p15, 0, %0, c9, c12, 4" +#define XREG_CP15_EVENT_CNTR_SEL "p15, 0, %0, c9, c12, 5" + +#define XREG_CP15_PERF_CYCLE_COUNTER "p15, 0, %0, c9, c13, 0" +#define XREG_CP15_EVENT_TYPE_SEL "p15, 0, %0, c9, c13, 1" +#define XREG_CP15_PERF_MONITOR_COUNT "p15, 0, %0, c9, c13, 2" + +#define XREG_CP15_USER_ENABLE "p15, 0, %0, c9, c14, 0" +#define XREG_CP15_INTR_ENABLE_SET "p15, 0, %0, c9, c14, 1" +#define XREG_CP15_INTR_ENABLE_CLR "p15, 0, %0, c9, c14, 2" + +/* C10 Register Defines */ +#define XREG_CP15_TLB_LOCKDWN "p15, 0, %0, c10, c0, 0" + +#define XREG_CP15_PRI_MEM_REMAP "p15, 0, %0, c10, c2, 0" +#define XREG_CP15_NORM_MEM_REMAP "p15, 0, %0, c10, c2, 1" + +/* C11 Register Defines */ +/* Not used */ + +/* C12 Register Defines */ +#define XREG_CP15_VEC_BASE_ADDR "p15, 0, %0, c12, c0, 0" +#define XREG_CP15_MONITOR_VEC_BASE_ADDR "p15, 0, %0, c12, c0, 1" + +#define XREG_CP15_INTERRUPT_STATUS "p15, 0, %0, c12, c1, 0" +#define XREG_CP15_VIRTUALIZATION_INTR "p15, 0, %0, c12, c1, 1" + +/* C13 Register Defines */ +#define XREG_CP15_CONTEXT_ID "p15, 0, %0, c13, c0, 1" +#define USER_RW_THREAD_PID "p15, 0, %0, c13, c0, 2" +#define USER_RO_THREAD_PID "p15, 0, %0, c13, c0, 3" +#define USER_PRIV_THREAD_PID "p15, 0, %0, c13, c0, 4" + +/* C14 Register Defines */ +/* not used */ + +/* C15 Register Defines */ +#define XREG_CP15_POWER_CTRL "p15, 0, %0, c15, c0, 0" +#define XREG_CP15_CONFIG_BASE_ADDR "p15, 4, %0, c15, c0, 0" + +#define XREG_CP15_READ_TLB_ENTRY "p15, 5, %0, c15, c4, 2" +#define XREG_CP15_WRITE_TLB_ENTRY "p15, 5, %0, c15, c4, 4" + +#define XREG_CP15_MAIN_TLB_VA "p15, 5, %0, c15, c5, 2" + +#define XREG_CP15_MAIN_TLB_PA "p15, 5, %0, c15, c6, 2" + +#define XREG_CP15_MAIN_TLB_ATTR "p15, 5, %0, c15, c7, 2" + +#else +/* C2 Register Defines */ +#define XREG_CP15_TTBR0 "cp15:0:c2:c0:0" +#define XREG_CP15_TTBR1 "cp15:0:c2:c0:1" +#define XREG_CP15_TTB_CONTROL "cp15:0:c2:c0:2" + +/* C3 Register Defines */ +#define XREG_CP15_DOMAIN_ACCESS_CTRL "cp15:0:c3:c0:0" + +/* C4 Register Defines */ +/* Not Used */ + +/* C5 Register Defines */ +#define XREG_CP15_DATA_FAULT_STATUS "cp15:0:c5:c0:0" +#define XREG_CP15_INST_FAULT_STATUS "cp15:0:c5:c0:1" + +#define XREG_CP15_AUX_DATA_FAULT_STATUS "cp15:0:c5:c1:0" +#define XREG_CP15_AUX_INST_FAULT_STATUS "cp15:0:c5:c1:1" + +/* C6 Register Defines */ +#define XREG_CP15_DATA_FAULT_ADDRESS "cp15:0:c6:c0:0" +#define XREG_CP15_INST_FAULT_ADDRESS "cp15:0:c6:c0:2" + +/* C7 Register Defines */ +#define XREG_CP15_NOP "cp15:0:c7:c0:4" + +#define XREG_CP15_INVAL_IC_POU_IS "cp15:0:c7:c1:0" +#define XREG_CP15_INVAL_BRANCH_ARRAY_IS "cp15:0:c7:c1:6" + +#define XREG_CP15_PHYS_ADDR "cp15:0:c7:c4:0" + +#define XREG_CP15_INVAL_IC_POU "cp15:0:c7:c5:0" +#define XREG_CP15_INVAL_IC_LINE_MVA_POU "cp15:0:c7:c5:1" + +/* The CP15 register access below has been deprecated in favor of the new + * isb instruction in Cortex A9. + */ +#define XREG_CP15_INST_SYNC_BARRIER "cp15:0:c7:c5:4" +#define XREG_CP15_INVAL_BRANCH_ARRAY "cp15:0:c7:c5:6" + +#define XREG_CP15_INVAL_DC_LINE_MVA_POC "cp15:0:c7:c6:1" +#define XREG_CP15_INVAL_DC_LINE_SW "cp15:0:c7:c6:2" + +#define XREG_CP15_VA_TO_PA_CURRENT_0 "cp15:0:c7:c8:0" +#define XREG_CP15_VA_TO_PA_CURRENT_1 "cp15:0:c7:c8:1" +#define XREG_CP15_VA_TO_PA_CURRENT_2 "cp15:0:c7:c8:2" +#define XREG_CP15_VA_TO_PA_CURRENT_3 "cp15:0:c7:c8:3" + +#define XREG_CP15_VA_TO_PA_OTHER_0 "cp15:0:c7:c8:4" +#define XREG_CP15_VA_TO_PA_OTHER_1 "cp15:0:c7:c8:5" +#define XREG_CP15_VA_TO_PA_OTHER_2 "cp15:0:c7:c8:6" +#define XREG_CP15_VA_TO_PA_OTHER_3 "cp15:0:c7:c8:7" + +#define XREG_CP15_CLEAN_DC_LINE_MVA_POC "cp15:0:c7:c10:1" +#define XREG_CP15_CLEAN_DC_LINE_SW "cp15:0:c7:c10:2" + +/* The next two CP15 register accesses below have been deprecated in favor + * of the new dsb and dmb instructions in Cortex A9. + */ +#define XREG_CP15_DATA_SYNC_BARRIER "cp15:0:c7:c10:4" +#define XREG_CP15_DATA_MEMORY_BARRIER "cp15:0:c7:c10:5" + +#define XREG_CP15_CLEAN_DC_LINE_MVA_POU "cp15:0:c7:c11:1" + +#define XREG_CP15_NOP2 "cp15:0:c7:c13:1" + +#define XREG_CP15_CLEAN_INVAL_DC_LINE_MVA_POC "cp15:0:c7:c14:1" +#define XREG_CP15_CLEAN_INVAL_DC_LINE_SW "cp15:0:c7:c14:2" + +/* C8 Register Defines */ +#define XREG_CP15_INVAL_TLB_IS "cp15:0:c8:c3:0" +#define XREG_CP15_INVAL_TLB_MVA_IS "cp15:0:c8:c3:1" +#define XREG_CP15_INVAL_TLB_ASID_IS "cp15:0:c8:c3:2" +#define XREG_CP15_INVAL_TLB_MVA_ASID_IS "cp15:0:c8:c3:3" + +#define XREG_CP15_INVAL_ITLB_UNLOCKED "cp15:0:c8:c5:0" +#define XREG_CP15_INVAL_ITLB_MVA "cp15:0:c8:c5:1" +#define XREG_CP15_INVAL_ITLB_ASID "cp15:0:c8:c5:2" + +#define XREG_CP15_INVAL_DTLB_UNLOCKED "cp15:0:c8:c6:0" +#define XREG_CP15_INVAL_DTLB_MVA "cp15:0:c8:c6:1" +#define XREG_CP15_INVAL_DTLB_ASID "cp15:0:c8:c6:2" + +#define XREG_CP15_INVAL_UTLB_UNLOCKED "cp15:0:c8:c7:0" +#define XREG_CP15_INVAL_UTLB_MVA "cp15:0:c8:c7:1" +#define XREG_CP15_INVAL_UTLB_ASID "cp15:0:c8:c7:2" +#define XREG_CP15_INVAL_UTLB_MVA_ASID "cp15:0:c8:c7:3" + +/* C9 Register Defines */ +#define XREG_CP15_PERF_MONITOR_CTRL "cp15:0:c9:c12:0" +#define XREG_CP15_COUNT_ENABLE_SET "cp15:0:c9:c12:1" +#define XREG_CP15_COUNT_ENABLE_CLR "cp15:0:c9:c12:2" +#define XREG_CP15_V_FLAG_STATUS "cp15:0:c9:c12:3" +#define XREG_CP15_SW_INC "cp15:0:c9:c12:4" +#define XREG_CP15_EVENT_CNTR_SEL "cp15:0:c9:c12:5" + +#define XREG_CP15_PERF_CYCLE_COUNTER "cp15:0:c9:c13:0" +#define XREG_CP15_EVENT_TYPE_SEL "cp15:0:c9:c13:1" +#define XREG_CP15_PERF_MONITOR_COUNT "cp15:0:c9:c13:2" + +#define XREG_CP15_USER_ENABLE "cp15:0:c9:c14:0" +#define XREG_CP15_INTR_ENABLE_SET "cp15:0:c9:c14:1" +#define XREG_CP15_INTR_ENABLE_CLR "cp15:0:c9:c14:2" + +/* C10 Register Defines */ +#define XREG_CP15_TLB_LOCKDWN "cp15:0:c10:c0:0" + +#define XREG_CP15_PRI_MEM_REMAP "cp15:0:c10:c2:0" +#define XREG_CP15_NORM_MEM_REMAP "cp15:0:c10:c2:1" + +/* C11 Register Defines */ +/* Not used */ + +/* C12 Register Defines */ +#define XREG_CP15_VEC_BASE_ADDR "cp15:0:c12:c0:0" +#define XREG_CP15_MONITOR_VEC_BASE_ADDR "cp15:0:c12:c0:1" + +#define XREG_CP15_INTERRUPT_STATUS "cp15:0:c12:c1:0" +#define XREG_CP15_VIRTUALIZATION_INTR "cp15:0:c12:c1:1" + +/* C13 Register Defines */ +#define XREG_CP15_CONTEXT_ID "cp15:0:c13:c0:1" +#define USER_RW_THREAD_PID "cp15:0:c13:c0:2" +#define USER_RO_THREAD_PID "cp15:0:c13:c0:3" +#define USER_PRIV_THREAD_PID "cp15:0:c13:c0:4" + +/* C14 Register Defines */ +/* not used */ + +/* C15 Register Defines */ +#define XREG_CP15_POWER_CTRL "cp15:0:c15:c0:0" +#define XREG_CP15_CONFIG_BASE_ADDR "cp15:4:c15:c0:0" + +#define XREG_CP15_READ_TLB_ENTRY "cp15:5:c15:c4:2" +#define XREG_CP15_WRITE_TLB_ENTRY "cp15:5:c15:c4:4" + +#define XREG_CP15_MAIN_TLB_VA "cp15:5:c15:c5:2" + +#define XREG_CP15_MAIN_TLB_PA "cp15:5:c15:c6:2" + +#define XREG_CP15_MAIN_TLB_ATTR "cp15:5:c15:c7:2" +#endif + + +/* MPE register definitions */ +#define XREG_FPSID c0 +#define XREG_FPSCR c1 +#define XREG_MVFR1 c6 +#define XREG_MVFR0 c7 +#define XREG_FPEXC c8 +#define XREG_FPINST c9 +#define XREG_FPINST2 c10 + +/* FPSID bits */ +#define XREG_FPSID_IMPLEMENTER_BIT (24) +#define XREG_FPSID_IMPLEMENTER_MASK (0xFF << FPSID_IMPLEMENTER_BIT) +#define XREG_FPSID_SOFTWARE (1<<23) +#define XREG_FPSID_ARCH_BIT (16) +#define XREG_FPSID_ARCH_MASK (0xF << FPSID_ARCH_BIT) +#define XREG_FPSID_PART_BIT (8) +#define XREG_FPSID_PART_MASK (0xFF << FPSID_PART_BIT) +#define XREG_FPSID_VARIANT_BIT (4) +#define XREG_FPSID_VARIANT_MASK (0xF << FPSID_VARIANT_BIT) +#define XREG_FPSID_REV_BIT (0) +#define XREG_FPSID_REV_MASK (0xF << FPSID_REV_BIT) + +/* FPSCR bits */ +#define XREG_FPSCR_N_BIT (1 << 31) +#define XREG_FPSCR_Z_BIT (1 << 30) +#define XREG_FPSCR_C_BIT (1 << 29) +#define XREG_FPSCR_V_BIT (1 << 28) +#define XREG_FPSCR_QC (1 << 27) +#define XREG_FPSCR_AHP (1 << 26) +#define XREG_FPSCR_DEFAULT_NAN (1 << 25) +#define XREG_FPSCR_FLUSHTOZERO (1 << 24) +#define XREG_FPSCR_ROUND_NEAREST (0 << 22) +#define XREG_FPSCR_ROUND_PLUSINF (1 << 22) +#define XREG_FPSCR_ROUND_MINUSINF (2 << 22) +#define XREG_FPSCR_ROUND_TOZERO (3 << 22) +#define XREG_FPSCR_RMODE_BIT (22) +#define XREG_FPSCR_RMODE_MASK (3 << FPSCR_RMODE_BIT) +#define XREG_FPSCR_STRIDE_BIT (20) +#define XREG_FPSCR_STRIDE_MASK (3 << FPSCR_STRIDE_BIT) +#define XREG_FPSCR_LENGTH_BIT (16) +#define XREG_FPSCR_LENGTH_MASK (7 << FPSCR_LENGTH_BIT) +#define XREG_FPSCR_IDC (1 << 7) +#define XREG_FPSCR_IXC (1 << 4) +#define XREG_FPSCR_UFC (1 << 3) +#define XREG_FPSCR_OFC (1 << 2) +#define XREG_FPSCR_DZC (1 << 1) +#define XREG_FPSCR_IOC (1 << 0) + +/* MVFR0 bits */ +#define XREG_MVFR0_RMODE_BIT (28) +#define XREG_MVFR0_RMODE_MASK (0xF << XREG_MVFR0_RMODE_BIT) +#define XREG_MVFR0_SHORT_VEC_BIT (24) +#define XREG_MVFR0_SHORT_VEC_MASK (0xF << XREG_MVFR0_SHORT_VEC_BIT) +#define XREG_MVFR0_SQRT_BIT (20) +#define XREG_MVFR0_SQRT_MASK (0xF << XREG_MVFR0_SQRT_BIT) +#define XREG_MVFR0_DIVIDE_BIT (16) +#define XREG_MVFR0_DIVIDE_MASK (0xF << XREG_MVFR0_DIVIDE_BIT) +#define XREG_MVFR0_EXEC_TRAP_BIT (12) +#define XREG_MVFR0_EXEC_TRAP_MASK (0xF << XREG_MVFR0_EXEC_TRAP_BIT) +#define XREG_MVFR0_DP_BIT (8) +#define XREG_MVFR0_DP_MASK (0xF << XREG_MVFR0_DP_BIT) +#define XREG_MVFR0_SP_BIT (4) +#define XREG_MVFR0_SP_MASK (0xF << XREG_MVFR0_SP_BIT) +#define XREG_MVFR0_A_SIMD_BIT (0) +#define XREG_MVFR0_A_SIMD_MASK (0xF << MVFR0_A_SIMD_BIT) + +/* FPEXC bits */ +#define XREG_FPEXC_EX (1 << 31) +#define XREG_FPEXC_EN (1 << 30) +#define XREG_FPEXC_DEX (1 << 29) + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* XREG_CORTEXA9_H */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xstatus.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xstatus.h new file mode 100644 index 0000000..1a212bf --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xstatus.h @@ -0,0 +1,533 @@ +/****************************************************************************** +* +* Copyright (C) 2002 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xstatus.h +* +* @addtogroup common_status_codes Xilinx® software status codes +* +* The xstatus.h file contains the Xilinx® software status codes.These codes are +* used throughout the Xilinx device drivers. +* +* @{ +******************************************************************************/ + +#ifndef XSTATUS_H /* prevent circular inclusions */ +#define XSTATUS_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +#include "xil_types.h" +#include "xil_assert.h" + +/************************** Constant Definitions *****************************/ + +/*********************** Common statuses 0 - 500 *****************************/ +/** +@name Common Status Codes for All Device Drivers +@{ +*/ +#define XST_SUCCESS 0L +#define XST_FAILURE 1L +#define XST_DEVICE_NOT_FOUND 2L +#define XST_DEVICE_BLOCK_NOT_FOUND 3L +#define XST_INVALID_VERSION 4L +#define XST_DEVICE_IS_STARTED 5L +#define XST_DEVICE_IS_STOPPED 6L +#define XST_FIFO_ERROR 7L /*!< An error occurred during an + operation with a FIFO such as + an underrun or overrun, this + error requires the device to + be reset */ +#define XST_RESET_ERROR 8L /*!< An error occurred which requires + the device to be reset */ +#define XST_DMA_ERROR 9L /*!< A DMA error occurred, this error + typically requires the device + using the DMA to be reset */ +#define XST_NOT_POLLED 10L /*!< The device is not configured for + polled mode operation */ +#define XST_FIFO_NO_ROOM 11L /*!< A FIFO did not have room to put + the specified data into */ +#define XST_BUFFER_TOO_SMALL 12L /*!< The buffer is not large enough + to hold the expected data */ +#define XST_NO_DATA 13L /*!< There was no data available */ +#define XST_REGISTER_ERROR 14L /*!< A register did not contain the + expected value */ +#define XST_INVALID_PARAM 15L /*!< An invalid parameter was passed + into the function */ +#define XST_NOT_SGDMA 16L /*!< The device is not configured for + scatter-gather DMA operation */ +#define XST_LOOPBACK_ERROR 17L /*!< A loopback test failed */ +#define XST_NO_CALLBACK 18L /*!< A callback has not yet been + registered */ +#define XST_NO_FEATURE 19L /*!< Device is not configured with + the requested feature */ +#define XST_NOT_INTERRUPT 20L /*!< Device is not configured for + interrupt mode operation */ +#define XST_DEVICE_BUSY 21L /*!< Device is busy */ +#define XST_ERROR_COUNT_MAX 22L /*!< The error counters of a device + have maxed out */ +#define XST_IS_STARTED 23L /*!< Used when part of device is + already started i.e. + sub channel */ +#define XST_IS_STOPPED 24L /*!< Used when part of device is + already stopped i.e. + sub channel */ +#define XST_DATA_LOST 26L /*!< Driver defined error */ +#define XST_RECV_ERROR 27L /*!< Generic receive error */ +#define XST_SEND_ERROR 28L /*!< Generic transmit error */ +#define XST_NOT_ENABLED 29L /*!< A requested service is not + available because it has not + been enabled */ +#define XST_NO_ACCESS 30L /* Generic access error */ +/** @} */ +/***************** Utility Component statuses 401 - 500 *********************/ +/** +@name Utility Component Status Codes 401 - 500 +@{ +*/ +#define XST_MEMTEST_FAILED 401L /*!< Memory test failed */ + +/** @} */ +/***************** Common Components statuses 501 - 1000 *********************/ +/** +@name Packet Fifo Status Codes 501 - 510 +@{ +*/ +/********************* Packet Fifo statuses 501 - 510 ************************/ + +#define XST_PFIFO_LACK_OF_DATA 501L /*!< Not enough data in FIFO */ +#define XST_PFIFO_NO_ROOM 502L /*!< Not enough room in FIFO */ +#define XST_PFIFO_BAD_REG_VALUE 503L /*!< Self test, a register value + was invalid after reset */ +#define XST_PFIFO_ERROR 504L /*!< Generic packet FIFO error */ +#define XST_PFIFO_DEADLOCK 505L /*!< Packet FIFO is reporting + * empty and full simultaneously + */ +/** @} */ +/** +@name DMA Status Codes 511 - 530 +@{ +*/ +/************************** DMA statuses 511 - 530 ***************************/ + +#define XST_DMA_TRANSFER_ERROR 511L /*!< Self test, DMA transfer + failed */ +#define XST_DMA_RESET_REGISTER_ERROR 512L /*!< Self test, a register value + was invalid after reset */ +#define XST_DMA_SG_LIST_EMPTY 513L /*!< Scatter gather list contains + no buffer descriptors ready + to be processed */ +#define XST_DMA_SG_IS_STARTED 514L /*!< Scatter gather not stopped */ +#define XST_DMA_SG_IS_STOPPED 515L /*!< Scatter gather not running */ +#define XST_DMA_SG_LIST_FULL 517L /*!< All the buffer desciptors of + the scatter gather list are + being used */ +#define XST_DMA_SG_BD_LOCKED 518L /*!< The scatter gather buffer + descriptor which is to be + copied over in the scatter + list is locked */ +#define XST_DMA_SG_NOTHING_TO_COMMIT 519L /*!< No buffer descriptors have been + put into the scatter gather + list to be commited */ +#define XST_DMA_SG_COUNT_EXCEEDED 521L /*!< The packet count threshold + specified was larger than the + total # of buffer descriptors + in the scatter gather list */ +#define XST_DMA_SG_LIST_EXISTS 522L /*!< The scatter gather list has + already been created */ +#define XST_DMA_SG_NO_LIST 523L /*!< No scatter gather list has + been created */ +#define XST_DMA_SG_BD_NOT_COMMITTED 524L /*!< The buffer descriptor which was + being started was not committed + to the list */ +#define XST_DMA_SG_NO_DATA 525L /*!< The buffer descriptor to start + has already been used by the + hardware so it can't be reused + */ +#define XST_DMA_SG_LIST_ERROR 526L /*!< General purpose list access + error */ +#define XST_DMA_BD_ERROR 527L /*!< General buffer descriptor + error */ +/** @} */ +/** +@name IPIF Status Codes Codes 531 - 550 +@{ +*/ +/************************** IPIF statuses 531 - 550 ***************************/ + +#define XST_IPIF_REG_WIDTH_ERROR 531L /*!< An invalid register width + was passed into the function */ +#define XST_IPIF_RESET_REGISTER_ERROR 532L /*!< The value of a register at + reset was not valid */ +#define XST_IPIF_DEVICE_STATUS_ERROR 533L /*!< A write to the device interrupt + status register did not read + back correctly */ +#define XST_IPIF_DEVICE_ACK_ERROR 534L /*!< The device interrupt status + register did not reset when + acked */ +#define XST_IPIF_DEVICE_ENABLE_ERROR 535L /*!< The device interrupt enable + register was not updated when + other registers changed */ +#define XST_IPIF_IP_STATUS_ERROR 536L /*!< A write to the IP interrupt + status register did not read + back correctly */ +#define XST_IPIF_IP_ACK_ERROR 537L /*!< The IP interrupt status register + did not reset when acked */ +#define XST_IPIF_IP_ENABLE_ERROR 538L /*!< IP interrupt enable register was + not updated correctly when other + registers changed */ +#define XST_IPIF_DEVICE_PENDING_ERROR 539L /*!< The device interrupt pending + register did not indicate the + expected value */ +#define XST_IPIF_DEVICE_ID_ERROR 540L /*!< The device interrupt ID register + did not indicate the expected + value */ +#define XST_IPIF_ERROR 541L /*!< Generic ipif error */ +/** @} */ + +/****************** Device specific statuses 1001 - 4095 *********************/ +/** +@name Ethernet Status Codes 1001 - 1050 +@{ +*/ +/********************* Ethernet statuses 1001 - 1050 *************************/ + +#define XST_EMAC_MEMORY_SIZE_ERROR 1001L /*!< Memory space is not big enough + * to hold the minimum number of + * buffers or descriptors */ +#define XST_EMAC_MEMORY_ALLOC_ERROR 1002L /*!< Memory allocation failed */ +#define XST_EMAC_MII_READ_ERROR 1003L /*!< MII read error */ +#define XST_EMAC_MII_BUSY 1004L /*!< An MII operation is in progress */ +#define XST_EMAC_OUT_OF_BUFFERS 1005L /*!< Driver is out of buffers */ +#define XST_EMAC_PARSE_ERROR 1006L /*!< Invalid driver init string */ +#define XST_EMAC_COLLISION_ERROR 1007L /*!< Excess deferral or late + * collision on polled send */ +/** @} */ +/** +@name UART Status Codes 1051 - 1075 +@{ +*/ +/*********************** UART statuses 1051 - 1075 ***************************/ +#define XST_UART + +#define XST_UART_INIT_ERROR 1051L +#define XST_UART_START_ERROR 1052L +#define XST_UART_CONFIG_ERROR 1053L +#define XST_UART_TEST_FAIL 1054L +#define XST_UART_BAUD_ERROR 1055L +#define XST_UART_BAUD_RANGE 1056L + +/** @} */ +/** +@name IIC Status Codes 1076 - 1100 +@{ +*/ +/************************ IIC statuses 1076 - 1100 ***************************/ + +#define XST_IIC_SELFTEST_FAILED 1076 /*!< self test failed */ +#define XST_IIC_BUS_BUSY 1077 /*!< bus found busy */ +#define XST_IIC_GENERAL_CALL_ADDRESS 1078 /*!< mastersend attempted with */ + /* general call address */ +#define XST_IIC_STAND_REG_RESET_ERROR 1079 /*!< A non parameterizable reg */ + /* value after reset not valid */ +#define XST_IIC_TX_FIFO_REG_RESET_ERROR 1080 /*!< Tx fifo included in design */ + /* value after reset not valid */ +#define XST_IIC_RX_FIFO_REG_RESET_ERROR 1081 /*!< Rx fifo included in design */ + /* value after reset not valid */ +#define XST_IIC_TBA_REG_RESET_ERROR 1082 /*!< 10 bit addr incl in design */ + /* value after reset not valid */ +#define XST_IIC_CR_READBACK_ERROR 1083 /*!< Read of the control register */ + /* didn't return value written */ +#define XST_IIC_DTR_READBACK_ERROR 1084 /*!< Read of the data Tx reg */ + /* didn't return value written */ +#define XST_IIC_DRR_READBACK_ERROR 1085 /*!< Read of the data Receive reg */ + /* didn't return value written */ +#define XST_IIC_ADR_READBACK_ERROR 1086 /*!< Read of the data Tx reg */ + /* didn't return value written */ +#define XST_IIC_TBA_READBACK_ERROR 1087 /*!< Read of the 10 bit addr reg */ + /* didn't return written value */ +#define XST_IIC_NOT_SLAVE 1088 /*!< The device isn't a slave */ +#define XST_IIC_ARB_LOST 1089 /*!< Arbitration lost for master */ +/** @} */ +/** +@name ATMC Status Codes 1101 - 1125 +@{ +*/ +/*********************** ATMC statuses 1101 - 1125 ***************************/ + +#define XST_ATMC_ERROR_COUNT_MAX 1101L /*!< the error counters in the ATM + controller hit the max value + which requires the statistics + to be cleared */ +/** @} */ +/** +@name Flash Status Codes 1126 - 1150 +@{ +*/ +/*********************** Flash statuses 1126 - 1150 **************************/ + +#define XST_FLASH_BUSY 1126L /*!< Flash is erasing or programming + */ +#define XST_FLASH_READY 1127L /*!< Flash is ready for commands */ +#define XST_FLASH_ERROR 1128L /*!< Flash had detected an internal + error. Use XFlash_DeviceControl + to retrieve device specific codes + */ +#define XST_FLASH_ERASE_SUSPENDED 1129L /*!< Flash is in suspended erase state + */ +#define XST_FLASH_WRITE_SUSPENDED 1130L /*!< Flash is in suspended write state + */ +#define XST_FLASH_PART_NOT_SUPPORTED 1131L /*!< Flash type not supported by + driver */ +#define XST_FLASH_NOT_SUPPORTED 1132L /*!< Operation not supported */ +#define XST_FLASH_TOO_MANY_REGIONS 1133L /*!< Too many erase regions */ +#define XST_FLASH_TIMEOUT_ERROR 1134L /*!< Programming or erase operation + aborted due to a timeout */ +#define XST_FLASH_ADDRESS_ERROR 1135L /*!< Accessed flash outside its + addressible range */ +#define XST_FLASH_ALIGNMENT_ERROR 1136L /*!< Write alignment error */ +#define XST_FLASH_BLOCKING_CALL_ERROR 1137L /*!< Couldn't return immediately from + write/erase function with + XFL_NON_BLOCKING_WRITE/ERASE + option cleared */ +#define XST_FLASH_CFI_QUERY_ERROR 1138L /*!< Failed to query the device */ +/** @} */ +/** +@name SPI Status Codes 1151 - 1175 +@{ +*/ +/*********************** SPI statuses 1151 - 1175 ****************************/ + +#define XST_SPI_MODE_FAULT 1151 /*!< master was selected as slave */ +#define XST_SPI_TRANSFER_DONE 1152 /*!< data transfer is complete */ +#define XST_SPI_TRANSMIT_UNDERRUN 1153 /*!< slave underruns transmit register */ +#define XST_SPI_RECEIVE_OVERRUN 1154 /*!< device overruns receive register */ +#define XST_SPI_NO_SLAVE 1155 /*!< no slave has been selected yet */ +#define XST_SPI_TOO_MANY_SLAVES 1156 /*!< more than one slave is being + * selected */ +#define XST_SPI_NOT_MASTER 1157 /*!< operation is valid only as master */ +#define XST_SPI_SLAVE_ONLY 1158 /*!< device is configured as slave-only + */ +#define XST_SPI_SLAVE_MODE_FAULT 1159 /*!< slave was selected while disabled */ +#define XST_SPI_SLAVE_MODE 1160 /*!< device has been addressed as slave */ +#define XST_SPI_RECEIVE_NOT_EMPTY 1161 /*!< device received data in slave mode */ + +#define XST_SPI_COMMAND_ERROR 1162 /*!< unrecognised command - qspi only */ +#define XST_SPI_POLL_DONE 1163 /*!< controller completed polling the + device for status */ +/** @} */ +/** +@name OPB Arbiter Status Codes 1176 - 1200 +@{ +*/ +/********************** OPB Arbiter statuses 1176 - 1200 *********************/ + +#define XST_OPBARB_INVALID_PRIORITY 1176 /*!< the priority registers have either + * one master assigned to two or more + * priorities, or one master not + * assigned to any priority + */ +#define XST_OPBARB_NOT_SUSPENDED 1177 /*!< an attempt was made to modify the + * priority levels without first + * suspending the use of priority + * levels + */ +#define XST_OPBARB_PARK_NOT_ENABLED 1178 /*!< bus parking by id was enabled but + * bus parking was not enabled + */ +#define XST_OPBARB_NOT_FIXED_PRIORITY 1179 /*!< the arbiter must be in fixed + * priority mode to allow the + * priorities to be changed + */ +/** @} */ +/** +@name INTC Status Codes 1201 - 1225 +@{ +*/ +/************************ Intc statuses 1201 - 1225 **************************/ + +#define XST_INTC_FAIL_SELFTEST 1201 /*!< self test failed */ +#define XST_INTC_CONNECT_ERROR 1202 /*!< interrupt already in use */ +/** @} */ +/** +@name TmrCtr Status Codes 1226 - 1250 +@{ +*/ +/********************** TmrCtr statuses 1226 - 1250 **************************/ + +#define XST_TMRCTR_TIMER_FAILED 1226 /*!< self test failed */ +/** @} */ +/** +@name WdtTb Status Codes 1251 - 1275 +@{ +*/ +/********************** WdtTb statuses 1251 - 1275 ***************************/ + +#define XST_WDTTB_TIMER_FAILED 1251L +/** @} */ +/** +@name PlbArb status Codes 1276 - 1300 +@{ +*/ +/********************** PlbArb statuses 1276 - 1300 **************************/ + +#define XST_PLBARB_FAIL_SELFTEST 1276L +/** @} */ +/** +@name Plb2Opb Status Codes 1301 - 1325 +@{ +*/ +/********************** Plb2Opb statuses 1301 - 1325 *************************/ + +#define XST_PLB2OPB_FAIL_SELFTEST 1301L +/** @} */ +/** +@name Opb2Plb Status 1326 - 1350 +@{ +*/ +/********************** Opb2Plb statuses 1326 - 1350 *************************/ + +#define XST_OPB2PLB_FAIL_SELFTEST 1326L +/** @} */ +/** +@name SysAce Status Codes 1351 - 1360 +@{ +*/ +/********************** SysAce statuses 1351 - 1360 **************************/ + +#define XST_SYSACE_NO_LOCK 1351L /*!< No MPU lock has been granted */ +/** @} */ +/** +@name PCI Bridge Status Codes 1361 - 1375 +@{ +*/ +/********************** PCI Bridge statuses 1361 - 1375 **********************/ + +#define XST_PCI_INVALID_ADDRESS 1361L +/** @} */ +/** +@name FlexRay Constants 1400 - 1409 +@{ +*/ +/********************** FlexRay constants 1400 - 1409 *************************/ + +#define XST_FR_TX_ERROR 1400 +#define XST_FR_TX_BUSY 1401 +#define XST_FR_BUF_LOCKED 1402 +#define XST_FR_NO_BUF 1403 +/** @} */ +/** +@name USB constants 1410 - 1420 +@{ +*/ +/****************** USB constants 1410 - 1420 *******************************/ + +#define XST_USB_ALREADY_CONFIGURED 1410 +#define XST_USB_BUF_ALIGN_ERROR 1411 +#define XST_USB_NO_DESC_AVAILABLE 1412 +#define XST_USB_BUF_TOO_BIG 1413 +#define XST_USB_NO_BUF 1414 +/** @} */ +/** +@name HWICAP constants 1421 - 1429 +@{ +*/ +/****************** HWICAP constants 1421 - 1429 *****************************/ + +#define XST_HWICAP_WRITE_DONE 1421 + +/** @} */ +/** +@name AXI VDMA constants 1430 - 1440 +@{ +*/ +/****************** AXI VDMA constants 1430 - 1440 *****************************/ + +#define XST_VDMA_MISMATCH_ERROR 1430 +/** @} */ +/** +@name NAND Flash Status Codes 1441 - 1459 +@{ +*/ +/*********************** NAND Flash statuses 1441 - 1459 *********************/ + +#define XST_NAND_BUSY 1441L /*!< Flash is erasing or + * programming + */ +#define XST_NAND_READY 1442L /*!< Flash is ready for commands + */ +#define XST_NAND_ERROR 1443L /*!< Flash had detected an + * internal error. + */ +#define XST_NAND_PART_NOT_SUPPORTED 1444L /*!< Flash type not supported by + * driver + */ +#define XST_NAND_OPT_NOT_SUPPORTED 1445L /*!< Operation not supported + */ +#define XST_NAND_TIMEOUT_ERROR 1446L /*!< Programming or erase + * operation aborted due to a + * timeout + */ +#define XST_NAND_ADDRESS_ERROR 1447L /*!< Accessed flash outside its + * addressible range + */ +#define XST_NAND_ALIGNMENT_ERROR 1448L /*!< Write alignment error + */ +#define XST_NAND_PARAM_PAGE_ERROR 1449L /*!< Failed to read parameter + * page of the device + */ +#define XST_NAND_CACHE_ERROR 1450L /*!< Flash page buffer error + */ + +#define XST_NAND_WRITE_PROTECTED 1451L /*!< Flash is write protected + */ +/** @} */ + +/**************************** Type Definitions *******************************/ + +typedef s32 XStatus; + +/***************** Macros (Inline Functions) Definitions *********************/ + + +/************************** Function Prototypes ******************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** +* @} End of "addtogroup common_status_codes". +*/ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xtime_l.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xtime_l.c new file mode 100644 index 0000000..a687473 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xtime_l.c @@ -0,0 +1,118 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* @file xtime_l.c +* +* This file contains low level functions to get/set time from the Global Timer +* register in the ARM Cortex A9 MP core. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date     Changes
+* ----- ------ -------- ---------------------------------------------------
+* 1.00a rp/sdm 11/03/09 Initial release.
+* 3.07a sgd    07/05/12 Upadted get/set time functions to make use Global Timer
+* 
+* +* @note None. +* +******************************************************************************/ +/***************************** Include Files *********************************/ + +#include "xtime_l.h" +#include "xpseudo_asm.h" +#include "xil_types.h" +#include "xil_assert.h" +#include "xil_io.h" + +/***************** Macros (Inline Functions) Definitions *********************/ + +/**************************** Type Definitions *******************************/ + +/************************** Constant Definitions *****************************/ + +/************************** Variable Definitions *****************************/ + +/************************** Function Prototypes ******************************/ + +/****************************************************************************/ +/** +* @brief Set the time in the Global Timer Counter Register. +* +* @param Xtime_Global: 64-bit Value to be written to the Global Timer +* Counter Register. +* +* @return None. +* +* @note When this function is called by any one processor in a multi- +* processor environment, reference time will reset/lost for all +* processors. +* +****************************************************************************/ +void XTime_SetTime(XTime Xtime_Global) +{ + /* Disable Global Timer */ + Xil_Out32((u32)GLOBAL_TMR_BASEADDR + (u32)GTIMER_CONTROL_OFFSET, (u32)0x0); + + /* Updating Global Timer Counter Register */ + Xil_Out32((u32)GLOBAL_TMR_BASEADDR + (u32)GTIMER_COUNTER_LOWER_OFFSET, (u32)Xtime_Global); + Xil_Out32((u32)GLOBAL_TMR_BASEADDR + (u32)GTIMER_COUNTER_UPPER_OFFSET, + (u32)((u32)(Xtime_Global>>32U))); + + /* Enable Global Timer */ + Xil_Out32((u32)GLOBAL_TMR_BASEADDR + (u32)GTIMER_CONTROL_OFFSET, (u32)0x1); +} + +/****************************************************************************/ +/** +* @brief Get the time from the Global Timer Counter Register. +* +* @param Xtime_Global: Pointer to the 64-bit location which will be +* updated with the current timer value. +* +* @return None. +* +* @note None. +* +****************************************************************************/ +void XTime_GetTime(XTime *Xtime_Global) +{ + u32 low; + u32 high; + + /* Reading Global Timer Counter Register */ + do + { + high = Xil_In32(GLOBAL_TMR_BASEADDR + GTIMER_COUNTER_UPPER_OFFSET); + low = Xil_In32(GLOBAL_TMR_BASEADDR + GTIMER_COUNTER_LOWER_OFFSET); + } while(Xil_In32(GLOBAL_TMR_BASEADDR + GTIMER_COUNTER_UPPER_OFFSET) != high); + + *Xtime_Global = (((XTime) high) << 32U) | (XTime) low; +} diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xtime_l.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xtime_l.h new file mode 100644 index 0000000..12004e1 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xtime_l.h @@ -0,0 +1,104 @@ +/****************************************************************************** +* +* Copyright (C) 2009 - 2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* @file xtime_l.h +* @addtogroup a9_time_apis Cortex A9 Time Functions +* +* xtime_l.h provides access to the 64-bit Global Counter in the PMU. This +* counter increases by one at every two processor cycles. These functions can +* be used to get/set time in the global timer. +* +* @{ +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date     Changes
+* ----- ------ -------- ---------------------------------------------------
+* 1.00a rp/sdm 11/03/09 Initial release.
+* 3.06a sgd    05/15/12 Upadted get/set time functions to make use Global Timer
+* 3.06a asa    06/17/12 Reverted back the changes to make use Global Timer.
+* 3.07a sgd    07/05/12 Upadted get/set time functions to make use Global Timer
+* 6.6   srm    10/23/17 Updated the macros to support user configurable sleep
+*						implementation
+* 6.8   aru  09/06/18 Removed compilation warnings for ARMCC toolchain.
+* 
+* +******************************************************************************/ + +#ifndef XTIME_H /* prevent circular inclusions */ +#define XTIME_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +#include "xil_types.h" +#include "xparameters.h" + +/***************** Macros (Inline Functions) Definitions *********************/ + +/**************************** Type Definitions *******************************/ + +typedef u64 XTime; + +/************************** Constant Definitions *****************************/ +#define GLOBAL_TMR_BASEADDR XPAR_GLOBAL_TMR_BASEADDR +#define GTIMER_COUNTER_LOWER_OFFSET 0x00U +#define GTIMER_COUNTER_UPPER_OFFSET 0x04U +#define GTIMER_CONTROL_OFFSET 0x08U + +#if defined (SLEEP_TIMER_BASEADDR) +#define COUNTS_PER_SECOND (SLEEP_TIMER_FREQUENCY) +#else +/* Global Timer is always clocked at half of the CPU frequency */ +#define COUNTS_PER_SECOND (XPAR_CPU_CORTEXA9_CORE_CLOCK_FREQ_HZ /2) +#endif + +#if defined (XSLEEP_TIMER_IS_DEFAULT_TIMER) +#ifdef __GNUC__ +#pragma message ("For the sleep routines, Global timer is being used") +#endif +#endif +/************************** Variable Definitions *****************************/ + +/************************** Function Prototypes ******************************/ + +void XTime_SetTime(XTime Xtime_Global); +void XTime_GetTime(XTime *Xtime_Global); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* XTIME_H */ +/** +* @} End of "addtogroup a9_time_apis". +*/ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/Makefile b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/Makefile new file mode 100644 index 0000000..88b1e62 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/Makefile @@ -0,0 +1,40 @@ +COMPILER= +ARCHIVER= +CP=cp +COMPILER_FLAGS= +EXTRA_COMPILER_FLAGS= +LIB=libxil.a + +CC_FLAGS = $(COMPILER_FLAGS) +ECC_FLAGS = $(EXTRA_COMPILER_FLAGS) + +RELEASEDIR=../../../lib +INCLUDEDIR=../../../include +INCLUDES=-I./. -I${INCLUDEDIR} + +OUTS = *.o + +LIBSOURCES:=*.c +INCLUDEFILES:=*.h + +OBJECTS = $(addsuffix .o, $(basename $(wildcard *.c))) + +libs: banner xuartps_libs clean + +%.o: %.c + ${COMPILER} $(CC_FLAGS) $(ECC_FLAGS) $(INCLUDES) -o $@ $< + +banner: + echo "Compiling uartps" + +xuartps_libs: ${OBJECTS} + $(ARCHIVER) -r ${RELEASEDIR}/${LIB} ${OBJECTS} + +.PHONY: include +include: xuartps_includes + +xuartps_includes: + ${CP} ${INCLUDEFILES} ${INCLUDEDIR} + +clean: + rm -rf ${OBJECTS} diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps.c new file mode 100644 index 0000000..944afa1 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps.c @@ -0,0 +1,642 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xuartps.c +* @addtogroup uartps_v3_5 +* @{ +* +* This file contains the implementation of the interface functions for XUartPs +* driver. Refer to the header file xuartps.h for more detailed information. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date	 Changes
+* ----- ------ -------- ----------------------------------------------
+* 1.00	drg/jz 01/13/10 First Release
+* 2.2   hk     06/23/14 SW reset of RX and TX should be done when changing
+*                       baud rate. CR# 804281.
+* 3.00  kvn    02/13/15 Modified code for MISRA-C:2012 compliance.
+* 3.1	kvn    04/10/15 Modified code for latest RTL changes.
+* 3.5	NK     09/26/17 Fix the RX Buffer Overflow issue.
+* 3.7   aru    08/17/18 Resolved MISRA-C mandatory violations.(CR#1007755)
+* 
+* +*****************************************************************************/ + +/***************************** Include Files ********************************/ + +#include "xstatus.h" +#include "xuartps.h" +#include "xil_io.h" + +/************************** Constant Definitions ****************************/ + +/* The following constant defines the amount of error that is allowed for + * a specified baud rate. This error is the difference between the actual + * baud rate that will be generated using the specified clock and the + * desired baud rate. + */ +#define XUARTPS_MAX_BAUD_ERROR_RATE 3U /* max % error allowed */ + +/**************************** Type Definitions ******************************/ + + +/***************** Macros (Inline Functions) Definitions ********************/ + + +/************************** Function Prototypes *****************************/ + +static void XUartPs_StubHandler(void *CallBackRef, u32 Event, + u32 ByteCount); + +u32 XUartPs_SendBuffer(XUartPs *InstancePtr); + +u32 XUartPs_ReceiveBuffer(XUartPs *InstancePtr); + +/************************** Variable Definitions ****************************/ + +/****************************************************************************/ +/** +* +* Initializes a specific XUartPs instance such that it is ready to be used. +* The data format of the device is setup for 8 data bits, 1 stop bit, and no +* parity by default. The baud rate is set to a default value specified by +* Config->DefaultBaudRate if set, otherwise it is set to 19.2K baud. The +* receive FIFO threshold is set for 8 bytes. The default operating mode of the +* driver is polled mode. +* +* @param InstancePtr is a pointer to the XUartPs instance. +* @param Config is a reference to a structure containing information +* about a specific XUartPs driver. +* @param EffectiveAddr is the device base address in the virtual memory +* address space. The caller is responsible for keeping the address +* mapping from EffectiveAddr to the device physical base address +* unchanged once this function is invoked. Unexpected errors may +* occur if the address mapping changes after this function is +* called. If address translation is not used, pass in the physical +* address instead. +* +* @return +* +* - XST_SUCCESS if initialization was successful +* - XST_UART_BAUD_ERROR if the baud rate is not possible because +* the inputclock frequency is not divisible with an acceptable +* amount of error +* +* @note +* +* The default configuration for the UART after initialization is: +* +* - 19,200 bps or XPAR_DFT_BAUDRATE if defined +* - 8 data bits +* - 1 stop bit +* - no parity +* - FIFO's are enabled with a receive threshold of 8 bytes +* - The RX timeout is enabled with a timeout of 1 (4 char times) +* +* All interrupts are disabled. +* +*****************************************************************************/ +s32 XUartPs_CfgInitialize(XUartPs *InstancePtr, + XUartPs_Config * Config, u32 EffectiveAddr) +{ + s32 Status; + u32 ModeRegister; + u32 BaudRate; + + /* Assert validates the input arguments */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(Config != NULL); + + /* Setup the driver instance using passed in parameters */ + InstancePtr->Config.BaseAddress = EffectiveAddr; + InstancePtr->Config.InputClockHz = Config->InputClockHz; + InstancePtr->Config.ModemPinsConnected = Config->ModemPinsConnected; + + /* Initialize other instance data to default values */ + InstancePtr->Handler = (XUartPs_Handler)XUartPs_StubHandler; + + InstancePtr->SendBuffer.NextBytePtr = NULL; + InstancePtr->SendBuffer.RemainingBytes = 0U; + InstancePtr->SendBuffer.RequestedBytes = 0U; + + InstancePtr->ReceiveBuffer.NextBytePtr = NULL; + InstancePtr->ReceiveBuffer.RemainingBytes = 0U; + InstancePtr->ReceiveBuffer.RequestedBytes = 0U; + + /* Initialize the platform data */ + InstancePtr->Platform = XGetPlatform_Info(); + + InstancePtr->is_rxbs_error = 0U; + + /* Flag that the driver instance is ready to use */ + InstancePtr->IsReady = XIL_COMPONENT_IS_READY; + + /* + * Set the default baud rate here, can be changed prior to + * starting the device + */ + BaudRate = (u32)XUARTPS_DFT_BAUDRATE; + Status = XUartPs_SetBaudRate(InstancePtr, BaudRate); + if (Status != (s32)XST_SUCCESS) { + InstancePtr->IsReady = 0U; + } else { + + /* + * Set up the default data format: 8 bit data, 1 stop bit, no + * parity + */ + ModeRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress, + XUARTPS_MR_OFFSET); + + /* Mask off what's already there */ + ModeRegister &= (~((u32)XUARTPS_MR_CHARLEN_MASK | + (u32)XUARTPS_MR_STOPMODE_MASK | + (u32)XUARTPS_MR_PARITY_MASK)); + + /* Set the register value to the desired data format */ + ModeRegister |= ((u32)XUARTPS_MR_CHARLEN_8_BIT | + (u32)XUARTPS_MR_STOPMODE_1_BIT | + (u32)XUARTPS_MR_PARITY_NONE); + + /* Write the mode register out */ + XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_MR_OFFSET, + ModeRegister); + + /* Set the RX FIFO trigger at 8 data bytes. */ + XUartPs_WriteReg(InstancePtr->Config.BaseAddress, + XUARTPS_RXWM_OFFSET, 0x08U); + + /* Set the RX timeout to 1, which will be 4 character time */ + XUartPs_WriteReg(InstancePtr->Config.BaseAddress, + XUARTPS_RXTOUT_OFFSET, 0x01U); + + /* Disable all interrupts, polled mode is the default */ + XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_IDR_OFFSET, + XUARTPS_IXR_MASK); + + Status = XST_SUCCESS; + } + return Status; +} + +/****************************************************************************/ +/** +* +* This functions sends the specified buffer using the device in either +* polled or interrupt driven mode. This function is non-blocking, if the device +* is busy sending data, it will return and indicate zero bytes were sent. +* Otherwise, it fills the TX FIFO as much as it can, and return the number of +* bytes sent. +* +* In a polled mode, this function will only send as much data as TX FIFO can +* buffer. The application may need to call it repeatedly to send the entire +* buffer. +* +* In interrupt mode, this function will start sending the specified buffer, +* then the interrupt handler will continue sending data until the entire +* buffer has been sent. A callback function, as specified by the application, +* will be called to indicate the completion of sending. +* +* @param InstancePtr is a pointer to the XUartPs instance. +* @param BufferPtr is pointer to a buffer of data to be sent. +* @param NumBytes contains the number of bytes to be sent. A value of +* zero will stop a previous send operation that is in progress +* in interrupt mode. Any data that was already put into the +* transmit FIFO will be sent. +* +* @return The number of bytes actually sent. +* +* @note +* +* The number of bytes is not asserted so that this function may be called with +* a value of zero to stop an operation that is already in progress. +*

+* +*****************************************************************************/ +u32 XUartPs_Send(XUartPs *InstancePtr, u8 *BufferPtr, + u32 NumBytes) +{ + u32 BytesSent; + + /* Asserts validate the input arguments */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(BufferPtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Disable the UART transmit interrupts to allow this call to stop a + * previous operation that may be interrupt driven. + */ + XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_IDR_OFFSET, + (XUARTPS_IXR_TXEMPTY | XUARTPS_IXR_TXFULL)); + + /* Setup the buffer parameters */ + InstancePtr->SendBuffer.RequestedBytes = NumBytes; + InstancePtr->SendBuffer.RemainingBytes = NumBytes; + InstancePtr->SendBuffer.NextBytePtr = BufferPtr; + + /* + * Transmit interrupts will be enabled in XUartPs_SendBuffer(), after + * filling the TX FIFO. + */ + BytesSent = XUartPs_SendBuffer(InstancePtr); + + return BytesSent; +} + +/****************************************************************************/ +/** +* +* This function attempts to receive a specified number of bytes of data +* from the device and store it into the specified buffer. This function works +* for both polled or interrupt driven modes. It is non-blocking. +* +* In a polled mode, this function will only receive the data already in the +* RX FIFO. The application may need to call it repeatedly to receive the +* entire buffer. Polled mode is the default mode of operation for the device. +* +* In interrupt mode, this function will start the receiving, if not the entire +* buffer has been received, the interrupt handler will continue receiving data +* until the entire buffer has been received. A callback function, as specified +* by the application, will be called to indicate the completion of the +* receiving or error conditions. +* +* @param InstancePtr is a pointer to the XUartPs instance +* @param BufferPtr is pointer to buffer for data to be received into +* @param NumBytes is the number of bytes to be received. A value of zero +* will stop a previous receive operation that is in progress in +* interrupt mode. +* +* @return The number of bytes received. +* +* @note +* +* The number of bytes is not asserted so that this function may be called +* with a value of zero to stop an operation that is already in progress. +* +*****************************************************************************/ +u32 XUartPs_Recv(XUartPs *InstancePtr, + u8 *BufferPtr, u32 NumBytes) +{ + u32 ReceivedCount; + u32 ImrRegister; + + /* Assert validates the input arguments */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(BufferPtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Disable all the interrupts. + * This stops a previous operation that may be interrupt driven + */ + ImrRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress, + XUARTPS_IMR_OFFSET); + XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_IDR_OFFSET, + XUARTPS_IXR_MASK); + + /* Setup the buffer parameters */ + InstancePtr->ReceiveBuffer.RequestedBytes = NumBytes; + InstancePtr->ReceiveBuffer.RemainingBytes = NumBytes; + InstancePtr->ReceiveBuffer.NextBytePtr = BufferPtr; + + /* Receive the data from the device */ + ReceivedCount = XUartPs_ReceiveBuffer(InstancePtr); + + /* Restore the interrupt state */ + XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_IER_OFFSET, + ImrRegister); + + return ReceivedCount; +} + +/****************************************************************************/ +/* +* +* This function sends a buffer that has been previously specified by setting +* up the instance variables of the instance. This function is an internal +* function for the XUartPs driver such that it may be called from a shell +* function that sets up the buffer or from an interrupt handler. +* +* This function sends the specified buffer in either polled or interrupt +* driven modes. This function is non-blocking. +* +* In a polled mode, this function only sends as much data as the TX FIFO +* can buffer. The application may need to call it repeatedly to send the +* entire buffer. +* +* In interrupt mode, this function starts the sending of the buffer, if not +* the entire buffer has been sent, then the interrupt handler continues the +* sending until the entire buffer has been sent. A callback function, as +* specified by the application, will be called to indicate the completion of +* sending. +* +* @param InstancePtr is a pointer to the XUartPs instance +* +* @return The number of bytes actually sent +* +* @note None. +* +*****************************************************************************/ +u32 XUartPs_SendBuffer(XUartPs *InstancePtr) +{ + u32 SentCount = 0U; + u32 ImrRegister; + + /* + * If the TX FIFO is full, send nothing. + * Otherwise put bytes into the TX FIFO unil it is full, or all of the + * data has been put into the FIFO. + */ + while ((!XUartPs_IsTransmitFull(InstancePtr->Config.BaseAddress)) && + (InstancePtr->SendBuffer.RemainingBytes > SentCount)) { + + /* Fill the FIFO from the buffer */ + XUartPs_WriteReg(InstancePtr->Config.BaseAddress, + XUARTPS_FIFO_OFFSET, + ((u32)InstancePtr->SendBuffer. + NextBytePtr[SentCount])); + + /* Increment the send count. */ + SentCount++; + } + + /* Update the buffer to reflect the bytes that were sent from it */ + InstancePtr->SendBuffer.NextBytePtr += SentCount; + InstancePtr->SendBuffer.RemainingBytes -= SentCount; + + /* + * If interrupts are enabled as indicated by the receive interrupt, then + * enable the TX FIFO empty interrupt, so further action can be taken + * for this sending. + */ + ImrRegister = + XUartPs_ReadReg(InstancePtr->Config.BaseAddress, + XUARTPS_IMR_OFFSET); + if (((ImrRegister & XUARTPS_IXR_RXFULL) != (u32)0) || + ((ImrRegister & XUARTPS_IXR_RXEMPTY) != (u32)0)|| + ((ImrRegister & XUARTPS_IXR_RXOVR) != (u32)0)) { + + XUartPs_WriteReg(InstancePtr->Config.BaseAddress, + XUARTPS_IER_OFFSET, + ImrRegister | (u32)XUARTPS_IXR_TXEMPTY); + } + + return SentCount; +} + +/****************************************************************************/ +/* +* +* This function receives a buffer that has been previously specified by setting +* up the instance variables of the instance. This function is an internal +* function, and it may be called from a shell function that sets up the buffer +* or from an interrupt handler. +* +* This function attempts to receive a specified number of bytes from the +* device and store it into the specified buffer. This function works for +* either polled or interrupt driven modes. It is non-blocking. +* +* In polled mode, this function only receives as much data as in the RX FIFO. +* The application may need to call it repeatedly to receive the entire buffer. +* Polled mode is the default mode for the driver. +* +* In interrupt mode, this function starts the receiving, if not the entire +* buffer has been received, the interrupt handler will continue until the +* entire buffer has been received. A callback function, as specified by the +* application, will be called to indicate the completion of the receiving or +* error conditions. +* +* @param InstancePtr is a pointer to the XUartPs instance +* +* @return The number of bytes received. +* +* @note None. +* +*****************************************************************************/ +u32 XUartPs_ReceiveBuffer(XUartPs *InstancePtr) +{ + u32 CsrRegister; + u32 ReceivedCount = 0U; + u32 ByteStatusValue, EventData; + u32 Event; + + /* + * Read the Channel Status Register to determine if there is any data in + * the RX FIFO + */ + CsrRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress, + XUARTPS_SR_OFFSET); + + /* + * Loop until there is no more data in RX FIFO or the specified + * number of bytes has been received + */ + while((ReceivedCount < InstancePtr->ReceiveBuffer.RemainingBytes)&& + (((CsrRegister & XUARTPS_SR_RXEMPTY) == (u32)0))){ + + if (InstancePtr->is_rxbs_error) { + ByteStatusValue = XUartPs_ReadReg( + InstancePtr->Config.BaseAddress, + XUARTPS_RXBS_OFFSET); + if((ByteStatusValue & XUARTPS_RXBS_MASK)!= (u32)0) { + EventData = ByteStatusValue; + Event = XUARTPS_EVENT_PARE_FRAME_BRKE; + /* + * Call the application handler to indicate that there is a receive + * error or a break interrupt, if the application cares about the + * error it call a function to get the last errors. + */ + InstancePtr->Handler(InstancePtr->CallBackRef, + Event, EventData); + } + } + + InstancePtr->ReceiveBuffer.NextBytePtr[ReceivedCount] = + XUartPs_ReadReg(InstancePtr->Config. + BaseAddress, + XUARTPS_FIFO_OFFSET); + + ReceivedCount++; + + CsrRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress, + XUARTPS_SR_OFFSET); + } + InstancePtr->is_rxbs_error = 0; + /* + * Update the receive buffer to reflect the number of bytes just + * received + */ + if(InstancePtr->ReceiveBuffer.NextBytePtr != NULL){ + InstancePtr->ReceiveBuffer.NextBytePtr += ReceivedCount; + } + InstancePtr->ReceiveBuffer.RemainingBytes -= ReceivedCount; + + return ReceivedCount; +} + +/*****************************************************************************/ +/** +* +* Sets the baud rate for the device. Checks the input value for +* validity and also verifies that the requested rate can be configured to +* within the maximum error range specified by XUARTPS_MAX_BAUD_ERROR_RATE. +* If the provided rate is not possible, the current setting is unchanged. +* +* @param InstancePtr is a pointer to the XUartPs instance +* @param BaudRate to be set +* +* @return +* - XST_SUCCESS if everything configured as expected +* - XST_UART_BAUD_ERROR if the requested rate is not available +* because there was too much error +* +* @note None. +* +*****************************************************************************/ +s32 XUartPs_SetBaudRate(XUartPs *InstancePtr, u32 BaudRate) +{ + u32 IterBAUDDIV; /* Iterator for available baud divisor values */ + u32 BRGR_Value; /* Calculated value for baud rate generator */ + u32 CalcBaudRate; /* Calculated baud rate */ + u32 BaudError; /* Diff between calculated and requested baud rate */ + u32 Best_BRGR = 0U; /* Best value for baud rate generator */ + u8 Best_BAUDDIV = 0U; /* Best value for baud divisor */ + u32 Best_Error = 0xFFFFFFFFU; + u32 PercentError; + u32 ModeReg; + u32 InputClk; + + /* Asserts validate the input arguments */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid(BaudRate <= (u32)XUARTPS_MAX_RATE); + Xil_AssertNonvoid(BaudRate >= (u32)XUARTPS_MIN_RATE); + + /* + * Make sure the baud rate is not impossilby large. + * Fastest possible baud rate is Input Clock / 2. + */ + if ((BaudRate * 2) > InstancePtr->Config.InputClockHz) { + return XST_UART_BAUD_ERROR; + } + /* Check whether the input clock is divided by 8 */ + ModeReg = XUartPs_ReadReg( InstancePtr->Config.BaseAddress, + XUARTPS_MR_OFFSET); + + InputClk = InstancePtr->Config.InputClockHz; + if(ModeReg & XUARTPS_MR_CLKSEL) { + InputClk = InstancePtr->Config.InputClockHz / 8; + } + + /* + * Determine the Baud divider. It can be 4to 254. + * Loop through all possible combinations + */ + for (IterBAUDDIV = 4; IterBAUDDIV < 255; IterBAUDDIV++) { + + /* Calculate the value for BRGR register */ + BRGR_Value = InputClk / (BaudRate * (IterBAUDDIV + 1)); + + /* Calculate the baud rate from the BRGR value */ + CalcBaudRate = InputClk/ (BRGR_Value * (IterBAUDDIV + 1)); + + /* Avoid unsigned integer underflow */ + if (BaudRate > CalcBaudRate) { + BaudError = BaudRate - CalcBaudRate; + } + else { + BaudError = CalcBaudRate - BaudRate; + } + + /* Find the calculated baud rate closest to requested baud rate. */ + if (Best_Error > BaudError) { + + Best_BRGR = BRGR_Value; + Best_BAUDDIV = IterBAUDDIV; + Best_Error = BaudError; + } + } + + /* Make sure the best error is not too large. */ + PercentError = (Best_Error * 100) / BaudRate; + if (XUARTPS_MAX_BAUD_ERROR_RATE < PercentError) { + return XST_UART_BAUD_ERROR; + } + + /* Disable TX and RX to avoid glitches when setting the baud rate. */ + XUartPs_DisableUart(InstancePtr); + + XUartPs_WriteReg(InstancePtr->Config.BaseAddress, + XUARTPS_BAUDGEN_OFFSET, Best_BRGR); + XUartPs_WriteReg(InstancePtr->Config.BaseAddress, + XUARTPS_BAUDDIV_OFFSET, Best_BAUDDIV); + + /* RX and TX SW reset */ + XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_CR_OFFSET, + XUARTPS_CR_TXRST | XUARTPS_CR_RXRST); + + /* Enable device */ + XUartPs_EnableUart(InstancePtr); + + InstancePtr->BaudRate = BaudRate; + + return XST_SUCCESS; + +} + +/****************************************************************************/ +/** +* +* This function is a stub handler that is the default handler such that if the +* application has not set the handler when interrupts are enabled, this +* function will be called. +* +* @param CallBackRef is unused by this function. +* @param Event is unused by this function. +* @param ByteCount is unused by this function. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +static void XUartPs_StubHandler(void *CallBackRef, u32 Event, + u32 ByteCount) +{ + (void) CallBackRef; + (void) Event; + (void) ByteCount; + /* Assert occurs always since this is a stub and should never be called */ + Xil_AssertVoidAlways(); +} +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps.h new file mode 100644 index 0000000..c6c2a0a --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps.h @@ -0,0 +1,517 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xuartps.h +* @addtogroup uartps_v3_5 +* @{ +* @details +* +* This driver supports the following features: +* +* - Dynamic data format (baud rate, data bits, stop bits, parity) +* - Polled mode +* - Interrupt driven mode +* - Transmit and receive FIFOs (32 byte FIFO depth) +* - Access to the external modem control lines +* +* Initialization & Configuration +* +* The XUartPs_Config structure is used by the driver to configure itself. +* Fields inside this structure are properties of XUartPs based on its hardware +* build. +* +* To support multiple runtime loading and initialization strategies employed +* by various operating systems, the driver instance can be initialized in the +* following way: +* +* - XUartPs_CfgInitialize(InstancePtr, CfgPtr, EffectiveAddr) - Uses a +* configuration structure provided by the caller. If running in a system +* with address translation, the parameter EffectiveAddr should be the +* virtual address. +* +* Baud Rate +* +* The UART has an internal baud rate generator, which furnishes the baud rate +* clock for both the receiver and the transmitter. Ther input clock frequency +* can be either the master clock or the master clock divided by 8, configured +* through the mode register. +* +* Accompanied with the baud rate divider register, the baud rate is determined +* by: +*
+*	baud_rate = input_clock / (bgen * (bdiv + 1)
+* 
+* where bgen is the value of the baud rate generator, and bdiv is the value of +* baud rate divider. +* +* Interrupts +* +* The FIFOs are not flushed when the driver is initialized, but a function is +* provided to allow the user to reset the FIFOs if desired. +* +* The driver defaults to no interrupts at initialization such that interrupts +* must be enabled if desired. An interrupt is generated for one of the +* following conditions. +* +* - A change in the modem signals +* - Data in the receive FIFO for a configuable time without receiver activity +* - A parity error +* - A framing error +* - An overrun error +* - Transmit FIFO is full +* - Transmit FIFO is empty +* - Receive FIFO is full +* - Receive FIFO is empty +* - Data in the receive FIFO equal to the receive threshold +* +* The application can control which interrupts are enabled using the +* XUartPs_SetInterruptMask() function. +* +* In order to use interrupts, it is necessary for the user to connect the +* driver interrupt handler, XUartPs_InterruptHandler(), to the interrupt +* system of the application. A separate handler should be provided by the +* application to communicate with the interrupt system, and conduct +* application specific interrupt handling. An application registers its own +* handler through the XUartPs_SetHandler() function. +* +* Data Transfer +* +* The functions, XUartPs_Send() and XUartPs_Recv(), are provided in the +* driver to allow data to be sent and received. They can be used in either +* polled or interrupt mode. +* +* @note +* +* The default configuration for the UART after initialization is: +* +* - 9,600 bps or XPAR_DFT_BAUDRATE if defined +* - 8 data bits +* - 1 stop bit +* - no parity +* - FIFO's are enabled with a receive threshold of 8 bytes +* - The RX timeout is enabled with a timeout of 1 (4 char times) +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date	Changes
+* ----- ------ -------- ----------------------------------------------
+* 1.00a	drg/jz 01/12/10 First Release
+* 1.00a sdm    09/27/11 Fixed compiler warnings and also a bug
+*		        in XUartPs_SetFlowDelay where the value was not
+*			being written to the register.
+* 1.01a sdm    12/20/11 Removed the InputClockHz parameter from the XUartPs
+*			instance structure and the driver is updated to use
+*			InputClockHz parameter from the XUartPs_Config config
+*			structure.
+*			Added a parameter to XUartPs_Config structure which
+*			specifies whether the user has selected Modem pins
+*			to be connected to MIO or FMIO.
+*			Added the tcl file to generate the xparameters.h
+* 1.02a sg     05/16/12	Changed XUARTPS_RXWM_MASK to 0x3F for CR 652540 fix.
+* 1.03a sg     07/16/12 Updated XUARTPS_FORMAT_7_BITS and XUARTPS_FORMAT_6_BITS
+*			with the correct values for CR 666724
+* 			Added defines for XUARTPS_IXR_TOVR,  XUARTPS_IXR_TNFUL
+*			and XUARTPS_IXR_TTRIG.
+*			Modified the name of these defines
+*			XUARTPS_MEDEMSR_DCDX to XUARTPS_MODEMSR_DDCD
+*			XUARTPS_MEDEMSR_RIX to XUARTPS_MODEMSR_TERI
+*			XUARTPS_MEDEMSR_DSRX to XUARTPS_MODEMSR_DDSR
+*			XUARTPS_MEDEMSR_CTSX to XUARTPS_MODEMSR_DCTS
+* 1.05a hk     08/22/13 Added API for uart reset and related
+*			constant definitions.
+* 2.0   hk      03/07/14 Version number revised.
+* 2.1   hk     04/16/14 Change XUARTPS_MAX_RATE to 921600. CR# 780625.
+* 2.2   hk     06/23/14 SW reset of RX and TX should be done when changing
+*                       baud rate. CR# 804281.
+* 3.0   vm     12/09/14 Modified source code according to misrac guideline.
+*			Support for Zynq Ultrascale Mp added.
+* 3.1	kvn    04/10/15 Modified code for latest RTL changes. Also added
+*						platform variable in driver instance structure.
+* 3.1   adk   14/03/16  Include interrupt examples in the peripheral test when
+*			uart is connected to a valid interrupt controller CR#946803.
+* 3.2   rk     07/20/16 Modified the logic for transmission break bit set
+* 3.4   ms     01/23/17 Added xil_printf statement in main function for all
+*                       examples to ensure that "Successfully ran" and "Failed"
+*                       strings are available in all examples. This is a fix
+*                       for CR-965028.
+*       ms     03/17/17 Added readme.txt file in examples folder for doxygen
+*                       generation.
+* 3.6   ms     02/16/18 Updates the flow control mode offset value in modem
+*                       control register.
+* 3.7   aru    08/17/18 Resolved MISRA-C:2012 compliance mandatory violations.
+*
+* 
+* +*****************************************************************************/ + +#ifndef XUARTPS_H /* prevent circular inclusions */ +#define XUARTPS_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files ********************************/ + +#include "xil_types.h" +#include "xil_assert.h" +#include "xstatus.h" +#include "xuartps_hw.h" +#include "xplatform_info.h" + +/************************** Constant Definitions ****************************/ + +/* + * The following constants indicate the max and min baud rates and these + * numbers are based only on the testing that has been done. The hardware + * is capable of other baud rates. + */ +#define XUARTPS_MAX_RATE 921600U +#define XUARTPS_MIN_RATE 110U + +#define XUARTPS_DFT_BAUDRATE 115200U /* Default baud rate */ + +/** @name Configuration options + * @{ + */ +/** + * These constants specify the options that may be set or retrieved + * with the driver, each is a unique bit mask such that multiple options + * may be specified. These constants indicate the available options + * in active state. + * + */ + +#define XUARTPS_OPTION_SET_BREAK 0x0080U /**< Starts break transmission */ +#define XUARTPS_OPTION_STOP_BREAK 0x0040U /**< Stops break transmission */ +#define XUARTPS_OPTION_RESET_TMOUT 0x0020U /**< Reset the receive timeout */ +#define XUARTPS_OPTION_RESET_TX 0x0010U /**< Reset the transmitter */ +#define XUARTPS_OPTION_RESET_RX 0x0008U /**< Reset the receiver */ +#define XUARTPS_OPTION_ASSERT_RTS 0x0004U /**< Assert the RTS bit */ +#define XUARTPS_OPTION_ASSERT_DTR 0x0002U /**< Assert the DTR bit */ +#define XUARTPS_OPTION_SET_FCM 0x0001U /**< Turn on flow control mode */ +/*@}*/ + + +/** @name Channel Operational Mode + * + * The UART can operate in one of four modes: Normal, Local Loopback, Remote + * Loopback, or automatic echo. + * + * @{ + */ + +#define XUARTPS_OPER_MODE_NORMAL (u8)0x00U /**< Normal Mode */ +#define XUARTPS_OPER_MODE_AUTO_ECHO (u8)0x01U /**< Auto Echo Mode */ +#define XUARTPS_OPER_MODE_LOCAL_LOOP (u8)0x02U /**< Local Loopback Mode */ +#define XUARTPS_OPER_MODE_REMOTE_LOOP (u8)0x03U /**< Remote Loopback Mode */ + +/* @} */ + +/** @name Data format values + * + * These constants specify the data format that the driver supports. + * The data format includes the number of data bits, the number of stop + * bits and parity. + * + * @{ + */ +#define XUARTPS_FORMAT_8_BITS 0U /**< 8 data bits */ +#define XUARTPS_FORMAT_7_BITS 2U /**< 7 data bits */ +#define XUARTPS_FORMAT_6_BITS 3U /**< 6 data bits */ + +#define XUARTPS_FORMAT_NO_PARITY 4U /**< No parity */ +#define XUARTPS_FORMAT_MARK_PARITY 3U /**< Mark parity */ +#define XUARTPS_FORMAT_SPACE_PARITY 2U /**< parity */ +#define XUARTPS_FORMAT_ODD_PARITY 1U /**< Odd parity */ +#define XUARTPS_FORMAT_EVEN_PARITY 0U /**< Even parity */ + +#define XUARTPS_FORMAT_2_STOP_BIT 2U /**< 2 stop bits */ +#define XUARTPS_FORMAT_1_5_STOP_BIT 1U /**< 1.5 stop bits */ +#define XUARTPS_FORMAT_1_STOP_BIT 0U /**< 1 stop bit */ +/*@}*/ + +/** @name Callback events + * + * These constants specify the handler events that an application can handle + * using its specific handler function. Note that these constants are not bit + * mask, so only one event can be passed to an application at a time. + * + * @{ + */ +#define XUARTPS_EVENT_RECV_DATA 1U /**< Data receiving done */ +#define XUARTPS_EVENT_RECV_TOUT 2U /**< A receive timeout occurred */ +#define XUARTPS_EVENT_SENT_DATA 3U /**< Data transmission done */ +#define XUARTPS_EVENT_RECV_ERROR 4U /**< A receive error detected */ +#define XUARTPS_EVENT_MODEM 5U /**< Modem status changed */ +#define XUARTPS_EVENT_PARE_FRAME_BRKE 6U /**< A receive parity, frame, break + * error detected */ +#define XUARTPS_EVENT_RECV_ORERR 7U /**< A receive overrun error detected */ +/*@}*/ + + +/**************************** Type Definitions ******************************/ + +/** + * This typedef contains configuration information for the device. + */ +typedef struct { + u16 DeviceId; /**< Unique ID of device */ + u32 BaseAddress; /**< Base address of device (IPIF) */ + u32 InputClockHz;/**< Input clock frequency */ + s32 ModemPinsConnected; /** Specifies whether modem pins are connected + * to MIO or FMIO */ +} XUartPs_Config; + +/* Keep track of state information about a data buffer in the interrupt mode. */ +typedef struct { + u8 *NextBytePtr; + u32 RequestedBytes; + u32 RemainingBytes; +} XUartPsBuffer; + +/** + * Keep track of data format setting of a device. + */ +typedef struct { + u32 BaudRate; /**< In bps, ie 1200 */ + u32 DataBits; /**< Number of data bits */ + u32 Parity; /**< Parity */ + u8 StopBits; /**< Number of stop bits */ +} XUartPsFormat; + +/******************************************************************************/ +/** + * This data type defines a handler that an application defines to communicate + * with interrupt system to retrieve state information about an application. + * + * @param CallBackRef is a callback reference passed in by the upper layer + * when setting the handler, and is passed back to the upper layer + * when the handler is called. It is used to find the device driver + * instance. + * @param Event contains one of the event constants indicating events that + * have occurred. + * @param EventData contains the number of bytes sent or received at the + * time of the call for send and receive events and contains the + * modem status for modem events. + * + ******************************************************************************/ +typedef void (*XUartPs_Handler) (void *CallBackRef, u32 Event, + u32 EventData); + +/** + * The XUartPs driver instance data structure. A pointer to an instance data + * structure is passed around by functions to refer to a specific driver + * instance. + */ +typedef struct { + XUartPs_Config Config; /* Configuration data structure */ + u32 InputClockHz; /* Input clock frequency */ + u32 IsReady; /* Device is initialized and ready */ + u32 BaudRate; /* Current baud rate */ + + XUartPsBuffer SendBuffer; + XUartPsBuffer ReceiveBuffer; + + XUartPs_Handler Handler; + void *CallBackRef; /* Callback reference for event handler */ + u32 Platform; + u8 is_rxbs_error; +} XUartPs; + + +/***************** Macros (Inline Functions) Definitions ********************/ + +/****************************************************************************/ +/** +* Get the UART Channel Status Register. +* +* @param InstancePtr is a pointer to the XUartPs instance. +* +* @return The value read from the register. +* +* @note C-Style signature: +* u16 XUartPs_GetChannelStatus(XUartPs *InstancePtr) +* +******************************************************************************/ +#define XUartPs_GetChannelStatus(InstancePtr) \ + Xil_In32(((InstancePtr)->Config.BaseAddress) + (u32)XUARTPS_SR_OFFSET) + +/****************************************************************************/ +/** +* Get the UART Mode Control Register. +* +* @param InstancePtr is a pointer to the XUartPs instance. +* +* @return The value read from the register. +* +* @note C-Style signature: +* u32 XUartPs_GetControl(XUartPs *InstancePtr) +* +******************************************************************************/ +#define XUartPs_GetModeControl(InstancePtr) \ + Xil_In32(((InstancePtr)->Config.BaseAddress) + (u32)XUARTPS_CR_OFFSET) + +/****************************************************************************/ +/** +* Set the UART Mode Control Register. +* +* @param InstancePtr is a pointer to the XUartPs instance. +* @param RegisterValue is the value to be written to the register. +* +* @return None. +* +* @note C-Style signature: +* void XUartPs_SetModeControl(XUartPs *InstancePtr, u16 RegisterValue) +* +******************************************************************************/ +#define XUartPs_SetModeControl(InstancePtr, RegisterValue) \ + Xil_Out32(((InstancePtr)->Config.BaseAddress) + (u32)XUARTPS_CR_OFFSET, \ + (u32)(RegisterValue)) + +/****************************************************************************/ +/** +* Enable the transmitter and receiver of the UART. +* +* @param InstancePtr is a pointer to the XUartPs instance. +* +* @return None. +* +* @note C-Style signature: +* void XUartPs_EnableUart(XUartPs *InstancePtr) +* +******************************************************************************/ +#define XUartPs_EnableUart(InstancePtr) \ + Xil_Out32(((InstancePtr)->Config.BaseAddress + (u32)XUARTPS_CR_OFFSET), \ + ((Xil_In32((InstancePtr)->Config.BaseAddress + (u32)XUARTPS_CR_OFFSET) & \ + (u32)(~XUARTPS_CR_EN_DIS_MASK)) | ((u32)XUARTPS_CR_RX_EN | (u32)XUARTPS_CR_TX_EN))) + +/****************************************************************************/ +/** +* Disable the transmitter and receiver of the UART. +* +* @param InstancePtr is a pointer to the XUartPs instance. +* +* @return None. +* +* @note C-Style signature: +* void XUartPs_DisableUart(XUartPs *InstancePtr) +* +******************************************************************************/ +#define XUartPs_DisableUart(InstancePtr) \ + Xil_Out32(((InstancePtr)->Config.BaseAddress + (u32)XUARTPS_CR_OFFSET), \ + (((Xil_In32((InstancePtr)->Config.BaseAddress + (u32)XUARTPS_CR_OFFSET)) & \ + (u32)(~XUARTPS_CR_EN_DIS_MASK)) | ((u32)XUARTPS_CR_RX_DIS | (u32)XUARTPS_CR_TX_DIS))) + +/****************************************************************************/ +/** +* Determine if the transmitter FIFO is empty. +* +* @param InstancePtr is a pointer to the XUartPs instance. +* +* @return +* - TRUE if a byte can be sent +* - FALSE if the Transmitter Fifo is not empty +* +* @note C-Style signature: +* u32 XUartPs_IsTransmitEmpty(XUartPs InstancePtr) +* +******************************************************************************/ +#define XUartPs_IsTransmitEmpty(InstancePtr) \ + ((Xil_In32(((InstancePtr)->Config.BaseAddress) + (u32)XUARTPS_SR_OFFSET) & \ + (u32)XUARTPS_SR_TXEMPTY) == (u32)XUARTPS_SR_TXEMPTY) + + +/************************** Function Prototypes *****************************/ + +/* Static lookup function implemented in xuartps_sinit.c */ +XUartPs_Config *XUartPs_LookupConfig(u16 DeviceId); + +/* Interface functions implemented in xuartps.c */ +s32 XUartPs_CfgInitialize(XUartPs *InstancePtr, + XUartPs_Config * Config, u32 EffectiveAddr); + +u32 XUartPs_Send(XUartPs *InstancePtr,u8 *BufferPtr, + u32 NumBytes); + +u32 XUartPs_Recv(XUartPs *InstancePtr,u8 *BufferPtr, + u32 NumBytes); + +s32 XUartPs_SetBaudRate(XUartPs *InstancePtr, u32 BaudRate); + +/* Options functions in xuartps_options.c */ +void XUartPs_SetOptions(XUartPs *InstancePtr, u16 Options); + +u16 XUartPs_GetOptions(XUartPs *InstancePtr); + +void XUartPs_SetFifoThreshold(XUartPs *InstancePtr, u8 TriggerLevel); + +u8 XUartPs_GetFifoThreshold(XUartPs *InstancePtr); + +u16 XUartPs_GetModemStatus(XUartPs *InstancePtr); + +u32 XUartPs_IsSending(XUartPs *InstancePtr); + +u8 XUartPs_GetOperMode(XUartPs *InstancePtr); + +void XUartPs_SetOperMode(XUartPs *InstancePtr, u8 OperationMode); + +u8 XUartPs_GetFlowDelay(XUartPs *InstancePtr); + +void XUartPs_SetFlowDelay(XUartPs *InstancePtr, u8 FlowDelayValue); + +u8 XUartPs_GetRecvTimeout(XUartPs *InstancePtr); + +void XUartPs_SetRecvTimeout(XUartPs *InstancePtr, u8 RecvTimeout); + +s32 XUartPs_SetDataFormat(XUartPs *InstancePtr, XUartPsFormat * FormatPtr); + +void XUartPs_GetDataFormat(XUartPs *InstancePtr, XUartPsFormat * FormatPtr); + +/* interrupt functions in xuartps_intr.c */ +u32 XUartPs_GetInterruptMask(XUartPs *InstancePtr); + +void XUartPs_SetInterruptMask(XUartPs *InstancePtr, u32 Mask); + +void XUartPs_InterruptHandler(XUartPs *InstancePtr); + +void XUartPs_SetHandler(XUartPs *InstancePtr, XUartPs_Handler FuncPtr, + void *CallBackRef); + +/* self-test functions in xuartps_selftest.c */ +s32 XUartPs_SelfTest(XUartPs *InstancePtr); + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_g.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_g.c new file mode 100644 index 0000000..023fcde --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_g.c @@ -0,0 +1,53 @@ + +/******************************************************************* +* +* CAUTION: This file is automatically generated by HSI. +* Version: 2019.1.3 +* DO NOT EDIT. +* +* Copyright (C) 2010-2023 Xilinx, Inc. All Rights Reserved.* +*Permission is hereby granted, free of charge, to any person obtaining a copy +*of this software and associated documentation files (the Software), to deal +*in the Software without restriction, including without limitation the rights +*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +*copies of the Software, and to permit persons to whom the Software is +*furnished to do so, subject to the following conditions: +* +*The above copyright notice and this permission notice shall be included in +*all copies or substantial portions of the Software. +* +*THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +*XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +*OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*Except as contained in this notice, the name of the Xilinx shall not be used +*in advertising or otherwise to promote the sale, use or other dealings in +*this Software without prior written authorization from Xilinx. +* + +* +* Description: Driver configuration +* +*******************************************************************/ + +#include "xparameters.h" +#include "xuartps.h" + +/* +* The configuration table for devices +*/ + +XUartPs_Config XUartPs_ConfigTable[XPAR_XUARTPS_NUM_INSTANCES] = +{ + { + XPAR_PS7_UART_0_DEVICE_ID, + XPAR_PS7_UART_0_BASEADDR, + XPAR_PS7_UART_0_UART_CLK_FREQ_HZ, + XPAR_PS7_UART_0_HAS_MODEM + } +}; + + diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_hw.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_hw.c new file mode 100644 index 0000000..11462ba --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_hw.c @@ -0,0 +1,176 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xuartps_hw.c +* @addtogroup uartps_v3_5 +* @{ +* +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date	Changes
+* ----- ------ -------- ----------------------------------------------
+* 1.00	drg/jz 01/12/10 First Release
+* 1.05a hk     08/22/13 Added reset function
+* 3.00  kvn    02/13/15 Modified code for MISRA-C:2012 compliance.
+* 
+* +*****************************************************************************/ + +/***************************** Include Files ********************************/ +#include "xuartps_hw.h" + +/************************** Constant Definitions ****************************/ + + +/***************** Macros (Inline Functions) Definitions ********************/ + + +/************************** Function Prototypes ******************************/ + + +/************************** Variable Definitions *****************************/ + +/****************************************************************************/ +/** +* +* This function sends one byte using the device. This function operates in +* polled mode and blocks until the data has been put into the TX FIFO register. +* +* @param BaseAddress contains the base address of the device. +* @param Data contains the byte to be sent. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XUartPs_SendByte(u32 BaseAddress, u8 Data) +{ + /* Wait until there is space in TX FIFO */ + while (XUartPs_IsTransmitFull(BaseAddress)) { + ; + } + + /* Write the byte into the TX FIFO */ + XUartPs_WriteReg(BaseAddress, XUARTPS_FIFO_OFFSET, (u32)Data); +} + +/****************************************************************************/ +/** +* +* This function receives a byte from the device. It operates in polled mode +* and blocks until a byte has received. +* +* @param BaseAddress contains the base address of the device. +* +* @return The data byte received. +* +* @note None. +* +*****************************************************************************/ +u8 XUartPs_RecvByte(u32 BaseAddress) +{ + u32 RecievedByte; + /* Wait until there is data */ + while (!XUartPs_IsReceiveData(BaseAddress)) { + ; + } + RecievedByte = XUartPs_ReadReg(BaseAddress, XUARTPS_FIFO_OFFSET); + /* Return the byte received */ + return (u8)RecievedByte; +} + +/****************************************************************************/ +/** +* +* This function resets UART +* +* @param BaseAddress contains the base address of the device. +* +* @return None +* +* @note None. +* +*****************************************************************************/ +void XUartPs_ResetHw(u32 BaseAddress) +{ + + /* Disable interrupts */ + XUartPs_WriteReg(BaseAddress, XUARTPS_IDR_OFFSET, XUARTPS_IXR_MASK); + + /* Disable receive and transmit */ + XUartPs_WriteReg(BaseAddress, XUARTPS_CR_OFFSET, + ((u32)XUARTPS_CR_RX_DIS | (u32)XUARTPS_CR_TX_DIS)); + + /* + * Software reset of receive and transmit + * This clears the FIFO. + */ + XUartPs_WriteReg(BaseAddress, XUARTPS_CR_OFFSET, + ((u32)XUARTPS_CR_TXRST | (u32)XUARTPS_CR_RXRST)); + + /* Clear status flags - SW reset wont clear sticky flags. */ + XUartPs_WriteReg(BaseAddress, XUARTPS_ISR_OFFSET, XUARTPS_IXR_MASK); + + /* + * Mode register reset value : All zeroes + * Normal mode, even parity, 1 stop bit + */ + XUartPs_WriteReg(BaseAddress, XUARTPS_MR_OFFSET, + XUARTPS_MR_CHMODE_NORM); + + /* Rx and TX trigger register reset values */ + XUartPs_WriteReg(BaseAddress, XUARTPS_RXWM_OFFSET, + XUARTPS_RXWM_RESET_VAL); + XUartPs_WriteReg(BaseAddress, XUARTPS_TXWM_OFFSET, + XUARTPS_TXWM_RESET_VAL); + + /* Rx timeout disabled by default */ + XUartPs_WriteReg(BaseAddress, XUARTPS_RXTOUT_OFFSET, + XUARTPS_RXTOUT_DISABLE); + + /* Baud rate generator and dividor reset values */ + XUartPs_WriteReg(BaseAddress, XUARTPS_BAUDGEN_OFFSET, + XUARTPS_BAUDGEN_RESET_VAL); + XUartPs_WriteReg(BaseAddress, XUARTPS_BAUDDIV_OFFSET, + XUARTPS_BAUDDIV_RESET_VAL); + + /* + * Control register reset value - + * RX and TX are disable by default + */ + XUartPs_WriteReg(BaseAddress, XUARTPS_CR_OFFSET, + ((u32)XUARTPS_CR_RX_DIS | (u32)XUARTPS_CR_TX_DIS | + (u32)XUARTPS_CR_STOPBRK)); + +} +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_hw.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_hw.h new file mode 100644 index 0000000..8c46ecf --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_hw.h @@ -0,0 +1,447 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2017 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xuartps_hw.h +* @addtogroup uartps_v3_5 +* @{ +* +* This header file contains the hardware interface of an XUartPs device. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date	Changes
+* ----- ------ -------- ----------------------------------------------
+* 1.00	drg/jz 01/12/10 First Release
+* 1.03a sg     09/04/12 Added defines for XUARTPS_IXR_TOVR,  XUARTPS_IXR_TNFUL
+*			and XUARTPS_IXR_TTRIG.
+*			Modified the names of these defines
+*			XUARTPS_MEDEMSR_DCDX to XUARTPS_MODEMSR_DDCD
+*			XUARTPS_MEDEMSR_RIX to XUARTPS_MODEMSR_TERI
+*			XUARTPS_MEDEMSR_DSRX to XUARTPS_MODEMSR_DDSR
+*			XUARTPS_MEDEMSR_CTSX to XUARTPS_MODEMSR_DCTS
+* 1.05a hk     08/22/13 Added prototype for uart reset and related
+*			constant definitions.
+* 3.00  kvn    02/13/15 Modified code for MISRA-C:2012 compliance.
+* 3.1	kvn    04/10/15 Modified code for latest RTL changes.
+* 3.6   ms     02/16/18 Updates flow control mode offset value in
+*			modem control register.
+*
+* 
+* +******************************************************************************/ +#ifndef XUARTPS_HW_H /* prevent circular inclusions */ +#define XUARTPS_HW_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +#include "xil_types.h" +#include "xil_assert.h" +#include "xil_io.h" + +/************************** Constant Definitions *****************************/ + +/** @name Register Map + * + * Register offsets for the UART. + * @{ + */ +#define XUARTPS_CR_OFFSET 0x0000U /**< Control Register [8:0] */ +#define XUARTPS_MR_OFFSET 0x0004U /**< Mode Register [9:0] */ +#define XUARTPS_IER_OFFSET 0x0008U /**< Interrupt Enable [12:0] */ +#define XUARTPS_IDR_OFFSET 0x000CU /**< Interrupt Disable [12:0] */ +#define XUARTPS_IMR_OFFSET 0x0010U /**< Interrupt Mask [12:0] */ +#define XUARTPS_ISR_OFFSET 0x0014U /**< Interrupt Status [12:0]*/ +#define XUARTPS_BAUDGEN_OFFSET 0x0018U /**< Baud Rate Generator [15:0] */ +#define XUARTPS_RXTOUT_OFFSET 0x001CU /**< RX Timeout [7:0] */ +#define XUARTPS_RXWM_OFFSET 0x0020U /**< RX FIFO Trigger Level [5:0] */ +#define XUARTPS_MODEMCR_OFFSET 0x0024U /**< Modem Control [5:0] */ +#define XUARTPS_MODEMSR_OFFSET 0x0028U /**< Modem Status [8:0] */ +#define XUARTPS_SR_OFFSET 0x002CU /**< Channel Status [14:0] */ +#define XUARTPS_FIFO_OFFSET 0x0030U /**< FIFO [7:0] */ +#define XUARTPS_BAUDDIV_OFFSET 0x0034U /**< Baud Rate Divider [7:0] */ +#define XUARTPS_FLOWDEL_OFFSET 0x0038U /**< Flow Delay [5:0] */ +#define XUARTPS_TXWM_OFFSET 0x0044U /**< TX FIFO Trigger Level [5:0] */ +#define XUARTPS_RXBS_OFFSET 0x0048U /**< RX FIFO Byte Status [11:0] */ +/* @} */ + +/** @name Control Register + * + * The Control register (CR) controls the major functions of the device. + * + * Control Register Bit Definition + */ + +#define XUARTPS_CR_STOPBRK 0x00000100U /**< Stop transmission of break */ +#define XUARTPS_CR_STARTBRK 0x00000080U /**< Set break */ +#define XUARTPS_CR_TORST 0x00000040U /**< RX timeout counter restart */ +#define XUARTPS_CR_TX_DIS 0x00000020U /**< TX disabled. */ +#define XUARTPS_CR_TX_EN 0x00000010U /**< TX enabled */ +#define XUARTPS_CR_RX_DIS 0x00000008U /**< RX disabled. */ +#define XUARTPS_CR_RX_EN 0x00000004U /**< RX enabled */ +#define XUARTPS_CR_EN_DIS_MASK 0x0000003CU /**< Enable/disable Mask */ +#define XUARTPS_CR_TXRST 0x00000002U /**< TX logic reset */ +#define XUARTPS_CR_RXRST 0x00000001U /**< RX logic reset */ +/* @}*/ + + +/** @name Mode Register + * + * The mode register (MR) defines the mode of transfer as well as the data + * format. If this register is modified during transmission or reception, + * data validity cannot be guaranteed. + * + * Mode Register Bit Definition + * @{ + */ +#define XUARTPS_MR_CCLK 0x00000400U /**< Input clock selection */ +#define XUARTPS_MR_CHMODE_R_LOOP 0x00000300U /**< Remote loopback mode */ +#define XUARTPS_MR_CHMODE_L_LOOP 0x00000200U /**< Local loopback mode */ +#define XUARTPS_MR_CHMODE_ECHO 0x00000100U /**< Auto echo mode */ +#define XUARTPS_MR_CHMODE_NORM 0x00000000U /**< Normal mode */ +#define XUARTPS_MR_CHMODE_SHIFT 8U /**< Mode shift */ +#define XUARTPS_MR_CHMODE_MASK 0x00000300U /**< Mode mask */ +#define XUARTPS_MR_STOPMODE_2_BIT 0x00000080U /**< 2 stop bits */ +#define XUARTPS_MR_STOPMODE_1_5_BIT 0x00000040U /**< 1.5 stop bits */ +#define XUARTPS_MR_STOPMODE_1_BIT 0x00000000U /**< 1 stop bit */ +#define XUARTPS_MR_STOPMODE_SHIFT 6U /**< Stop bits shift */ +#define XUARTPS_MR_STOPMODE_MASK 0x000000A0U /**< Stop bits mask */ +#define XUARTPS_MR_PARITY_NONE 0x00000020U /**< No parity mode */ +#define XUARTPS_MR_PARITY_MARK 0x00000018U /**< Mark parity mode */ +#define XUARTPS_MR_PARITY_SPACE 0x00000010U /**< Space parity mode */ +#define XUARTPS_MR_PARITY_ODD 0x00000008U /**< Odd parity mode */ +#define XUARTPS_MR_PARITY_EVEN 0x00000000U /**< Even parity mode */ +#define XUARTPS_MR_PARITY_SHIFT 3U /**< Parity setting shift */ +#define XUARTPS_MR_PARITY_MASK 0x00000038U /**< Parity mask */ +#define XUARTPS_MR_CHARLEN_6_BIT 0x00000006U /**< 6 bits data */ +#define XUARTPS_MR_CHARLEN_7_BIT 0x00000004U /**< 7 bits data */ +#define XUARTPS_MR_CHARLEN_8_BIT 0x00000000U /**< 8 bits data */ +#define XUARTPS_MR_CHARLEN_SHIFT 1U /**< Data Length shift */ +#define XUARTPS_MR_CHARLEN_MASK 0x00000006U /**< Data length mask */ +#define XUARTPS_MR_CLKSEL 0x00000001U /**< Input clock selection */ +/* @} */ + + +/** @name Interrupt Registers + * + * Interrupt control logic uses the interrupt enable register (IER) and the + * interrupt disable register (IDR) to set the value of the bits in the + * interrupt mask register (IMR). The IMR determines whether to pass an + * interrupt to the interrupt status register (ISR). + * Writing a 1 to IER Enbables an interrupt, writing a 1 to IDR disables an + * interrupt. IMR and ISR are read only, and IER and IDR are write only. + * Reading either IER or IDR returns 0x00. + * + * All four registers have the same bit definitions. + * + * @{ + */ +#define XUARTPS_IXR_RBRK 0x00002000U /**< Rx FIFO break detect interrupt */ +#define XUARTPS_IXR_TOVR 0x00001000U /**< Tx FIFO Overflow interrupt */ +#define XUARTPS_IXR_TNFUL 0x00000800U /**< Tx FIFO Nearly Full interrupt */ +#define XUARTPS_IXR_TTRIG 0x00000400U /**< Tx Trig interrupt */ +#define XUARTPS_IXR_DMS 0x00000200U /**< Modem status change interrupt */ +#define XUARTPS_IXR_TOUT 0x00000100U /**< Timeout error interrupt */ +#define XUARTPS_IXR_PARITY 0x00000080U /**< Parity error interrupt */ +#define XUARTPS_IXR_FRAMING 0x00000040U /**< Framing error interrupt */ +#define XUARTPS_IXR_OVER 0x00000020U /**< Overrun error interrupt */ +#define XUARTPS_IXR_TXFULL 0x00000010U /**< TX FIFO full interrupt. */ +#define XUARTPS_IXR_TXEMPTY 0x00000008U /**< TX FIFO empty interrupt. */ +#define XUARTPS_IXR_RXFULL 0x00000004U /**< RX FIFO full interrupt. */ +#define XUARTPS_IXR_RXEMPTY 0x00000002U /**< RX FIFO empty interrupt. */ +#define XUARTPS_IXR_RXOVR 0x00000001U /**< RX FIFO trigger interrupt. */ +#define XUARTPS_IXR_MASK 0x00003FFFU /**< Valid bit mask */ +/* @} */ + + +/** @name Baud Rate Generator Register + * + * The baud rate generator control register (BRGR) is a 16 bit register that + * controls the receiver bit sample clock and baud rate. + * Valid values are 1 - 65535. + * + * Bit Sample Rate = CCLK / BRGR, where the CCLK is selected by the MR_CCLK bit + * in the MR register. + * @{ + */ +#define XUARTPS_BAUDGEN_DISABLE 0x00000000U /**< Disable clock */ +#define XUARTPS_BAUDGEN_MASK 0x0000FFFFU /**< Valid bits mask */ +#define XUARTPS_BAUDGEN_RESET_VAL 0x0000028BU /**< Reset value */ + +/** @name Baud Divisor Rate register + * + * The baud rate divider register (BDIV) controls how much the bit sample + * rate is divided by. It sets the baud rate. + * Valid values are 0x04 to 0xFF. Writing a value less than 4 will be ignored. + * + * Baud rate = CCLK / ((BAUDDIV + 1) x BRGR), where the CCLK is selected by + * the MR_CCLK bit in the MR register. + * @{ + */ +#define XUARTPS_BAUDDIV_MASK 0x000000FFU /**< 8 bit baud divider mask */ +#define XUARTPS_BAUDDIV_RESET_VAL 0x0000000FU /**< Reset value */ +/* @} */ + + +/** @name Receiver Timeout Register + * + * Use the receiver timeout register (RTR) to detect an idle condition on + * the receiver data line. + * + * @{ + */ +#define XUARTPS_RXTOUT_DISABLE 0x00000000U /**< Disable time out */ +#define XUARTPS_RXTOUT_MASK 0x000000FFU /**< Valid bits mask */ + +/** @name Receiver FIFO Trigger Level Register + * + * Use the Receiver FIFO Trigger Level Register (RTRIG) to set the value at + * which the RX FIFO triggers an interrupt event. + * @{ + */ + +#define XUARTPS_RXWM_DISABLE 0x00000000U /**< Disable RX trigger interrupt */ +#define XUARTPS_RXWM_MASK 0x0000003FU /**< Valid bits mask */ +#define XUARTPS_RXWM_RESET_VAL 0x00000020U /**< Reset value */ +/* @} */ + +/** @name Transmit FIFO Trigger Level Register + * + * Use the Transmit FIFO Trigger Level Register (TTRIG) to set the value at + * which the TX FIFO triggers an interrupt event. + * @{ + */ + +#define XUARTPS_TXWM_MASK 0x0000003FU /**< Valid bits mask */ +#define XUARTPS_TXWM_RESET_VAL 0x00000020U /**< Reset value */ +/* @} */ + +/** @name Modem Control Register + * + * This register (MODEMCR) controls the interface with the modem or data set, + * or a peripheral device emulating a modem. + * + * @{ + */ +#define XUARTPS_MODEMCR_FCM 0x00000020U /**< Flow control mode */ +#define XUARTPS_MODEMCR_RTS 0x00000002U /**< Request to send */ +#define XUARTPS_MODEMCR_DTR 0x00000001U /**< Data terminal ready */ +/* @} */ + +/** @name Modem Status Register + * + * This register (MODEMSR) indicates the current state of the control lines + * from a modem, or another peripheral device, to the CPU. In addition, four + * bits of the modem status register provide change information. These bits + * are set to a logic 1 whenever a control input from the modem changes state. + * + * Note: Whenever the DCTS, DDSR, TERI, or DDCD bit is set to logic 1, a modem + * status interrupt is generated and this is reflected in the modem status + * register. + * + * @{ + */ +#define XUARTPS_MODEMSR_FCMS 0x00000100U /**< Flow control mode (FCMS) */ +#define XUARTPS_MODEMSR_DCD 0x00000080U /**< Complement of DCD input */ +#define XUARTPS_MODEMSR_RI 0x00000040U /**< Complement of RI input */ +#define XUARTPS_MODEMSR_DSR 0x00000020U /**< Complement of DSR input */ +#define XUARTPS_MODEMSR_CTS 0x00000010U /**< Complement of CTS input */ +#define XUARTPS_MODEMSR_DDCD 0x00000008U /**< Delta DCD indicator */ +#define XUARTPS_MODEMSR_TERI 0x00000004U /**< Trailing Edge Ring Indicator */ +#define XUARTPS_MODEMSR_DDSR 0x00000002U /**< Change of DSR */ +#define XUARTPS_MODEMSR_DCTS 0x00000001U /**< Change of CTS */ +/* @} */ + +/** @name Channel Status Register + * + * The channel status register (CSR) is provided to enable the control logic + * to monitor the status of bits in the channel interrupt status register, + * even if these are masked out by the interrupt mask register. + * + * @{ + */ +#define XUARTPS_SR_TNFUL 0x00004000U /**< TX FIFO Nearly Full Status */ +#define XUARTPS_SR_TTRIG 0x00002000U /**< TX FIFO Trigger Status */ +#define XUARTPS_SR_FLOWDEL 0x00001000U /**< RX FIFO fill over flow delay */ +#define XUARTPS_SR_TACTIVE 0x00000800U /**< TX active */ +#define XUARTPS_SR_RACTIVE 0x00000400U /**< RX active */ +#define XUARTPS_SR_TXFULL 0x00000010U /**< TX FIFO full */ +#define XUARTPS_SR_TXEMPTY 0x00000008U /**< TX FIFO empty */ +#define XUARTPS_SR_RXFULL 0x00000004U /**< RX FIFO full */ +#define XUARTPS_SR_RXEMPTY 0x00000002U /**< RX FIFO empty */ +#define XUARTPS_SR_RXOVR 0x00000001U /**< RX FIFO fill over trigger */ +/* @} */ + +/** @name Flow Delay Register + * + * Operation of the flow delay register (FLOWDEL) is very similar to the + * receive FIFO trigger register. An internal trigger signal activates when the + * FIFO is filled to the level set by this register. This trigger will not + * cause an interrupt, although it can be read through the channel status + * register. In hardware flow control mode, RTS is deactivated when the trigger + * becomes active. RTS only resets when the FIFO level is four less than the + * level of the flow delay trigger and the flow delay trigger is not activated. + * A value less than 4 disables the flow delay. + * @{ + */ +#define XUARTPS_FLOWDEL_MASK XUARTPS_RXWM_MASK /**< Valid bit mask */ +/* @} */ + +/** @name Receiver FIFO Byte Status Register + * + * The Receiver FIFO Status register is used to have a continuous + * monitoring of the raw unmasked byte status information. The register + * contains frame, parity and break status information for the top + * four bytes in the RX FIFO. + * + * Receiver FIFO Byte Status Register Bit Definition + * @{ + */ +#define XUARTPS_RXBS_BYTE3_BRKE 0x00000800U /**< Byte3 Break Error */ +#define XUARTPS_RXBS_BYTE3_FRME 0x00000400U /**< Byte3 Frame Error */ +#define XUARTPS_RXBS_BYTE3_PARE 0x00000200U /**< Byte3 Parity Error */ +#define XUARTPS_RXBS_BYTE2_BRKE 0x00000100U /**< Byte2 Break Error */ +#define XUARTPS_RXBS_BYTE2_FRME 0x00000080U /**< Byte2 Frame Error */ +#define XUARTPS_RXBS_BYTE2_PARE 0x00000040U /**< Byte2 Parity Error */ +#define XUARTPS_RXBS_BYTE1_BRKE 0x00000020U /**< Byte1 Break Error */ +#define XUARTPS_RXBS_BYTE1_FRME 0x00000010U /**< Byte1 Frame Error */ +#define XUARTPS_RXBS_BYTE1_PARE 0x00000008U /**< Byte1 Parity Error */ +#define XUARTPS_RXBS_BYTE0_BRKE 0x00000004U /**< Byte0 Break Error */ +#define XUARTPS_RXBS_BYTE0_FRME 0x00000002U /**< Byte0 Frame Error */ +#define XUARTPS_RXBS_BYTE0_PARE 0x00000001U /**< Byte0 Parity Error */ +#define XUARTPS_RXBS_MASK 0x00000007U /**< 3 bit RX byte status mask */ +/* @} */ + + +/* + * Defines for backwards compatabilty, will be removed + * in the next version of the driver + */ +#define XUARTPS_MEDEMSR_DCDX XUARTPS_MODEMSR_DDCD +#define XUARTPS_MEDEMSR_RIX XUARTPS_MODEMSR_TERI +#define XUARTPS_MEDEMSR_DSRX XUARTPS_MODEMSR_DDSR +#define XUARTPS_MEDEMSR_CTSX XUARTPS_MODEMSR_DCTS + + + +/**************************** Type Definitions *******************************/ + + +/***************** Macros (Inline Functions) Definitions *********************/ + +/****************************************************************************/ +/** +* Read a UART register. +* +* @param BaseAddress contains the base address of the device. +* @param RegOffset contains the offset from the base address of the +* device. +* +* @return The value read from the register. +* +* @note C-Style signature: +* u32 XUartPs_ReadReg(u32 BaseAddress, int RegOffset) +* +******************************************************************************/ +#define XUartPs_ReadReg(BaseAddress, RegOffset) \ + Xil_In32((BaseAddress) + (u32)(RegOffset)) + +/***************************************************************************/ +/** +* Write a UART register. +* +* @param BaseAddress contains the base address of the device. +* @param RegOffset contains the offset from the base address of the +* device. +* @param RegisterValue is the value to be written to the register. +* +* @return None. +* +* @note C-Style signature: +* void XUartPs_WriteReg(u32 BaseAddress, int RegOffset, +* u16 RegisterValue) +* +******************************************************************************/ +#define XUartPs_WriteReg(BaseAddress, RegOffset, RegisterValue) \ + Xil_Out32((BaseAddress) + (u32)(RegOffset), (u32)(RegisterValue)) + +/****************************************************************************/ +/** +* Determine if there is receive data in the receiver and/or FIFO. +* +* @param BaseAddress contains the base address of the device. +* +* @return TRUE if there is receive data, FALSE otherwise. +* +* @note C-Style signature: +* u32 XUartPs_IsReceiveData(u32 BaseAddress) +* +******************************************************************************/ +#define XUartPs_IsReceiveData(BaseAddress) \ + !((Xil_In32((BaseAddress) + XUARTPS_SR_OFFSET) & \ + (u32)XUARTPS_SR_RXEMPTY) == (u32)XUARTPS_SR_RXEMPTY) + +/****************************************************************************/ +/** +* Determine if a byte of data can be sent with the transmitter. +* +* @param BaseAddress contains the base address of the device. +* +* @return TRUE if the TX FIFO is full, FALSE if a byte can be put in the +* FIFO. +* +* @note C-Style signature: +* u32 XUartPs_IsTransmitFull(u32 BaseAddress) +* +******************************************************************************/ +#define XUartPs_IsTransmitFull(BaseAddress) \ + ((Xil_In32((BaseAddress) + XUARTPS_SR_OFFSET) & \ + (u32)XUARTPS_SR_TXFULL) == (u32)XUARTPS_SR_TXFULL) + +/************************** Function Prototypes ******************************/ + +void XUartPs_SendByte(u32 BaseAddress, u8 Data); + +u8 XUartPs_RecvByte(u32 BaseAddress); + +void XUartPs_ResetHw(u32 BaseAddress); + +/************************** Variable Definitions *****************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_intr.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_intr.c new file mode 100644 index 0000000..88eed1e --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_intr.c @@ -0,0 +1,447 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xuartps_intr.c +* @addtogroup uartps_v3_5 +* @{ +* +* This file contains the functions for interrupt handling +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date	Changes
+* ----- ------ -------- -----------------------------------------------
+* 1.00  drg/jz 01/13/10 First Release
+* 3.00  kvn    02/13/15 Modified code for MISRA-C:2012 compliance.
+* 3.1	kvn    04/10/15 Modified code for latest RTL changes.
+* 3.7   aru    08/17/18 Resolved MISRA-C mandatory violations.(CR#1007755)
+* 
+* +*****************************************************************************/ + +/***************************** Include Files ********************************/ + +#include "xuartps.h" + +/************************** Constant Definitions ****************************/ + +/**************************** Type Definitions ******************************/ + +/***************** Macros (Inline Functions) Definitions ********************/ + +/************************** Function Prototypes *****************************/ + +static void ReceiveDataHandler(XUartPs *InstancePtr); +static void SendDataHandler(XUartPs *InstancePtr, u32 IsrStatus); +static void ReceiveErrorHandler(XUartPs *InstancePtr, u32 IsrStatus); +static void ReceiveTimeoutHandler(XUartPs *InstancePtr); +static void ModemHandler(XUartPs *InstancePtr); + + +/* Internal function prototypes implemented in xuartps.c */ +extern u32 XUartPs_ReceiveBuffer(XUartPs *InstancePtr); +extern u32 XUartPs_SendBuffer(XUartPs *InstancePtr); + +/************************** Variable Definitions ****************************/ + +typedef void (*Handler)(XUartPs *InstancePtr); + +/****************************************************************************/ +/** +* +* This function gets the interrupt mask +* +* @param InstancePtr is a pointer to the XUartPs instance. +* +* @return +* The current interrupt mask. The mask indicates which interupts +* are enabled. +* +* @note None. +* +*****************************************************************************/ +u32 XUartPs_GetInterruptMask(XUartPs *InstancePtr) +{ + /* Assert validates the input argument */ + Xil_AssertNonvoid(InstancePtr != NULL); + + /* Read the Interrupt Mask register */ + return (XUartPs_ReadReg(InstancePtr->Config.BaseAddress, + XUARTPS_IMR_OFFSET)); +} + +/****************************************************************************/ +/** +* +* This function sets the interrupt mask. +* +* @param InstancePtr is a pointer to the XUartPs instance +* @param Mask contains the interrupts to be enabled or disabled. +* A '1' enables an interupt, and a '0' disables. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XUartPs_SetInterruptMask(XUartPs *InstancePtr, u32 Mask) +{ + u32 TempMask = Mask; + /* Assert validates the input arguments */ + Xil_AssertVoid(InstancePtr != NULL); + + TempMask &= (u32)XUARTPS_IXR_MASK; + + /* Write the mask to the IER Register */ + XUartPs_WriteReg(InstancePtr->Config.BaseAddress, + XUARTPS_IER_OFFSET, TempMask); + + /* Write the inverse of the Mask to the IDR register */ + XUartPs_WriteReg(InstancePtr->Config.BaseAddress, + XUARTPS_IDR_OFFSET, (~TempMask)); + +} + +/****************************************************************************/ +/** +* +* This function sets the handler that will be called when an event (interrupt) +* occurs that needs application's attention. +* +* @param InstancePtr is a pointer to the XUartPs instance +* @param FuncPtr is the pointer to the callback function. +* @param CallBackRef is the upper layer callback reference passed back +* when the callback function is invoked. +* +* @return None. +* +* @note +* +* There is no assert on the CallBackRef since the driver doesn't know what it +* is (nor should it) +* +*****************************************************************************/ +void XUartPs_SetHandler(XUartPs *InstancePtr, XUartPs_Handler FuncPtr, + void *CallBackRef) +{ + /* + * Asserts validate the input arguments + * CallBackRef not checked, no way to know what is valid + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(FuncPtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + InstancePtr->Handler = (XUartPs_Handler)FuncPtr; + InstancePtr->CallBackRef = CallBackRef; +} + +/****************************************************************************/ +/** +* +* This function is the interrupt handler for the driver. +* It must be connected to an interrupt system by the application such that it +* can be called when an interrupt occurs. +* +* @param InstancePtr contains a pointer to the driver instance +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XUartPs_InterruptHandler(XUartPs *InstancePtr) +{ + u32 IsrStatus; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the interrupt ID register to determine which + * interrupt is active + */ + IsrStatus = XUartPs_ReadReg(InstancePtr->Config.BaseAddress, + XUARTPS_IMR_OFFSET); + + IsrStatus &= XUartPs_ReadReg(InstancePtr->Config.BaseAddress, + XUARTPS_ISR_OFFSET); + + /* Dispatch an appropriate handler. */ + if((IsrStatus & ((u32)XUARTPS_IXR_RXOVR | (u32)XUARTPS_IXR_RXEMPTY | + (u32)XUARTPS_IXR_RXFULL)) != (u32)0) { + /* Received data interrupt */ + ReceiveDataHandler(InstancePtr); + } + + if((IsrStatus & ((u32)XUARTPS_IXR_TXEMPTY | (u32)XUARTPS_IXR_TXFULL)) + != (u32)0) { + /* Transmit data interrupt */ + SendDataHandler(InstancePtr, IsrStatus); + } + + /* XUARTPS_IXR_RBRK is applicable only for Zynq Ultrascale+ MP */ + if ((IsrStatus & ((u32)XUARTPS_IXR_OVER | (u32)XUARTPS_IXR_FRAMING | + (u32)XUARTPS_IXR_PARITY | (u32)XUARTPS_IXR_RBRK)) != (u32)0) { + /* Received Error Status interrupt */ + ReceiveErrorHandler(InstancePtr, IsrStatus); + } + + if((IsrStatus & ((u32)XUARTPS_IXR_TOUT)) != (u32)0) { + /* Received Timeout interrupt */ + ReceiveTimeoutHandler(InstancePtr); + } + + if((IsrStatus & ((u32)XUARTPS_IXR_DMS)) != (u32)0) { + /* Modem status interrupt */ + ModemHandler(InstancePtr); + } + + /* Clear the interrupt status. */ + XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_ISR_OFFSET, + IsrStatus); + +} + +/****************************************************************************/ +/* +* +* This function handles interrupts for receive errors which include +* overrun errors, framing errors, parity errors, and the break interrupt. +* +* @param InstancePtr is a pointer to the XUartPs instance. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +static void ReceiveErrorHandler(XUartPs *InstancePtr, u32 IsrStatus) +{ + u32 EventData; + u32 Event; + + InstancePtr->is_rxbs_error = 0; + + if ((InstancePtr->Platform == XPLAT_ZYNQ_ULTRA_MP) && + (IsrStatus & ((u32)XUARTPS_IXR_PARITY | (u32)XUARTPS_IXR_RBRK + | (u32)XUARTPS_IXR_FRAMING))) { + InstancePtr->is_rxbs_error = 1; + } + /* + * If there are bytes still to be received in the specified buffer + * go ahead and receive them. Removing bytes from the RX FIFO will + * clear the interrupt. + */ + + (void)XUartPs_ReceiveBuffer(InstancePtr); + + if (!(InstancePtr->is_rxbs_error)) { + Event = XUARTPS_EVENT_RECV_ERROR; + EventData = InstancePtr->ReceiveBuffer.RequestedBytes - + InstancePtr->ReceiveBuffer.RemainingBytes; + + /* + * Call the application handler to indicate that there is a receive + * error or a break interrupt, if the application cares about the + * error it call a function to get the last errors. + */ + InstancePtr->Handler(InstancePtr->CallBackRef, + Event, + EventData); + } +} + +/****************************************************************************/ +/** +* +* This function handles the receive timeout interrupt. This interrupt occurs +* whenever a number of bytes have been present in the RX FIFO and the receive +* data line has been idle for at lease 4 or more character times, (the timeout +* is set using XUartPs_SetrecvTimeout() function). +* +* @param InstancePtr is a pointer to the XUartPs instance +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +static void ReceiveTimeoutHandler(XUartPs *InstancePtr) +{ + u32 Event; + + /* + * If there are bytes still to be received in the specified buffer + * go ahead and receive them. Removing bytes from the RX FIFO will + * clear the interrupt. + */ + if (InstancePtr->ReceiveBuffer.RemainingBytes != (u32)0) { + (void)XUartPs_ReceiveBuffer(InstancePtr); + } + + /* + * If there are no more bytes to receive then indicate that this is + * not a receive timeout but the end of the buffer reached, a timeout + * normally occurs if # of bytes is not divisible by FIFO threshold, + * don't rely on previous test of remaining bytes since receive + * function updates it + */ + if (InstancePtr->ReceiveBuffer.RemainingBytes != (u32)0) { + Event = XUARTPS_EVENT_RECV_TOUT; + } else { + Event = XUARTPS_EVENT_RECV_DATA; + } + + /* + * Call the application handler to indicate that there is a receive + * timeout or data event + */ + InstancePtr->Handler(InstancePtr->CallBackRef, Event, + InstancePtr->ReceiveBuffer.RequestedBytes - + InstancePtr->ReceiveBuffer.RemainingBytes); + +} +/****************************************************************************/ +/** +* +* This function handles the interrupt when data is in RX FIFO. +* +* @param InstancePtr is a pointer to the XUartPs instance +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +static void ReceiveDataHandler(XUartPs *InstancePtr) +{ + /* + * If there are bytes still to be received in the specified buffer + * go ahead and receive them. Removing bytes from the RX FIFO will + * clear the interrupt. + */ + if (InstancePtr->ReceiveBuffer.RemainingBytes != (u32)0) { + (void)XUartPs_ReceiveBuffer(InstancePtr); + } + + /* If the last byte of a message was received then call the application + * handler, this code should not use an else from the previous check of + * the number of bytes to receive because the call to receive the buffer + * updates the bytes ramained + */ + if (InstancePtr->ReceiveBuffer.RemainingBytes == (u32)0) { + InstancePtr->Handler(InstancePtr->CallBackRef, + XUARTPS_EVENT_RECV_DATA, + (InstancePtr->ReceiveBuffer.RequestedBytes - + InstancePtr->ReceiveBuffer.RemainingBytes)); + } + +} + +/****************************************************************************/ +/** +* +* This function handles the interrupt when data has been sent, the transmit +* FIFO is empty (transmitter holding register). +* +* @param InstancePtr is a pointer to the XUartPs instance +* @param IsrStatus is the register value for channel status register +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +static void SendDataHandler(XUartPs *InstancePtr, u32 IsrStatus) +{ + + /* + * If there are not bytes to be sent from the specified buffer then disable + * the transmit interrupt so it will stop interrupting as it interrupts + * any time the FIFO is empty + */ + if (InstancePtr->SendBuffer.RemainingBytes == (u32)0) { + XUartPs_WriteReg(InstancePtr->Config.BaseAddress, + XUARTPS_IDR_OFFSET, + ((u32)XUARTPS_IXR_TXEMPTY | (u32)XUARTPS_IXR_TXFULL)); + + /* Call the application handler to indicate the sending is done */ + InstancePtr->Handler(InstancePtr->CallBackRef, + XUARTPS_EVENT_SENT_DATA, + InstancePtr->SendBuffer.RequestedBytes - + InstancePtr->SendBuffer.RemainingBytes); + } + + /* If TX FIFO is empty, send more. */ + else if((IsrStatus & ((u32)XUARTPS_IXR_TXEMPTY)) != (u32)0) { + (void)XUartPs_SendBuffer(InstancePtr); + } + else { + /* Else with dummy entry for MISRA-C Compliance.*/ + ; + } +} + +/****************************************************************************/ +/** +* +* This function handles modem interrupts. It does not do any processing +* except to call the application handler to indicate a modem event. +* +* @param InstancePtr is a pointer to the XUartPs instance +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +static void ModemHandler(XUartPs *InstancePtr) +{ + u32 MsrRegister; + + /* + * Read the modem status register so that the interrupt is acknowledged + * and it can be passed to the callback handler with the event + */ + MsrRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress, + XUARTPS_MODEMSR_OFFSET); + + /* + * Call the application handler to indicate the modem status changed, + * passing the modem status and the event data in the call + */ + InstancePtr->Handler(InstancePtr->CallBackRef, + XUARTPS_EVENT_MODEM, + MsrRegister); + +} +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_options.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_options.c new file mode 100644 index 0000000..ee0db5f --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_options.c @@ -0,0 +1,760 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xuartps_options.c +* @addtogroup uartps_v3_5 +* @{ +* +* The implementation of the options functions for the XUartPs driver. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date	Changes
+* ----- ------ -------- -----------------------------------------------
+* 1.00  drg/jz 01/13/10 First Release
+* 1.00  sdm    09/27/11 Fixed a bug in XUartPs_SetFlowDelay where the input
+*			value was not being written to the register.
+* 3.00  kvn    02/13/15 Modified code for MISRA-C:2012 compliance.
+* 3.2   rk     07/20/16 Modified the logic for transmission break bit set
+*
+* 
+* +*****************************************************************************/ + +/***************************** Include Files ********************************/ + +#include "xuartps.h" + +/************************** Constant Definitions ****************************/ + +/**************************** Type Definitions ******************************/ + +/***************** Macros (Inline Functions) Definitions ********************/ + +/************************** Variable Definitions ****************************/ +/* + * The following data type is a map from an option to the offset in the + * register to which it belongs as well as its bit mask in that register. + */ +typedef struct { + u16 Option; + u16 RegisterOffset; + u32 Mask; +} Mapping; + +/* + * Create the table which contains options which are to be processed to get/set + * the options. These options are table driven to allow easy maintenance and + * expansion of the options. + */ + +static Mapping OptionsTable[] = { + {XUARTPS_OPTION_SET_BREAK, XUARTPS_CR_OFFSET, XUARTPS_CR_STARTBRK}, + {XUARTPS_OPTION_STOP_BREAK, XUARTPS_CR_OFFSET, XUARTPS_CR_STOPBRK}, + {XUARTPS_OPTION_RESET_TMOUT, XUARTPS_CR_OFFSET, XUARTPS_CR_TORST}, + {XUARTPS_OPTION_RESET_TX, XUARTPS_CR_OFFSET, XUARTPS_CR_TXRST}, + {XUARTPS_OPTION_RESET_RX, XUARTPS_CR_OFFSET, XUARTPS_CR_RXRST}, + {XUARTPS_OPTION_ASSERT_RTS, XUARTPS_MODEMCR_OFFSET, + XUARTPS_MODEMCR_RTS}, + {XUARTPS_OPTION_ASSERT_DTR, XUARTPS_MODEMCR_OFFSET, + XUARTPS_MODEMCR_DTR}, + {XUARTPS_OPTION_SET_FCM, XUARTPS_MODEMCR_OFFSET, XUARTPS_MODEMCR_FCM} +}; + +/* Create a constant for the number of entries in the table */ + +#define XUARTPS_NUM_OPTIONS (sizeof(OptionsTable) / sizeof(Mapping)) + +/************************** Function Prototypes *****************************/ + +/****************************************************************************/ +/** +* +* Gets the options for the specified driver instance. The options are +* implemented as bit masks such that multiple options may be enabled or +* disabled simulataneously. +* +* @param InstancePtr is a pointer to the XUartPs instance. +* +* @return +* +* The current options for the UART. The optionss are bit masks that are +* contained in the file xuartps.h and named XUARTPS_OPTION_*. +* +* @note None. +* +*****************************************************************************/ +u16 XUartPs_GetOptions(XUartPs *InstancePtr) +{ + u16 Options = 0U; + u32 Register; + u32 Index; + + /* Assert validates the input arguments */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Loop thru the options table to map the physical options in the + * registers of the UART to the logical options to be returned + */ + for (Index = 0U; Index < XUARTPS_NUM_OPTIONS; Index++) { + Register = XUartPs_ReadReg(InstancePtr->Config.BaseAddress, + OptionsTable[Index]. + RegisterOffset); + + /* + * If the bit in the register which correlates to the option + * is set, then set the corresponding bit in the options, + * ignoring any bits which are zero since the options variable + * is initialized to zero + */ + if ((Register & OptionsTable[Index].Mask) != (u32)0) { + Options |= OptionsTable[Index].Option; + } + } + + return Options; +} + +/****************************************************************************/ +/** +* +* Sets the options for the specified driver instance. The options are +* implemented as bit masks such that multiple options may be enabled or +* disabled simultaneously. +* +* The GetOptions function may be called to retrieve the currently enabled +* options. The result is ORed in the desired new settings to be enabled and +* ANDed with the inverse to clear the settings to be disabled. The resulting +* value is then used as the options for the SetOption function call. +* +* @param InstancePtr is a pointer to the XUartPs instance. +* @param Options contains the options to be set which are bit masks +* contained in the file xuartps.h and named XUARTPS_OPTION_*. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XUartPs_SetOptions(XUartPs *InstancePtr, u16 Options) +{ + u32 Index; + u32 Register; + + /* Assert validates the input arguments */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Loop thru the options table to map the logical options to the + * physical options in the registers of the UART. + */ + for (Index = 0U; Index < XUARTPS_NUM_OPTIONS; Index++) { + + /* + * Read the register which contains option so that the register + * can be changed without destoying any other bits of the + * register. + */ + Register = XUartPs_ReadReg(InstancePtr->Config.BaseAddress, + OptionsTable[Index]. + RegisterOffset); + + /* + * If the option is set in the input, then set the corresponding + * bit in the specified register, otherwise clear the bit in + * the register. + */ + if ((Options & OptionsTable[Index].Option) != (u16)0) { + if(OptionsTable[Index].Option == XUARTPS_OPTION_SET_BREAK) + Register &= ~XUARTPS_CR_STOPBRK; + Register |= OptionsTable[Index].Mask; + } + else { + Register &= ~OptionsTable[Index].Mask; + } + + /* Write the new value to the register to set the option */ + XUartPs_WriteReg(InstancePtr->Config.BaseAddress, + OptionsTable[Index].RegisterOffset, + Register); + } + +} + +/****************************************************************************/ +/** +* +* This function gets the receive FIFO trigger level. The receive trigger +* level indicates the number of bytes in the receive FIFO that cause a receive +* data event (interrupt) to be generated. +* +* @param InstancePtr is a pointer to the XUartPs instance. +* +* @return The current receive FIFO trigger level. This is a value +* from 0-31. +* +* @note None. +* +*****************************************************************************/ +u8 XUartPs_GetFifoThreshold(XUartPs *InstancePtr) +{ + u8 RtrigRegister; + + /* Assert validates the input arguments */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the value of the FIFO control register so that the threshold + * can be retrieved, this read takes special register processing + */ + RtrigRegister = (u8) XUartPs_ReadReg(InstancePtr->Config.BaseAddress, + XUARTPS_RXWM_OFFSET); + + /* Return only the trigger level from the register value */ + + RtrigRegister &= (u8)XUARTPS_RXWM_MASK; + return RtrigRegister; +} + +/****************************************************************************/ +/** +* +* This functions sets the receive FIFO trigger level. The receive trigger +* level specifies the number of bytes in the receive FIFO that cause a receive +* data event (interrupt) to be generated. +* +* @param InstancePtr is a pointer to the XUartPs instance. +* @param TriggerLevel contains the trigger level to set. +* +* @return None +* +* @note None. +* +*****************************************************************************/ +void XUartPs_SetFifoThreshold(XUartPs *InstancePtr, u8 TriggerLevel) +{ + u32 RtrigRegister; + + /* Assert validates the input arguments */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(TriggerLevel <= (u8)XUARTPS_RXWM_MASK); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + RtrigRegister = ((u32)TriggerLevel) & (u32)XUARTPS_RXWM_MASK; + + /* + * Write the new value for the FIFO control register to it such that the + * threshold is changed + */ + XUartPs_WriteReg(InstancePtr->Config.BaseAddress, + XUARTPS_RXWM_OFFSET, RtrigRegister); + +} + +/****************************************************************************/ +/** +* +* This function gets the modem status from the specified UART. The modem +* status indicates any changes of the modem signals. This function allows +* the modem status to be read in a polled mode. The modem status is updated +* whenever it is read such that reading it twice may not yield the same +* results. +* +* @param InstancePtr is a pointer to the XUartPs instance. +* +* @return +* +* The modem status which are bit masks that are contained in the file +* xuartps.h and named XUARTPS_MODEM_*. +* +* @note +* +* The bit masks used for the modem status are the exact bits of the modem +* status register with no abstraction. +* +*****************************************************************************/ +u16 XUartPs_GetModemStatus(XUartPs *InstancePtr) +{ + u32 ModemStatusRegister; + u16 TmpRegister; + /* Assert validates the input arguments */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* Read the modem status register to return + */ + ModemStatusRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress, + XUARTPS_MODEMSR_OFFSET); + TmpRegister = (u16)ModemStatusRegister; + return TmpRegister; +} + +/****************************************************************************/ +/** +* +* This function determines if the specified UART is sending data. +* +* @param InstancePtr is a pointer to the XUartPs instance. +* +* @return +* - TRUE if the UART is sending data +* - FALSE if UART is not sending data +* +* @note None. +* +*****************************************************************************/ +u32 XUartPs_IsSending(XUartPs *InstancePtr) +{ + u32 ChanStatRegister; + u32 ChanTmpSRegister; + u32 ActiveResult; + u32 EmptyResult; + + /* Assert validates the input arguments */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the channel status register to determine if the transmitter is + * active + */ + ChanStatRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress, + XUARTPS_SR_OFFSET); + + /* + * If the transmitter is active, or the TX FIFO is not empty, then indicate + * that the UART is still sending some data + */ + ActiveResult = ChanStatRegister & ((u32)XUARTPS_SR_TACTIVE); + EmptyResult = ChanStatRegister & ((u32)XUARTPS_SR_TXEMPTY); + ChanTmpSRegister = (((u32)XUARTPS_SR_TACTIVE) == ActiveResult) || + (((u32)XUARTPS_SR_TXEMPTY) != EmptyResult); + + return ChanTmpSRegister; +} + +/****************************************************************************/ +/** +* +* This function gets the operational mode of the UART. The UART can operate +* in one of four modes: Normal, Local Loopback, Remote Loopback, or automatic +* echo. +* +* @param InstancePtr is a pointer to the XUartPs instance. +* +* @return +* +* The operational mode is specified by constants defined in xuartps.h. The +* constants are named XUARTPS_OPER_MODE_* +* +* @note None. +* +*****************************************************************************/ +u8 XUartPs_GetOperMode(XUartPs *InstancePtr) +{ + u32 ModeRegister; + u8 OperMode; + + /* Assert validates the input arguments */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* Read the Mode register. */ + ModeRegister = + XUartPs_ReadReg(InstancePtr->Config.BaseAddress, + XUARTPS_MR_OFFSET); + + ModeRegister &= (u32)XUARTPS_MR_CHMODE_MASK; + /* Return the constant */ + switch (ModeRegister) { + case XUARTPS_MR_CHMODE_NORM: + OperMode = XUARTPS_OPER_MODE_NORMAL; + break; + case XUARTPS_MR_CHMODE_ECHO: + OperMode = XUARTPS_OPER_MODE_AUTO_ECHO; + break; + case XUARTPS_MR_CHMODE_L_LOOP: + OperMode = XUARTPS_OPER_MODE_LOCAL_LOOP; + break; + case XUARTPS_MR_CHMODE_R_LOOP: + OperMode = XUARTPS_OPER_MODE_REMOTE_LOOP; + break; + default: + OperMode = (u8) ((ModeRegister & (u32)XUARTPS_MR_CHMODE_MASK) >> + XUARTPS_MR_CHMODE_SHIFT); + break; + } + + return OperMode; +} + +/****************************************************************************/ +/** +* +* This function sets the operational mode of the UART. The UART can operate +* in one of four modes: Normal, Local Loopback, Remote Loopback, or automatic +* echo. +* +* @param InstancePtr is a pointer to the XUartPs instance. +* @param OperationMode is the mode of the UART. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XUartPs_SetOperMode(XUartPs *InstancePtr, u8 OperationMode) +{ + u32 ModeRegister; + + /* Assert validates the input arguments. */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid(OperationMode <= XUARTPS_OPER_MODE_REMOTE_LOOP); + + /* Read the Mode register. */ + ModeRegister = + XUartPs_ReadReg(InstancePtr->Config.BaseAddress, + XUARTPS_MR_OFFSET); + + /* Set the correct value by masking the bits, then ORing the const. */ + ModeRegister &= (u32)(~XUARTPS_MR_CHMODE_MASK); + + switch (OperationMode) { + case XUARTPS_OPER_MODE_NORMAL: + ModeRegister |= (u32)XUARTPS_MR_CHMODE_NORM; + break; + case XUARTPS_OPER_MODE_AUTO_ECHO: + ModeRegister |= (u32)XUARTPS_MR_CHMODE_ECHO; + break; + case XUARTPS_OPER_MODE_LOCAL_LOOP: + ModeRegister |= (u32)XUARTPS_MR_CHMODE_L_LOOP; + break; + case XUARTPS_OPER_MODE_REMOTE_LOOP: + ModeRegister |= (u32)XUARTPS_MR_CHMODE_R_LOOP; + break; + default: + /* Default case made for MISRA-C Compliance. */ + break; + } + + XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_MR_OFFSET, + ModeRegister); + +} + +/****************************************************************************/ +/** +* +* This function sets the Flow Delay. +* 0 - 3: Flow delay inactive +* 4 - 32: If Flow Control mode is enabled, UART_rtsN is deactivated when the +* receive FIFO fills to this level. +* +* @param InstancePtr is a pointer to the XUartPs instance. +* +* @return +* +* The Flow Delay is specified by constants defined in xuartps_hw.h. The +* constants are named XUARTPS_FLOWDEL* +* +* @note None. +* +*****************************************************************************/ +u8 XUartPs_GetFlowDelay(XUartPs *InstancePtr) +{ + u32 FdelTmpRegister; + + /* Assert validates the input arguments */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* Read the Mode register. */ + FdelTmpRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress, + XUARTPS_FLOWDEL_OFFSET); + + /* Return the contents of the flow delay register */ + FdelTmpRegister = (u8)(FdelTmpRegister & (u32)XUARTPS_FLOWDEL_MASK); + return FdelTmpRegister; +} + +/****************************************************************************/ +/** +* +* This function sets the Flow Delay. +* 0 - 3: Flow delay inactive +* 4 - 63: If Flow Control mode is enabled, UART_rtsN is deactivated when the +* receive FIFO fills to this level. +* +* @param InstancePtr is a pointer to the XUartPs instance. +* @param FlowDelayValue is the Setting for the flow delay. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XUartPs_SetFlowDelay(XUartPs *InstancePtr, u8 FlowDelayValue) +{ + u32 FdelRegister; + + /* Assert validates the input arguments */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(FlowDelayValue > (u8)XUARTPS_FLOWDEL_MASK); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Set the correct value by shifting the input constant, then masking + * the bits + */ + FdelRegister = ((u32)FlowDelayValue) & (u32)XUARTPS_FLOWDEL_MASK; + + XUartPs_WriteReg(InstancePtr->Config.BaseAddress, + XUARTPS_FLOWDEL_OFFSET, FdelRegister); + +} + +/****************************************************************************/ +/** +* +* This function gets the Receive Timeout of the UART. +* +* @param InstancePtr is a pointer to the XUartPs instance. +* +* @return The current setting for receive time out. +* +* @note None. +* +*****************************************************************************/ +u8 XUartPs_GetRecvTimeout(XUartPs *InstancePtr) +{ + u32 RtoRegister; + u8 RtoRTmpRegister; + + /* Assert validates the input arguments */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* Read the Receive Timeout register. */ + RtoRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress, + XUARTPS_RXTOUT_OFFSET); + + /* Return the contents of the mode register shifted appropriately */ + RtoRTmpRegister = (u8)(RtoRegister & (u32)XUARTPS_RXTOUT_MASK); + return RtoRTmpRegister; +} + +/****************************************************************************/ +/** +* +* This function sets the Receive Timeout of the UART. +* +* @param InstancePtr is a pointer to the XUartPs instance. +* @param RecvTimeout setting allows the UART to detect an idle connection +* on the reciever data line. +* Timeout duration = RecvTimeout x 4 x Bit Period. 0 disables the +* timeout function. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XUartPs_SetRecvTimeout(XUartPs *InstancePtr, u8 RecvTimeout) +{ + u32 RtoRegister; + + /* Assert validates the input arguments */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* Set the correct value by masking the bits */ + RtoRegister = ((u32)RecvTimeout & (u32)XUARTPS_RXTOUT_MASK); + + XUartPs_WriteReg(InstancePtr->Config.BaseAddress, + XUARTPS_RXTOUT_OFFSET, RtoRegister); + + /* Configure CR to restart the receiver timeout counter */ + RtoRegister = + XUartPs_ReadReg(InstancePtr->Config.BaseAddress, + XUARTPS_CR_OFFSET); + XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_CR_OFFSET, + (RtoRegister | XUARTPS_CR_TORST)); + +} +/****************************************************************************/ +/** +* +* Sets the data format for the device. The data format includes the +* baud rate, number of data bits, number of stop bits, and parity. It is the +* caller's responsibility to ensure that the UART is not sending or receiving +* data when this function is called. +* +* @param InstancePtr is a pointer to the XUartPs instance. +* @param FormatPtr is a pointer to a format structure containing the data +* format to be set. +* +* @return +* - XST_SUCCESS if the data format was successfully set. +* - XST_UART_BAUD_ERROR indicates the baud rate could not be +* set because of the amount of error with the baud rate and +* the input clock frequency. +* - XST_INVALID_PARAM if one of the parameters was not valid. +* +* @note +* +* The data types in the format type, data bits and parity, are 32 bit fields +* to prevent a compiler warning. +* The asserts in this function will cause a warning if these fields are +* bytes. +*

+* +*****************************************************************************/ +s32 XUartPs_SetDataFormat(XUartPs *InstancePtr, + XUartPsFormat * FormatPtr) +{ + s32 Status; + u32 ModeRegister; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(FormatPtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* Verify the inputs specified are valid */ + if ((FormatPtr->DataBits > ((u32)XUARTPS_FORMAT_6_BITS)) || + (FormatPtr->StopBits > ((u8)XUARTPS_FORMAT_2_STOP_BIT)) || + (FormatPtr->Parity > ((u32)XUARTPS_FORMAT_NO_PARITY))) { + Status = XST_INVALID_PARAM; + } else { + + /* + * Try to set the baud rate and if it's not successful then don't + * continue altering the data format, this is done first to avoid the + * format from being altered when an error occurs + */ + Status = XUartPs_SetBaudRate(InstancePtr, FormatPtr->BaudRate); + if (Status != (s32)XST_SUCCESS) { + ; + } else { + + ModeRegister = + XUartPs_ReadReg(InstancePtr->Config.BaseAddress, + XUARTPS_MR_OFFSET); + + /* + * Set the length of data (8,7,6) by first clearing out the bits + * that control it in the register, then set the length in the register + */ + ModeRegister &= (u32)(~XUARTPS_MR_CHARLEN_MASK); + ModeRegister |= (FormatPtr->DataBits << XUARTPS_MR_CHARLEN_SHIFT); + + /* + * Set the number of stop bits in the mode register by first clearing + * out the bits that control it in the register, then set the number + * of stop bits in the register. + */ + ModeRegister &= (u32)(~XUARTPS_MR_STOPMODE_MASK); + ModeRegister |= (((u32)FormatPtr->StopBits) << XUARTPS_MR_STOPMODE_SHIFT); + + /* + * Set the parity by first clearing out the bits that control it in the + * register, then set the bits in the register, the default is no parity + * after clearing the register bits + */ + ModeRegister &= (u32)(~XUARTPS_MR_PARITY_MASK); + ModeRegister |= (FormatPtr->Parity << XUARTPS_MR_PARITY_SHIFT); + + /* Update the mode register */ + XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_MR_OFFSET, + ModeRegister); + + Status = XST_SUCCESS; + } + } + return Status; +} + +/****************************************************************************/ +/** +* +* Gets the data format for the specified UART. The data format includes the +* baud rate, number of data bits, number of stop bits, and parity. +* +* @param InstancePtr is a pointer to the XUartPs instance. +* @param FormatPtr is a pointer to a format structure that will contain +* the data format after this call completes. +* +* @return None. +* +* @note None. +* +* +*****************************************************************************/ +void XUartPs_GetDataFormat(XUartPs *InstancePtr, XUartPsFormat * FormatPtr) +{ + u32 ModeRegister; + + + /* Assert validates the input arguments */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(FormatPtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Get the baud rate from the instance, this is not retrieved from the + * hardware because it is only kept as a divisor such that it is more + * difficult to get back to the baud rate + */ + FormatPtr->BaudRate = InstancePtr->BaudRate; + + ModeRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress, + XUARTPS_MR_OFFSET); + + /* Get the length of data (8,7,6,5) */ + FormatPtr->DataBits = + ((ModeRegister & (u32)XUARTPS_MR_CHARLEN_MASK) >> + XUARTPS_MR_CHARLEN_SHIFT); + + /* Get the number of stop bits */ + FormatPtr->StopBits = + (u8)((ModeRegister & (u32)XUARTPS_MR_STOPMODE_MASK) >> + XUARTPS_MR_STOPMODE_SHIFT); + + /* Determine what parity is */ + FormatPtr->Parity = + (u32)((ModeRegister & (u32)XUARTPS_MR_PARITY_MASK) >> + XUARTPS_MR_PARITY_SHIFT); +} +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_selftest.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_selftest.c new file mode 100644 index 0000000..f26176a --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_selftest.c @@ -0,0 +1,162 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xuartps_selftest.c +* @addtogroup uartps_v3_5 +* @{ +* +* This file contains the self-test functions for the XUartPs driver. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date	Changes
+* ----- ------ -------- -----------------------------------------------
+* 1.00	drg/jz 01/13/10 First Release
+* 3.00  kvn    02/13/15 Modified code for MISRA-C:2012 compliance.
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xstatus.h" +#include "xuartps.h" + +/************************** Constant Definitions *****************************/ + + +/**************************** Type Definitions *******************************/ + + +/***************** Macros (Inline Functions) Definitions *********************/ + +#define XUARTPS_TOTAL_BYTES (u8)32 + +/************************** Variable Definitions *****************************/ + +static u8 TestString[XUARTPS_TOTAL_BYTES]="abcdefghABCDEFGH012345677654321"; +static u8 ReturnString[XUARTPS_TOTAL_BYTES]; + +/************************** Function Prototypes ******************************/ + + +/****************************************************************************/ +/** +* +* This function runs a self-test on the driver and hardware device. This self +* test performs a local loopback and verifies data can be sent and received. +* +* The time for this test is proportional to the baud rate that has been set +* prior to calling this function. +* +* The mode and control registers are restored before return. +* +* @param InstancePtr is a pointer to the XUartPs instance +* +* @return +* - XST_SUCCESS if the test was successful +* - XST_UART_TEST_FAIL if the test failed looping back the data +* +* @note +* +* This function can hang if the hardware is not functioning properly. +* +******************************************************************************/ +s32 XUartPs_SelfTest(XUartPs *InstancePtr) +{ + s32 Status = XST_SUCCESS; + u32 IntrRegister; + u32 ModeRegister; + u8 Index; + u32 ReceiveDataResult; + + /* Assert validates the input arguments */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* Disable all interrupts in the interrupt disable register */ + IntrRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress, + XUARTPS_IMR_OFFSET); + XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_IDR_OFFSET, + XUARTPS_IXR_MASK); + + /* Setup for local loopback */ + ModeRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress, + XUARTPS_MR_OFFSET); + XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_MR_OFFSET, + ((ModeRegister & (u32)(~XUARTPS_MR_CHMODE_MASK)) | + (u32)XUARTPS_MR_CHMODE_L_LOOP)); + + /* Send a number of bytes and receive them, one at a time. */ + for (Index = 0U; Index < XUARTPS_TOTAL_BYTES; Index++) { + /* + * Send out the byte and if it was not sent then the failure + * will be caught in the comparison at the end + */ + (void)XUartPs_Send(InstancePtr, &TestString[Index], 1U); + + /* + * Wait until the byte is received. This can hang if the HW + * is broken. Watch for the FIFO empty flag to be false. + */ + ReceiveDataResult = Xil_In32((InstancePtr->Config.BaseAddress) + XUARTPS_SR_OFFSET) & + XUARTPS_SR_RXEMPTY; + while (ReceiveDataResult == XUARTPS_SR_RXEMPTY ) { + ReceiveDataResult = Xil_In32((InstancePtr->Config.BaseAddress) + XUARTPS_SR_OFFSET) & + XUARTPS_SR_RXEMPTY; + } + + /* Receive the byte */ + (void)XUartPs_Recv(InstancePtr, &ReturnString[Index], 1U); + } + + /* + * Compare the bytes received to the bytes sent to verify the exact data + * was received + */ + for (Index = 0U; Index < XUARTPS_TOTAL_BYTES; Index++) { + if (TestString[Index] != ReturnString[Index]) { + Status = XST_UART_TEST_FAIL; + } + } + + /* + * Restore the registers which were altered to put into polling and + * loopback modes so that this test is not destructive + */ + XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_IER_OFFSET, + IntrRegister); + XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_MR_OFFSET, + ModeRegister); + + return Status; +} +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_sinit.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_sinit.c new file mode 100644 index 0000000..c3e809b --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_sinit.c @@ -0,0 +1,95 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xuartps_sinit.c +* @addtogroup uartps_v3_5 +* @{ +* +* The implementation of the XUartPs driver's static initialzation +* functionality. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date	Changes
+* ----- ------ -------- -----------------------------------------------
+* 1.00  drg/jz 01/13/10 First Release
+* 3.00  kvn    02/13/15 Modified code for MISRA-C:2012 compliance.
+* 
+* +*****************************************************************************/ + +/***************************** Include Files ********************************/ + +#include "xstatus.h" +#include "xparameters.h" +#include "xuartps.h" + +/************************** Constant Definitions ****************************/ + +/**************************** Type Definitions ******************************/ + +/***************** Macros (Inline Functions) Definitions ********************/ + +/************************** Variable Definitions ****************************/ +extern XUartPs_Config XUartPs_ConfigTable[XPAR_XUARTPS_NUM_INSTANCES]; + +/************************** Function Prototypes *****************************/ + +/****************************************************************************/ +/** +* +* Looks up the device configuration based on the unique device ID. The table +* contains the configuration info for each device in the system. +* +* @param DeviceId contains the ID of the device +* +* @return A pointer to the configuration structure or NULL if the +* specified device is not in the system. +* +* @note None. +* +******************************************************************************/ +XUartPs_Config *XUartPs_LookupConfig(u16 DeviceId) +{ + XUartPs_Config *CfgPtr = NULL; + + u32 Index; + + for (Index = 0U; Index < (u32)XPAR_XUARTPS_NUM_INSTANCES; Index++) { + if (XUartPs_ConfigTable[Index].DeviceId == DeviceId) { + CfgPtr = &XUartPs_ConfigTable[Index]; + break; + } + } + + return (XUartPs_Config *)CfgPtr; +} +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/Makefile b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/Makefile new file mode 100644 index 0000000..837ca13 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/Makefile @@ -0,0 +1,40 @@ +COMPILER= +ARCHIVER= +CP=cp +COMPILER_FLAGS= +EXTRA_COMPILER_FLAGS= +LIB=libxil.a + +CC_FLAGS = $(COMPILER_FLAGS) +ECC_FLAGS = $(EXTRA_COMPILER_FLAGS) + +RELEASEDIR=../../../lib +INCLUDEDIR=../../../include +INCLUDES=-I./. -I${INCLUDEDIR} + +OUTS = *.o + +LIBSOURCES:=*.c +INCLUDEFILES:=*.h + +OBJECTS = $(addsuffix .o, $(basename $(wildcard *.c))) + +libs: banner xadcps_libs clean + +%.o: %.c + ${COMPILER} $(CC_FLAGS) $(ECC_FLAGS) $(INCLUDES) -o $@ $< + +banner: + echo "Compiling xadcps" + +xadcps_libs: ${OBJECTS} + $(ARCHIVER) -r ${RELEASEDIR}/${LIB} ${OBJECTS} + +.PHONY: include +include: xadcps_includes + +xadcps_includes: + ${CP} ${INCLUDEFILES} ${INCLUDEDIR} + +clean: + rm -rf ${OBJECTS} diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/xadcps.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/xadcps.c new file mode 100644 index 0000000..5ec5a93 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/xadcps.c @@ -0,0 +1,1830 @@ +/****************************************************************************** +* +* Copyright (C) 2011 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xadcps.c +* @addtogroup xadcps_v2_3 +* @{ +* +* This file contains the driver API functions that can be used to access +* the XADC device. +* +* Refer to the xadcps.h header file for more information about this driver. +* +* @note None. +* +*
+*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date     Changes
+* ----- -----  -------- -----------------------------------------------------
+* 1.00a ssb    12/22/11 First release based on the XPS/AXI xadc driver
+* 1.01a bss    02/18/13	Modified XAdcPs_SetSeqChEnables,XAdcPs_SetSeqAvgEnables
+*			XAdcPs_SetSeqInputMode and XAdcPs_SetSeqAcqTime APIs
+*			to fix CR #693371
+* 2.1   bss    08/05/14	Modified Assert for XAdcPs_SetSingleChParams to fix
+*			CR #807563.
+* 2.2	bss	   04/27/14 Modified to use correct Device Config base address
+*						(CR#854437).
+* 2.3   mn     07/09/18 Fix Doxygen warning
+* 
+* +*****************************************************************************/ + +/***************************** Include Files ********************************/ + +#include "xadcps.h" + +/************************** Constant Definitions ****************************/ + +/**************************** Type Definitions ******************************/ + +/***************** Macros (Inline Functions) Definitions ********************/ + +/************************** Function Prototypes *****************************/ + +void XAdcPs_WriteInternalReg(XAdcPs *InstancePtr, u32 RegOffset, u32 Data); +u32 XAdcPs_ReadInternalReg(XAdcPs *InstancePtr, u32 RegOffset); + + +/************************** Variable Definitions ****************************/ + + +/*****************************************************************************/ +/** +* +* This function initializes a specific XAdcPs device/instance. This function +* must be called prior to using the XADC device. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param ConfigPtr points to the XAdcPs device configuration structure. +* @param EffectiveAddr is the device base address in the virtual memory +* address space. If the address translation is not used then the +* physical address is passed. +* Unexpected errors may occur if the address mapping is changed +* after this function is invoked. +* +* @return +* - XST_SUCCESS if successful. +* +* @note The user needs to first call the XAdcPs_LookupConfig() API +* which returns the Configuration structure pointer which is +* passed as a parameter to the XAdcPs_CfgInitialize() API. +* +******************************************************************************/ +int XAdcPs_CfgInitialize(XAdcPs *InstancePtr, XAdcPs_Config *ConfigPtr, + u32 EffectiveAddr) +{ + + u32 RegValue; + /* + * Assert the input arguments. + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(ConfigPtr != NULL); + + + /* + * Set the values read from the device config and the base address. + */ + InstancePtr->Config.DeviceId = ConfigPtr->DeviceId; + InstancePtr->Config.BaseAddress = EffectiveAddr; + + /* Write Unlock value to Device Config Unlock register */ + XAdcPs_WriteReg(XPAR_XDCFG_0_BASEADDR, + XADCPS_UNLK_OFFSET, XADCPS_UNLK_VALUE); + + /* Enable the PS access of xadc and set FIFO thresholds */ + + RegValue = XAdcPs_ReadReg((InstancePtr)->Config.BaseAddress, + XADCPS_CFG_OFFSET); + + RegValue = RegValue | XADCPS_CFG_ENABLE_MASK | + XADCPS_CFG_CFIFOTH_MASK | XADCPS_CFG_DFIFOTH_MASK; + + XAdcPs_WriteReg((InstancePtr)->Config.BaseAddress, + XADCPS_CFG_OFFSET, RegValue); + + /* Release xadc from reset */ + + XAdcPs_WriteReg((InstancePtr)->Config.BaseAddress, + XADCPS_MCTL_OFFSET, 0x00); + + /* + * Indicate the instance is now ready to use and + * initialized without error. + */ + InstancePtr->IsReady = XIL_COMPONENT_IS_READY; + + return XST_SUCCESS; +} + + +/****************************************************************************/ +/** +* +* The functions sets the contents of the Config Register. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param Data is the 32 bit data to be written to the Register. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XAdcPs_SetConfigRegister(XAdcPs *InstancePtr, u32 Data) +{ + /* + * Assert the arguments. + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + XAdcPs_WriteReg((InstancePtr)->Config.BaseAddress, + XADCPS_CFG_OFFSET, Data); + +} + + +/****************************************************************************/ +/** +* +* The functions reads the contents of the Config Register. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @return A 32-bit value representing the contents of the Config Register. +* Use the XADCPS_SR_*_MASK constants defined in xadcps_hw.h to +* interpret the returned value. +* +* @note None. +* +*****************************************************************************/ +u32 XAdcPs_GetConfigRegister(XAdcPs *InstancePtr) +{ + /* + * Assert the arguments. + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the Config Register and return the value. + */ + return XAdcPs_ReadReg((InstancePtr)->Config.BaseAddress, + XADCPS_CFG_OFFSET); +} + + +/****************************************************************************/ +/** +* +* The functions reads the contents of the Miscellaneous Status Register. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @return A 32-bit value representing the contents of the Miscellaneous +* Status Register. Use the XADCPS_MSTS_*_MASK constants defined +* in xadcps_hw.h to interpret the returned value. +* +* @note None. +* +*****************************************************************************/ +u32 XAdcPs_GetMiscStatus(XAdcPs *InstancePtr) +{ + /* + * Assert the arguments. + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the Miscellaneous Status Register and return the value. + */ + return XAdcPs_ReadReg((InstancePtr)->Config.BaseAddress, + XADCPS_MSTS_OFFSET); +} + + +/****************************************************************************/ +/** +* +* The functions sets the contents of the Miscellaneous Control register. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param Data is the 32 bit data to be written to the Register. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XAdcPs_SetMiscCtrlRegister(XAdcPs *InstancePtr, u32 Data) +{ + /* + * Assert the arguments. + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Write to the Miscellaneous control register Register. + */ + XAdcPs_WriteReg((InstancePtr)->Config.BaseAddress, + XADCPS_MCTL_OFFSET, Data); +} + + +/****************************************************************************/ +/** +* +* The functions reads the contents of the Miscellaneous control register. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @return A 32-bit value representing the contents of the Config Register. +* Use the XADCPS_SR_*_MASK constants defined in xadcps_hw.h to +* interpret the returned value. +* +* @note None. +* +*****************************************************************************/ +u32 XAdcPs_GetMiscCtrlRegister(XAdcPs *InstancePtr) +{ + /* + * Assert the arguments. + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the Miscellaneous control register and return the value. + */ + return XAdcPs_ReadReg((InstancePtr)->Config.BaseAddress, + XADCPS_MCTL_OFFSET); +} + + +/*****************************************************************************/ +/** +* +* This function resets the XADC Hard Macro in the device. +* +* @param InstancePtr is a pointer to the Xxadc instance. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XAdcPs_Reset(XAdcPs *InstancePtr) +{ + /* + * Assert the arguments. + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Generate the reset by Control + * register and release from reset + */ + XAdcPs_WriteReg((InstancePtr)->Config.BaseAddress, + XADCPS_MCTL_OFFSET, 0x10); + XAdcPs_WriteReg((InstancePtr)->Config.BaseAddress, + XADCPS_MCTL_OFFSET, 0x00); +} + + +/****************************************************************************/ +/** +* +* Get the ADC converted data for the specified channel. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param Channel is the channel number. Use the XADCPS_CH_* defined in +* the file xadcps.h. +* The valid channels are +* - 0 to 6 +* - 13 to 31 +* +* @return A 16-bit value representing the ADC converted data for the +* specified channel. The XADC Monitor/ADC device guarantees +* a 10 bit resolution for the ADC converted data and data is the +* 10 MSB bits of the 16 data read from the device. +* +* @note The channels 7,8,9 are used for calibration of the device and +* hence there is no associated data with this channel. +* +*****************************************************************************/ +u16 XAdcPs_GetAdcData(XAdcPs *InstancePtr, u8 Channel) +{ + + u32 RegData; + + /* + * Assert the arguments. + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid((Channel <= XADCPS_CH_VBRAM) || + ((Channel >= XADCPS_CH_VCCPINT) && + (Channel <= XADCPS_CH_AUX_MAX))); + + RegData = XAdcPs_ReadInternalReg(InstancePtr, + (XADCPS_TEMP_OFFSET + + Channel)); + return (u16) RegData; +} + +/****************************************************************************/ +/** +* +* This function gets the calibration coefficient data for the specified +* parameter. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param CoeffType specifies the calibration coefficient +* to be read. Use XADCPS_CALIB_* constants defined in xadcps.h to +* specify the calibration coefficient to be read. +* +* @return A 16-bit value representing the calibration coefficient. +* The XADC device guarantees a 10 bit resolution for +* the ADC converted data and data is the 10 MSB bits of the 16 +* data read from the device. +* +* @note None. +* +*****************************************************************************/ +u16 XAdcPs_GetCalibCoefficient(XAdcPs *InstancePtr, u8 CoeffType) +{ + u32 RegData; + + /* + * Assert the arguments. + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid(CoeffType <= XADCPS_CALIB_GAIN_ERROR_COEFF); + + /* + * Read the selected calibration coefficient. + */ + RegData = XAdcPs_ReadInternalReg(InstancePtr, + (XADCPS_ADC_A_SUPPLY_CALIB_OFFSET + + CoeffType)); + return (u16) RegData; +} + +/****************************************************************************/ +/** +* +* This function reads the Minimum/Maximum measurement for one of the +* specified parameters. Use XADCPS_MAX_* and XADCPS_MIN_* constants defined in +* xadcps.h to specify the parameters (Temperature, VccInt, VccAux, VBram, +* VccPInt, VccPAux and VccPDro). +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param MeasurementType specifies the parameter for which the +* Minimum/Maximum measurement has to be read. +* Use XADCPS_MAX_* and XADCPS_MIN_* constants defined in xadcps.h to +* specify the data to be read. +* +* @return A 16-bit value representing the maximum/minimum measurement for +* specified parameter. +* The XADC device guarantees a 10 bit resolution for +* the ADC converted data and data is the 10 MSB bits of the 16 +* data read from the device. +* +* @note None. +* +*****************************************************************************/ +u16 XAdcPs_GetMinMaxMeasurement(XAdcPs *InstancePtr, u8 MeasurementType) +{ + u32 RegData; + /* + * Assert the arguments. + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid((MeasurementType <= XADCPS_MAX_VCCPDRO) || + ((MeasurementType >= XADCPS_MIN_VCCPINT) && + (MeasurementType <= XADCPS_MIN_VCCPDRO))) + + /* + * Read and return the specified Minimum/Maximum measurement. + */ + RegData = XAdcPs_ReadInternalReg(InstancePtr, + (XADCPS_MAX_TEMP_OFFSET + + MeasurementType)); + return (u16) RegData; +} + +/****************************************************************************/ +/** +* +* This function sets the number of samples of averaging that is to be done for +* all the channels in both the single channel mode and sequence mode of +* operations. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param Average is the number of samples of averaging programmed to the +* Configuration Register 0. Use the XADCPS_AVG_* definitions defined +* in xadcps.h file : +* - XADCPS_AVG_0_SAMPLES for no averaging +* - XADCPS_AVG_16_SAMPLES for 16 samples of averaging +* - XADCPS_AVG_64_SAMPLES for 64 samples of averaging +* - XADCPS_AVG_256_SAMPLES for 256 samples of averaging +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XAdcPs_SetAvg(XAdcPs *InstancePtr, u8 Average) +{ + u32 RegData; + + /* + * Assert the arguments. + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid(Average <= XADCPS_AVG_256_SAMPLES); + + /* + * Write the averaging value into the Configuration Register 0. + */ + RegData = XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_CFR0_OFFSET) & + (~XADCPS_CFR0_AVG_VALID_MASK); + + RegData |= (((u32) Average << XADCPS_CFR0_AVG_SHIFT)); + XAdcPs_WriteInternalReg(InstancePtr, XADCPS_CFR0_OFFSET, + RegData); + +} + +/****************************************************************************/ +/** +* +* This function returns the number of samples of averaging configured for all +* the channels in the Configuration Register 0. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @return The averaging read from the Configuration Register 0 is +* returned. Use the XADCPS_AVG_* bit definitions defined in +* xadcps.h file to interpret the returned value : +* - XADCPS_AVG_0_SAMPLES means no averaging +* - XADCPS_AVG_16_SAMPLES means 16 samples of averaging +* - XADCPS_AVG_64_SAMPLES means 64 samples of averaging +* - XADCPS_AVG_256_SAMPLES means 256 samples of averaging +* +* @note None. +* +*****************************************************************************/ +u8 XAdcPs_GetAvg(XAdcPs *InstancePtr) +{ + u32 Average; + + /* + * Assert the arguments. + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the averaging value from the Configuration Register 0. + */ + Average = XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_CFR0_OFFSET) & XADCPS_CFR0_AVG_VALID_MASK; + + + return ((u8) (Average >> XADCPS_CFR0_AVG_SHIFT)); +} + +/****************************************************************************/ +/** +* +* The function sets the given parameters in the Configuration Register 0 in +* the single channel mode. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param Channel is the channel number for the singel channel mode. +* The valid channels are 0 to 6, 8, and 13 to 31. +* If the external Mux is used then this specifies the channel +* oonnected to the external Mux. Please read the Device Spec +* to know which channels are valid. +* @param IncreaseAcqCycles is a boolean parameter which specifies whether +* the Acquisition time for the external channels has to be +* increased to 10 ADCCLK cycles (specify TRUE) or remain at the +* default 4 ADCCLK cycles (specify FALSE). This parameter is +* only valid for the external channels. +* @param IsEventMode specifies whether the operation of the ADC is Event +* driven or Continuous mode. +* @param IsDifferentialMode is a boolean parameter which specifies +* unipolar(specify FALSE) or differential mode (specify TRUE) for +* the analog inputs. The input mode is only valid for the +* external channels. +* +* @return +* - XST_SUCCESS if the given values were written successfully to +* the Configuration Register 0. +* - XST_FAILURE if the channel sequencer is enabled or the input +* parameters are not valid for the selected channel. +* +* @note +* - The number of samples for the averaging for all the channels +* is set by using the function XAdcPs_SetAvg. +* - The calibration of the device is done by doing a ADC +* conversion on the calibration channel(channel 8). The input +* parameters IncreaseAcqCycles, IsDifferentialMode and +* IsEventMode are not valid for this channel +* +* +*****************************************************************************/ +int XAdcPs_SetSingleChParams(XAdcPs *InstancePtr, + u8 Channel, + int IncreaseAcqCycles, + int IsEventMode, + int IsDifferentialMode) +{ + u32 RegValue; + + /* + * Assert the arguments. + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid((Channel <= XADCPS_CH_VBRAM) || + (Channel == XADCPS_CH_ADC_CALIB) || + ((Channel >= XADCPS_CH_VCCPINT) && + (Channel <= XADCPS_CH_AUX_MAX))); + Xil_AssertNonvoid((IncreaseAcqCycles == TRUE) || + (IncreaseAcqCycles == FALSE)); + Xil_AssertNonvoid((IsEventMode == TRUE) || (IsEventMode == FALSE)); + Xil_AssertNonvoid((IsDifferentialMode == TRUE) || + (IsDifferentialMode == FALSE)); + + /* + * Check if the device is in single channel mode else return failure + */ + if ((XAdcPs_GetSequencerMode(InstancePtr) != + XADCPS_SEQ_MODE_SINGCHAN)) { + return XST_FAILURE; + } + + /* + * Read the Configuration Register 0. + */ + RegValue = XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_CFR0_OFFSET) & + XADCPS_CFR0_AVG_VALID_MASK; + + /* + * Select the number of acquisition cycles. The acquisition cycles is + * only valid for the external channels. + */ + if (IncreaseAcqCycles == TRUE) { + if (((Channel >= XADCPS_CH_AUX_MIN) && + (Channel <= XADCPS_CH_AUX_MAX)) || + (Channel == XADCPS_CH_VPVN)){ + RegValue |= XADCPS_CFR0_ACQ_MASK; + } else { + return XST_FAILURE; + } + + } + + /* + * Select the input mode. The input mode is only valid for the + * external channels. + */ + if (IsDifferentialMode == TRUE) { + + if (((Channel >= XADCPS_CH_AUX_MIN) && + (Channel <= XADCPS_CH_AUX_MAX)) || + (Channel == XADCPS_CH_VPVN)){ + RegValue |= XADCPS_CFR0_DU_MASK; + } else { + return XST_FAILURE; + } + } + + /* + * Select the ADC mode. + */ + if (IsEventMode == TRUE) { + RegValue |= XADCPS_CFR0_EC_MASK; + } + + /* + * Write the given values into the Configuration Register 0. + */ + RegValue |= (Channel & XADCPS_CFR0_CHANNEL_MASK); + XAdcPs_WriteInternalReg(InstancePtr, XADCPS_CFR0_OFFSET, + RegValue); + + return XST_SUCCESS; +} + +/****************************************************************************/ +/** +* +* This function enables the alarm outputs for the specified alarms in the +* Configuration Register 1. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param AlmEnableMask is the bit-mask of the alarm outputs to be enabled +* in the Configuration Register 1. +* Bit positions of 1 will be enabled. Bit positions of 0 will be +* disabled. This mask is formed by OR'ing XADCPS_CFR1_ALM_*_MASK and +* XADCPS_CFR1_OT_MASK masks defined in xadcps_hw.h. +* +* @return None. +* +* @note The implementation of the alarm enables in the Configuration +* register 1 is such that the alarms for bit positions of 1 will +* be disabled and alarms for bit positions of 0 will be enabled. +* The alarm outputs specified by the AlmEnableMask are negated +* before writing to the Configuration Register 1. +* +* +*****************************************************************************/ +void XAdcPs_SetAlarmEnables(XAdcPs *InstancePtr, u16 AlmEnableMask) +{ + u32 RegValue; + + /* + * Assert the arguments. + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + + RegValue = XAdcPs_ReadInternalReg(InstancePtr, XADCPS_CFR1_OFFSET); + + RegValue &= (u32)~XADCPS_CFR1_ALM_ALL_MASK; + RegValue |= (~AlmEnableMask & XADCPS_CFR1_ALM_ALL_MASK); + + /* + * Enable/disables the alarm enables for the specified alarm bits in the + * Configuration Register 1. + */ + XAdcPs_WriteInternalReg(InstancePtr, XADCPS_CFR1_OFFSET, + RegValue); +} + +/****************************************************************************/ +/** +* +* This function gets the status of the alarm output enables in the +* Configuration Register 1. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @return This is the bit-mask of the enabled alarm outputs in the +* Configuration Register 1. Use the masks XADCPS_CFR1_ALM*_* and +* XADCPS_CFR1_OT_MASK defined in xadcps_hw.h to interpret the +* returned value. +* Bit positions of 1 indicate that the alarm output is enabled. +* Bit positions of 0 indicate that the alarm output is disabled. +* +* +* @note The implementation of the alarm enables in the Configuration +* register 1 is such that alarms for the bit positions of 1 will +* be disabled and alarms for bit positions of 0 will be enabled. +* The enabled alarm outputs returned by this function is the +* negated value of the the data read from the Configuration +* Register 1. +* +*****************************************************************************/ +u16 XAdcPs_GetAlarmEnables(XAdcPs *InstancePtr) +{ + u32 RegValue; + + /* + * Assert the arguments + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the status of alarm output enables from the Configuration + * Register 1. + */ + RegValue = XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_CFR1_OFFSET) & XADCPS_CFR1_ALM_ALL_MASK; + return (u16) (~RegValue & XADCPS_CFR1_ALM_ALL_MASK); +} + +/****************************************************************************/ +/** +* +* This function enables the specified calibration in the Configuration +* Register 1 : +* +* - XADCPS_CFR1_CAL_ADC_OFFSET_MASK : Calibration 0 -ADC offset correction +* - XADCPS_CFR1_CAL_ADC_GAIN_OFFSET_MASK : Calibration 1 -ADC gain and offset +* correction +* - XADCPS_CFR1_CAL_PS_OFFSET_MASK : Calibration 2 -Power Supply sensor +* offset correction +* - XADCPS_CFR1_CAL_PS_GAIN_OFFSET_MASK : Calibration 3 -Power Supply sensor +* gain and offset correction +* - XADCPS_CFR1_CAL_DISABLE_MASK : No Calibration +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param Calibration is the Calibration to be applied. +* Use XADCPS_CFR1_CAL*_* bits defined in xadcps_hw.h. +* Multiple calibrations can be enabled at a time by oring the +* XADCPS_CFR1_CAL_ADC_* and XADCPS_CFR1_CAL_PS_* bits. +* Calibration can be disabled by specifying + XADCPS_CFR1_CAL_DISABLE_MASK; +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XAdcPs_SetCalibEnables(XAdcPs *InstancePtr, u16 Calibration) +{ + u32 RegValue; + + /* + * Assert the arguments. + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid(((Calibration >= XADCPS_CFR1_CAL_ADC_OFFSET_MASK) && + (Calibration <= XADCPS_CFR1_CAL_VALID_MASK)) || + (Calibration == XADCPS_CFR1_CAL_DISABLE_MASK)); + + /* + * Set the specified calibration in the Configuration Register 1. + */ + RegValue = XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_CFR1_OFFSET); + + RegValue &= (~ XADCPS_CFR1_CAL_VALID_MASK); + RegValue |= (Calibration & XADCPS_CFR1_CAL_VALID_MASK); + XAdcPs_WriteInternalReg(InstancePtr, XADCPS_CFR1_OFFSET, + RegValue); + +} + +/****************************************************************************/ +/** +* +* This function reads the value of the calibration enables from the +* Configuration Register 1. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @return The value of the calibration enables in the Configuration +* Register 1 : +* - XADCPS_CFR1_CAL_ADC_OFFSET_MASK : ADC offset correction +* - XADCPS_CFR1_CAL_ADC_GAIN_OFFSET_MASK : ADC gain and offset +* correction +* - XADCPS_CFR1_CAL_PS_OFFSET_MASK : Power Supply sensor offset +* correction +* - XADCPS_CFR1_CAL_PS_GAIN_OFFSET_MASK : Power Supply sensor +* gain and offset correction +* - XADCPS_CFR1_CAL_DISABLE_MASK : No Calibration +* +* @note None. +* +*****************************************************************************/ +u16 XAdcPs_GetCalibEnables(XAdcPs *InstancePtr) +{ + /* + * Assert the arguments. + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the calibration enables from the Configuration Register 1. + */ + return (u16) XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_CFR1_OFFSET) & XADCPS_CFR1_CAL_VALID_MASK; + +} + +/****************************************************************************/ +/** +* +* This function sets the specified Channel Sequencer Mode in the Configuration +* Register 1 : +* - Default safe mode (XADCPS_SEQ_MODE_SAFE) +* - One pass through sequence (XADCPS_SEQ_MODE_ONEPASS) +* - Continuous channel sequencing (XADCPS_SEQ_MODE_CONTINPASS) +* - Single Channel/Sequencer off (XADCPS_SEQ_MODE_SINGCHAN) +* - Simulataneous sampling mode (XADCPS_SEQ_MODE_SIMUL_SAMPLING) +* - Independent mode (XADCPS_SEQ_MODE_INDEPENDENT) +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param SequencerMode is the sequencer mode to be set. +* Use XADCPS_SEQ_MODE_* bits defined in xadcps.h. +* @return None. +* +* @note Only one of the modes can be enabled at a time. Please +* read the Spec of the XADC for further information about the +* sequencer modes. +* +* +*****************************************************************************/ +void XAdcPs_SetSequencerMode(XAdcPs *InstancePtr, u8 SequencerMode) +{ + u32 RegValue; + + /* + * Assert the arguments. + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid((SequencerMode <= XADCPS_SEQ_MODE_SIMUL_SAMPLING) || + (SequencerMode == XADCPS_SEQ_MODE_INDEPENDENT)); + + /* + * Set the specified sequencer mode in the Configuration Register 1. + */ + RegValue = XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_CFR1_OFFSET); + RegValue &= (~ XADCPS_CFR1_SEQ_VALID_MASK); + RegValue |= ((SequencerMode << XADCPS_CFR1_SEQ_SHIFT) & + XADCPS_CFR1_SEQ_VALID_MASK); + XAdcPs_WriteInternalReg(InstancePtr, XADCPS_CFR1_OFFSET, + RegValue); + +} + +/****************************************************************************/ +/** +* +* This function gets the channel sequencer mode from the Configuration +* Register 1. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @return The channel sequencer mode : +* - XADCPS_SEQ_MODE_SAFE : Default safe mode +* - XADCPS_SEQ_MODE_ONEPASS : One pass through sequence +* - XADCPS_SEQ_MODE_CONTINPASS : Continuous channel sequencing +* - XADCPS_SEQ_MODE_SINGCHAN : Single channel/Sequencer off +* - XADCPS_SEQ_MODE_SIMUL_SAMPLING : Simulataneous sampling mode +* - XADCPS_SEQ_MODE_INDEPENDENT : Independent mode +* +* +* @note None. +* +*****************************************************************************/ +u8 XAdcPs_GetSequencerMode(XAdcPs *InstancePtr) +{ + /* + * Assert the arguments. + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the channel sequencer mode from the Configuration Register 1. + */ + return ((u8) ((XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_CFR1_OFFSET) & XADCPS_CFR1_SEQ_VALID_MASK) >> + XADCPS_CFR1_SEQ_SHIFT)); + +} + +/****************************************************************************/ +/** +* +* The function sets the frequency of the ADCCLK by configuring the DCLK to +* ADCCLK ratio in the Configuration Register #2 +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param Divisor is clock divisor used to derive ADCCLK from DCLK. +* Valid values of the divisor are +* - 0 to 255. Values 0, 1, 2 are all mapped to 2. +* Refer to the device specification for more details +* +* @return None. +* +* @note - The ADCCLK is an internal clock used by the ADC and is +* synchronized to the DCLK clock. The ADCCLK is equal to DCLK +* divided by the user selection in the Configuration Register 2. +* - There is no Assert on the minimum value of the Divisor. +* +*****************************************************************************/ +void XAdcPs_SetAdcClkDivisor(XAdcPs *InstancePtr, u8 Divisor) +{ + /* + * Assert the arguments. + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Write the divisor value into the Configuration Register #2. + */ + XAdcPs_WriteInternalReg(InstancePtr, XADCPS_CFR2_OFFSET, + Divisor << XADCPS_CFR2_CD_SHIFT); + +} + +/****************************************************************************/ +/** +* +* The function gets the ADCCLK divisor from the Configuration Register 2. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @return The divisor read from the Configuration Register 2. +* +* @note The ADCCLK is an internal clock used by the ADC and is +* synchronized to the DCLK clock. The ADCCLK is equal to DCLK +* divided by the user selection in the Configuration Register 2. +* +*****************************************************************************/ +u8 XAdcPs_GetAdcClkDivisor(XAdcPs *InstancePtr) +{ + u16 Divisor; + + /* + * Assert the arguments. + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the divisor value from the Configuration Register 2. + */ + Divisor = (u16) XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_CFR2_OFFSET); + + return (u8) (Divisor >> XADCPS_CFR2_CD_SHIFT); +} + +/****************************************************************************/ +/** +* +* This function enables the specified channels in the ADC Channel Selection +* Sequencer Registers. The sequencer must be disabled before writing to these +* regsiters. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param ChEnableMask is the bit mask of all the channels to be enabled. +* Use XADCPS_SEQ_CH__* defined in xadcps_hw.h to specify the Channel +* numbers. Bit masks of 1 will be enabled and bit mask of 0 will +* be disabled. +* The ChEnableMask is a 32 bit mask that is written to the two +* 16 bit ADC Channel Selection Sequencer Registers. +* +* @return +* - XST_SUCCESS if the given values were written successfully to +* the ADC Channel Selection Sequencer Registers. +* - XST_FAILURE if the channel sequencer is enabled. +* +* @note None +* +*****************************************************************************/ +int XAdcPs_SetSeqChEnables(XAdcPs *InstancePtr, u32 ChEnableMask) +{ + /* + * Assert the arguments. + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * The sequencer must be disabled for writing any of these registers + * Return XST_FAILURE if the channel sequencer is enabled. + */ + if ((XAdcPs_GetSequencerMode(InstancePtr) != XADCPS_SEQ_MODE_SAFE)) { + return XST_FAILURE; + } + + /* + * Enable the specified channels in the ADC Channel Selection Sequencer + * Registers. + */ + XAdcPs_WriteInternalReg(InstancePtr, + XADCPS_SEQ00_OFFSET, + (ChEnableMask & XADCPS_SEQ00_CH_VALID_MASK)); + + XAdcPs_WriteInternalReg(InstancePtr, + XADCPS_SEQ01_OFFSET, + (ChEnableMask >> XADCPS_SEQ_CH_AUX_SHIFT) & + XADCPS_SEQ01_CH_VALID_MASK); + + return XST_SUCCESS; +} + +/****************************************************************************/ +/** +* +* This function gets the channel enable bits status from the ADC Channel +* Selection Sequencer Registers. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @return Gets the channel enable bits. Use XADCPS_SEQ_CH__* defined in +* xadcps_hw.h to interpret the Channel numbers. Bit masks of 1 +* are the channels that are enabled and bit mask of 0 are +* the channels that are disabled. +* +* @return None +* +* @note None +* +*****************************************************************************/ +u32 XAdcPs_GetSeqChEnables(XAdcPs *InstancePtr) +{ + u32 RegValEnable; + + /* + * Assert the arguments. + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the channel enable bits for all the channels from the ADC + * Channel Selection Register. + */ + RegValEnable = XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_SEQ00_OFFSET) & + XADCPS_SEQ00_CH_VALID_MASK; + RegValEnable |= (XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_SEQ01_OFFSET) & + XADCPS_SEQ01_CH_VALID_MASK) << + XADCPS_SEQ_CH_AUX_SHIFT; + + + return RegValEnable; +} + +/****************************************************************************/ +/** +* +* This function enables the averaging for the specified channels in the ADC +* Channel Averaging Enable Sequencer Registers. The sequencer must be disabled +* before writing to these regsiters. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param AvgEnableChMask is the bit mask of all the channels for which +* averaging is to be enabled. Use XADCPS_SEQ_CH__* defined in +* xadcps_hw.h to specify the Channel numbers. Averaging will be +* enabled for bit masks of 1 and disabled for bit mask of 0. +* The AvgEnableChMask is a 32 bit mask that is written to the two +* 16 bit ADC Channel Averaging Enable Sequencer Registers. +* +* @return +* - XST_SUCCESS if the given values were written successfully to +* the ADC Channel Averaging Enables Sequencer Registers. +* - XST_FAILURE if the channel sequencer is enabled. +* +* @note None +* +*****************************************************************************/ +int XAdcPs_SetSeqAvgEnables(XAdcPs *InstancePtr, u32 AvgEnableChMask) +{ + /* + * Assert the arguments. + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * The sequencer must be disabled for writing any of these registers + * Return XST_FAILURE if the channel sequencer is enabled. + */ + if ((XAdcPs_GetSequencerMode(InstancePtr) != XADCPS_SEQ_MODE_SAFE)) { + return XST_FAILURE; + } + + /* + * Enable/disable the averaging for the specified channels in the + * ADC Channel Averaging Enables Sequencer Registers. + */ + XAdcPs_WriteInternalReg(InstancePtr, + XADCPS_SEQ02_OFFSET, + (AvgEnableChMask & XADCPS_SEQ02_CH_VALID_MASK)); + + XAdcPs_WriteInternalReg(InstancePtr, + XADCPS_SEQ03_OFFSET, + (AvgEnableChMask >> XADCPS_SEQ_CH_AUX_SHIFT) & + XADCPS_SEQ03_CH_VALID_MASK); + + return XST_SUCCESS; +} + +/****************************************************************************/ +/** +* +* This function returns the channels for which the averaging has been enabled +* in the ADC Channel Averaging Enables Sequencer Registers. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @returns The status of averaging (enabled/disabled) for all the channels. +* Use XADCPS_SEQ_CH__* defined in xadcps_hw.h to interpret the +* Channel numbers. Bit masks of 1 are the channels for which +* averaging is enabled and bit mask of 0 are the channels for +* averaging is disabled +* +* @note None +* +*****************************************************************************/ +u32 XAdcPs_GetSeqAvgEnables(XAdcPs *InstancePtr) +{ + u32 RegValAvg; + + /* + * Assert the arguments. + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the averaging enable status for all the channels from the + * ADC Channel Averaging Enables Sequencer Registers. + */ + RegValAvg = XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_SEQ02_OFFSET) & XADCPS_SEQ02_CH_VALID_MASK; + RegValAvg |= (XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_SEQ03_OFFSET) & XADCPS_SEQ03_CH_VALID_MASK) << + XADCPS_SEQ_CH_AUX_SHIFT; + + return RegValAvg; +} + +/****************************************************************************/ +/** +* +* This function sets the Analog input mode for the specified channels in the ADC +* Channel Analog-Input Mode Sequencer Registers. The sequencer must be disabled +* before writing to these regsiters. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param InputModeChMask is the bit mask of all the channels for which +* the input mode is differential mode. Use XADCPS_SEQ_CH__* defined +* in xadcps_hw.h to specify the channel numbers. Differential +* input mode will be set for bit masks of 1 and unipolar input +* mode for bit masks of 0. +* The InputModeChMask is a 32 bit mask that is written to the two +* 16 bit ADC Channel Analog-Input Mode Sequencer Registers. +* +* @return +* - XST_SUCCESS if the given values were written successfully to +* the ADC Channel Analog-Input Mode Sequencer Registers. +* - XST_FAILURE if the channel sequencer is enabled. +* +* @note None +* +*****************************************************************************/ +int XAdcPs_SetSeqInputMode(XAdcPs *InstancePtr, u32 InputModeChMask) +{ + /* + * Assert the arguments. + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * The sequencer must be disabled for writing any of these registers + * Return XST_FAILURE if the channel sequencer is enabled. + */ + if ((XAdcPs_GetSequencerMode(InstancePtr) != XADCPS_SEQ_MODE_SAFE)) { + return XST_FAILURE; + } + + /* + * Set the input mode for the specified channels in the ADC Channel + * Analog-Input Mode Sequencer Registers. + */ + XAdcPs_WriteInternalReg(InstancePtr, + XADCPS_SEQ04_OFFSET, + (InputModeChMask & XADCPS_SEQ04_CH_VALID_MASK)); + + XAdcPs_WriteInternalReg(InstancePtr, + XADCPS_SEQ05_OFFSET, + (InputModeChMask >> XADCPS_SEQ_CH_AUX_SHIFT) & + XADCPS_SEQ05_CH_VALID_MASK); + + return XST_SUCCESS; +} + +/****************************************************************************/ +/** +* +* This function gets the Analog input mode for all the channels from +* the ADC Channel Analog-Input Mode Sequencer Registers. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @returns The input mode for all the channels. +* Use XADCPS_SEQ_CH_* defined in xadcps_hw.h to interpret the +* Channel numbers. Bit masks of 1 are the channels for which +* input mode is differential and bit mask of 0 are the channels +* for which input mode is unipolar. +* +* @note None. +* +*****************************************************************************/ +u32 XAdcPs_GetSeqInputMode(XAdcPs *InstancePtr) +{ + u32 InputMode; + + /* + * Assert the arguments. + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Get the input mode for all the channels from the ADC Channel + * Analog-Input Mode Sequencer Registers. + */ + InputMode = XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_SEQ04_OFFSET) & + XADCPS_SEQ04_CH_VALID_MASK; + InputMode |= (XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_SEQ05_OFFSET) & + XADCPS_SEQ05_CH_VALID_MASK) << + XADCPS_SEQ_CH_AUX_SHIFT; + + return InputMode; +} + +/****************************************************************************/ +/** +* +* This function sets the number of Acquisition cycles in the ADC Channel +* Acquisition Time Sequencer Registers. The sequencer must be disabled +* before writing to these regsiters. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param AcqCyclesChMask is the bit mask of all the channels for which +* the number of acquisition cycles is to be extended. +* Use XADCPS_SEQ_CH__* defined in xadcps_hw.h to specify the Channel +* numbers. Acquisition cycles will be extended to 10 ADCCLK cycles +* for bit masks of 1 and will be the default 4 ADCCLK cycles for +* bit masks of 0. +* The AcqCyclesChMask is a 32 bit mask that is written to the two +* 16 bit ADC Channel Acquisition Time Sequencer Registers. +* +* @return +* - XST_SUCCESS if the given values were written successfully to +* the Channel Sequencer Registers. +* - XST_FAILURE if the channel sequencer is enabled. +* +* @note None. +* +*****************************************************************************/ +int XAdcPs_SetSeqAcqTime(XAdcPs *InstancePtr, u32 AcqCyclesChMask) +{ + /* + * Assert the arguments. + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * The sequencer must be disabled for writing any of these registers + * Return XST_FAILURE if the channel sequencer is enabled. + */ + if ((XAdcPs_GetSequencerMode(InstancePtr) != + XADCPS_SEQ_MODE_SAFE)) { + return XST_FAILURE; + } + + /* + * Set the Acquisition time for the specified channels in the + * ADC Channel Acquisition Time Sequencer Registers. + */ + XAdcPs_WriteInternalReg(InstancePtr, + XADCPS_SEQ06_OFFSET, + (AcqCyclesChMask & XADCPS_SEQ06_CH_VALID_MASK)); + + XAdcPs_WriteInternalReg(InstancePtr, + XADCPS_SEQ07_OFFSET, + (AcqCyclesChMask >> XADCPS_SEQ_CH_AUX_SHIFT) & + XADCPS_SEQ07_CH_VALID_MASK); + + return XST_SUCCESS; +} + +/****************************************************************************/ +/** +* +* This function gets the status of acquisition from the ADC Channel Acquisition +* Time Sequencer Registers. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @returns The acquisition time for all the channels. +* Use XADCPS_SEQ_CH__* defined in xadcps_hw.h to interpret the +* Channel numbers. Bit masks of 1 are the channels for which +* acquisition cycles are extended and bit mask of 0 are the +* channels for which acquisition cycles are not extended. +* +* @note None +* +*****************************************************************************/ +u32 XAdcPs_GetSeqAcqTime(XAdcPs *InstancePtr) +{ + u32 RegValAcq; + + /* + * Assert the arguments. + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Get the Acquisition cycles for the specified channels from the ADC + * Channel Acquisition Time Sequencer Registers. + */ + RegValAcq = XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_SEQ06_OFFSET) & + XADCPS_SEQ06_CH_VALID_MASK; + RegValAcq |= (XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_SEQ07_OFFSET) & + XADCPS_SEQ07_CH_VALID_MASK) << + XADCPS_SEQ_CH_AUX_SHIFT; + + return RegValAcq; +} + +/****************************************************************************/ +/** +* +* This functions sets the contents of the given Alarm Threshold Register. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param AlarmThrReg is the index of an Alarm Threshold Register to +* be set. Use XADCPS_ATR_* constants defined in xadcps.h to +* specify the index. +* @param Value is the 16-bit threshold value to write into the register. +* +* @return None. +* +* @note Use XAdcPs_SetOverTemp() to set the Over Temperature upper +* threshold value. +* +*****************************************************************************/ +void XAdcPs_SetAlarmThreshold(XAdcPs *InstancePtr, u8 AlarmThrReg, u16 Value) +{ + + /* + * Assert the arguments. + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid(AlarmThrReg <= XADCPS_ATR_VCCPDRO_LOWER); + + /* + * Write the value into the specified Alarm Threshold Register. + */ + XAdcPs_WriteInternalReg(InstancePtr, XADCPS_ATR_TEMP_UPPER_OFFSET + + AlarmThrReg,Value); + +} + +/****************************************************************************/ +/** +* +* This function returns the contents of the specified Alarm Threshold Register. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param AlarmThrReg is the index of an Alarm Threshold Register +* to be read. Use XADCPS_ATR_* constants defined in xadcps_hw.h +* to specify the index. +* +* @return A 16-bit value representing the contents of the selected Alarm +* Threshold Register. +* +* @note None. +* +*****************************************************************************/ +u16 XAdcPs_GetAlarmThreshold(XAdcPs *InstancePtr, u8 AlarmThrReg) +{ + u32 RegData; + /* + * Assert the arguments. + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid(AlarmThrReg <= XADCPS_ATR_VCCPDRO_LOWER); + + /* + * Read the specified Alarm Threshold Register and return + * the value + */ + RegData = XAdcPs_ReadInternalReg(InstancePtr, + (XADCPS_ATR_TEMP_UPPER_OFFSET + AlarmThrReg)); + + return (u16) RegData; +} + + +/****************************************************************************/ +/** +* +* This function enables programming of the powerdown temperature for the +* OverTemp signal in the OT Powerdown register. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XAdcPs_EnableUserOverTemp(XAdcPs *InstancePtr) +{ + u16 OtUpper; + + /* + * Assert the arguments. + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the OT upper Alarm Threshold Register. + */ + OtUpper = XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_ATR_OT_UPPER_OFFSET); + OtUpper &= ~(XADCPS_ATR_OT_UPPER_ENB_MASK); + + /* + * Preserve the powerdown value and write OT enable value the into the + * OT Upper Alarm Threshold Register. + */ + OtUpper |= XADCPS_ATR_OT_UPPER_ENB_VAL; + XAdcPs_WriteInternalReg(InstancePtr, + XADCPS_ATR_OT_UPPER_OFFSET, OtUpper); +} + +/****************************************************************************/ +/** +* +* This function disables programming of the powerdown temperature for the +* OverTemp signal in the OT Powerdown register. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @return None. +* +* @note None. +* +* +*****************************************************************************/ +void XAdcPs_DisableUserOverTemp(XAdcPs *InstancePtr) +{ + u16 OtUpper; + + /* + * Assert the arguments. + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the OT Upper Alarm Threshold Register. + */ + OtUpper = XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_ATR_OT_UPPER_OFFSET); + OtUpper &= ~(XADCPS_ATR_OT_UPPER_ENB_MASK); + + XAdcPs_WriteInternalReg(InstancePtr, + XADCPS_ATR_OT_UPPER_OFFSET, OtUpper); +} + + +/****************************************************************************/ +/** +* +* The function enables the Event mode or Continuous mode in the sequencer mode. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param IsEventMode is a boolean parameter that specifies continuous +* sampling (specify FALSE) or event driven sampling mode (specify +* TRUE) for the given channel. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XAdcPs_SetSequencerEvent(XAdcPs *InstancePtr, int IsEventMode) +{ + u32 RegValue; + + /* + * Assert the arguments. + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid((IsEventMode == TRUE) || (IsEventMode == FALSE)); + + /* + * Read the Configuration Register 0. + */ + RegValue = XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_CFR0_OFFSET) & + (~XADCPS_CFR0_EC_MASK); + + /* + * Set the ADC mode. + */ + if (IsEventMode == TRUE) { + RegValue |= XADCPS_CFR0_EC_MASK; + } else { + RegValue &= ~XADCPS_CFR0_EC_MASK; + } + + XAdcPs_WriteInternalReg(InstancePtr, XADCPS_CFR0_OFFSET, + RegValue); +} + + +/****************************************************************************/ +/** +* +* This function returns the sampling mode. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @return The sampling mode +* - 0 specifies continuous sampling +* - 1 specifies event driven sampling mode +* +* @note None. +* +*****************************************************************************/ +int XAdcPs_GetSamplingMode(XAdcPs *InstancePtr) +{ + u32 Mode; + + /* + * Assert the arguments. + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the sampling mode from the Configuration Register 0. + */ + Mode = XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_CFR0_OFFSET) & + XADCPS_CFR0_EC_MASK; + if (Mode) { + + return 1; + } + + return (0); +} + + +/****************************************************************************/ +/** +* +* This function sets the External Mux mode. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param MuxMode specifies whether External Mux is used +* - FALSE specifies NO external MUX +* - TRUE specifies External Mux is used +* @param Channel specifies the channel to be used for the +* external Mux. Please read the Device Spec for which +* channels are valid for which mode. +* +* @return None. +* +* @note There is no Assert in this function for checking the channel +* number if the external Mux is used. The user should provide a +* valid channel number. +* +*****************************************************************************/ +void XAdcPs_SetMuxMode(XAdcPs *InstancePtr, int MuxMode, u8 Channel) +{ + u32 RegValue; + + /* + * Assert the arguments. + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid((MuxMode == TRUE) || (MuxMode == FALSE)); + + /* + * Read the Configuration Register 0. + */ + RegValue = XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_CFR0_OFFSET) & + (~XADCPS_CFR0_MUX_MASK); + /* + * Select the Mux mode and the channel to be used. + */ + if (MuxMode == TRUE) { + RegValue |= XADCPS_CFR0_MUX_MASK; + RegValue |= (Channel & XADCPS_CFR0_CHANNEL_MASK); + + } + + /* + * Write the mux mode into the Configuration Register 0. + */ + XAdcPs_WriteInternalReg(InstancePtr, XADCPS_CFR0_OFFSET, + RegValue); +} + + +/****************************************************************************/ +/** +* +* This function sets the Power Down mode. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param Mode specifies the Power Down Mode +* - XADCPS_PD_MODE_NONE specifies NO Power Down (Both ADC A and +* ADC B are enabled) +* - XADCPS_PD_MODE_ADCB specfies the Power Down of ADC B +* - XADCPS_PD_MODE_XADC specifies the Power Down of +* both ADC A and ADC B. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XAdcPs_SetPowerdownMode(XAdcPs *InstancePtr, u32 Mode) +{ + u32 RegValue; + + /* + * Assert the arguments. + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid(Mode < XADCPS_PD_MODE_XADC); + + + /* + * Read the Configuration Register 2. + */ + RegValue = XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_CFR2_OFFSET) & + (~XADCPS_CFR2_PD_MASK); + /* + * Select the Power Down mode. + */ + RegValue |= (Mode << XADCPS_CFR2_PD_SHIFT); + + XAdcPs_WriteInternalReg(InstancePtr, XADCPS_CFR2_OFFSET, + RegValue); +} + +/****************************************************************************/ +/** +* +* This function gets the Power Down mode. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @return Mode specifies the Power Down Mode +* - XADCPS_PD_MODE_NONE specifies NO Power Down (Both ADC A and +* ADC B are enabled) +* - XADCPS_PD_MODE_ADCB specfies the Power Down of ADC B +* - XADCPS_PD_MODE_XADC specifies the Power Down of +* both ADC A and ADC B. +* +* @note None. +* +*****************************************************************************/ +u32 XAdcPs_GetPowerdownMode(XAdcPs *InstancePtr) +{ + u32 RegValue; + + /* + * Assert the arguments. + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the Power Down Mode. + */ + RegValue = XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_CFR2_OFFSET) & + (~XADCPS_CFR2_PD_MASK); + /* + * Return the Power Down mode. + */ + return (RegValue >> XADCPS_CFR2_PD_SHIFT); + +} + +/****************************************************************************/ +/** +* +* This function is used for writing to XADC Registers using the command FIFO. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param RegOffset is the offset of the XADC register to be written. +* @param Data is the data to be written. +* +* @return None. +* +* @note None. +* +* +*****************************************************************************/ +void XAdcPs_WriteInternalReg(XAdcPs *InstancePtr, u32 RegOffset, u32 Data) +{ + u32 RegData; + + /* + * Write the Data into the FIFO Register. + */ + RegData = XAdcPs_FormatWriteData(RegOffset, Data, TRUE); + + XAdcPs_WriteFifo(InstancePtr, RegData); + + /* Read the Read FIFO after any write since for each write + * one location of Read FIFO gets updated + */ + XAdcPs_ReadFifo(InstancePtr); + +} + + +/****************************************************************************/ +/** +* +* This function is used for reading from the XADC Registers using the Data FIFO. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param RegOffset is the offset of the XADC register to be read. +* +* @return Data read from the FIFO +* +* @note None. +* +* +*****************************************************************************/ +u32 XAdcPs_ReadInternalReg(XAdcPs *InstancePtr, u32 RegOffset) +{ + + u32 RegData; + + RegData = XAdcPs_FormatWriteData(RegOffset, 0x0, FALSE); + + /* Read cmd to FIFO*/ + XAdcPs_WriteFifo(InstancePtr, RegData); + + /* Do a Dummy read */ + RegData = XAdcPs_ReadFifo(InstancePtr); + + /* Do a Dummy write to get the actual read */ + XAdcPs_WriteFifo(InstancePtr, RegData); + + /* Do the Actual read */ + RegData = XAdcPs_ReadFifo(InstancePtr); + + return RegData; + +} +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/xadcps.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/xadcps.h new file mode 100644 index 0000000..900edf0 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/xadcps.h @@ -0,0 +1,589 @@ +/****************************************************************************** +* +* Copyright (C) 2011 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xadcps.h +* @addtogroup xadcps_v2_3 +* @{ +* @details +* +* The XAdcPs driver supports the Xilinx XADC/ADC device. +* +* The XADC/ADC device has the following features: +* - 10-bit, 200-KSPS (kilo samples per second) +* Analog-to-Digital Converter (ADC) +* - Monitoring of on-chip supply voltages and temperature +* - 1 dedicated differential analog-input pair and +* 16 auxiliary differential analog-input pairs +* - Automatic alarms based on user defined limits for the on-chip +* supply voltages and temperature +* - Automatic Channel Sequencer, programmable averaging, programmable +* acquisition time for the external inputs, unipolar or differential +* input selection for the external inputs +* - Inbuilt Calibration +* - Optional interrupt request generation +* +* +* The user should refer to the hardware device specification for detailed +* information about the device. +* +* This header file contains the prototypes of driver functions that can +* be used to access the XADC/ADC device. +* +* +* XADC Channel Sequencer Modes +* +* The XADC Channel Sequencer supports the following operating modes: +* +* - Default : This is the default mode after power up. +* In this mode of operation the XADC operates in +* a sequence mode, monitoring the on chip sensors: +* Temperature, VCCINT, and VCCAUX. +* - One pass through sequence : In this mode the XADC +* converts the channels enabled in the Sequencer Channel Enable +* registers for a single pass and then stops. +* - Continuous cycling of sequence : In this mode the XADC +* converts the channels enabled in the Sequencer Channel Enable +* registers continuously. +* - Single channel mode: In this mode the XADC Channel +* Sequencer is disabled and the XADC operates in a +* Single Channel Mode. +* The XADC can operate either in a Continuous or Event +* driven sampling mode in the single channel mode. +* - Simultaneous Sampling Mode: In this mode the XADC Channel +* Sequencer will automatically sequence through eight fixed pairs +* of auxiliary analog input channels for simulataneous conversion. +* - Independent ADC mode: In this mode the first ADC (A) is used to +* is used to implement a fixed monitoring mode similar to the +* default mode but the alarm fucntions ar eenabled. +* The second ADC (B) is available to be used with external analog +* input channels only. +* +* Read the XADC spec for more information about the sequencer modes. +* +* Initialization and Configuration +* +* The device driver enables higher layer software (e.g., an application) to +* communicate to the XADC/ADC device. +* +* XAdcPs_CfgInitialize() API is used to initialize the XADC/ADC +* device. The user needs to first call the XAdcPs_LookupConfig() API which +* returns the Configuration structure pointer which is passed as a parameter to +* the XAdcPs_CfgInitialize() API. +* +* +* Interrupts +* +* The XADC/ADC device supports interrupt driven mode and the default +* operation mode is polling mode. +* +* The interrupt mode is available only if hardware is configured to support +* interrupts. +* +* This driver does not provide a Interrupt Service Routine (ISR) for the device. +* It is the responsibility of the application to provide one if needed. Refer to +* the interrupt example provided with this driver for details on using the +* device in interrupt mode. +* +* +* Virtual Memory +* +* This driver supports Virtual Memory. The RTOS is responsible for calculating +* the correct device base address in Virtual Memory space. +* +* +* Threads +* +* This driver is not thread safe. Any needs for threads or thread mutual +* exclusion must be satisfied by the layer above this driver. +* +* +* Asserts +* +* Asserts are used within all Xilinx drivers to enforce constraints on argument +* values. Asserts can be turned off on a system-wide basis by defining, at +* compile time, the NDEBUG identifier. By default, asserts are turned on and it +* is recommended that users leave asserts on during development. +* +* +* Building the driver +* +* The XAdcPs driver is composed of several source files. This allows the user +* to build and link only those parts of the driver that are necessary. +* +* Limitations of the driver +* +* XADC/ADC device can be accessed through the JTAG port and the PLB +* interface. The driver implementation does not support the simultaneous access +* of the device by both these interfaces. The user has to care of this situation +* in the user application code. +* +*

+* +*
+*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date     Changes
+* ----- -----  -------- -----------------------------------------------------
+* 1.00a ssb    12/22/11 First release based on the XPS/AXI xadc driver
+* 1.01a bss    02/18/13	Modified XAdcPs_SetSeqChEnables,XAdcPs_SetSeqAvgEnables
+*			XAdcPs_SetSeqInputMode and XAdcPs_SetSeqAcqTime APIs
+*			in xadcps.c to fix CR #693371
+* 1.03a bss    11/01/13 Modified xadcps_hw.h to use correct Register offsets
+*			CR#749687
+* 2.1   bss    08/05/14 Added declarations for XAdcPs_SetSequencerEvent,
+*			XAdcPs_GetSamplingMode, XAdcPs_SetMuxMode,
+*			XAdcPs_SetPowerdownMode and XAdcPs_GetPowerdownMode
+*			functions.
+*			Modified Assert for XAdcPs_SetSingleChParams in
+*			xadcps.c to fix CR #807563.
+* 2.2   bss    04/27/14 Modified to use correct Device Config base address in
+*						xadcps.c (CR#854437).
+*       ms     01/23/17 Added xil_printf statement in main function for all
+*                       examples to ensure that "Successfully ran" and "Failed"
+*                       strings are available in all examples. This is a fix
+*                       for CR-965028.
+*       ms     03/17/17 Added readme.txt file in examples folder for doxygen
+*                       generation.
+*       ms     04/05/17 Modified Comment lines in functions of xadcps
+*                       examples to recognize it as documentation block
+*                       for doxygen generation.
+* 2.3   mn     07/09/18 Fix Doxygen warning
+*
+* 
+* +*****************************************************************************/ +#ifndef XADCPS_H /* Prevent circular inclusions */ +#define XADCPS_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files ********************************/ + +#include "xil_types.h" +#include "xil_assert.h" +#include "xstatus.h" +#include "xadcps_hw.h" + +/************************** Constant Definitions ****************************/ + + +/** + * @name Indexes for the different channels. + * @{ + */ +#define XADCPS_CH_TEMP 0x0 /**< On Chip Temperature */ +#define XADCPS_CH_VCCINT 0x1 /**< VCCINT */ +#define XADCPS_CH_VCCAUX 0x2 /**< VCCAUX */ +#define XADCPS_CH_VPVN 0x3 /**< VP/VN Dedicated analog inputs */ +#define XADCPS_CH_VREFP 0x4 /**< VREFP */ +#define XADCPS_CH_VREFN 0x5 /**< VREFN */ +#define XADCPS_CH_VBRAM 0x6 /**< On-chip VBRAM Data Reg, 7 series */ +#define XADCPS_CH_SUPPLY_CALIB 0x07 /**< Supply Calib Data Reg */ +#define XADCPS_CH_ADC_CALIB 0x08 /**< ADC Offset Channel Reg */ +#define XADCPS_CH_GAINERR_CALIB 0x09 /**< Gain Error Channel Reg */ +#define XADCPS_CH_VCCPINT 0x0D /**< On-chip PS VCCPINT Channel , Zynq */ +#define XADCPS_CH_VCCPAUX 0x0E /**< On-chip PS VCCPAUX Channel , Zynq */ +#define XADCPS_CH_VCCPDRO 0x0F /**< On-chip PS VCCPDRO Channel , Zynq */ +#define XADCPS_CH_AUX_MIN 16 /**< Channel number for 1st Aux Channel */ +#define XADCPS_CH_AUX_MAX 31 /**< Channel number for Last Aux channel */ + +/*@}*/ + + +/** + * @name Indexes for reading the Calibration Coefficient Data. + * @{ + */ +#define XADCPS_CALIB_SUPPLY_COEFF 0 /**< Supply Offset Calib Coefficient */ +#define XADCPS_CALIB_ADC_COEFF 1 /**< ADC Offset Calib Coefficient */ +#define XADCPS_CALIB_GAIN_ERROR_COEFF 2 /**< Gain Error Calib Coefficient*/ +/*@}*/ + + +/** + * @name Indexes for reading the Minimum/Maximum Measurement Data. + * @{ + */ +#define XADCPS_MAX_TEMP 0 /**< Maximum Temperature Data */ +#define XADCPS_MAX_VCCINT 1 /**< Maximum VCCINT Data */ +#define XADCPS_MAX_VCCAUX 2 /**< Maximum VCCAUX Data */ +#define XADCPS_MAX_VBRAM 3 /**< Maximum VBRAM Data */ +#define XADCPS_MIN_TEMP 4 /**< Minimum Temperature Data */ +#define XADCPS_MIN_VCCINT 5 /**< Minimum VCCINT Data */ +#define XADCPS_MIN_VCCAUX 6 /**< Minimum VCCAUX Data */ +#define XADCPS_MIN_VBRAM 7 /**< Minimum VBRAM Data */ +#define XADCPS_MAX_VCCPINT 8 /**< Maximum VCCPINT Register , Zynq */ +#define XADCPS_MAX_VCCPAUX 9 /**< Maximum VCCPAUX Register , Zynq */ +#define XADCPS_MAX_VCCPDRO 0xA /**< Maximum VCCPDRO Register , Zynq */ +#define XADCPS_MIN_VCCPINT 0xC /**< Minimum VCCPINT Register , Zynq */ +#define XADCPS_MIN_VCCPAUX 0xD /**< Minimum VCCPAUX Register , Zynq */ +#define XADCPS_MIN_VCCPDRO 0xE /**< Minimum VCCPDRO Register , Zynq */ + +/*@}*/ + + +/** + * @name Alarm Threshold(Limit) Register (ATR) indexes. + * @{ + */ +#define XADCPS_ATR_TEMP_UPPER 0 /**< High user Temperature */ +#define XADCPS_ATR_VCCINT_UPPER 1 /**< VCCINT high voltage limit register */ +#define XADCPS_ATR_VCCAUX_UPPER 2 /**< VCCAUX high voltage limit register */ +#define XADCPS_ATR_OT_UPPER 3 /**< VCCAUX high voltage limit register */ +#define XADCPS_ATR_TEMP_LOWER 4 /**< Upper Over Temperature limit Reg */ +#define XADCPS_ATR_VCCINT_LOWER 5 /**< VCCINT high voltage limit register */ +#define XADCPS_ATR_VCCAUX_LOWER 6 /**< VCCAUX low voltage limit register */ +#define XADCPS_ATR_OT_LOWER 7 /**< Lower Over Temperature limit */ +#define XADCPS_ATR_VBRAM_UPPER_ 8 /**< VRBAM Upper Alarm Reg, 7 Series */ +#define XADCPS_ATR_VCCPINT_UPPER 9 /**< VCCPINT Upper Alarm Reg, Zynq */ +#define XADCPS_ATR_VCCPAUX_UPPER 0xA /**< VCCPAUX Upper Alarm Reg, Zynq */ +#define XADCPS_ATR_VCCPDRO_UPPER 0xB /**< VCCPDRO Upper Alarm Reg, Zynq */ +#define XADCPS_ATR_VBRAM_LOWER 0xC /**< VRBAM Lower Alarm Reg, 7 Series */ +#define XADCPS_ATR_VCCPINT_LOWER 0xD /**< VCCPINT Lower Alarm Reg , Zynq */ +#define XADCPS_ATR_VCCPAUX_LOWER 0xE /**< VCCPAUX Lower Alarm Reg , Zynq */ +#define XADCPS_ATR_VCCPDRO_LOWER 0xF /**< VCCPDRO Lower Alarm Reg , Zynq */ + +/*@}*/ + + +/** + * @name Averaging to be done for the channels. + * @{ + */ +#define XADCPS_AVG_0_SAMPLES 0 /**< No Averaging */ +#define XADCPS_AVG_16_SAMPLES 1 /**< Average 16 samples */ +#define XADCPS_AVG_64_SAMPLES 2 /**< Average 64 samples */ +#define XADCPS_AVG_256_SAMPLES 3 /**< Average 256 samples */ + +/*@}*/ + + +/** + * @name Channel Sequencer Modes of operation + * @{ + */ +#define XADCPS_SEQ_MODE_SAFE 0 /**< Default Safe Mode */ +#define XADCPS_SEQ_MODE_ONEPASS 1 /**< Onepass through Sequencer */ +#define XADCPS_SEQ_MODE_CONTINPASS 2 /**< Continuous Cycling Sequencer */ +#define XADCPS_SEQ_MODE_SINGCHAN 3 /**< Single channel -No Sequencing */ +#define XADCPS_SEQ_MODE_SIMUL_SAMPLING 4 /**< Simultaneous sampling */ +#define XADCPS_SEQ_MODE_INDEPENDENT 8 /**< Independent mode */ + +/*@}*/ + + + +/** + * @name Power Down Modes + * @{ + */ +#define XADCPS_PD_MODE_NONE 0 /**< No Power Down */ +#define XADCPS_PD_MODE_ADCB 1 /**< Power Down ADC B */ +#define XADCPS_PD_MODE_XADC 2 /**< Power Down ADC A and ADC B */ +/*@}*/ + +/**************************** Type Definitions ******************************/ + +/** + * This typedef contains configuration information for the XADC/ADC + * device. + */ +typedef struct { + u16 DeviceId; /**< Unique ID of device */ + u32 BaseAddress; /**< Device base address */ +} XAdcPs_Config; + + +/** + * The driver's instance data. The user is required to allocate a variable + * of this type for every XADC/ADC device in the system. A pointer to + * a variable of this type is then passed to the driver API functions. + */ +typedef struct { + XAdcPs_Config Config; /**< XAdcPs_Config of current device */ + u32 IsReady; /**< Device is initialized and ready */ + +} XAdcPs; + +/***************** Macros (Inline Functions) Definitions ********************/ + +/****************************************************************************/ +/** +* +* This macro checks if the XADC device is in Event Sampling mode. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @return +* - TRUE if the device is in Event Sampling Mode. +* - FALSE if the device is in Continuous Sampling Mode. +* +* @note C-Style signature: +* int XAdcPs_IsEventSamplingMode(XAdcPs *InstancePtr); +* +*****************************************************************************/ +#define XAdcPs_IsEventSamplingModeSet(InstancePtr) \ + (((XAdcPs_ReadInternalReg(InstancePtr, \ + XADCPS_CFR0_OFFSET) & XADCPS_CFR0_EC_MASK) ? \ + TRUE : FALSE)) + + +/****************************************************************************/ +/** +* +* This macro checks if the XADC device is in External Mux mode. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @return +* - TRUE if the device is in External Mux Mode. +* - FALSE if the device is NOT in External Mux Mode. +* +* @note C-Style signature: +* int XAdcPs_IsExternalMuxMode(XAdcPs *InstancePtr); +* +*****************************************************************************/ +#define XAdcPs_IsExternalMuxModeSet(InstancePtr) \ + (((XAdcPs_ReadInternalReg(InstancePtr, \ + XADCPS_CFR0_OFFSET) & XADCPS_CFR0_MUX_MASK) ? \ + TRUE : FALSE)) + +/****************************************************************************/ +/** +* +* This macro converts XADC Raw Data to Temperature(centigrades). +* +* @param AdcData is the Raw ADC Data from XADC. +* +* @return The Temperature in centigrades. +* +* @note C-Style signature: +* float XAdcPs_RawToTemperature(u32 AdcData); +* +*****************************************************************************/ +#define XAdcPs_RawToTemperature(AdcData) \ + ((((float)(AdcData)/65536.0f)/0.00198421639f ) - 273.15f) + +/****************************************************************************/ +/** +* +* This macro converts XADC/ADC Raw Data to Voltage(volts). +* +* @param AdcData is the XADC/ADC Raw Data. +* +* @return The Voltage in volts. +* +* @note C-Style signature: +* float XAdcPs_RawToVoltage(u32 AdcData); +* +*****************************************************************************/ +#define XAdcPs_RawToVoltage(AdcData) \ + ((((float)(AdcData))* (3.0f))/65536.0f) + +/****************************************************************************/ +/** +* +* This macro converts Temperature in centigrades to XADC/ADC Raw Data. +* +* @param Temperature is the Temperature in centigrades to be +* converted to XADC/ADC Raw Data. +* +* @return The XADC/ADC Raw Data. +* +* @note C-Style signature: +* int XAdcPs_TemperatureToRaw(float Temperature); +* +*****************************************************************************/ +#define XAdcPs_TemperatureToRaw(Temperature) \ + ((int)(((Temperature) + 273.15f)*65536.0f*0.00198421639f)) + +/****************************************************************************/ +/** +* +* This macro converts Voltage in Volts to XADC/ADC Raw Data. +* +* @param Voltage is the Voltage in volts to be converted to +* XADC/ADC Raw Data. +* +* @return The XADC/ADC Raw Data. +* +* @note C-Style signature: +* int XAdcPs_VoltageToRaw(float Voltage); +* +*****************************************************************************/ +#define XAdcPs_VoltageToRaw(Voltage) \ + ((int)((Voltage)*65536.0f/3.0f)) + + +/****************************************************************************/ +/** +* +* This macro is used for writing to the XADC Registers using the +* command FIFO. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param Data is the value to be written to XADC register. +* +* @return None. +* +* @note C-Style signature: +* void XAdcPs_WriteFifo(XAdcPs *InstancePtr, u32 Data); +* +*****************************************************************************/ +#define XAdcPs_WriteFifo(InstancePtr, Data) \ + XAdcPs_WriteReg((InstancePtr)->Config.BaseAddress, \ + XADCPS_CMDFIFO_OFFSET, Data); + + +/****************************************************************************/ +/** +* +* This macro is used for reading from the XADC Registers using the +* data FIFO. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @return Data read from the FIFO +* +* @note C-Style signature: +* u32 XAdcPs_ReadFifo(XAdcPs *InstancePtr); +* +*****************************************************************************/ +#define XAdcPs_ReadFifo(InstancePtr) \ + XAdcPs_ReadReg((InstancePtr)->Config.BaseAddress, \ + XADCPS_RDFIFO_OFFSET); + + +/************************** Function Prototypes *****************************/ + + + +/** + * Functions in xadcps_sinit.c + */ +XAdcPs_Config *XAdcPs_LookupConfig(u16 DeviceId); + +/** + * Functions in xadcps.c + */ +int XAdcPs_CfgInitialize(XAdcPs *InstancePtr, + XAdcPs_Config *ConfigPtr, + u32 EffectiveAddr); + + +u32 XAdcPs_GetStatus(XAdcPs *InstancePtr); + +u32 XAdcPs_GetAlarmOutputStatus(XAdcPs *InstancePtr); + +void XAdcPs_StartAdcConversion(XAdcPs *InstancePtr); + +void XAdcPs_Reset(XAdcPs *InstancePtr); + +u16 XAdcPs_GetAdcData(XAdcPs *InstancePtr, u8 Channel); + +u16 XAdcPs_GetCalibCoefficient(XAdcPs *InstancePtr, u8 CoeffType); + +u16 XAdcPs_GetMinMaxMeasurement(XAdcPs *InstancePtr, u8 MeasurementType); + +void XAdcPs_SetAvg(XAdcPs *InstancePtr, u8 Average); +u8 XAdcPs_GetAvg(XAdcPs *InstancePtr); + +int XAdcPs_SetSingleChParams(XAdcPs *InstancePtr, + u8 Channel, + int IncreaseAcqCycles, + int IsEventMode, + int IsDifferentialMode); + + +void XAdcPs_SetAlarmEnables(XAdcPs *InstancePtr, u16 AlmEnableMask); +u16 XAdcPs_GetAlarmEnables(XAdcPs *InstancePtr); + +void XAdcPs_SetCalibEnables(XAdcPs *InstancePtr, u16 Calibration); +u16 XAdcPs_GetCalibEnables(XAdcPs *InstancePtr); + +void XAdcPs_SetSequencerMode(XAdcPs *InstancePtr, u8 SequencerMode); +u8 XAdcPs_GetSequencerMode(XAdcPs *InstancePtr); + +void XAdcPs_SetAdcClkDivisor(XAdcPs *InstancePtr, u8 Divisor); +u8 XAdcPs_GetAdcClkDivisor(XAdcPs *InstancePtr); + +int XAdcPs_SetSeqChEnables(XAdcPs *InstancePtr, u32 ChEnableMask); +u32 XAdcPs_GetSeqChEnables(XAdcPs *InstancePtr); + +int XAdcPs_SetSeqAvgEnables(XAdcPs *InstancePtr, u32 AvgEnableChMask); +u32 XAdcPs_GetSeqAvgEnables(XAdcPs *InstancePtr); + +int XAdcPs_SetSeqInputMode(XAdcPs *InstancePtr, u32 InputModeChMask); +u32 XAdcPs_GetSeqInputMode(XAdcPs *InstancePtr); + +int XAdcPs_SetSeqAcqTime(XAdcPs *InstancePtr, u32 AcqCyclesChMask); +u32 XAdcPs_GetSeqAcqTime(XAdcPs *InstancePtr); + +void XAdcPs_SetAlarmThreshold(XAdcPs *InstancePtr, u8 AlarmThrReg, u16 Value); +u16 XAdcPs_GetAlarmThreshold(XAdcPs *InstancePtr, u8 AlarmThrReg); + +void XAdcPs_EnableUserOverTemp(XAdcPs *InstancePtr); +void XAdcPs_DisableUserOverTemp(XAdcPs *InstancePtr); + +void XAdcPs_SetSequencerEvent(XAdcPs *InstancePtr, int IsEventMode); + +int XAdcPs_GetSamplingMode(XAdcPs *InstancePtr); + +void XAdcPs_SetMuxMode(XAdcPs *InstancePtr, int MuxMode, u8 Channel); + +void XAdcPs_SetPowerdownMode(XAdcPs *InstancePtr, u32 Mode); + +u32 XAdcPs_GetPowerdownMode(XAdcPs *InstancePtr); + +/** + * Functions in xadcps_selftest.c + */ +int XAdcPs_SelfTest(XAdcPs *InstancePtr); + +/** + * Functions in xadcps_intr.c + */ +void XAdcPs_IntrEnable(XAdcPs *InstancePtr, u32 Mask); +void XAdcPs_IntrDisable(XAdcPs *InstancePtr, u32 Mask); +u32 XAdcPs_IntrGetEnabled(XAdcPs *InstancePtr); + +u32 XAdcPs_IntrGetStatus(XAdcPs *InstancePtr); +void XAdcPs_IntrClear(XAdcPs *InstancePtr, u32 Mask); + + +#ifdef __cplusplus +} +#endif + +#endif /* End of protection macro. */ +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/xadcps_g.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/xadcps_g.c new file mode 100644 index 0000000..abcd1ec --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/xadcps_g.c @@ -0,0 +1,51 @@ + +/******************************************************************* +* +* CAUTION: This file is automatically generated by HSI. +* Version: 2019.1.3 +* DO NOT EDIT. +* +* Copyright (C) 2010-2023 Xilinx, Inc. All Rights Reserved.* +*Permission is hereby granted, free of charge, to any person obtaining a copy +*of this software and associated documentation files (the Software), to deal +*in the Software without restriction, including without limitation the rights +*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +*copies of the Software, and to permit persons to whom the Software is +*furnished to do so, subject to the following conditions: +* +*The above copyright notice and this permission notice shall be included in +*all copies or substantial portions of the Software. +* +*THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +*XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +*OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*Except as contained in this notice, the name of the Xilinx shall not be used +*in advertising or otherwise to promote the sale, use or other dealings in +*this Software without prior written authorization from Xilinx. +* + +* +* Description: Driver configuration +* +*******************************************************************/ + +#include "xparameters.h" +#include "xadcps.h" + +/* +* The configuration table for devices +*/ + +XAdcPs_Config XAdcPs_ConfigTable[XPAR_XADCPS_NUM_INSTANCES] = +{ + { + XPAR_PS7_XADC_0_DEVICE_ID, + XPAR_PS7_XADC_0_BASEADDR + } +}; + + diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/xadcps_hw.h b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/xadcps_hw.h new file mode 100644 index 0000000..dd51473 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/xadcps_hw.h @@ -0,0 +1,498 @@ +/****************************************************************************** +* +* Copyright (C) 2011 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xadcps_hw.h +* @addtogroup xadcps_v2_3 +* @{ +* +* This header file contains identifiers and basic driver functions (or +* macros) that can be used to access the XADC device through the Device +* Config Interface of the Zynq. +* +* +* Refer to the device specification for more information about this driver. +* +* @note None. +* +* +*
+*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date     Changes
+* ----- -----  -------- -----------------------------------------------------
+* 1.00a bss    12/22/11 First release based on the XPS/AXI xadc driver
+* 1.03a bss    11/01/13 Modified macros to use correct Register offsets
+*			CR#749687
+*
+* 
+* +*****************************************************************************/ +#ifndef XADCPS_HW_H /* Prevent circular inclusions */ +#define XADCPS_HW_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files ********************************/ + +#include "xil_types.h" +#include "xil_assert.h" +#include "xil_io.h" + +/************************** Constant Definitions ****************************/ + + +/**@name Register offsets of XADC in the Device Config + * + * The following constants provide access to each of the registers of the + * XADC device. + * @{ + */ + +#define XADCPS_CFG_OFFSET 0x00 /**< Configuration Register */ +#define XADCPS_INT_STS_OFFSET 0x04 /**< Interrupt Status Register */ +#define XADCPS_INT_MASK_OFFSET 0x08 /**< Interrupt Mask Register */ +#define XADCPS_MSTS_OFFSET 0x0C /**< Misc status register */ +#define XADCPS_CMDFIFO_OFFSET 0x10 /**< Command FIFO Register */ +#define XADCPS_RDFIFO_OFFSET 0x14 /**< Read FIFO Register */ +#define XADCPS_MCTL_OFFSET 0x18 /**< Misc control register */ + +/* @} */ + + + + + +/** @name XADC Config Register Bit definitions + * @{ + */ +#define XADCPS_CFG_ENABLE_MASK 0x80000000 /**< Enable access from PS mask */ +#define XADCPS_CFG_CFIFOTH_MASK 0x00F00000 /**< Command FIFO Threshold mask */ +#define XADCPS_CFG_DFIFOTH_MASK 0x000F0000 /**< Data FIFO Threshold mask */ +#define XADCPS_CFG_WEDGE_MASK 0x00002000 /**< Write Edge Mask */ +#define XADCPS_CFG_REDGE_MASK 0x00001000 /**< Read Edge Mask */ +#define XADCPS_CFG_TCKRATE_MASK 0x00000300 /**< Clock freq control */ +#define XADCPS_CFG_IGAP_MASK 0x0000001F /**< Idle Gap between + * successive commands */ +/* @} */ + + +/** @name XADC Interrupt Status/Mask Register Bit definitions + * + * The definitions are same for the Interrupt Status Register and + * Interrupt Mask Register. They are defined only once. + * @{ + */ +#define XADCPS_INTX_ALL_MASK 0x000003FF /**< Alarm Signals Mask */ +#define XADCPS_INTX_CFIFO_LTH_MASK 0x00000200 /**< CMD FIFO less than threshold */ +#define XADCPS_INTX_DFIFO_GTH_MASK 0x00000100 /**< Data FIFO greater than threshold */ +#define XADCPS_INTX_OT_MASK 0x00000080 /**< Over temperature Alarm Status */ +#define XADCPS_INTX_ALM_ALL_MASK 0x0000007F /**< Alarm Signals Mask */ +#define XADCPS_INTX_ALM6_MASK 0x00000040 /**< Alarm 6 Mask */ +#define XADCPS_INTX_ALM5_MASK 0x00000020 /**< Alarm 5 Mask */ +#define XADCPS_INTX_ALM4_MASK 0x00000010 /**< Alarm 4 Mask */ +#define XADCPS_INTX_ALM3_MASK 0x00000008 /**< Alarm 3 Mask */ +#define XADCPS_INTX_ALM2_MASK 0x00000004 /**< Alarm 2 Mask */ +#define XADCPS_INTX_ALM1_MASK 0x00000002 /**< Alarm 1 Mask */ +#define XADCPS_INTX_ALM0_MASK 0x00000001 /**< Alarm 0 Mask */ + +/* @} */ + + +/** @name XADC Miscellaneous Register Bit definitions + * @{ + */ +#define XADCPS_MSTS_CFIFO_LVL_MASK 0x000F0000 /**< Command FIFO Level mask */ +#define XADCPS_MSTS_DFIFO_LVL_MASK 0x0000F000 /**< Data FIFO Level Mask */ +#define XADCPS_MSTS_CFIFOF_MASK 0x00000800 /**< Command FIFO Full Mask */ +#define XADCPS_MSTS_CFIFOE_MASK 0x00000400 /**< Command FIFO Empty Mask */ +#define XADCPS_MSTS_DFIFOF_MASK 0x00000200 /**< Data FIFO Full Mask */ +#define XADCPS_MSTS_DFIFOE_MASK 0x00000100 /**< Data FIFO Empty Mask */ +#define XADCPS_MSTS_OT_MASK 0x00000080 /**< Over Temperature Mask */ +#define XADCPS_MSTS_ALM_MASK 0x0000007F /**< Alarms Mask */ +/* @} */ + + +/** @name XADC Miscellaneous Control Register Bit definitions + * @{ + */ +#define XADCPS_MCTL_RESET_MASK 0x00000010 /**< Reset XADC */ +#define XADCPS_MCTL_FLUSH_MASK 0x00000001 /**< Flush the FIFOs */ +/* @} */ + + +/**@name Internal Register offsets of the XADC + * + * The following constants provide access to each of the internal registers of + * the XADC device. + * @{ + */ + +/* + * XADC Internal Channel Registers + */ +#define XADCPS_TEMP_OFFSET 0x00 /**< On-chip Temperature Reg */ +#define XADCPS_VCCINT_OFFSET 0x01 /**< On-chip VCCINT Data Reg */ +#define XADCPS_VCCAUX_OFFSET 0x02 /**< On-chip VCCAUX Data Reg */ +#define XADCPS_VPVN_OFFSET 0x03 /**< ADC out of VP/VN */ +#define XADCPS_VREFP_OFFSET 0x04 /**< On-chip VREFP Data Reg */ +#define XADCPS_VREFN_OFFSET 0x05 /**< On-chip VREFN Data Reg */ +#define XADCPS_VBRAM_OFFSET 0x06 /**< On-chip VBRAM , 7 Series */ +#define XADCPS_ADC_A_SUPPLY_CALIB_OFFSET 0x08 /**< ADC A Supply Offset Reg */ +#define XADCPS_ADC_A_OFFSET_CALIB_OFFSET 0x09 /**< ADC A Offset Data Reg */ +#define XADCPS_ADC_A_GAINERR_CALIB_OFFSET 0x0A /**< ADC A Gain Error Reg */ +#define XADCPS_VCCPINT_OFFSET 0x0D /**< On-chip VCCPINT Reg, Zynq */ +#define XADCPS_VCCPAUX_OFFSET 0x0E /**< On-chip VCCPAUX Reg, Zynq */ +#define XADCPS_VCCPDRO_OFFSET 0x0F /**< On-chip VCCPDRO Reg, Zynq */ + +/* + * XADC External Channel Registers + */ +#define XADCPS_AUX00_OFFSET 0x10 /**< ADC out of VAUXP0/VAUXN0 */ +#define XADCPS_AUX01_OFFSET 0x11 /**< ADC out of VAUXP1/VAUXN1 */ +#define XADCPS_AUX02_OFFSET 0x12 /**< ADC out of VAUXP2/VAUXN2 */ +#define XADCPS_AUX03_OFFSET 0x13 /**< ADC out of VAUXP3/VAUXN3 */ +#define XADCPS_AUX04_OFFSET 0x14 /**< ADC out of VAUXP4/VAUXN4 */ +#define XADCPS_AUX05_OFFSET 0x15 /**< ADC out of VAUXP5/VAUXN5 */ +#define XADCPS_AUX06_OFFSET 0x16 /**< ADC out of VAUXP6/VAUXN6 */ +#define XADCPS_AUX07_OFFSET 0x17 /**< ADC out of VAUXP7/VAUXN7 */ +#define XADCPS_AUX08_OFFSET 0x18 /**< ADC out of VAUXP8/VAUXN8 */ +#define XADCPS_AUX09_OFFSET 0x19 /**< ADC out of VAUXP9/VAUXN9 */ +#define XADCPS_AUX10_OFFSET 0x1A /**< ADC out of VAUXP10/VAUXN10 */ +#define XADCPS_AUX11_OFFSET 0x1B /**< ADC out of VAUXP11/VAUXN11 */ +#define XADCPS_AUX12_OFFSET 0x1C /**< ADC out of VAUXP12/VAUXN12 */ +#define XADCPS_AUX13_OFFSET 0x1D /**< ADC out of VAUXP13/VAUXN13 */ +#define XADCPS_AUX14_OFFSET 0x1E /**< ADC out of VAUXP14/VAUXN14 */ +#define XADCPS_AUX15_OFFSET 0x1F /**< ADC out of VAUXP15/VAUXN15 */ + +/* + * XADC Registers for Maximum/Minimum data captured for the + * on chip Temperature/VCCINT/VCCAUX data. + */ +#define XADCPS_MAX_TEMP_OFFSET 0x20 /**< Max Temperature Reg */ +#define XADCPS_MAX_VCCINT_OFFSET 0x21 /**< Max VCCINT Register */ +#define XADCPS_MAX_VCCAUX_OFFSET 0x22 /**< Max VCCAUX Register */ +#define XADCPS_MAX_VCCBRAM_OFFSET 0x23 /**< Max BRAM Register, 7 series */ +#define XADCPS_MIN_TEMP_OFFSET 0x24 /**< Min Temperature Reg */ +#define XADCPS_MIN_VCCINT_OFFSET 0x25 /**< Min VCCINT Register */ +#define XADCPS_MIN_VCCAUX_OFFSET 0x26 /**< Min VCCAUX Register */ +#define XADCPS_MIN_VCCBRAM_OFFSET 0x27 /**< Min BRAM Register, 7 series */ +#define XADCPS_MAX_VCCPINT_OFFSET 0x28 /**< Max VCCPINT Register, Zynq */ +#define XADCPS_MAX_VCCPAUX_OFFSET 0x29 /**< Max VCCPAUX Register, Zynq */ +#define XADCPS_MAX_VCCPDRO_OFFSET 0x2A /**< Max VCCPDRO Register, Zynq */ +#define XADCPS_MIN_VCCPINT_OFFSET 0x2C /**< Min VCCPINT Register, Zynq */ +#define XADCPS_MIN_VCCPAUX_OFFSET 0x2D /**< Min VCCPAUX Register, Zynq */ +#define XADCPS_MIN_VCCPDRO_OFFSET 0x2E /**< Min VCCPDRO Register,Zynq */ + /* Undefined 0x2F to 0x3E */ +#define XADCPS_FLAG_OFFSET 0x3F /**< Flag Register */ + +/* + * XADC Configuration Registers + */ +#define XADCPS_CFR0_OFFSET 0x40 /**< Configuration Register 0 */ +#define XADCPS_CFR1_OFFSET 0x41 /**< Configuration Register 1 */ +#define XADCPS_CFR2_OFFSET 0x42 /**< Configuration Register 2 */ + +/* Test Registers 0x43 to 0x47 */ + +/* + * XADC Sequence Registers + */ +#define XADCPS_SEQ00_OFFSET 0x48 /**< Seq Reg 00 Adc Channel Selection */ +#define XADCPS_SEQ01_OFFSET 0x49 /**< Seq Reg 01 Adc Channel Selection */ +#define XADCPS_SEQ02_OFFSET 0x4A /**< Seq Reg 02 Adc Average Enable */ +#define XADCPS_SEQ03_OFFSET 0x4B /**< Seq Reg 03 Adc Average Enable */ +#define XADCPS_SEQ04_OFFSET 0x4C /**< Seq Reg 04 Adc Input Mode Select */ +#define XADCPS_SEQ05_OFFSET 0x4D /**< Seq Reg 05 Adc Input Mode Select */ +#define XADCPS_SEQ06_OFFSET 0x4E /**< Seq Reg 06 Adc Acquisition Select */ +#define XADCPS_SEQ07_OFFSET 0x4F /**< Seq Reg 07 Adc Acquisition Select */ + +/* + * XADC Alarm Threshold/Limit Registers (ATR) + */ +#define XADCPS_ATR_TEMP_UPPER_OFFSET 0x50 /**< Temp Upper Alarm Register */ +#define XADCPS_ATR_VCCINT_UPPER_OFFSET 0x51 /**< VCCINT Upper Alarm Reg */ +#define XADCPS_ATR_VCCAUX_UPPER_OFFSET 0x52 /**< VCCAUX Upper Alarm Reg */ +#define XADCPS_ATR_OT_UPPER_OFFSET 0x53 /**< Over Temp Upper Alarm Reg */ +#define XADCPS_ATR_TEMP_LOWER_OFFSET 0x54 /**< Temp Lower Alarm Register */ +#define XADCPS_ATR_VCCINT_LOWER_OFFSET 0x55 /**< VCCINT Lower Alarm Reg */ +#define XADCPS_ATR_VCCAUX_LOWER_OFFSET 0x56 /**< VCCAUX Lower Alarm Reg */ +#define XADCPS_ATR_OT_LOWER_OFFSET 0x57 /**< Over Temp Lower Alarm Reg */ +#define XADCPS_ATR_VBRAM_UPPER_OFFSET 0x58 /**< VBRAM Upper Alarm, 7 series */ +#define XADCPS_ATR_VCCPINT_UPPER_OFFSET 0x59 /**< VCCPINT Upper Alarm, Zynq */ +#define XADCPS_ATR_VCCPAUX_UPPER_OFFSET 0x5A /**< VCCPAUX Upper Alarm, Zynq */ +#define XADCPS_ATR_VCCPDRO_UPPER_OFFSET 0x5B /**< VCCPDRO Upper Alarm, Zynq */ +#define XADCPS_ATR_VBRAM_LOWER_OFFSET 0x5C /**< VRBAM Lower Alarm, 7 Series */ +#define XADCPS_ATR_VCCPINT_LOWER_OFFSET 0x5D /**< VCCPINT Lower Alarm, Zynq */ +#define XADCPS_ATR_VCCPAUX_LOWER_OFFSET 0x5E /**< VCCPAUX Lower Alarm, Zynq */ +#define XADCPS_ATR_VCCPDRO_LOWER_OFFSET 0x5F /**< VCCPDRO Lower Alarm, Zynq */ + +/* Undefined 0x60 to 0x7F */ + +/*@}*/ + + + +/** + * @name Configuration Register 0 (CFR0) mask(s) + * @{ + */ +#define XADCPS_CFR0_CAL_AVG_MASK 0x8000 /**< Averaging enable Mask */ +#define XADCPS_CFR0_AVG_VALID_MASK 0x3000 /**< Averaging bit Mask */ +#define XADCPS_CFR0_AVG1_MASK 0x0000 /**< No Averaging */ +#define XADCPS_CFR0_AVG16_MASK 0x1000 /**< Average 16 samples */ +#define XADCPS_CFR0_AVG64_MASK 0x2000 /**< Average 64 samples */ +#define XADCPS_CFR0_AVG256_MASK 0x3000 /**< Average 256 samples */ +#define XADCPS_CFR0_AVG_SHIFT 12 /**< Averaging bits shift */ +#define XADCPS_CFR0_MUX_MASK 0x0800 /**< External Mask Enable */ +#define XADCPS_CFR0_DU_MASK 0x0400 /**< Bipolar/Unipolar mode */ +#define XADCPS_CFR0_EC_MASK 0x0200 /**< Event driven/ + * Continuous mode selection + */ +#define XADCPS_CFR0_ACQ_MASK 0x0100 /**< Add acquisition by 6 ADCCLK */ +#define XADCPS_CFR0_CHANNEL_MASK 0x001F /**< Channel number bit Mask */ + +/*@}*/ + +/** + * @name Configuration Register 1 (CFR1) mask(s) + * @{ + */ +#define XADCPS_CFR1_SEQ_VALID_MASK 0xF000 /**< Sequence bit Mask */ +#define XADCPS_CFR1_SEQ_SAFEMODE_MASK 0x0000 /**< Default Safe Mode */ +#define XADCPS_CFR1_SEQ_ONEPASS_MASK 0x1000 /**< Onepass through Seq */ +#define XADCPS_CFR1_SEQ_CONTINPASS_MASK 0x2000 /**< Continuous Cycling Seq */ +#define XADCPS_CFR1_SEQ_SINGCHAN_MASK 0x3000 /**< Single channel - No Seq */ +#define XADCPS_CFR1_SEQ_SIMUL_SAMPLING_MASK 0x4000 /**< Simulataneous Sampling Mask */ +#define XADCPS_CFR1_SEQ_INDEPENDENT_MASK 0x8000 /**< Independent Mode */ +#define XADCPS_CFR1_SEQ_SHIFT 12 /**< Sequence bit shift */ +#define XADCPS_CFR1_ALM_VCCPDRO_MASK 0x0800 /**< Alm 6 - VCCPDRO, Zynq */ +#define XADCPS_CFR1_ALM_VCCPAUX_MASK 0x0400 /**< Alm 5 - VCCPAUX, Zynq */ +#define XADCPS_CFR1_ALM_VCCPINT_MASK 0x0200 /**< Alm 4 - VCCPINT, Zynq */ +#define XADCPS_CFR1_ALM_VBRAM_MASK 0x0100 /**< Alm 3 - VBRAM, 7 series */ +#define XADCPS_CFR1_CAL_VALID_MASK 0x00F0 /**< Valid Calibration Mask */ +#define XADCPS_CFR1_CAL_PS_GAIN_OFFSET_MASK 0x0080 /**< Calibration 3 -Power + Supply Gain/Offset + Enable */ +#define XADCPS_CFR1_CAL_PS_OFFSET_MASK 0x0040 /**< Calibration 2 -Power + Supply Offset Enable */ +#define XADCPS_CFR1_CAL_ADC_GAIN_OFFSET_MASK 0x0020 /**< Calibration 1 -ADC Gain + Offset Enable */ +#define XADCPS_CFR1_CAL_ADC_OFFSET_MASK 0x0010 /**< Calibration 0 -ADC Offset + Enable */ +#define XADCPS_CFR1_CAL_DISABLE_MASK 0x0000 /**< No Calibration */ +#define XADCPS_CFR1_ALM_ALL_MASK 0x0F0F /**< Mask for all alarms */ +#define XADCPS_CFR1_ALM_VCCAUX_MASK 0x0008 /**< Alarm 2 - VCCAUX Enable */ +#define XADCPS_CFR1_ALM_VCCINT_MASK 0x0004 /**< Alarm 1 - VCCINT Enable */ +#define XADCPS_CFR1_ALM_TEMP_MASK 0x0002 /**< Alarm 0 - Temperature */ +#define XADCPS_CFR1_OT_MASK 0x0001 /**< Over Temperature Enable */ + +/*@}*/ + +/** + * @name Configuration Register 2 (CFR2) mask(s) + * @{ + */ +#define XADCPS_CFR2_CD_VALID_MASK 0xFF00 /** +* +* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ----- -------- ----------------------------------------------------- +* 1.00a ssb 12/22/11 First release based on the XPS/AXI xadc driver +* +* +* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xadcps.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/************************** Variable Definitions *****************************/ + + +/****************************************************************************/ +/** +* +* This function enables the specified interrupts in the device. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param Mask is the bit-mask of the interrupts to be enabled. +* Bit positions of 1 will be enabled. Bit positions of 0 will +* keep the previous setting. This mask is formed by OR'ing +* XADCPS_INTX_* bits defined in xadcps_hw.h. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XAdcPs_IntrEnable(XAdcPs *InstancePtr, u32 Mask) +{ + u32 RegValue; + + /* + * Assert the arguments. + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Disable the specified interrupts in the IPIER. + */ + RegValue = XAdcPs_ReadReg(InstancePtr->Config.BaseAddress, + XADCPS_INT_MASK_OFFSET); + RegValue &= ~(Mask & XADCPS_INTX_ALL_MASK); + XAdcPs_WriteReg(InstancePtr->Config.BaseAddress, + XADCPS_INT_MASK_OFFSET, + RegValue); +} + + +/****************************************************************************/ +/** +* +* This function disables the specified interrupts in the device. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param Mask is the bit-mask of the interrupts to be disabled. +* Bit positions of 1 will be disabled. Bit positions of 0 will +* keep the previous setting. This mask is formed by OR'ing +* XADCPS_INTX_* bits defined in xadcps_hw.h. +* +* @return None. +* +* @note None +* +*****************************************************************************/ +void XAdcPs_IntrDisable(XAdcPs *InstancePtr, u32 Mask) +{ + u32 RegValue; + + /* + * Assert the arguments. + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Enable the specified interrupts in the IPIER. + */ + RegValue = XAdcPs_ReadReg(InstancePtr->Config.BaseAddress, + XADCPS_INT_MASK_OFFSET); + RegValue |= (Mask & XADCPS_INTX_ALL_MASK); + XAdcPs_WriteReg(InstancePtr->Config.BaseAddress, + XADCPS_INT_MASK_OFFSET, + RegValue); +} +/****************************************************************************/ +/** +* +* This function returns the enabled interrupts read from the Interrupt Mask +* Register (IPIER). Use the XADCPS_IPIXR_* constants defined in xadcps_hw.h to +* interpret the returned value. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @return A 32-bit value representing the contents of the I. +* +* @note None. +* +*****************************************************************************/ +u32 XAdcPs_IntrGetEnabled(XAdcPs *InstancePtr) +{ + /* + * Assert the arguments. + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Return the value read from the Interrupt Enable Register. + */ + return (~ XAdcPs_ReadReg(InstancePtr->Config.BaseAddress, + XADCPS_INT_MASK_OFFSET) & XADCPS_INTX_ALL_MASK); +} + +/****************************************************************************/ +/** +* +* This function returns the interrupt status read from Interrupt Status +* Register(IPISR). Use the XADCPS_IPIXR_* constants defined in xadcps_hw.h +* to interpret the returned value. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @return A 32-bit value representing the contents of the IPISR. +* +* @note The device must be configured at hardware build time to include +* interrupt component for this function to work. +* +*****************************************************************************/ +u32 XAdcPs_IntrGetStatus(XAdcPs *InstancePtr) +{ + /* + * Assert the arguments. + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Return the value read from the Interrupt Status register. + */ + return XAdcPs_ReadReg(InstancePtr->Config.BaseAddress, + XADCPS_INT_STS_OFFSET) & XADCPS_INTX_ALL_MASK; +} + +/****************************************************************************/ +/** +* +* This function clears the specified interrupts in the Interrupt Status +* Register (IPISR). +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param Mask is the bit-mask of the interrupts to be cleared. +* Bit positions of 1 will be cleared. Bit positions of 0 will not +* change the previous interrupt status. This mask is formed by +* OR'ing XADCPS_IPIXR_* bits which are defined in xadcps_hw.h. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XAdcPs_IntrClear(XAdcPs *InstancePtr, u32 Mask) +{ + u32 RegValue; + + /* + * Assert the arguments. + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Clear the specified interrupts in the Interrupt Status register. + */ + RegValue = XAdcPs_ReadReg(InstancePtr->Config.BaseAddress, + XADCPS_INT_STS_OFFSET); + RegValue &= (Mask & XADCPS_INTX_ALL_MASK); + XAdcPs_WriteReg(InstancePtr->Config.BaseAddress, XADCPS_INT_STS_OFFSET, + RegValue); + +} +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/xadcps_selftest.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/xadcps_selftest.c new file mode 100644 index 0000000..2d2a7f2 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/xadcps_selftest.c @@ -0,0 +1,137 @@ +/****************************************************************************** +* +* Copyright (C) 2011 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xadcps_selftest.c +* @addtogroup xadcps_v2_3 +* @{ +* +* This file contains a diagnostic self test function for the XAdcPs driver. +* The self test function does a simple read/write test of the Alarm Threshold +* Register. +* +* See xadcps.h for more information. +* +* @note None. +* +*
+*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date     Changes
+* ----- -----  -------- -----------------------------------------------------
+* 1.00a ssb    12/22/11 First release based on the XPS/AXI xadc driver
+*
+* 
+* +*****************************************************************************/ + +/***************************** Include Files ********************************/ + +#include "xadcps.h" + +/************************** Constant Definitions ****************************/ + +/* + * The following constant defines the test value to be written + * to the Alarm Threshold Register + */ +#define XADCPS_ATR_TEST_VALUE 0x55 + +/**************************** Type Definitions ******************************/ + +/***************** Macros (Inline Functions) Definitions ********************/ + +/************************** Variable Definitions ****************************/ + +/************************** Function Prototypes *****************************/ + +/*****************************************************************************/ +/** +* +* Run a self-test on the driver/device. The test +* - Resets the device, +* - Writes a value into the Alarm Threshold register and reads it back +* for comparison. +* - Resets the device again. +* +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @return +* - XST_SUCCESS if the value read from the Alarm Threshold +* register is the same as the value written. +* - XST_FAILURE Otherwise +* +* @note This is a destructive test in that resets of the device are +* performed. Refer to the device specification for the +* device status after the reset operation. +* +******************************************************************************/ +int XAdcPs_SelfTest(XAdcPs *InstancePtr) +{ + int Status; + u32 RegValue; + + /* + * Assert the argument + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + + /* + * Reset the device to get it back to its default state + */ + XAdcPs_Reset(InstancePtr); + + /* + * Write a value into the Alarm Threshold registers, read it back, and + * do the comparison + */ + XAdcPs_SetAlarmThreshold(InstancePtr, XADCPS_ATR_VCCINT_UPPER, + XADCPS_ATR_TEST_VALUE); + RegValue = XAdcPs_GetAlarmThreshold(InstancePtr, XADCPS_ATR_VCCINT_UPPER); + + if (RegValue == XADCPS_ATR_TEST_VALUE) { + Status = XST_SUCCESS; + } else { + Status = XST_FAILURE; + } + + /* + * Reset the device again to its default state. + */ + XAdcPs_Reset(InstancePtr); + /* + * Return the test result. + */ + return Status; +} +/** @} */ diff --git a/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/xadcps_sinit.c b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/xadcps_sinit.c new file mode 100644 index 0000000..5572976 --- /dev/null +++ b/df_datalink_sp/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/xadcps_sinit.c @@ -0,0 +1,99 @@ +/****************************************************************************** +* +* Copyright (C) 2011 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xadcps_sinit.c +* @addtogroup xadcps_v2_3 +* @{ +* +* This file contains the implementation of the XAdcPs driver's static +* initialization functionality. +* +* @note None. +* +*
+*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date     Changes
+* ----- -----  -------- -----------------------------------------------------
+* 1.00a ssb    12/22/11 First release based on the XPS/AXI XADC driver
+*
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xparameters.h" +#include "xadcps.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/************************** Variable Definitions *****************************/ +extern XAdcPs_Config XAdcPs_ConfigTable[]; + +/*****************************************************************************/ +/** +* +* This function looks up the device configuration based on the unique device ID. +* The table XAdcPs_ConfigTable contains the configuration info for each device +* in the system. +* +* @param DeviceId contains the ID of the device for which the +* device configuration pointer is to be returned. +* +* @return +* - A pointer to the configuration found. +* - NULL if the specified device ID was not found. +* +* @note None. +* +******************************************************************************/ +XAdcPs_Config *XAdcPs_LookupConfig(u16 DeviceId) +{ + XAdcPs_Config *CfgPtr = NULL; + u32 Index; + + for (Index=0; Index < 1; Index++) { + if (XAdcPs_ConfigTable[Index].DeviceId == DeviceId) { + CfgPtr = &XAdcPs_ConfigTable[Index]; + break; + } + } + + return CfgPtr; +} +/** @} */ diff --git a/df_datalink_sp/bsp/system.mss b/df_datalink_sp/bsp/system.mss new file mode 100644 index 0000000..685d2ad --- /dev/null +++ b/df_datalink_sp/bsp/system.mss @@ -0,0 +1,232 @@ + + PARAMETER VERSION = 2.2.0 + + +BEGIN OS + PARAMETER OS_NAME = standalone + PARAMETER OS_VER = 7.0 + PARAMETER PROC_INSTANCE = ps7_cortexa9_0 + PARAMETER stdin = ps7_uart_0 + PARAMETER stdout = ps7_uart_0 +END + + +BEGIN PROCESSOR + PARAMETER DRIVER_NAME = cpu_cortexa9 + PARAMETER DRIVER_VER = 2.7 + PARAMETER HW_INSTANCE = ps7_cortexa9_0 + PARAMETER extra_compiler_flags = -DDEBUG -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -nostartfiles -g -Wall -Wextra +END + + +BEGIN DRIVER + PARAMETER DRIVER_NAME = generic + PARAMETER DRIVER_VER = 2.0 + PARAMETER HW_INSTANCE = axi_spi_engine_axi_spi_engine +END + +BEGIN DRIVER + PARAMETER DRIVER_NAME = bram + PARAMETER DRIVER_VER = 4.3 + PARAMETER HW_INSTANCE = phy_data_interface_ant_config_axi_bram_ctrl +END + +BEGIN DRIVER + PARAMETER DRIVER_NAME = bram + PARAMETER DRIVER_VER = 4.3 + PARAMETER HW_INSTANCE = phy_data_interface_phy_rx_buff_axi_bram_ctrl +END + +BEGIN DRIVER + PARAMETER DRIVER_NAME = bram + PARAMETER DRIVER_VER = 4.3 + PARAMETER HW_INSTANCE = phy_data_interface_phy_tx_buff_axi_bram_ctrl +END + +BEGIN DRIVER + PARAMETER DRIVER_NAME = generic + PARAMETER DRIVER_VER = 2.0 + PARAMETER HW_INSTANCE = ps7_afi_0 +END + +BEGIN DRIVER + PARAMETER DRIVER_NAME = generic + PARAMETER DRIVER_VER = 2.0 + PARAMETER HW_INSTANCE = ps7_afi_1 +END + +BEGIN DRIVER + PARAMETER DRIVER_NAME = generic + PARAMETER DRIVER_VER = 2.0 + PARAMETER HW_INSTANCE = ps7_afi_2 +END + +BEGIN DRIVER + PARAMETER DRIVER_NAME = generic + PARAMETER DRIVER_VER = 2.0 + PARAMETER HW_INSTANCE = ps7_afi_3 +END + +BEGIN DRIVER + PARAMETER DRIVER_NAME = coresightps_dcc + PARAMETER DRIVER_VER = 1.5 + PARAMETER HW_INSTANCE = ps7_coresight_comp_0 +END + +BEGIN DRIVER + PARAMETER DRIVER_NAME = ddrps + PARAMETER DRIVER_VER = 1.0 + PARAMETER HW_INSTANCE = ps7_ddr_0 +END + +BEGIN DRIVER + PARAMETER DRIVER_NAME = generic + PARAMETER DRIVER_VER = 2.0 + PARAMETER HW_INSTANCE = ps7_ddrc_0 +END + +BEGIN DRIVER + PARAMETER DRIVER_NAME = devcfg + PARAMETER DRIVER_VER = 3.5 + PARAMETER HW_INSTANCE = ps7_dev_cfg_0 +END + +BEGIN DRIVER + PARAMETER DRIVER_NAME = dmaps + PARAMETER DRIVER_VER = 2.4 + PARAMETER HW_INSTANCE = ps7_dma_ns +END + +BEGIN DRIVER + PARAMETER DRIVER_NAME = dmaps + PARAMETER DRIVER_VER = 2.4 + PARAMETER HW_INSTANCE = ps7_dma_s +END + +BEGIN DRIVER + PARAMETER DRIVER_NAME = generic + PARAMETER DRIVER_VER = 2.0 + PARAMETER HW_INSTANCE = ps7_globaltimer_0 +END + +BEGIN DRIVER + PARAMETER DRIVER_NAME = gpiops + PARAMETER DRIVER_VER = 3.5 + PARAMETER HW_INSTANCE = ps7_gpio_0 +END + +BEGIN DRIVER + PARAMETER DRIVER_NAME = generic + PARAMETER DRIVER_VER = 2.0 + PARAMETER HW_INSTANCE = ps7_gpv_0 +END + +BEGIN DRIVER + PARAMETER DRIVER_NAME = generic + PARAMETER DRIVER_VER = 2.0 + PARAMETER HW_INSTANCE = ps7_intc_dist_0 +END + +BEGIN DRIVER + PARAMETER DRIVER_NAME = generic + PARAMETER DRIVER_VER = 2.0 + PARAMETER HW_INSTANCE = ps7_iop_bus_config_0 +END + +BEGIN DRIVER + PARAMETER DRIVER_NAME = generic + PARAMETER DRIVER_VER = 2.0 + PARAMETER HW_INSTANCE = ps7_l2cachec_0 +END + +BEGIN DRIVER + PARAMETER DRIVER_NAME = generic + PARAMETER DRIVER_VER = 2.0 + PARAMETER HW_INSTANCE = ps7_ocmc_0 +END + +BEGIN DRIVER + PARAMETER DRIVER_NAME = generic + PARAMETER DRIVER_VER = 2.0 + PARAMETER HW_INSTANCE = ps7_pl310_0 +END + +BEGIN DRIVER + PARAMETER DRIVER_NAME = generic + PARAMETER DRIVER_VER = 2.0 + PARAMETER HW_INSTANCE = ps7_pmu_0 +END + +BEGIN DRIVER + PARAMETER DRIVER_NAME = qspips + PARAMETER DRIVER_VER = 3.6 + PARAMETER HW_INSTANCE = ps7_qspi_0 +END + +BEGIN DRIVER + PARAMETER DRIVER_NAME = generic + PARAMETER DRIVER_VER = 2.0 + PARAMETER HW_INSTANCE = ps7_qspi_linear_0 +END + +BEGIN DRIVER + PARAMETER DRIVER_NAME = generic + PARAMETER DRIVER_VER = 2.0 + PARAMETER HW_INSTANCE = ps7_ram_0 +END + +BEGIN DRIVER + PARAMETER DRIVER_NAME = generic + PARAMETER DRIVER_VER = 2.0 + PARAMETER HW_INSTANCE = ps7_ram_1 +END + +BEGIN DRIVER + PARAMETER DRIVER_NAME = generic + PARAMETER DRIVER_VER = 2.0 + PARAMETER HW_INSTANCE = ps7_scuc_0 +END + +BEGIN DRIVER + PARAMETER DRIVER_NAME = scugic + PARAMETER DRIVER_VER = 4.0 + PARAMETER HW_INSTANCE = ps7_scugic_0 +END + +BEGIN DRIVER + PARAMETER DRIVER_NAME = scutimer + PARAMETER DRIVER_VER = 2.1 + PARAMETER HW_INSTANCE = ps7_scutimer_0 +END + +BEGIN DRIVER + PARAMETER DRIVER_NAME = scuwdt + PARAMETER DRIVER_VER = 2.1 + PARAMETER HW_INSTANCE = ps7_scuwdt_0 +END + +BEGIN DRIVER + PARAMETER DRIVER_NAME = generic + PARAMETER DRIVER_VER = 2.0 + PARAMETER HW_INSTANCE = ps7_slcr_0 +END + +BEGIN DRIVER + PARAMETER DRIVER_NAME = uartps + PARAMETER DRIVER_VER = 3.7 + PARAMETER HW_INSTANCE = ps7_uart_0 +END + +BEGIN DRIVER + PARAMETER DRIVER_NAME = xadcps + PARAMETER DRIVER_VER = 2.3 + PARAMETER HW_INSTANCE = ps7_xadc_0 +END + +BEGIN DRIVER + PARAMETER DRIVER_NAME = generic + PARAMETER DRIVER_VER = 2.0 + PARAMETER HW_INSTANCE = systembus +END + + diff --git a/df_datalink_sp/build/Xilinx.spec b/df_datalink_sp/build/Xilinx.spec new file mode 100644 index 0000000..8eea377 --- /dev/null +++ b/df_datalink_sp/build/Xilinx.spec @@ -0,0 +1,2 @@ +*startfile: +crti%O%s crtbegin%O%s diff --git a/df_datalink_sp/build/makefile b/df_datalink_sp/build/makefile new file mode 100644 index 0000000..62f8c14 --- /dev/null +++ b/df_datalink_sp/build/makefile @@ -0,0 +1,82 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +-include ../makefile.init + +CC = /tools/Xilinx/SDK/2019.1/gnu/aarch32/lin/gcc-arm-none-eabi/bin/arm-none-eabi-gcc +XILIN_A9_PRE := /tools/Xilinx/SDK/2019.1/bin/a9-linaro-pre-build-step + +RM := rm -rf + +# All of the sources participating in the build are defined here +-include sources.mk +-include src/util/subdir.mk +-include src/systembus/subdir.mk +-include src/networking/phy_layer/subdir.mk +-include src/networking/link_layer/geometry/subdir.mk +-include src/networking/link_layer/subdir.mk +-include src/drivers/rf-transceiver/ad9361_reg/subdir.mk +-include src/drivers/rf-transceiver/ad9361/subdir.mk +-include src/drivers/platform/subdir.mk +-include src/drivers/frequency/hmc7044/subdir.mk +-include src/drivers/axi_core/spi_engine/subdir.mk +-include src/drivers/axi_core/axi_dmac/subdir.mk +-include src/drivers/api/subdir.mk +-include src/drivers/adc/ad9694/subdir.mk +-include src/dev_profile/subdir.mk +-include src/subdir.mk +-include subdir.mk +-include objects.mk + +ifneq ($(MAKECMDGOALS),clean) +ifneq ($(strip $(S_UPPER_DEPS)),) +-include $(S_UPPER_DEPS) +endif +ifneq ($(strip $(C_DEPS)),) +-include $(C_DEPS) +endif +endif + +-include ../makefile.defs + +# Add inputs and outputs from these tool invocations to the build variables +ELFSIZE += \ +df_datalink.elf.size \ + + +# All Target +all: pre-build main-build + +# Main-build Target +main-build: df_datalink.elf secondary-outputs + +# Tool invocations +df_datalink.elf: $(OBJS) ../src/lscript.ld $(USER_OBJS) + @echo 'Building target: $@' + @echo 'Invoking: ARM v7 gcc linker' + $(CC) -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -Wl,-build-id=none -specs=Xilinx.spec -Wl,-T -Wl,../src/lscript.ld -L../bsp/ps7_cortexa9_0/lib -o "df_datalink.elf" $(OBJS) $(USER_OBJS) $(LIBS) + @echo 'Finished building target: $@' + @echo ' ' + +df_datalink.elf.size: df_datalink.elf + @echo 'Invoking: ARM v7 Print Size' + arm-none-eabi-size df_datalink.elf |tee "df_datalink.elf.size" + @echo 'Finished building: $@' + @echo ' ' + +# Other Targets +clean: + -$(RM) $(EXECUTABLES)$(OBJS)$(S_UPPER_DEPS)$(C_DEPS)$(ELFSIZE) df_datalink.elf + -@echo ' ' + +pre-build: + -$(XILIN_A9_PRE) + -@echo ' ' + +secondary-outputs: $(ELFSIZE) + +.PHONY: all clean dependents +.SECONDARY: main-build pre-build + +-include ../makefile.targets diff --git a/df_datalink_sp/build/objects.mk b/df_datalink_sp/build/objects.mk new file mode 100644 index 0000000..24a8ef2 --- /dev/null +++ b/df_datalink_sp/build/objects.mk @@ -0,0 +1,8 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +USER_OBJS := + +LIBS := -lm -Wl,--start-group,-lxil,-lgcc,-lc,--end-group + diff --git a/df_datalink_sp/build/sources.mk b/df_datalink_sp/build/sources.mk new file mode 100644 index 0000000..215a5fc --- /dev/null +++ b/df_datalink_sp/build/sources.mk @@ -0,0 +1,34 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +LD_SRCS := +OBJ_SRCS := +S_SRCS := +C_SRCS := +S_UPPER_SRCS := +O_SRCS := +EXECUTABLES := +OBJS := +S_UPPER_DEPS := +C_DEPS := +ELFSIZE := + +# Every subdirectory with source files must be described here +SUBDIRS := \ +src/dev_profile \ +src/drivers/adc/ad9694 \ +src/drivers/api \ +src/drivers/axi_core/axi_dmac \ +src/drivers/axi_core/spi_engine \ +src/drivers/frequency/hmc7044 \ +src/drivers/platform \ +src/drivers/rf-transceiver/ad9361 \ +src/drivers/rf-transceiver/ad9361_reg \ +src \ +src/networking/link_layer \ +src/networking/link_layer/geometry \ +src/networking/phy_layer \ +src/systembus \ +src/util \ + diff --git a/df_datalink_sp/build/src/dev_profile/subdir.mk b/df_datalink_sp/build/src/dev_profile/subdir.mk new file mode 100644 index 0000000..d31cf5b --- /dev/null +++ b/df_datalink_sp/build/src/dev_profile/subdir.mk @@ -0,0 +1,39 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +# Add inputs and outputs from these tool invocations to the build variables +C_SRCS += \ +../src/dev_profile/ad9361_profile.c \ +../src/dev_profile/ad9361_reg_profile.c \ +../src/dev_profile/global_timer_profile.c \ +../src/dev_profile/hmc7044_profile.c \ +../src/dev_profile/intc_profile.c \ +../src/dev_profile/timer_profile.c + +OBJS += \ +./src/dev_profile/ad9361_profile.o \ +./src/dev_profile/ad9361_reg_profile.o \ +./src/dev_profile/global_timer_profile.o \ +./src/dev_profile/hmc7044_profile.o \ +./src/dev_profile/intc_profile.o \ +./src/dev_profile/timer_profile.o + +C_DEPS += \ +./src/dev_profile/ad9361_profile.d \ +./src/dev_profile/ad9361_reg_profile.d \ +./src/dev_profile/global_timer_profile.d \ +./src/dev_profile/hmc7044_profile.d \ +./src/dev_profile/intc_profile.d \ +./src/dev_profile/timer_profile.d + + +# Each subdirectory must supply rules for building sources it contributes +src/dev_profile/%.o: ../src/dev_profile/%.c + @echo 'Building file: $<' + @echo 'Invoking: ARM v7 gcc compiler' + $(CC) -Wall -Wformat=2 -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<" + @echo 'Finished building: $<' + @echo ' ' + + diff --git a/df_datalink_sp/build/src/drivers/adc/ad9694/subdir.mk b/df_datalink_sp/build/src/drivers/adc/ad9694/subdir.mk new file mode 100644 index 0000000..81776ea --- /dev/null +++ b/df_datalink_sp/build/src/drivers/adc/ad9694/subdir.mk @@ -0,0 +1,24 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +# Add inputs and outputs from these tool invocations to the build variables +C_SRCS += \ +../src/drivers/adc/ad9694/ad9694.c + +OBJS += \ +./src/drivers/adc/ad9694/ad9694.o + +C_DEPS += \ +./src/drivers/adc/ad9694/ad9694.d + + +# Each subdirectory must supply rules for building sources it contributes +src/drivers/adc/ad9694/%.o: ../src/drivers/adc/ad9694/%.c + @echo 'Building file: $<' + @echo 'Invoking: ARM v7 gcc compiler' + $(CC) -Wall -Wformat=2 -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<" + @echo 'Finished building: $<' + @echo ' ' + + diff --git a/df_datalink_sp/build/src/drivers/api/subdir.mk b/df_datalink_sp/build/src/drivers/api/subdir.mk new file mode 100644 index 0000000..db7c080 --- /dev/null +++ b/df_datalink_sp/build/src/drivers/api/subdir.mk @@ -0,0 +1,39 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +# Add inputs and outputs from these tool invocations to the build variables +C_SRCS += \ +../src/drivers/api/gpio.c \ +../src/drivers/api/i2c.c \ +../src/drivers/api/irq.c \ +../src/drivers/api/spi.c \ +../src/drivers/api/timer.c \ +../src/drivers/api/trng.c + +OBJS += \ +./src/drivers/api/gpio.o \ +./src/drivers/api/i2c.o \ +./src/drivers/api/irq.o \ +./src/drivers/api/spi.o \ +./src/drivers/api/timer.o \ +./src/drivers/api/trng.o + +C_DEPS += \ +./src/drivers/api/gpio.d \ +./src/drivers/api/i2c.d \ +./src/drivers/api/irq.d \ +./src/drivers/api/spi.d \ +./src/drivers/api/timer.d \ +./src/drivers/api/trng.d + + +# Each subdirectory must supply rules for building sources it contributes +src/drivers/api/%.o: ../src/drivers/api/%.c + @echo 'Building file: $<' + @echo 'Invoking: ARM v7 gcc compiler' + $(CC) -Wall -Wformat=2 -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<" + @echo 'Finished building: $<' + @echo ' ' + + diff --git a/df_datalink_sp/build/src/drivers/axi_core/axi_dmac/subdir.mk b/df_datalink_sp/build/src/drivers/axi_core/axi_dmac/subdir.mk new file mode 100644 index 0000000..7d19fa4 --- /dev/null +++ b/df_datalink_sp/build/src/drivers/axi_core/axi_dmac/subdir.mk @@ -0,0 +1,24 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +# Add inputs and outputs from these tool invocations to the build variables +C_SRCS += \ +../src/drivers/axi_core/axi_dmac/axi_dmac.c + +OBJS += \ +./src/drivers/axi_core/axi_dmac/axi_dmac.o + +C_DEPS += \ +./src/drivers/axi_core/axi_dmac/axi_dmac.d + + +# Each subdirectory must supply rules for building sources it contributes +src/drivers/axi_core/axi_dmac/%.o: ../src/drivers/axi_core/axi_dmac/%.c + @echo 'Building file: $<' + @echo 'Invoking: ARM v7 gcc compiler' + $(CC) -Wall -Wformat=2 -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<" + @echo 'Finished building: $<' + @echo ' ' + + diff --git a/df_datalink_sp/build/src/drivers/axi_core/spi_engine/subdir.mk b/df_datalink_sp/build/src/drivers/axi_core/spi_engine/subdir.mk new file mode 100644 index 0000000..444dd4b --- /dev/null +++ b/df_datalink_sp/build/src/drivers/axi_core/spi_engine/subdir.mk @@ -0,0 +1,24 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +# Add inputs and outputs from these tool invocations to the build variables +C_SRCS += \ +../src/drivers/axi_core/spi_engine/spi_engine.c + +OBJS += \ +./src/drivers/axi_core/spi_engine/spi_engine.o + +C_DEPS += \ +./src/drivers/axi_core/spi_engine/spi_engine.d + + +# Each subdirectory must supply rules for building sources it contributes +src/drivers/axi_core/spi_engine/%.o: ../src/drivers/axi_core/spi_engine/%.c + @echo 'Building file: $<' + @echo 'Invoking: ARM v7 gcc compiler' + $(CC) -Wall -Wformat=2 -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<" + @echo 'Finished building: $<' + @echo ' ' + + diff --git a/df_datalink_sp/build/src/drivers/frequency/hmc7044/subdir.mk b/df_datalink_sp/build/src/drivers/frequency/hmc7044/subdir.mk new file mode 100644 index 0000000..01e999b --- /dev/null +++ b/df_datalink_sp/build/src/drivers/frequency/hmc7044/subdir.mk @@ -0,0 +1,24 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +# Add inputs and outputs from these tool invocations to the build variables +C_SRCS += \ +../src/drivers/frequency/hmc7044/hmc7044.c + +OBJS += \ +./src/drivers/frequency/hmc7044/hmc7044.o + +C_DEPS += \ +./src/drivers/frequency/hmc7044/hmc7044.d + + +# Each subdirectory must supply rules for building sources it contributes +src/drivers/frequency/hmc7044/%.o: ../src/drivers/frequency/hmc7044/%.c + @echo 'Building file: $<' + @echo 'Invoking: ARM v7 gcc compiler' + $(CC) -Wall -Wformat=2 -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<" + @echo 'Finished building: $<' + @echo ' ' + + diff --git a/df_datalink_sp/build/src/drivers/platform/subdir.mk b/df_datalink_sp/build/src/drivers/platform/subdir.mk new file mode 100644 index 0000000..47931e4 --- /dev/null +++ b/df_datalink_sp/build/src/drivers/platform/subdir.mk @@ -0,0 +1,48 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +# Add inputs and outputs from these tool invocations to the build variables +C_SRCS += \ +../src/drivers/platform/xilinx_axi_io.c \ +../src/drivers/platform/xilinx_delay.c \ +../src/drivers/platform/xilinx_gpio.c \ +../src/drivers/platform/xilinx_gpio_irq.c \ +../src/drivers/platform/xilinx_i2c.c \ +../src/drivers/platform/xilinx_irq.c \ +../src/drivers/platform/xilinx_spi.c \ +../src/drivers/platform/xilinx_spi_pl.c \ +../src/drivers/platform/xilinx_timer.c + +OBJS += \ +./src/drivers/platform/xilinx_axi_io.o \ +./src/drivers/platform/xilinx_delay.o \ +./src/drivers/platform/xilinx_gpio.o \ +./src/drivers/platform/xilinx_gpio_irq.o \ +./src/drivers/platform/xilinx_i2c.o \ +./src/drivers/platform/xilinx_irq.o \ +./src/drivers/platform/xilinx_spi.o \ +./src/drivers/platform/xilinx_spi_pl.o \ +./src/drivers/platform/xilinx_timer.o + +C_DEPS += \ +./src/drivers/platform/xilinx_axi_io.d \ +./src/drivers/platform/xilinx_delay.d \ +./src/drivers/platform/xilinx_gpio.d \ +./src/drivers/platform/xilinx_gpio_irq.d \ +./src/drivers/platform/xilinx_i2c.d \ +./src/drivers/platform/xilinx_irq.d \ +./src/drivers/platform/xilinx_spi.d \ +./src/drivers/platform/xilinx_spi_pl.d \ +./src/drivers/platform/xilinx_timer.d + + +# Each subdirectory must supply rules for building sources it contributes +src/drivers/platform/%.o: ../src/drivers/platform/%.c + @echo 'Building file: $<' + @echo 'Invoking: ARM v7 gcc compiler' + $(CC) -Wall -Wformat=2 -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<" + @echo 'Finished building: $<' + @echo ' ' + + diff --git a/df_datalink_sp/build/src/drivers/rf-transceiver/ad9361/subdir.mk b/df_datalink_sp/build/src/drivers/rf-transceiver/ad9361/subdir.mk new file mode 100644 index 0000000..4619d7c --- /dev/null +++ b/df_datalink_sp/build/src/drivers/rf-transceiver/ad9361/subdir.mk @@ -0,0 +1,33 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +# Add inputs and outputs from these tool invocations to the build variables +C_SRCS += \ +../src/drivers/rf-transceiver/ad9361/ad9361.c \ +../src/drivers/rf-transceiver/ad9361/ad9361_api.c \ +../src/drivers/rf-transceiver/ad9361/ad9361_conv.c \ +../src/drivers/rf-transceiver/ad9361/ad9361_util.c + +OBJS += \ +./src/drivers/rf-transceiver/ad9361/ad9361.o \ +./src/drivers/rf-transceiver/ad9361/ad9361_api.o \ +./src/drivers/rf-transceiver/ad9361/ad9361_conv.o \ +./src/drivers/rf-transceiver/ad9361/ad9361_util.o + +C_DEPS += \ +./src/drivers/rf-transceiver/ad9361/ad9361.d \ +./src/drivers/rf-transceiver/ad9361/ad9361_api.d \ +./src/drivers/rf-transceiver/ad9361/ad9361_conv.d \ +./src/drivers/rf-transceiver/ad9361/ad9361_util.d + + +# Each subdirectory must supply rules for building sources it contributes +src/drivers/rf-transceiver/ad9361/%.o: ../src/drivers/rf-transceiver/ad9361/%.c + @echo 'Building file: $<' + @echo 'Invoking: ARM v7 gcc compiler' + $(CC) -Wall -Wformat=2 -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<" + @echo 'Finished building: $<' + @echo ' ' + + diff --git a/df_datalink_sp/build/src/drivers/rf-transceiver/ad9361_reg/subdir.mk b/df_datalink_sp/build/src/drivers/rf-transceiver/ad9361_reg/subdir.mk new file mode 100644 index 0000000..37fe424 --- /dev/null +++ b/df_datalink_sp/build/src/drivers/rf-transceiver/ad9361_reg/subdir.mk @@ -0,0 +1,24 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +# Add inputs and outputs from these tool invocations to the build variables +C_SRCS += \ +../src/drivers/rf-transceiver/ad9361_reg/ad9361_reg.c + +OBJS += \ +./src/drivers/rf-transceiver/ad9361_reg/ad9361_reg.o + +C_DEPS += \ +./src/drivers/rf-transceiver/ad9361_reg/ad9361_reg.d + + +# Each subdirectory must supply rules for building sources it contributes +src/drivers/rf-transceiver/ad9361_reg/%.o: ../src/drivers/rf-transceiver/ad9361_reg/%.c + @echo 'Building file: $<' + @echo 'Invoking: ARM v7 gcc compiler' + $(CC) -Wall -Wformat=2 -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<" + @echo 'Finished building: $<' + @echo ' ' + + diff --git a/df_datalink_sp/build/src/networking/link_layer/geometry/subdir.mk b/df_datalink_sp/build/src/networking/link_layer/geometry/subdir.mk new file mode 100644 index 0000000..42d54b8 --- /dev/null +++ b/df_datalink_sp/build/src/networking/link_layer/geometry/subdir.mk @@ -0,0 +1,30 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +# Add inputs and outputs from these tool invocations to the build variables +C_SRCS += \ +../src/networking/link_layer/geometry/coord.c \ +../src/networking/link_layer/geometry/eulerangles.c \ +../src/networking/link_layer/geometry/quaternion.c + +OBJS += \ +./src/networking/link_layer/geometry/coord.o \ +./src/networking/link_layer/geometry/eulerangles.o \ +./src/networking/link_layer/geometry/quaternion.o + +C_DEPS += \ +./src/networking/link_layer/geometry/coord.d \ +./src/networking/link_layer/geometry/eulerangles.d \ +./src/networking/link_layer/geometry/quaternion.d + + +# Each subdirectory must supply rules for building sources it contributes +src/networking/link_layer/geometry/%.o: ../src/networking/link_layer/geometry/%.c + @echo 'Building file: $<' + @echo 'Invoking: ARM v7 gcc compiler' + $(CC) -Wall -Wformat=2 -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<" + @echo 'Finished building: $<' + @echo ' ' + + diff --git a/df_datalink_sp/build/src/networking/link_layer/subdir.mk b/df_datalink_sp/build/src/networking/link_layer/subdir.mk new file mode 100644 index 0000000..14547b6 --- /dev/null +++ b/df_datalink_sp/build/src/networking/link_layer/subdir.mk @@ -0,0 +1,42 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +# Add inputs and outputs from these tool invocations to the build variables +C_SRCS += \ +../src/networking/link_layer/framing.c \ +../src/networking/link_layer/link_layer.c \ +../src/networking/link_layer/node_list.c \ +../src/networking/link_layer/routine_table.c \ +../src/networking/link_layer/scan.c \ +../src/networking/link_layer/service.c \ +../src/networking/link_layer/time_sync.c + +OBJS += \ +./src/networking/link_layer/framing.o \ +./src/networking/link_layer/link_layer.o \ +./src/networking/link_layer/node_list.o \ +./src/networking/link_layer/routine_table.o \ +./src/networking/link_layer/scan.o \ +./src/networking/link_layer/service.o \ +./src/networking/link_layer/time_sync.o + +C_DEPS += \ +./src/networking/link_layer/framing.d \ +./src/networking/link_layer/link_layer.d \ +./src/networking/link_layer/node_list.d \ +./src/networking/link_layer/routine_table.d \ +./src/networking/link_layer/scan.d \ +./src/networking/link_layer/service.d \ +./src/networking/link_layer/time_sync.d + + +# Each subdirectory must supply rules for building sources it contributes +src/networking/link_layer/%.o: ../src/networking/link_layer/%.c + @echo 'Building file: $<' + @echo 'Invoking: ARM v7 gcc compiler' + $(CC) -Wall -Wformat=2 -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<" + @echo 'Finished building: $<' + @echo ' ' + + diff --git a/df_datalink_sp/build/src/networking/phy_layer/subdir.mk b/df_datalink_sp/build/src/networking/phy_layer/subdir.mk new file mode 100644 index 0000000..782ccc4 --- /dev/null +++ b/df_datalink_sp/build/src/networking/phy_layer/subdir.mk @@ -0,0 +1,27 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +# Add inputs and outputs from these tool invocations to the build variables +C_SRCS += \ +../src/networking/phy_layer/phy_antenna.c \ +../src/networking/phy_layer/phy_layer.c + +OBJS += \ +./src/networking/phy_layer/phy_antenna.o \ +./src/networking/phy_layer/phy_layer.o + +C_DEPS += \ +./src/networking/phy_layer/phy_antenna.d \ +./src/networking/phy_layer/phy_layer.d + + +# Each subdirectory must supply rules for building sources it contributes +src/networking/phy_layer/%.o: ../src/networking/phy_layer/%.c + @echo 'Building file: $<' + @echo 'Invoking: ARM v7 gcc compiler' + $(CC) -Wall -Wformat=2 -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<" + @echo 'Finished building: $<' + @echo ' ' + + diff --git a/df_datalink_sp/build/src/subdir.mk b/df_datalink_sp/build/src/subdir.mk new file mode 100644 index 0000000..a6521bd --- /dev/null +++ b/df_datalink_sp/build/src/subdir.mk @@ -0,0 +1,30 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +# Add inputs and outputs from these tool invocations to the build variables +LD_SRCS += \ +../src/lscript.ld + +C_SRCS += \ +../src/main.c \ +../src/system_monitor.c + +OBJS += \ +./src/main.o \ +./src/system_monitor.o + +C_DEPS += \ +./src/main.d \ +./src/system_monitor.d + + +# Each subdirectory must supply rules for building sources it contributes +src/%.o: ../src/%.c + @echo 'Building file: $<' + @echo 'Invoking: ARM v7 gcc compiler' + $(CC) -Wall -Wformat=2 -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<" + @echo 'Finished building: $<' + @echo ' ' + + diff --git a/df_datalink_sp/build/src/systembus/subdir.mk b/df_datalink_sp/build/src/systembus/subdir.mk new file mode 100644 index 0000000..70bfa55 --- /dev/null +++ b/df_datalink_sp/build/src/systembus/subdir.mk @@ -0,0 +1,27 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +# Add inputs and outputs from these tool invocations to the build variables +C_SRCS += \ +../src/systembus/systembus.c \ +../src/systembus/systembus_uart.c + +OBJS += \ +./src/systembus/systembus.o \ +./src/systembus/systembus_uart.o + +C_DEPS += \ +./src/systembus/systembus.d \ +./src/systembus/systembus_uart.d + + +# Each subdirectory must supply rules for building sources it contributes +src/systembus/%.o: ../src/systembus/%.c + @echo 'Building file: $<' + @echo 'Invoking: ARM v7 gcc compiler' + $(CC) -Wall -Wformat=2 -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<" + @echo 'Finished building: $<' + @echo ' ' + + diff --git a/df_datalink_sp/build/src/util/subdir.mk b/df_datalink_sp/build/src/util/subdir.mk new file mode 100644 index 0000000..dbe7d72 --- /dev/null +++ b/df_datalink_sp/build/src/util/subdir.mk @@ -0,0 +1,36 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +# Add inputs and outputs from these tool invocations to the build variables +C_SRCS += \ +../src/util/circ_queue.c \ +../src/util/common.c \ +../src/util/crc.c \ +../src/util/list.c \ +../src/util/util.c + +OBJS += \ +./src/util/circ_queue.o \ +./src/util/common.o \ +./src/util/crc.o \ +./src/util/list.o \ +./src/util/util.o + +C_DEPS += \ +./src/util/circ_queue.d \ +./src/util/common.d \ +./src/util/crc.d \ +./src/util/list.d \ +./src/util/util.d + + +# Each subdirectory must supply rules for building sources it contributes +src/util/%.o: ../src/util/%.c + @echo 'Building file: $<' + @echo 'Invoking: ARM v7 gcc compiler' + $(CC) -Wall -Wformat=2 -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<" + @echo 'Finished building: $<' + @echo ' ' + + diff --git a/df_datalink_sp/src/Xilinx.spec b/df_datalink_sp/src/Xilinx.spec new file mode 100644 index 0000000..8eea377 --- /dev/null +++ b/df_datalink_sp/src/Xilinx.spec @@ -0,0 +1,2 @@ +*startfile: +crti%O%s crtbegin%O%s diff --git a/df_datalink_sp/src/config/app_config.h b/df_datalink_sp/src/config/app_config.h new file mode 100644 index 0000000..2fdb43b --- /dev/null +++ b/df_datalink_sp/src/config/app_config.h @@ -0,0 +1,194 @@ +/*****************************************************************************/ +/** + * Description: Global configurations. + * + * Date: 2021-04-28 13:19 + * Last Editors: Fan Hao + * Last Edit Time: [2022-05-23 20:32] + * + * Revisions: Rev 0.0 + * History: + * [2021-04-28]: Initial edition. + * + * Copyright(c) 2021 Beijing Institute of Technology. + * Lab of Communication and Networking + * + ******************************************************************************/ + +#ifndef __APP_CONFIG_H_ +#define __APP_CONFIG_H_ + +#define XILINX_PLATFORM + +#include "xparameters.h" + +/******** Software Version ********/ +#define _APP_VER 0x00010008 + +#define _APP_VER_MAIN ((_APP_VER & 0xFF000000) >> 24) +#define _APP_VER_MINOR ((_APP_VER & 0x00FF0000) >> 16) +#define _APP_VER_PATCH (_APP_VER & 0x0000FFFF) + +/*********** Debug Info Level ************/ + #define _DEBUG_LEVEL 1 +// 3 - print all debug info +// 2 - print warnings and errors +// 1 - print only errors +// other - print nothing + +//#define DATALINK_ENABLE_AUTORECONNECT +#define DATALINK_ENABLE_AUTOTIMESYNC +//#define DATALINK_ENABLE_BERTEST + +/************ Hardware Configs ************/ +#define CPU_CLK_HZ XPAR_CPU_CORTEXA9_0_CPU_CLK_FREQ_HZ +#define GLOBAL_TIMER_CLK_HZ (CPU_CLK_HZ/2) +#define SCU_TIMER_CLK_HZ (CPU_CLK_HZ/2) +#define FCLK_CLK0_HZ 100000000 + +/********* Zynq Platform Configs **********/ +// SCU Timer (for logging) +#define SCUTIMER_DEVICE_ID XPAR_PS7_SCUTIMER_0_DEVICE_ID +#define SCUTIMER_INTR_ID XPAR_SCUTIMER_INTR + +// Physical Layer Configs +#define PHY_DEVICE_ID 0 +#define PHY_BASEADDR XPAR_PHY_BASEADDR +#define PHY_BEAM_SET_PRESET +#define PHY_BEAM_FORMING_ENABLE +// -- Antenna Bram Configs +#define PHY_ANTCONFIG_BRAM_DEVICE_ID XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_AXI_BRAM_CTRL_DEVICE_ID +// -- Buffers +#define PHY_TXBUFF_BRAM_DEVICE_ID XPAR_PHY_DATA_INTERFACE_PHY_TX_BUFF_AXI_BRAM_CTRL_DEVICE_ID +#define PHY_RXBUFF_BRAM_DEVICE_ID XPAR_PHY_DATA_INTERFACE_PHY_RX_BUFF_AXI_BRAM_CTRL_DEVICE_ID +// -- Xadc +#define PHY_HW_XADC_DEVICE_ID XPAR_PS7_XADC_0_DEVICE_ID +// -- Interrupt id +#define PHY_INTR_ID XPAR_FABRIC_PHY_IRQ_INTR + +// System Bus Configs +#define SYSBUS_BASE_ADDR XPAR_SYSTEMBUS_BASEADDR +#define SYSBUS_TX_INTR_ID XPAR_FABRIC_SYSTEMBUS_TX_DONE_INTR +#define SYSBUS_RX_INTR_ID XPAR_FABRIC_SYSTEMBUS_RX_DONE_INTR + +// Global Timer config +#define GLOBAL_TIMER_DEVICE_ID XPAR_GLOBAL_TMR_DEVICE_ID +#define GLOBAL_TIMER_BASEADDR XPAR_GLOBAL_TMR_BASEADDR +#define GLOBAL_TIMER_INTR_ID XPAR_GLOBAL_TMR_INTR + +// INTC configis +#define INTC_DEVICE_ID XPAR_SCUGIC_0_DEVICE_ID + +// AD9361 Configuration +#define SPI_INTERFACE_SPI_ENGINE +#define HAVE_SPLIT_GAIN_TABLE 1 /* only set to 0 in case split_gain_table_mode_enable = 0*/ +#define HAVE_TDD_SYNTH_TABLE 1 /* only set to 0 in case split_gain_table_mode_enable = 0*/ +#define AD9361_DEVICE 1 /* set it 1 if AD9361 device is used, 0 otherwise */ +#define AD9364_DEVICE 0 /* set it 1 if AD9364 device is used, 0 otherwise */ +#define AD9363A_DEVICE 0 /* set it 1 if AD9363A device is used, 0 otherwise */ +#define HAVE_VERBOSE_MESSAGES /* Recommended during development prints errors and warnings */ +//#define HAVE_DEBUG_MESSAGES /* For Debug purposes only */ +// -- AD9361 SPI Engine Configuration +#define AD9361_SPI_DEVICE_ID 0 +#define AD9361_SPI_ENGINE_REF_CLK FCLK_CLK0_HZ +#define AD9361_SPI_ENGINE_MAX_SPEED 5000000 +#define AD9361_SPI_ENGINE_BASEADDR XPAR_AXI_SPI_ENGINE_AXI_SPI_ENGINE_BASEADDR +#define AD9361_SPI_ENGINE_DATA_WIDTH 8 +#define AD9361_SPI_ENGINE_CS_DELAY 3 +#define AD9361_SPI_CS_AD9361_1 0x01 +#define AD9361_SPI_CS_AD9361_2 0x02 +#define AD9361_TIMEOUT_TH 2000 +// AD9361 GPIO Configurations +#define AD9361_GPIO_DEVICE_ID 0 +#define AD9361_GPIO_OFFSET 54 +#define AD9361_GPIO_INPUT 0 +#define AD9361_GPIO_OUTPUT 1 +#define AD9361_GPIO_DISABLE 0 +#define AD9361_GPIO_ENABLE 1 +// -- AD9361-1 +#define AD9361_1_TXNRX (AD9361_GPIO_OFFSET+6) +#define AD9361_1_ENABLE (AD9361_GPIO_OFFSET+7) +#define AD9361_1_EN_AGC (AD9361_GPIO_OFFSET+8) +#define AD9361_1_RESET_B (AD9361_GPIO_OFFSET+9) +#define AD9361_1_CTRL_OUT0 (AD9361_GPIO_OFFSET+10) +#define AD9361_1_CTRL_OUT1 (AD9361_GPIO_OFFSET+11) +#define AD9361_1_CTRL_OUT2 (AD9361_GPIO_OFFSET+12) +#define AD9361_1_CTRL_OUT3 (AD9361_GPIO_OFFSET+13) +#define AD9361_1_CTRL_OUT4 (AD9361_GPIO_OFFSET+14) +#define AD9361_1_CTRL_OUT5 (AD9361_GPIO_OFFSET+15) +#define AD9361_1_CTRL_OUT6 (AD9361_GPIO_OFFSET+16) +#define AD9361_1_CTRL_OUT7 (AD9361_GPIO_OFFSET+17) +#define AD9361_1_CTRL_IN0 (AD9361_GPIO_OFFSET+18) +#define AD9361_1_CTRL_IN1 (AD9361_GPIO_OFFSET+19) +#define AD9361_1_CTRL_IN2 (AD9361_GPIO_OFFSET+20) +#define AD9361_1_CTRL_IN3 (AD9361_GPIO_OFFSET+21) +// AD9361-2 +#define AD9361_2_TXNRX (AD9361_GPIO_OFFSET+22) +#define AD9361_2_ENABLE (AD9361_GPIO_OFFSET+23) +#define AD9361_2_EN_AGC (AD9361_GPIO_OFFSET+24) +#define AD9361_2_RESET_B (AD9361_GPIO_OFFSET+25) +#define AD9361_2_CTRL_OUT0 (AD9361_GPIO_OFFSET+26) +#define AD9361_2_CTRL_OUT1 (AD9361_GPIO_OFFSET+27) +#define AD9361_2_CTRL_OUT2 (AD9361_GPIO_OFFSET+28) +#define AD9361_2_CTRL_OUT3 (AD9361_GPIO_OFFSET+29) +#define AD9361_2_CTRL_OUT4 (AD9361_GPIO_OFFSET+30) +#define AD9361_2_CTRL_OUT5 (AD9361_GPIO_OFFSET+31) +#define AD9361_2_CTRL_OUT6 (AD9361_GPIO_OFFSET+32) +#define AD9361_2_CTRL_OUT7 (AD9361_GPIO_OFFSET+33) +#define AD9361_2_CTRL_IN0 (AD9361_GPIO_OFFSET+34) +#define AD9361_2_CTRL_IN1 (AD9361_GPIO_OFFSET+35) +#define AD9361_2_CTRL_IN2 (AD9361_GPIO_OFFSET+36) +#define AD9361_2_CTRL_IN3 (AD9361_GPIO_OFFSET+37) +// AD9361-Status Code +#define AD9361_SYNC (AD9361_GPIO_OFFSET+38) +#define AD9361_RX_FIFO_RST (AD9361_GPIO_OFFSET+39) +#define AD9361_1_CAL_START (AD9361_GPIO_OFFSET+40) +#define AD9361_2_CAL_START (AD9361_GPIO_OFFSET+41) +#define AD9361_RECAL (AD9361_GPIO_OFFSET+42) +#define AD9361_TX_SWITCH (AD9361_GPIO_OFFSET+43) +#define AD9361_1_CAL_DONE (AD9361_GPIO_OFFSET+44) +#define AD9361_2_CAL_DONE (AD9361_GPIO_OFFSET+45) +#define AD9361_CAL_RESULT (AD9361_GPIO_OFFSET+46) + +typedef enum +{ + TX_FREQ_125, + TX_FREQ_126, + TX_FREQ_4125 +} ad9361TxFreq; + +// HMC7044 Configurations +#define HMC7044_GPIO_DEVICE_ID 0 +#define HMC7044_GPIO_OFFSET 54 +#define HMC7044_RESET (HMC7044_GPIO_OFFSET+0) +#define HMC7044_SYNC (HMC7044_GPIO_OFFSET+1) +#define HMC7044_GPIO_0 (HMC7044_GPIO_OFFSET+2) +#define HMC7044_GPIO_1 (HMC7044_GPIO_OFFSET+3) +#define HMC7044_GPIO_2 (HMC7044_GPIO_OFFSET+4) +#define HMC7044_GPIO_3 (HMC7044_GPIO_OFFSET+5) +// -- HMC7044 SPI Engine Configuration +#define HMC7044_SPI_DEVICE_ID 0 +#define HMC7044_SPI_ENGINE_REF_CLK FCLK_CLK0_HZ +#define HMC7044_SPI_ENGINE_MAX_SPEED 5000000 +#define HMC7044_SPI_ENGINE_BASEADDR XPAR_AXI_SPI_ENGINE_AXI_SPI_ENGINE_BASEADDR +#define HMC7044_SPI_ENGINE_DATA_WIDTH 8 +#define HMC7044_SPI_ENGINE_CS_DELAY 3 +#define HMC7044_SPI_CS_HMC7044 0x00 + + +// Configuration Check +#if defined(PHY_BEAM_SET_PRESET) && !defined(PHY_BEAM_FORMING_ENABLE) +#define PHY_BEAM_FORMING_ENABLE +#warning To impliment beam scan must enable beam forming... +#endif + +#if defined(DATALINK_ENABLE_BERTEST) +#if !defined(DATALINK_ENABLE_AUTOTIMESYNC) + #warning To enbale bit error rate test, auto time-sync should be enabled... +#endif +#if defined(DATALINK_ENABLE_AUTORECONNECT) + #error Do not support auto reconnnect in bit error rate test mode... +#endif +#endif + +#endif //__APP_CONFIG_H_ diff --git a/df_datalink_sp/src/dev_profile/ad9361_profile.c b/df_datalink_sp/src/dev_profile/ad9361_profile.c new file mode 100644 index 0000000..90de27b --- /dev/null +++ b/df_datalink_sp/src/dev_profile/ad9361_profile.c @@ -0,0 +1,340 @@ +#include "dev_profile.h" +#include "../config/app_config.h" +#include "../drivers/rf-transceiver/ad9361/ad9361_api.h" +#include "../drivers/axi_core/spi_engine/spi_engine.h" +#include "../drivers/platform/xilinx_gpio.h" + +struct spi_engine_init_param spi_engine_param = { + .ref_clk_hz = AD9361_SPI_ENGINE_REF_CLK, + .type = SPI_ENGINE, + .spi_engine_baseaddr = AD9361_SPI_ENGINE_BASEADDR, + .cs_delay = AD9361_SPI_ENGINE_CS_DELAY, + .data_width = AD9361_SPI_ENGINE_DATA_WIDTH +}; + +struct xil_gpio_init_param xil_gpio_param = { + .type = GPIO_PS, + .device_id = AD9361_GPIO_DEVICE_ID +}; + +AD9361_InitParam ad9361_default_init_param = { + /* Device selection */ + ID_AD9361, // dev_sel + /* Reference Clock */ + 48000000UL, //reference_clk_rate + /* Base Configuration */ + 1, //two_rx_two_tx_mode_enable *** adi,2rx-2tx-mode-enable + 1, //one_rx_one_tx_mode_use_rx_num *** adi,1rx-1tx-mode-use-rx-num + 1, //one_rx_one_tx_mode_use_tx_num *** adi,1rx-1tx-mode-use-tx-num + 1, //frequency_division_duplex_mode_enable *** adi,frequency-division-duplex-mode-enable + 0, //frequency_division_duplex_independent_mode_enable *** adi,frequency-division-duplex-independent-mode-enable + 0, //tdd_use_dual_synth_mode_enable *** adi,tdd-use-dual-synth-mode-enable + 0, //tdd_skip_vco_cal_enable *** adi,tdd-skip-vco-cal-enable + 0, //tx_fastlock_delay_ns *** adi,tx-fastlock-delay-ns + 0, //rx_fastlock_delay_ns *** adi,rx-fastlock-delay-ns + 0, //rx_fastlock_pincontrol_enable *** adi,rx-fastlock-pincontrol-enable + 0, //tx_fastlock_pincontrol_enable *** adi,tx-fastlock-pincontrol-enable + 0, //external_rx_lo_enable *** adi,external-rx-lo-enable + 0, //external_tx_lo_enable *** adi,external-tx-lo-enable + 5, //dc_offset_tracking_update_event_mask *** adi,dc-offset-tracking-update-event-mask + 6, //dc_offset_attenuation_high_range *** adi,dc-offset-attenuation-high-range + 5, //dc_offset_attenuation_low_range *** adi,dc-offset-attenuation-low-range + 0x28, //dc_offset_count_high_range *** adi,dc-offset-count-high-range + 0x32, //dc_offset_count_low_range *** adi,dc-offset-count-low-range + 0, //split_gain_table_mode_enable *** adi,split-gain-table-mode-enable + MAX_SYNTH_FREF, //trx_synthesizer_target_fref_overwrite_hz *** adi,trx-synthesizer-target-fref-overwrite-hz + 0, // qec_tracking_slow_mode_enable *** adi,qec-tracking-slow-mode-enable + /* ENSM Control */ + 0, //ensm_enable_pin_pulse_mode_enable *** adi,ensm-enable-pin-pulse-mode-enable + 0, //ensm_enable_txnrx_control_enable *** adi,ensm-enable-txnrx-control-enable + /* LO Control */ + 4125000000UL, //rx_synthesizer_frequency_hz *** adi,rx-synthesizer-frequency-hz + 4126000000UL, //tx_synthesizer_frequency_hz *** adi,tx-synthesizer-frequency-hz + 1, //tx_lo_powerdown_managed_enable *** adi,tx-lo-powerdown-managed-enable + /* Rate & BW Control */ + {768000000, 192000000, 96000000, 48000000, 24000000, 24000000},// rx_path_clock_frequencies[6] *** adi,rx-path-clock-frequencies + {768000000, 192000000, 96000000, 48000000, 24000000, 24000000},// tx_path_clock_frequencies[6] *** adi,tx-path-clock-frequencies + 18000000,//rf_rx_bandwidth_hz *** adi,rf-rx-bandwidth-hz + 18000000,//rf_tx_bandwidth_hz *** adi,rf-tx-bandwidth-hz + /* RF Port Control */ + 0, //rx_rf_port_input_select *** adi,rx-rf-port-input-select + 0, //tx_rf_port_input_select *** adi,tx-rf-port-input-select + /* TX Attenuation Control */ + 10000, //tx_attenuation_mdB *** adi,tx-attenuation-mdB + 0, //update_tx_gain_in_alert_enable *** adi,update-tx-gain-in-alert-enable + /* Reference Clock Control */ + 0, //xo_disable_use_ext_refclk_enable *** adi,xo-disable-use-ext-refclk-enable + {8, 5920}, //dcxo_coarse_and_fine_tune[2] *** adi,dcxo-coarse-and-fine-tune + CLKOUT_DISABLE, //clk_output_mode_select *** adi,clk-output-mode-select + /* Gain Control */ + 2, //gc_rx1_mode *** adi,gc-rx1-mode + 2, //gc_rx2_mode *** adi,gc-rx2-mode + 58, //gc_adc_large_overload_thresh *** adi,gc-adc-large-overload-thresh + 4, //gc_adc_ovr_sample_size *** adi,gc-adc-ovr-sample-size + 47, //gc_adc_small_overload_thresh *** adi,gc-adc-small-overload-thresh + 8192, //gc_dec_pow_measurement_duration *** adi,gc-dec-pow-measurement-duration + 0, //gc_dig_gain_enable *** adi,gc-dig-gain-enable + 800, //gc_lmt_overload_high_thresh *** adi,gc-lmt-overload-high-thresh + 704, //gc_lmt_overload_low_thresh *** adi,gc-lmt-overload-low-thresh + 24, //gc_low_power_thresh *** adi,gc-low-power-thresh + 15, //gc_max_dig_gain *** adi,gc-max-dig-gain + 0, //gc_use_rx_fir_out_for_dec_pwr_meas_enable *** adi,gc-use-rx-fir-out-for-dec-pwr-meas-enable + /* Gain MGC Control */ + 2, //mgc_dec_gain_step *** adi,mgc-dec-gain-step + 2, //mgc_inc_gain_step *** adi,mgc-inc-gain-step + 0, //mgc_rx1_ctrl_inp_enable *** adi,mgc-rx1-ctrl-inp-enable + 0, //mgc_rx2_ctrl_inp_enable *** adi,mgc-rx2-ctrl-inp-enable + 0, //mgc_split_table_ctrl_inp_gain_mode *** adi,mgc-split-table-ctrl-inp-gain-mode + /* Gain AGC Control */ + 10, //agc_adc_large_overload_exceed_counter *** adi,agc-adc-large-overload-exceed-counter + 2, //agc_adc_large_overload_inc_steps *** adi,agc-adc-large-overload-inc-steps + 0, //agc_adc_lmt_small_overload_prevent_gain_inc_enable *** adi,agc-adc-lmt-small-overload-prevent-gain-inc-enable + 10, //agc_adc_small_overload_exceed_counter *** adi,agc-adc-small-overload-exceed-counter + 4, //agc_dig_gain_step_size *** adi,agc-dig-gain-step-size + 3, //agc_dig_saturation_exceed_counter *** adi,agc-dig-saturation-exceed-counter + 1000, // agc_gain_update_interval_us *** adi,agc-gain-update-interval-us + 0, //agc_immed_gain_change_if_large_adc_overload_enable *** adi,agc-immed-gain-change-if-large-adc-overload-enable + 0, //agc_immed_gain_change_if_large_lmt_overload_enable *** adi,agc-immed-gain-change-if-large-lmt-overload-enable + 10, //agc_inner_thresh_high *** adi,agc-inner-thresh-high + 1, //agc_inner_thresh_high_dec_steps *** adi,agc-inner-thresh-high-dec-steps + 12, //agc_inner_thresh_low *** adi,agc-inner-thresh-low + 1, //agc_inner_thresh_low_inc_steps *** adi,agc-inner-thresh-low-inc-steps + 10, //agc_lmt_overload_large_exceed_counter *** adi,agc-lmt-overload-large-exceed-counter + 2, //agc_lmt_overload_large_inc_steps *** adi,agc-lmt-overload-large-inc-steps + 10, //agc_lmt_overload_small_exceed_counter *** adi,agc-lmt-overload-small-exceed-counter + 5, //agc_outer_thresh_high *** adi,agc-outer-thresh-high + 2, //agc_outer_thresh_high_dec_steps *** adi,agc-outer-thresh-high-dec-steps + 18, //agc_outer_thresh_low *** adi,agc-outer-thresh-low + 2, //agc_outer_thresh_low_inc_steps *** adi,agc-outer-thresh-low-inc-steps + 1, //agc_attack_delay_extra_margin_us; *** adi,agc-attack-delay-extra-margin-us + 0, //agc_sync_for_gain_counter_enable *** adi,agc-sync-for-gain-counter-enable + /* Fast AGC */ + 64, //fagc_dec_pow_measuremnt_duration *** adi,fagc-dec-pow-measurement-duration + 260, //fagc_state_wait_time_ns *** adi,fagc-state-wait-time-ns + /* Fast AGC - Low Power */ + 0, //fagc_allow_agc_gain_increase *** adi,fagc-allow-agc-gain-increase-enable + 5, //fagc_lp_thresh_increment_time *** adi,fagc-lp-thresh-increment-time + 1, //fagc_lp_thresh_increment_steps *** adi,fagc-lp-thresh-increment-steps + /* Fast AGC - Lock Level (Lock Level is set via slow AGC inner high threshold) */ + 1, //fagc_lock_level_lmt_gain_increase_en *** adi,fagc-lock-level-lmt-gain-increase-enable + 5, //fagc_lock_level_gain_increase_upper_limit *** adi,fagc-lock-level-gain-increase-upper-limit + /* Fast AGC - Peak Detectors and Final Settling */ + 1, //fagc_lpf_final_settling_steps *** adi,fagc-lpf-final-settling-steps + 1, //fagc_lmt_final_settling_steps *** adi,fagc-lmt-final-settling-steps + 3, //fagc_final_overrange_count *** adi,fagc-final-overrange-count + /* Fast AGC - Final Power Test */ + 0, //fagc_gain_increase_after_gain_lock_en *** adi,fagc-gain-increase-after-gain-lock-enable + /* Fast AGC - Unlocking the Gain */ + 0, //fagc_gain_index_type_after_exit_rx_mode *** adi,fagc-gain-index-type-after-exit-rx-mode + 1, //fagc_use_last_lock_level_for_set_gain_en *** adi,fagc-use-last-lock-level-for-set-gain-enable + 1, //fagc_rst_gla_stronger_sig_thresh_exceeded_en *** adi,fagc-rst-gla-stronger-sig-thresh-exceeded-enable + 5, //fagc_optimized_gain_offset *** adi,fagc-optimized-gain-offset + 10, //fagc_rst_gla_stronger_sig_thresh_above_ll *** adi,fagc-rst-gla-stronger-sig-thresh-above-ll + 1, //fagc_rst_gla_engergy_lost_sig_thresh_exceeded_en *** adi,fagc-rst-gla-engergy-lost-sig-thresh-exceeded-enable + 1, //fagc_rst_gla_engergy_lost_goto_optim_gain_en *** adi,fagc-rst-gla-engergy-lost-goto-optim-gain-enable + 10, //fagc_rst_gla_engergy_lost_sig_thresh_below_ll *** adi,fagc-rst-gla-engergy-lost-sig-thresh-below-ll + 8, //fagc_energy_lost_stronger_sig_gain_lock_exit_cnt *** adi,fagc-energy-lost-stronger-sig-gain-lock-exit-cnt + 1, //fagc_rst_gla_large_adc_overload_en *** adi,fagc-rst-gla-large-adc-overload-enable + 1, //fagc_rst_gla_large_lmt_overload_en *** adi,fagc-rst-gla-large-lmt-overload-enable + 0, //fagc_rst_gla_en_agc_pulled_high_en *** adi,fagc-rst-gla-en-agc-pulled-high-enable + 0, //fagc_rst_gla_if_en_agc_pulled_high_mode *** adi,fagc-rst-gla-if-en-agc-pulled-high-mode + 64, //fagc_power_measurement_duration_in_state5 *** adi,fagc-power-measurement-duration-in-state5 + 2, //fagc_large_overload_inc_steps *** adi,fagc-adc-large-overload-inc-steps + /* RSSI Control */ + 1, //rssi_delay *** adi,rssi-delay + 1000, //rssi_duration *** adi,rssi-duration + 3, //rssi_restart_mode *** adi,rssi-restart-mode + 0, //rssi_unit_is_rx_samples_enable *** adi,rssi-unit-is-rx-samples-enable + 1, //rssi_wait *** adi,rssi-wait + /* Aux ADC Control */ + 256, //aux_adc_decimation *** adi,aux-adc-decimation + 48000000UL, //aux_adc_rate *** adi,aux-adc-rate + /* AuxDAC Control */ + 1, //aux_dac_manual_mode_enable *** adi,aux-dac-manual-mode-enable + 0, //aux_dac1_default_value_mV *** adi,aux-dac1-default-value-mV + 0, //aux_dac1_active_in_rx_enable *** adi,aux-dac1-active-in-rx-enable + 0, //aux_dac1_active_in_tx_enable *** adi,aux-dac1-active-in-tx-enable + 0, //aux_dac1_active_in_alert_enable *** adi,aux-dac1-active-in-alert-enable + 0, //aux_dac1_rx_delay_us *** adi,aux-dac1-rx-delay-us + 0, //aux_dac1_tx_delay_us *** adi,aux-dac1-tx-delay-us + 0, //aux_dac2_default_value_mV *** adi,aux-dac2-default-value-mV + 0, //aux_dac2_active_in_rx_enable *** adi,aux-dac2-active-in-rx-enable + 0, //aux_dac2_active_in_tx_enable *** adi,aux-dac2-active-in-tx-enable + 0, //aux_dac2_active_in_alert_enable *** adi,aux-dac2-active-in-alert-enable + 0, //aux_dac2_rx_delay_us *** adi,aux-dac2-rx-delay-us + 0, //aux_dac2_tx_delay_us *** adi,aux-dac2-tx-delay-us + /* Temperature Sensor Control */ + 256, //temp_sense_decimation *** adi,temp-sense-decimation + 1000, //temp_sense_measurement_interval_ms *** adi,temp-sense-measurement-interval-ms + 0xCE, //temp_sense_offset_signed *** adi,temp-sense-offset-signed + 1, //temp_sense_periodic_measurement_enable *** adi,temp-sense-periodic-measurement-enable + /* Control Out Setup */ + 0xFF, //ctrl_outs_enable_mask *** adi,ctrl-outs-enable-mask + 0, //ctrl_outs_index *** adi,ctrl-outs-index + /* External LNA Control */ + 0, //elna_settling_delay_ns *** adi,elna-settling-delay-ns + 0, //elna_gain_mdB *** adi,elna-gain-mdB + 0, //elna_bypass_loss_mdB *** adi,elna-bypass-loss-mdB + 0, //elna_rx1_gpo0_control_enable *** adi,elna-rx1-gpo0-control-enable + 0, //elna_rx2_gpo1_control_enable *** adi,elna-rx2-gpo1-control-enable + 0, //elna_gaintable_all_index_enable *** adi,elna-gaintable-all-index-enable + /* Digital Interface Control */ + 0, //digital_interface_tune_skip_mode *** adi,digital-interface-tune-skip-mode + 0, //digital_interface_tune_fir_disable *** adi,digital-interface-tune-fir-disable + 1, //pp_tx_swap_enable *** adi,pp-tx-swap-enable + 1, //pp_rx_swap_enable *** adi,pp-rx-swap-enable + 0, //tx_channel_swap_enable *** adi,tx-channel-swap-enable + 0, //rx_channel_swap_enable *** adi,rx-channel-swap-enable + 1, //rx_frame_pulse_mode_enable *** adi,rx-frame-pulse-mode-enable + 0, //two_t_two_r_timing_enable *** adi,2t2r-timing-enable + 0, //invert_data_bus_enable *** adi,invert-data-bus-enable + 0, //invert_data_clk_enable *** adi,invert-data-clk-enable + 0, //fdd_alt_word_order_enable *** adi,fdd-alt-word-order-enable + 0, //invert_rx_frame_enable *** adi,invert-rx-frame-enable + 0, //fdd_rx_rate_2tx_enable *** adi,fdd-rx-rate-2tx-enable + 0, //swap_ports_enable *** adi,swap-ports-enable + 0, //single_data_rate_enable *** adi,single-data-rate-enable + 1, //lvds_mode_enable *** adi,lvds-mode-enable + 0, //half_duplex_mode_enable *** adi,half-duplex-mode-enable + 0, //single_port_mode_enable *** adi,single-port-mode-enable + 0, //full_port_enable *** adi,full-port-enable + 0, //full_duplex_swap_bits_enable *** adi,full-duplex-swap-bits-enable + 0, //delay_rx_data *** adi,delay-rx-data + 0, //rx_data_clock_delay *** adi,rx-data-clock-delay + 4, //rx_data_delay *** adi,rx-data-delay + 7, //tx_fb_clock_delay *** adi,tx-fb-clock-delay + 0, //tx_data_delay *** adi,tx-data-delay + 150, //lvds_bias_mV *** adi,lvds-bias-mV + 1, //lvds_rx_onchip_termination_enable *** adi,lvds-rx-onchip-termination-enable + 0, //rx1rx2_phase_inversion_en *** adi,rx1-rx2-phase-inversion-enable + 0xFF, //lvds_invert1_control *** adi,lvds-invert1-control + 0x0F, //lvds_invert2_control *** adi,lvds-invert2-control + /* GPO Control */ + 0, //gpo_manual_mode_enable *** adi,gpo-manual-mode-enable + 0, //gpo_manual_mode_enable_mask *** adi,gpo-manual-mode-enable-mask + 0, //gpo0_inactive_state_high_enable *** adi,gpo0-inactive-state-high-enable + 0, //gpo1_inactive_state_high_enable *** adi,gpo1-inactive-state-high-enable + 0, //gpo2_inactive_state_high_enable *** adi,gpo2-inactive-state-high-enable + 0, //gpo3_inactive_state_high_enable *** adi,gpo3-inactive-state-high-enable + 0, //gpo0_slave_rx_enable *** adi,gpo0-slave-rx-enable + 0, //gpo0_slave_tx_enable *** adi,gpo0-slave-tx-enable + 0, //gpo1_slave_rx_enable *** adi,gpo1-slave-rx-enable + 0, //gpo1_slave_tx_enable *** adi,gpo1-slave-tx-enable + 0, //gpo2_slave_rx_enable *** adi,gpo2-slave-rx-enable + 0, //gpo2_slave_tx_enable *** adi,gpo2-slave-tx-enable + 0, //gpo3_slave_rx_enable *** adi,gpo3-slave-rx-enable + 0, //gpo3_slave_tx_enable *** adi,gpo3-slave-tx-enable + 0, //gpo0_rx_delay_us *** adi,gpo0-rx-delay-us + 0, //gpo0_tx_delay_us *** adi,gpo0-tx-delay-us + 0, //gpo1_rx_delay_us *** adi,gpo1-rx-delay-us + 0, //gpo1_tx_delay_us *** adi,gpo1-tx-delay-us + 0, //gpo2_rx_delay_us *** adi,gpo2-rx-delay-us + 0, //gpo2_tx_delay_us *** adi,gpo2-tx-delay-us + 0, //gpo3_rx_delay_us *** adi,gpo3-rx-delay-us + 0, //gpo3_tx_delay_us *** adi,gpo3-tx-delay-us + /* Tx Monitor Control */ + 37000, //low_high_gain_threshold_mdB *** adi,txmon-low-high-thresh + 0, //low_gain_dB *** adi,txmon-low-gain + 24, //high_gain_dB *** adi,txmon-high-gain + 0, //tx_mon_track_en *** adi,txmon-dc-tracking-enable + 0, //one_shot_mode_en *** adi,txmon-one-shot-mode-enable + 511, //tx_mon_delay *** adi,txmon-delay + 8192, //tx_mon_duration *** adi,txmon-duration + 2, //tx1_mon_front_end_gain *** adi,txmon-1-front-end-gain + 2, //tx2_mon_front_end_gain *** adi,txmon-2-front-end-gain + 48, //tx1_mon_lo_cm *** adi,txmon-1-lo-cm + 48, //tx2_mon_lo_cm *** adi,txmon-2-lo-cm + /* GPIO definitions */ + /* Reset_b */ + { + .number = AD9361_1_RESET_B, + .platform_ops = &xil_gpio_ops, + .extra = &xil_gpio_param + }, //gpio_resetb *** reset-gpios + /* MCS Sync */ + { + .number = -1, + .platform_ops = &xil_gpio_ops, + .extra = &xil_gpio_param + }, //gpio_sync *** sync-gpios + /* Cal-SW1 */ + { + .number = -1, + .platform_ops = &xil_gpio_ops, + .extra = &xil_gpio_param + }, //gpio_cal_sw1 *** cal-sw1-gpios + /* Cal-SW2 */ + { + .number = -1, + .platform_ops = &xil_gpio_ops, + .extra = &xil_gpio_param + }, //gpio_cal_sw2 *** cal-sw2-gpios + + { + .device_id = AD9361_SPI_DEVICE_ID, + .mode = SPI_MODE_1, + .chip_select = AD9361_SPI_CS_AD9361_1, + .platform_ops = &spi_eng_platform_ops, + .extra = &spi_engine_param + }, + + /* External LO clocks */ + NULL, //(*ad9361_rfpll_ext_recalc_rate)() + NULL, //(*ad9361_rfpll_ext_round_rate)() + NULL, //(*ad9361_rfpll_ext_set_rate)() +}; + +AD9361_RXFIRConfig rx_fir_config = { // BPF PASSBAND 3/20 fs to 1/4 fs + 3, // rx + 0, // rx_gain + 1, // rx_dec + { + -4, -6, -37, 35, 186, 86, -284, -315, + 107, 219, -4, 271, 558, -307, -1182, -356, + 658, 157, 207, 1648, 790, -2525, -2553, 748, + 865, -476, 3737, 6560, -3583, -14731, -5278, 14819, + 14819, -5278, -14731, -3583, 6560, 3737, -476, 865, + 748, -2553, -2525, 790, 1648, 207, 157, 658, + -356, -1182, -307, 558, 271, -4, 219, 107, + -315, -284, 86, 186, 35, -37, -6, -4, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 + }, // rx_coef[128] + 64, // rx_coef_size + {0, 0, 0, 0, 0, 0}, //rx_path_clks[6] + 0 // rx_bandwidth +}; + +AD9361_TXFIRConfig tx_fir_config = { // BPF PASSBAND 3/20 fs to 1/4 fs + 3, // tx + -6, // tx_gain + 1, // tx_int + { + -4, -6, -37, 35, 186, 86, -284, -315, + 107, 219, -4, 271, 558, -307, -1182, -356, + 658, 157, 207, 1648, 790, -2525, -2553, 748, + 865, -476, 3737, 6560, -3583, -14731, -5278, 14819, + 14819, -5278, -14731, -3583, 6560, 3737, -476, 865, + 748, -2553, -2525, 790, 1648, 207, 157, 658, + -356, -1182, -307, 558, 271, -4, 219, 107, + -315, -284, 86, 186, 35, -37, -6, -4, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 + }, // tx_coef[128] + 64, // tx_coef_size + {0, 0, 0, 0, 0, 0}, // tx_path_clks[6] + 0 // tx_bandwidth +}; + diff --git a/df_datalink_sp/src/dev_profile/ad9361_reg_profile.c b/df_datalink_sp/src/dev_profile/ad9361_reg_profile.c new file mode 100644 index 0000000..ce57c82 --- /dev/null +++ b/df_datalink_sp/src/dev_profile/ad9361_reg_profile.c @@ -0,0 +1,1746 @@ +#include "dev_profile.h" +#include "spi.h" +#include "../config/app_config.h" +#include "../drivers/rf-transceiver/ad9361_reg/ad9361_reg.h" +#include "../drivers/axi_core/spi_engine/spi_engine.h" +#include "../drivers/platform/xilinx_gpio.h" + +#define TIMEOUT_TH AD9361_TIMEOUT_TH + +static struct spi_engine_init_param spi_engine_param = { + .ref_clk_hz = AD9361_SPI_ENGINE_REF_CLK, + .type = SPI_ENGINE, + .spi_engine_baseaddr = AD9361_SPI_ENGINE_BASEADDR, + .cs_delay = AD9361_SPI_ENGINE_CS_DELAY, + .data_width = AD9361_SPI_ENGINE_DATA_WIDTH +}; + +static struct xil_gpio_init_param xil_gpio_param = { + .type = GPIO_PS, + .device_id = AD9361_GPIO_DEVICE_ID +}; + +// ad9361-1 +static struct spi_init_param ad9361_1_reg_spi_init = { + .device_id = AD9361_SPI_DEVICE_ID, + .max_speed_hz = AD9361_SPI_ENGINE_MAX_SPEED, + .mode = SPI_MODE_1, + .chip_select = AD9361_SPI_CS_AD9361_1, + .platform_ops = &spi_eng_platform_ops, + .extra = &spi_engine_param +}; + +static struct gpio_init_param ad9361_1_reg_gpio_resetb_init = { + .number = AD9361_1_RESET_B, + .platform_ops = &xil_gpio_ops, + .extra = &xil_gpio_param +}; +struct ad9361_reg_init_param ad9361_1_reg_default_init_param = { + /* SPI */ + .spi_init = &ad9361_1_reg_spi_init, + .gpio_resetb = &ad9361_1_reg_gpio_resetb_init +}; + +// ad9361-2 +static struct spi_init_param ad9361_2_reg_spi_init = { + .device_id = AD9361_SPI_DEVICE_ID, + .max_speed_hz = AD9361_SPI_ENGINE_MAX_SPEED, + .mode = SPI_MODE_1, + .chip_select = AD9361_SPI_CS_AD9361_2, + .platform_ops = &spi_eng_platform_ops, + .extra = &spi_engine_param +}; + +static struct gpio_init_param ad9361_2_reg_gpio_resetb_init = { + .number = AD9361_2_RESET_B, + .platform_ops = &xil_gpio_ops, + .extra = &xil_gpio_param +}; +struct ad9361_reg_init_param ad9361_2_reg_default_init_param = { + /* SPI */ + .spi_init = &ad9361_2_reg_spi_init, + .gpio_resetb = &ad9361_2_reg_gpio_resetb_init +}; + +uint32_t ad9361_reg_config(struct ad9361_reg_dev *dev){ + int32_t status = 0; + uint8_t value = 0; + int32_t time_out_cnt = 0; + +//************************************************************ +// AD9361 R2 Auto Generated Initialization Script: This script was +// generated using the AD9361 Customer software Version 2.1.3 +//************************************************************ +// Profile: Custom +// REFCLK_IN: 25.000 MHz + + + status = ad9361_reg_write(dev, 0x03DF, 0x01); // Required for proper operation + status = ad9361_reg_write(dev, 0x02A6, 0x0E); // Enable Master Bias + status = ad9361_reg_write(dev, 0x02A8, 0x0E); // Set Bandgap Trim + status = ad9361_reg_write(dev, 0x02AB, 0x07); // Set RF PLL reflclk scale to REFCLK * 2 + status = ad9361_reg_write(dev, 0x02AC, 0xFF); // Set RF PLL reflclk scale to REFCLK * 2 + status = ad9361_reg_write(dev, 0x0009, 0x17); // Enable Clocks + mdelay(20) ;// waits 20 ms + +//************************************************************ +// Set BBPLL Frequency: 1152.000000 +//************************************************************ + status = ad9361_reg_write(dev, 0x0045, 0x03); // Set BBPLL reflclk scale to REFCLK * 2 + status = ad9361_reg_write(dev, 0x0046, 0x03); // Set BBPLL Loop Filter Charge Pump current + status = ad9361_reg_write(dev, 0x0048, 0xE8); // Set BBPLL Loop Filter C1, R1 + status = ad9361_reg_write(dev, 0x0049, 0x5B); // Set BBPLL Loop Filter R2, C2, C1 + status = ad9361_reg_write(dev, 0x004A, 0x35); // Set BBPLL Loop Filter C3,R2 + status = ad9361_reg_write(dev, 0x004B, 0xE0); // Allow calibration to occur and set cal count to 1024 for max accuracy + status = ad9361_reg_write(dev, 0x004E, 0x10); // Set calibration clock to REFCLK/4 for more accuracy + status = ad9361_reg_write(dev, 0x0043, 0x66); // BBPLL Freq Word (Fractional[7:0]) + status = ad9361_reg_write(dev, 0x0042, 0x46); // BBPLL Freq Word (Fractional[15:8]) + status = ad9361_reg_write(dev, 0x0041, 0x01); // BBPLL Freq Word (Fractional[23:16]) + status = ad9361_reg_write(dev, 0x0044, 0x17); // BBPLL Freq Word (Integer[7:0]) + status = ad9361_reg_write(dev, 0x003F, 0x05); // Start BBPLL Calibration + status = ad9361_reg_write(dev, 0x003F, 0x01); // Clear BBPLL start calibration bit + status = ad9361_reg_write(dev, 0x004C, 0x86); // Increase BBPLL KV and phase margin + status = ad9361_reg_write(dev, 0x004D, 0x01); // Increase BBPLL KV and phase margin + status = ad9361_reg_write(dev, 0x004D, 0x05); // Increase BBPLL KV and phase margin + + // Wait for BBPLL to lock, Timeout 2sec, Max BBPLL VCO Cal Time: 276.480 us (Done when 0x05E[7]==1) + time_out_cnt = 0; + do{ + status |= ad9361_reg_read(dev, 0x005E, &value); + mdelay(1);// Wait 1ms + time_out_cnt++; + } while((value & 0x80) != 0x80 && time_out_cnt <= AD9361_TIMEOUT_TH); + + + status = ad9361_reg_write(dev, 0x0002, 0xA4); // Setup Tx Digital Filters/ Channels + status = ad9361_reg_write(dev, 0x0003, 0xE5); // Setup Rx Digital Filters/ Channels + status = ad9361_reg_write(dev, 0x0004, 0x03); // Select Rx input pin(A,B,C)/ Tx out pin (A,B) + status = ad9361_reg_write(dev, 0x000A, 0x12); // Set BBPLL post divide rate + +//************************************************************ +// Program Rx FIR: C:\Users\josh\Desktop\Config\rx64.txt +//************************************************************ + status = ad9361_reg_write(dev, 0x00F5, 0x9A); // Enable clock to Rx FIR Filter + status = ad9361_reg_write(dev, 0x00F6, 0x02); // Write Filter Gain setting + status = ad9361_reg_write(dev, 0x00F0, 0x00); // Write FIR coefficient address + status = ad9361_reg_write(dev, 0x00F1, 0x00); // Write FIR coefficient data[7:0] + status = ad9361_reg_write(dev, 0x00F2, 0x00); // Write FIR coefficient data[15:8] + status = ad9361_reg_write(dev, 0x00F5, 0x9E); // Set Write EN to push data into FIR filter register map + status = ad9361_reg_write(dev, 0x00F4, 0x00); // Dummy Write to Read only register to delay ~1us + status = ad9361_reg_write(dev, 0x00F4, 0x00); // Dummy Write to Read only register to delay ~1us + status = ad9361_reg_write(dev, 0x00F0, 0x01); + status = ad9361_reg_write(dev, 0x00F1, 0xB6); + status = ad9361_reg_write(dev, 0x00F2, 0xFF); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x02); + status = ad9361_reg_write(dev, 0x00F1, 0xA5); + status = ad9361_reg_write(dev, 0x00F2, 0xFF); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x03); + status = ad9361_reg_write(dev, 0x00F1, 0xEA); + status = ad9361_reg_write(dev, 0x00F2, 0xFF); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x04); + status = ad9361_reg_write(dev, 0x00F1, 0x61); + status = ad9361_reg_write(dev, 0x00F2, 0x00); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x05); + status = ad9361_reg_write(dev, 0x00F1, 0xA3); + status = ad9361_reg_write(dev, 0x00F2, 0x00); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x06); + status = ad9361_reg_write(dev, 0x00F1, 0x4D); + status = ad9361_reg_write(dev, 0x00F2, 0x00); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x07); + status = ad9361_reg_write(dev, 0x00F1, 0x77); + status = ad9361_reg_write(dev, 0x00F2, 0xFF); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x08); + status = ad9361_reg_write(dev, 0x00F1, 0xD5); + status = ad9361_reg_write(dev, 0x00F2, 0xFE); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x09); + status = ad9361_reg_write(dev, 0x00F1, 0x38); + status = ad9361_reg_write(dev, 0x00F2, 0xFF); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x0A); + status = ad9361_reg_write(dev, 0x00F1, 0xA5); + status = ad9361_reg_write(dev, 0x00F2, 0x00); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x0B); + status = ad9361_reg_write(dev, 0x00F1, 0xF8); + status = ad9361_reg_write(dev, 0x00F2, 0x01); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x0C); + status = ad9361_reg_write(dev, 0x00F1, 0xAD); + status = ad9361_reg_write(dev, 0x00F2, 0x01); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x0D); + status = ad9361_reg_write(dev, 0x00F1, 0x75); + status = ad9361_reg_write(dev, 0x00F2, 0xFF); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x0E); + status = ad9361_reg_write(dev, 0x00F1, 0xFD); + status = ad9361_reg_write(dev, 0x00F2, 0xFC); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x0F); + status = ad9361_reg_write(dev, 0x00F1, 0xD8); + status = ad9361_reg_write(dev, 0x00F2, 0xFC); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x10); + status = ad9361_reg_write(dev, 0x00F1, 0x00); + status = ad9361_reg_write(dev, 0x00F2, 0x00); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x11); + status = ad9361_reg_write(dev, 0x00F1, 0x3A); + status = ad9361_reg_write(dev, 0x00F2, 0x04); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x12); + status = ad9361_reg_write(dev, 0x00F1, 0x6B); + status = ad9361_reg_write(dev, 0x00F2, 0x05); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x13); + status = ad9361_reg_write(dev, 0x00F1, 0x51); + status = ad9361_reg_write(dev, 0x00F2, 0x01); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x14); + status = ad9361_reg_write(dev, 0x00F1, 0x80); + status = ad9361_reg_write(dev, 0x00F2, 0xFA); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x15); + status = ad9361_reg_write(dev, 0x00F1, 0x34); + status = ad9361_reg_write(dev, 0x00F2, 0xF7); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x16); + status = ad9361_reg_write(dev, 0x00F1, 0x08); + status = ad9361_reg_write(dev, 0x00F2, 0xFC); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x17); + status = ad9361_reg_write(dev, 0x00F1, 0xB2); + status = ad9361_reg_write(dev, 0x00F2, 0x06); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x18); + status = ad9361_reg_write(dev, 0x00F1, 0x1A); + status = ad9361_reg_write(dev, 0x00F2, 0x0E); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x19); + status = ad9361_reg_write(dev, 0x00F1, 0x44); + status = ad9361_reg_write(dev, 0x00F2, 0x09); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x1A); + status = ad9361_reg_write(dev, 0x00F1, 0x54); + status = ad9361_reg_write(dev, 0x00F2, 0xF8); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x1B); + status = ad9361_reg_write(dev, 0x00F1, 0xD1); + status = ad9361_reg_write(dev, 0x00F2, 0xE7); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x1C); + status = ad9361_reg_write(dev, 0x00F1, 0xC2); + status = ad9361_reg_write(dev, 0x00F2, 0xE9); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x1D); + status = ad9361_reg_write(dev, 0x00F1, 0x4F); + status = ad9361_reg_write(dev, 0x00F2, 0x08); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x1E); + status = ad9361_reg_write(dev, 0x00F1, 0xB2); + status = ad9361_reg_write(dev, 0x00F2, 0x3B); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x1F); + status = ad9361_reg_write(dev, 0x00F1, 0x2A); + status = ad9361_reg_write(dev, 0x00F2, 0x6C); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x20); + status = ad9361_reg_write(dev, 0x00F1, 0xFF); + status = ad9361_reg_write(dev, 0x00F2, 0x7F); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x21); + status = ad9361_reg_write(dev, 0x00F1, 0x2A); + status = ad9361_reg_write(dev, 0x00F2, 0x6C); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x22); + status = ad9361_reg_write(dev, 0x00F1, 0xB2); + status = ad9361_reg_write(dev, 0x00F2, 0x3B); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x23); + status = ad9361_reg_write(dev, 0x00F1, 0x4F); + status = ad9361_reg_write(dev, 0x00F2, 0x08); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x24); + status = ad9361_reg_write(dev, 0x00F1, 0xC2); + status = ad9361_reg_write(dev, 0x00F2, 0xE9); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x25); + status = ad9361_reg_write(dev, 0x00F1, 0xD1); + status = ad9361_reg_write(dev, 0x00F2, 0xE7); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x26); + status = ad9361_reg_write(dev, 0x00F1, 0x54); + status = ad9361_reg_write(dev, 0x00F2, 0xF8); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x27); + status = ad9361_reg_write(dev, 0x00F1, 0x44); + status = ad9361_reg_write(dev, 0x00F2, 0x09); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x28); + status = ad9361_reg_write(dev, 0x00F1, 0x1A); + status = ad9361_reg_write(dev, 0x00F2, 0x0E); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x29); + status = ad9361_reg_write(dev, 0x00F1, 0xB2); + status = ad9361_reg_write(dev, 0x00F2, 0x06); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x2A); + status = ad9361_reg_write(dev, 0x00F1, 0x08); + status = ad9361_reg_write(dev, 0x00F2, 0xFC); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x2B); + status = ad9361_reg_write(dev, 0x00F1, 0x34); + status = ad9361_reg_write(dev, 0x00F2, 0xF7); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x2C); + status = ad9361_reg_write(dev, 0x00F1, 0x80); + status = ad9361_reg_write(dev, 0x00F2, 0xFA); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x2D); + status = ad9361_reg_write(dev, 0x00F1, 0x51); + status = ad9361_reg_write(dev, 0x00F2, 0x01); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x2E); + status = ad9361_reg_write(dev, 0x00F1, 0x6B); + status = ad9361_reg_write(dev, 0x00F2, 0x05); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x2F); + status = ad9361_reg_write(dev, 0x00F1, 0x3A); + status = ad9361_reg_write(dev, 0x00F2, 0x04); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x30); + status = ad9361_reg_write(dev, 0x00F1, 0x00); + status = ad9361_reg_write(dev, 0x00F2, 0x00); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x31); + status = ad9361_reg_write(dev, 0x00F1, 0xD8); + status = ad9361_reg_write(dev, 0x00F2, 0xFC); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x32); + status = ad9361_reg_write(dev, 0x00F1, 0xFD); + status = ad9361_reg_write(dev, 0x00F2, 0xFC); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x33); + status = ad9361_reg_write(dev, 0x00F1, 0x75); + status = ad9361_reg_write(dev, 0x00F2, 0xFF); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x34); + status = ad9361_reg_write(dev, 0x00F1, 0xAD); + status = ad9361_reg_write(dev, 0x00F2, 0x01); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x35); + status = ad9361_reg_write(dev, 0x00F1, 0xF8); + status = ad9361_reg_write(dev, 0x00F2, 0x01); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x36); + status = ad9361_reg_write(dev, 0x00F1, 0xA5); + status = ad9361_reg_write(dev, 0x00F2, 0x00); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x37); + status = ad9361_reg_write(dev, 0x00F1, 0x38); + status = ad9361_reg_write(dev, 0x00F2, 0xFF); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x38); + status = ad9361_reg_write(dev, 0x00F1, 0xD5); + status = ad9361_reg_write(dev, 0x00F2, 0xFE); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x39); + status = ad9361_reg_write(dev, 0x00F1, 0x77); + status = ad9361_reg_write(dev, 0x00F2, 0xFF); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x3A); + status = ad9361_reg_write(dev, 0x00F1, 0x4D); + status = ad9361_reg_write(dev, 0x00F2, 0x00); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x3B); + status = ad9361_reg_write(dev, 0x00F1, 0xA3); + status = ad9361_reg_write(dev, 0x00F2, 0x00); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x3C); + status = ad9361_reg_write(dev, 0x00F1, 0x61); + status = ad9361_reg_write(dev, 0x00F2, 0x00); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x3D); + status = ad9361_reg_write(dev, 0x00F1, 0xEA); + status = ad9361_reg_write(dev, 0x00F2, 0xFF); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x3E); + status = ad9361_reg_write(dev, 0x00F1, 0xA5); + status = ad9361_reg_write(dev, 0x00F2, 0xFF); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x3F); + status = ad9361_reg_write(dev, 0x00F1, 0xB6); + status = ad9361_reg_write(dev, 0x00F2, 0xFF); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x40); + status = ad9361_reg_write(dev, 0x00F1, 0x00); + status = ad9361_reg_write(dev, 0x00F2, 0x00); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x41); + status = ad9361_reg_write(dev, 0x00F1, 0x00); + status = ad9361_reg_write(dev, 0x00F2, 0x00); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x42); + status = ad9361_reg_write(dev, 0x00F1, 0x00); + status = ad9361_reg_write(dev, 0x00F2, 0x00); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x43); + status = ad9361_reg_write(dev, 0x00F1, 0x00); + status = ad9361_reg_write(dev, 0x00F2, 0x00); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x44); + status = ad9361_reg_write(dev, 0x00F1, 0x00); + status = ad9361_reg_write(dev, 0x00F2, 0x00); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x45); + status = ad9361_reg_write(dev, 0x00F1, 0x00); + status = ad9361_reg_write(dev, 0x00F2, 0x00); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x46); + status = ad9361_reg_write(dev, 0x00F1, 0x00); + status = ad9361_reg_write(dev, 0x00F2, 0x00); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x47); + status = ad9361_reg_write(dev, 0x00F1, 0x00); + status = ad9361_reg_write(dev, 0x00F2, 0x00); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x48); + status = ad9361_reg_write(dev, 0x00F1, 0x00); + status = ad9361_reg_write(dev, 0x00F2, 0x00); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x49); + status = ad9361_reg_write(dev, 0x00F1, 0x00); + status = ad9361_reg_write(dev, 0x00F2, 0x00); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x4A); + status = ad9361_reg_write(dev, 0x00F1, 0x00); + status = ad9361_reg_write(dev, 0x00F2, 0x00); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x4B); + status = ad9361_reg_write(dev, 0x00F1, 0x00); + status = ad9361_reg_write(dev, 0x00F2, 0x00); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x4C); + status = ad9361_reg_write(dev, 0x00F1, 0x00); + status = ad9361_reg_write(dev, 0x00F2, 0x00); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x4D); + status = ad9361_reg_write(dev, 0x00F1, 0x00); + status = ad9361_reg_write(dev, 0x00F2, 0x00); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x4E); + status = ad9361_reg_write(dev, 0x00F1, 0x00); + status = ad9361_reg_write(dev, 0x00F2, 0x00); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F0, 0x4F); + status = ad9361_reg_write(dev, 0x00F1, 0x00); + status = ad9361_reg_write(dev, 0x00F2, 0x00); + status = ad9361_reg_write(dev, 0x00F5, 0x9E); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F4, 0x00); + status = ad9361_reg_write(dev, 0x00F5, 0x98); // Disable clock to Rx Filter + +//************************************************************ +// Setup the Parallel Port (Digital Data Interface) +//************************************************************ + status = ad9361_reg_write(dev, 0x0010, 0xC8); // I/O Config. Tx Swap IQ; Rx Swap IQ; Tx CH Swap, Rx CH Swap; Rx Frame Mode; 2R2T bit; Invert data bus; Invert DATA_CLK + status = ad9361_reg_write(dev, 0x0011, 0x00); // I/O Config. Alt Word Order; -Rx1; -Rx2; -Tx1; -Tx2; Invert Rx Frame; Delay Rx Data + status = ad9361_reg_write(dev, 0x0012, 0x02); // I/O Config. Rx=2*Tx; Swap Ports; SDR; LVDS; Half Duplex; Single Port; Full Port; Swap Bits + status = ad9361_reg_write(dev, 0x0006, 0x00); // PPORT Rx Delay (adjusts Tco Dataclk->Data) + status = ad9361_reg_write(dev, 0x0007, 0x0F); // PPORT TX Delay (adjusts setup/hold FBCLK->Data) + +//************************************************************ +// Setup AuxDAC +//************************************************************ + status = ad9361_reg_write(dev, 0x0018, 0x00); // AuxDAC1 Word[9:2] + status = ad9361_reg_write(dev, 0x0019, 0x00); // AuxDAC2 Word[9:2] + status = ad9361_reg_write(dev, 0x001A, 0x00); // AuxDAC1 Config and Word[1:0] + status = ad9361_reg_write(dev, 0x001B, 0x00); // AuxDAC2 Config and Word[1:0] + status = ad9361_reg_write(dev, 0x0023, 0xFF); // AuxDAC Manaul/Auto Control + status = ad9361_reg_write(dev, 0x0026, 0x00); // AuxDAC Manual Select Bit/GPO Manual Select + status = ad9361_reg_write(dev, 0x0030, 0x00); // AuxDAC1 Rx Delay + status = ad9361_reg_write(dev, 0x0031, 0x00); // AuxDAC1 Tx Delay + status = ad9361_reg_write(dev, 0x0032, 0x00); // AuxDAC2 Rx Delay + status = ad9361_reg_write(dev, 0x0033, 0x00); // AuxDAC2 Tx Delay + +//************************************************************ +// Setup AuxADC +//************************************************************ + status = ad9361_reg_write(dev, 0x000B, 0x00); // Temp Sensor Setup (Offset) + status = ad9361_reg_write(dev, 0x000C, 0x00); // Temp Sensor Setup (Temp Window) + status = ad9361_reg_write(dev, 0x000D, 0x03); // Temp Sensor Setup (Periodic Measure) + status = ad9361_reg_write(dev, 0x000F, 0x04); // Temp Sensor Setup (Decimation) + status = ad9361_reg_write(dev, 0x001C, 0x00); // AuxADC Setup (Clock Div) + status = ad9361_reg_write(dev, 0x001D, 0x01); // AuxADC Setup (Decimation/Enable) + +//************************************************************ +// Setup Control Outs +//************************************************************ + status = ad9361_reg_write(dev, 0x0035, 0x00); // Ctrl Out index + status = ad9361_reg_write(dev, 0x0036, 0xFF); // Ctrl Out [7:0] output enable + +//************************************************************ +// Setup GPO +//************************************************************ + status = ad9361_reg_write(dev, 0x003A, 0x18); // Set number of REFCLK cycles for 1us delay timer + status = ad9361_reg_write(dev, 0x0020, 0x00); // GPO Auto Enable Setup in RX and TX + status = ad9361_reg_write(dev, 0x0027, 0x00); // GPO Manual and GPO auto value in ALERT + status = ad9361_reg_write(dev, 0x0028, 0x00); // GPO_0 RX Delay + status = ad9361_reg_write(dev, 0x0029, 0x00); // GPO_1 RX Delay + status = ad9361_reg_write(dev, 0x002A, 0x00); // GPO_2 RX Delay + status = ad9361_reg_write(dev, 0x002B, 0x00); // GPO_3 RX Delay + status = ad9361_reg_write(dev, 0x002C, 0x00); // GPO_0 TX Delay + status = ad9361_reg_write(dev, 0x002D, 0x00); // GPO_1 TX Delay + status = ad9361_reg_write(dev, 0x002E, 0x00); // GPO_2 TX Delay + status = ad9361_reg_write(dev, 0x002F, 0x00); // GPO_3 TX Delay + +//************************************************************ +// Setup RF PLL non-frequency-dependent registers +//************************************************************ + status = ad9361_reg_write(dev, 0x0261, 0x00); // Set Rx LO Power mode + status = ad9361_reg_write(dev, 0x02A1, 0x00); // Set Tx LO Power mode + status = ad9361_reg_write(dev, 0x0248, 0x0B); // Enable Rx VCO LDO + status = ad9361_reg_write(dev, 0x0288, 0x0B); // Enable Tx VCO LDO + status = ad9361_reg_write(dev, 0x0246, 0x02); // Set VCO Power down TCF bits + status = ad9361_reg_write(dev, 0x0286, 0x02); // Set VCO Power down TCF bits + status = ad9361_reg_write(dev, 0x0249, 0x8E); // Set VCO cal length + status = ad9361_reg_write(dev, 0x0289, 0x8E); // Set VCO cal length + status = ad9361_reg_write(dev, 0x023B, 0x80); // Enable Rx VCO cal + status = ad9361_reg_write(dev, 0x027B, 0x80); // Enable Tx VCO cal + status = ad9361_reg_write(dev, 0x0243, 0x0D); // Set Rx prescaler bias + status = ad9361_reg_write(dev, 0x0283, 0x0D); // Set Tx prescaler bias + status = ad9361_reg_write(dev, 0x023D, 0x00); // Clear Half VCO cal clock setting + status = ad9361_reg_write(dev, 0x027D, 0x00); // Clear Half VCO cal clock setting + + status = ad9361_reg_write(dev, 0x0015, 0x0C); // Set Dual Synth mode bit + status = ad9361_reg_write(dev, 0x0014, 0x1D); // Set Force ALERT State bit + status = ad9361_reg_write(dev, 0x0013, 0x01); // Set ENSM FDD mode + mdelay(1); // waits 1 ms + + status = ad9361_reg_write(dev, 0x023D, 0x04); // Start RX CP cal + + // Wait for CP cal to complete, Max RXCP Cal time: 737.280 (us)(Done when 0x244[7]==1) + time_out_cnt = 0; + do{ + status |= ad9361_reg_read(dev, 0x0244, &value); + mdelay(1);// Wait 1ms + time_out_cnt++; + } while((value & 0x80) != 0x80 && time_out_cnt <= AD9361_TIMEOUT_TH); + + status = ad9361_reg_write(dev, 0x027D, 0x04); // Start TX CP cal + + // Wait for CP cal to complete, Max TXCP Cal time: 737.280 (us)(Done when 0x284[7]==1) + time_out_cnt = 0; + do{ + status |= ad9361_reg_read(dev, 0x0284, &value); + mdelay(1);// Wait 1ms + time_out_cnt++; + } while((value & 0x80) != 0x80 && time_out_cnt <= AD9361_TIMEOUT_TH); + + status = ad9361_reg_write(dev, 0x023D, 0x00); // Disable RX CP Calibration since the CP Cal start bit is not self-clearing. Only important if the script is run again without restting the DUT + status = ad9361_reg_write(dev, 0x027D, 0x00); // Disable TX CP Calibration since the CP Cal start bit is not self-clearing. Only important if the script is run again without restting the DUT +//************************************************************ +// FDD RX,TX Synth Frequency: 125.000000,4125.000000 MHz +//************************************************************ +//************************************************************ +// Setup Rx Frequency-Dependent Syntheisizer Registers +//************************************************************ + status = ad9361_reg_write(dev, 0x023A, 0x4A); // Set VCO Output level[3:0] + status = ad9361_reg_write(dev, 0x0239, 0xC1); // Set Init ALC Value[3:0] and VCO Varactor[3:0] + status = ad9361_reg_write(dev, 0x0242, 0x0E); // Set VCO Bias Tcf[1:0] and VCO Bias Ref[2:0] + status = ad9361_reg_write(dev, 0x0238, 0x78); // Set VCO Cal Offset[3:0] + status = ad9361_reg_write(dev, 0x0245, 0x00); // Set VCO Cal Ref Tcf[2:0] + status = ad9361_reg_write(dev, 0x0251, 0x0B); // Set VCO Varactor Reference[3:0] + status = ad9361_reg_write(dev, 0x0250, 0x70); // Set VCO Varactor Ref Tcf[2:0] and VCO Varactor Offset[3:0] + status = ad9361_reg_write(dev, 0x023B, 0x94); // Set Synth Loop Filter charge pump current (Icp) + status = ad9361_reg_write(dev, 0x023E, 0xF4); // Set Synth Loop Filter C2 and C1 + status = ad9361_reg_write(dev, 0x023F, 0xDF); // Set Synth Loop Filter R1 and C3 + status = ad9361_reg_write(dev, 0x0240, 0x0A); // Set Synth Loop Filter R3 + +//************************************************************ +// Setup Tx Frequency-Dependent Syntheisizer Registers +//************************************************************ + status = ad9361_reg_write(dev, 0x027A, 0x4A); // Set VCO Output level[3:0] + status = ad9361_reg_write(dev, 0x0279, 0xC1); // Set Init ALC Value[3:0] and VCO Varactor[3:0] + status = ad9361_reg_write(dev, 0x0282, 0x0E); // Set VCO Bias Tcf[1:0] and VCO Bias Ref[2:0] + status = ad9361_reg_write(dev, 0x0278, 0x78); // Set VCO Cal Offset[3:0] + status = ad9361_reg_write(dev, 0x0285, 0x00); // Set VCO Cal Ref Tcf[2:0] + status = ad9361_reg_write(dev, 0x0291, 0x0B); // Set VCO Varactor Reference[3:0] + status = ad9361_reg_write(dev, 0x0290, 0x70); // Set VCO Varactor Ref Tcf[2:0] and VCO Varactor Offset[3:0] + status = ad9361_reg_write(dev, 0x027B, 0x93); // Set Synth Loop Filter charge pump current (Icp) + status = ad9361_reg_write(dev, 0x027E, 0xF4); // Set Synth Loop Filter C2 and C1 + status = ad9361_reg_write(dev, 0x027F, 0xDF); // Set Synth Loop Filter R1 and C3 + status = ad9361_reg_write(dev, 0x0280, 0x0A); // Set Synth Loop Filter R3 + +//************************************************************ +// Write Rx and Tx Frequency Words +//************************************************************ + status = ad9361_reg_write(dev, 0x0233, 0x00); // Write Rx Synth Fractional Freq Word[7:0] + status = ad9361_reg_write(dev, 0x0234, 0x00); // Write Rx Synth Fractional Freq Word[15:8] + status = ad9361_reg_write(dev, 0x0235, 0x00); // Write Rx Synth Fractional Freq Word[22:16] + status = ad9361_reg_write(dev, 0x0232, 0x00); // Write Rx Synth Integer Freq Word[10:8] + status = ad9361_reg_write(dev, 0x0231, 0xA0); // Write Rx Synth Integer Freq Word[7:0] + status = ad9361_reg_write(dev, 0x0005, 0x05); // Set LO divider setting + status = ad9361_reg_write(dev, 0x0273, 0x00); // Write Tx Synth Fractional Freq Word[7:0] + status = ad9361_reg_write(dev, 0x0274, 0x00); // Write Tx Synth Fractional Freq Word[15:8] + status = ad9361_reg_write(dev, 0x0275, 0x00); // Write Tx Synth Fractional Freq Word[22:16] + status = ad9361_reg_write(dev, 0x0272, 0x00); // Write Tx Synth Integer Freq Word[10:8] + status = ad9361_reg_write(dev, 0x0271, 0xA5); // Write Tx Synth Integer Freq Word[7:0] (starts VCO cal) + status = ad9361_reg_write(dev, 0x0005, 0x05); // Set LO divider setting + +//************************************************************ +// Program Mixer GM Sub-table +//************************************************************ + status = ad9361_reg_write(dev, 0x013F, 0x02); // Start Clock + status = ad9361_reg_write(dev, 0x0138, 0x0F); // Addr Table Index + status = ad9361_reg_write(dev, 0x0139, 0x78); // Gain + status = ad9361_reg_write(dev, 0x013A, 0x00); // Bias + status = ad9361_reg_write(dev, 0x013B, 0x00); // GM + status = ad9361_reg_write(dev, 0x013F, 0x06); // Write Words + status = ad9361_reg_write(dev, 0x013C, 0x00); // Delay for 3 ADCCLK/16 clock cycles (Dummy Write) + status = ad9361_reg_write(dev, 0x013C, 0x00); // Delay ~1us (Dummy Write) + status = ad9361_reg_write(dev, 0x0138, 0x0E); // Addr Table Index + status = ad9361_reg_write(dev, 0x0139, 0x74); // Gain + status = ad9361_reg_write(dev, 0x013A, 0x00); // Bias + status = ad9361_reg_write(dev, 0x013B, 0x0D); // GM + status = ad9361_reg_write(dev, 0x013F, 0x06); // Write Words + status = ad9361_reg_write(dev, 0x013C, 0x00); // Delay for 3 ADCCLK/16 clock cycles (Dummy Write) + status = ad9361_reg_write(dev, 0x013C, 0x00); // Delay ~1us (Dummy Write) + status = ad9361_reg_write(dev, 0x0138, 0x0D); // Addr Table Index + status = ad9361_reg_write(dev, 0x0139, 0x70); // Gain + status = ad9361_reg_write(dev, 0x013A, 0x00); // Bias + status = ad9361_reg_write(dev, 0x013B, 0x15); // GM + status = ad9361_reg_write(dev, 0x013F, 0x06); // Write Words + status = ad9361_reg_write(dev, 0x013C, 0x00); // Delay for 3 ADCCLK/16 clock cycles (Dummy Write) + status = ad9361_reg_write(dev, 0x013C, 0x00); // Delay ~1us (Dummy Write) + status = ad9361_reg_write(dev, 0x0138, 0x0C); // Addr Table Index + status = ad9361_reg_write(dev, 0x0139, 0x6C); // Gain + status = ad9361_reg_write(dev, 0x013A, 0x00); // Bias + status = ad9361_reg_write(dev, 0x013B, 0x1B); // GM + status = ad9361_reg_write(dev, 0x013F, 0x06); // Write Words + status = ad9361_reg_write(dev, 0x013C, 0x00); // Delay for 3 ADCCLK/16 clock cycles (Dummy Write) + status = ad9361_reg_write(dev, 0x013C, 0x00); // Delay ~1us (Dummy Write) + status = ad9361_reg_write(dev, 0x0138, 0x0B); // Addr Table Index + status = ad9361_reg_write(dev, 0x0139, 0x68); // Gain + status = ad9361_reg_write(dev, 0x013A, 0x00); // Bias + status = ad9361_reg_write(dev, 0x013B, 0x21); // GM + status = ad9361_reg_write(dev, 0x013F, 0x06); // Write Words + status = ad9361_reg_write(dev, 0x013C, 0x00); // Delay for 3 ADCCLK/16 clock cycles (Dummy Write) + status = ad9361_reg_write(dev, 0x013C, 0x00); // Delay ~1us (Dummy Write) + status = ad9361_reg_write(dev, 0x0138, 0x0A); // Addr Table Index + status = ad9361_reg_write(dev, 0x0139, 0x64); // Gain + status = ad9361_reg_write(dev, 0x013A, 0x00); // Bias + status = ad9361_reg_write(dev, 0x013B, 0x25); // GM + status = ad9361_reg_write(dev, 0x013F, 0x06); // Write Words + status = ad9361_reg_write(dev, 0x013C, 0x00); // Delay for 3 ADCCLK/16 clock cycles (Dummy Write) + status = ad9361_reg_write(dev, 0x013C, 0x00); // Delay ~1us (Dummy Write) + status = ad9361_reg_write(dev, 0x0138, 0x09); // Addr Table Index + status = ad9361_reg_write(dev, 0x0139, 0x60); // Gain + status = ad9361_reg_write(dev, 0x013A, 0x00); // Bias + status = ad9361_reg_write(dev, 0x013B, 0x29); // GM + status = ad9361_reg_write(dev, 0x013F, 0x06); // Write Words + status = ad9361_reg_write(dev, 0x013C, 0x00); // Delay for 3 ADCCLK/16 clock cycles (Dummy Write) + status = ad9361_reg_write(dev, 0x013C, 0x00); // Delay ~1us (Dummy Write) + status = ad9361_reg_write(dev, 0x0138, 0x08); // Addr Table Index + status = ad9361_reg_write(dev, 0x0139, 0x5C); // Gain + status = ad9361_reg_write(dev, 0x013A, 0x00); // Bias + status = ad9361_reg_write(dev, 0x013B, 0x2C); // GM + status = ad9361_reg_write(dev, 0x013F, 0x06); // Write Words + status = ad9361_reg_write(dev, 0x013C, 0x00); // Delay for 3 ADCCLK/16 clock cycles (Dummy Write) + status = ad9361_reg_write(dev, 0x013C, 0x00); // Delay ~1us (Dummy Write) + status = ad9361_reg_write(dev, 0x0138, 0x07); // Addr Table Index + status = ad9361_reg_write(dev, 0x0139, 0x58); // Gain + status = ad9361_reg_write(dev, 0x013A, 0x00); // Bias + status = ad9361_reg_write(dev, 0x013B, 0x2F); // GM + status = ad9361_reg_write(dev, 0x013F, 0x06); // Write Words + status = ad9361_reg_write(dev, 0x013C, 0x00); // Delay for 3 ADCCLK/16 clock cycles (Dummy Write) + status = ad9361_reg_write(dev, 0x013C, 0x00); // Delay ~1us (Dummy Write) + status = ad9361_reg_write(dev, 0x0138, 0x06); // Addr Table Index + status = ad9361_reg_write(dev, 0x0139, 0x54); // Gain + status = ad9361_reg_write(dev, 0x013A, 0x00); // Bias + status = ad9361_reg_write(dev, 0x013B, 0x31); // GM + status = ad9361_reg_write(dev, 0x013F, 0x06); // Write Words + status = ad9361_reg_write(dev, 0x013C, 0x00); // Delay for 3 ADCCLK/16 clock cycles (Dummy Write) + status = ad9361_reg_write(dev, 0x013C, 0x00); // Delay ~1us (Dummy Write) + status = ad9361_reg_write(dev, 0x0138, 0x05); // Addr Table Index + status = ad9361_reg_write(dev, 0x0139, 0x50); // Gain + status = ad9361_reg_write(dev, 0x013A, 0x00); // Bias + status = ad9361_reg_write(dev, 0x013B, 0x33); // GM + status = ad9361_reg_write(dev, 0x013F, 0x06); // Write Words + status = ad9361_reg_write(dev, 0x013C, 0x00); // Delay for 3 ADCCLK/16 clock cycles (Dummy Write) + status = ad9361_reg_write(dev, 0x013C, 0x00); // Delay ~1us (Dummy Write) + status = ad9361_reg_write(dev, 0x0138, 0x04); // Addr Table Index + status = ad9361_reg_write(dev, 0x0139, 0x4C); // Gain + status = ad9361_reg_write(dev, 0x013A, 0x00); // Bias + status = ad9361_reg_write(dev, 0x013B, 0x34); // GM + status = ad9361_reg_write(dev, 0x013F, 0x06); // Write Words + status = ad9361_reg_write(dev, 0x013C, 0x00); // Delay for 3 ADCCLK/16 clock cycles (Dummy Write) + status = ad9361_reg_write(dev, 0x013C, 0x00); // Delay ~1us (Dummy Write) + status = ad9361_reg_write(dev, 0x0138, 0x03); // Addr Table Index + status = ad9361_reg_write(dev, 0x0139, 0x48); // Gain + status = ad9361_reg_write(dev, 0x013A, 0x00); // Bias + status = ad9361_reg_write(dev, 0x013B, 0x35); // GM + status = ad9361_reg_write(dev, 0x013F, 0x06); // Write Words + status = ad9361_reg_write(dev, 0x013C, 0x00); // Delay for 3 ADCCLK/16 clock cycles (Dummy Write) + status = ad9361_reg_write(dev, 0x013C, 0x00); // Delay ~1us (Dummy Write) + status = ad9361_reg_write(dev, 0x0138, 0x02); // Addr Table Index + status = ad9361_reg_write(dev, 0x0139, 0x30); // Gain + status = ad9361_reg_write(dev, 0x013A, 0x00); // Bias + status = ad9361_reg_write(dev, 0x013B, 0x3A); // GM + status = ad9361_reg_write(dev, 0x013F, 0x06); // Write Words + status = ad9361_reg_write(dev, 0x013C, 0x00); // Delay for 3 ADCCLK/16 clock cycles (Dummy Write) + status = ad9361_reg_write(dev, 0x013C, 0x00); // Delay ~1us (Dummy Write) + status = ad9361_reg_write(dev, 0x0138, 0x01); // Addr Table Index + status = ad9361_reg_write(dev, 0x0139, 0x18); // Gain + status = ad9361_reg_write(dev, 0x013A, 0x00); // Bias + status = ad9361_reg_write(dev, 0x013B, 0x3D); // GM + status = ad9361_reg_write(dev, 0x013F, 0x06); // Write Words + status = ad9361_reg_write(dev, 0x013C, 0x00); // Delay for 3 ADCCLK/16 clock cycles (Dummy Write) + status = ad9361_reg_write(dev, 0x013C, 0x00); // Delay ~1us (Dummy Write) + status = ad9361_reg_write(dev, 0x0138, 0x00); // Addr Table Index + status = ad9361_reg_write(dev, 0x0139, 0x00); // Gain + status = ad9361_reg_write(dev, 0x013A, 0x00); // Bias + status = ad9361_reg_write(dev, 0x013B, 0x3E); // GM + status = ad9361_reg_write(dev, 0x013F, 0x06); // Write Words + status = ad9361_reg_write(dev, 0x013C, 0x00); // Delay for 3 ADCCLK/16 clock cycles (Dummy Write) + status = ad9361_reg_write(dev, 0x013C, 0x00); // Delay ~1us (Dummy Write) + status = ad9361_reg_write(dev, 0x013F, 0x02); // Clear Write Bit + status = ad9361_reg_write(dev, 0x013C, 0x00); // Delay for 3 ADCCLK/16 clock cycles (Dummy Write) + status = ad9361_reg_write(dev, 0x013C, 0x00); // Delay ~1us (Dummy Write) + status = ad9361_reg_write(dev, 0x013F, 0x00); // Stop Clock + +//************************************************************ +// Program Rx Gain Tables with GainTable800MHz.csv +//************************************************************ + + status = ad9361_reg_write(dev, 0x0137, 0x1A); // Start Gain Table Clock + status = ad9361_reg_write(dev, 0x0130, 0x00); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x00); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x00); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x20); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x01); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x00); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x00); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x02); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x00); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x00); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x03); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x00); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x01); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x04); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x00); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x02); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x05); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x00); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x03); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x06); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x00); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x04); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x07); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x00); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x05); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x08); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x01); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x03); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x20); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x09); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x01); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x04); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x0A); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x01); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x05); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x0B); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x01); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x06); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x0C); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x01); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x07); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x0D); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x01); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x08); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x0E); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x01); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x09); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x0F); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x01); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x0A); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x10); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x01); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x0B); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x11); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x01); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x0C); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x12); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x01); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x0D); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x13); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x01); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x0E); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x14); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x02); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x09); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x20); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x15); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x02); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x0A); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x16); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x02); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x0B); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x17); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x02); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x0C); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x18); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x02); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x0D); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x19); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x02); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x0E); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x1A); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x02); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x0F); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x1B); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x02); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x10); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x1C); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x02); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x2B); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x20); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x1D); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x02); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x2C); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x1E); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x04); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x28); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x20); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x1F); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x04); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x29); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x20); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x04); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x2A); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x21); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x04); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x2B); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x22); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x24); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x20); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x20); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x23); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x24); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x21); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x24); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x44); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x20); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x20); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x25); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x44); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x21); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x26); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x44); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x22); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x27); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x44); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x23); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x28); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x44); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x24); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x29); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x44); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x25); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x2A); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x44); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x26); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x2B); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x44); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x27); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x2C); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x44); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x28); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x2D); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x44); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x29); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x2E); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x44); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x2A); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x2F); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x44); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x2B); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x30); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x44); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x2C); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x31); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x44); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x2D); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x32); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x44); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x2E); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x33); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x44); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x2F); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x34); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x44); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x30); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x35); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x44); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x31); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x36); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x44); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x32); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x37); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x64); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x2E); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x20); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x38); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x64); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x2F); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x39); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x64); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x30); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x3A); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x64); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x31); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x3B); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x64); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x32); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x3C); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x64); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x33); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x3D); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x64); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x34); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x3E); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x64); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x35); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x3F); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x64); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x36); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x40); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x64); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x37); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x41); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x64); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x38); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x42); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x65); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x38); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x20); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x43); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x66); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x38); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x20); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x44); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x67); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x38); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x20); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x45); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x68); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x38); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x20); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x46); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x69); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x38); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x20); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x47); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x6A); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x38); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x20); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x48); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x6B); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x38); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x20); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x49); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x6C); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x38); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x20); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x4A); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x6D); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x38); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x20); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x4B); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x6E); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x38); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x20); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x4C); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x6F); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x38); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x20); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x4D); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x00); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x00); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x4E); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x00); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x00); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x4F); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x00); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x00); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x50); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x00); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x00); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x51); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x00); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x00); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x52); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x00); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x00); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x53); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x00); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x00); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x54); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x00); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x00); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x55); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x00); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x00); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x56); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x00); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x00); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x57); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x00); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x00); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x58); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x00); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x00); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x59); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x00); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x00); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0130, 0x5A); // Gain Table Index + status = ad9361_reg_write(dev, 0x0131, 0x00); // Ext LNA, Int LNA, & Mixer Gain Word + status = ad9361_reg_write(dev, 0x0132, 0x00); // TIA & LPF Word + status = ad9361_reg_write(dev, 0x0133, 0x00); // DC Cal bit & Dig Gain Word + status = ad9361_reg_write(dev, 0x0137, 0x1E); // Write Words + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay 3 ADCCLK/16 cycles + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0137, 0x1A); // Clear Write Bit + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0134, 0x00); // Dummy Write to delay ~1us + status = ad9361_reg_write(dev, 0x0137, 0x00); // Stop Gain Table Clock +//************************************************************ +// Setup Rx Manual Gain Registers +//************************************************************ + status = ad9361_reg_write(dev, 0x00FA, 0xE0); // Gain Control Mode Select + status = ad9361_reg_write(dev, 0x00FB, 0x08); // Table, Digital Gain, Man Gain Ctrl + status = ad9361_reg_write(dev, 0x00FC, 0x23); // Incr Step Size, ADC Overrange Size + status = ad9361_reg_write(dev, 0x00FD, 0x4C); // Max Full/LMT Gain Table Index + status = ad9361_reg_write(dev, 0x00FE, 0x44); // Decr Step Size, Peak Overload Time + status = ad9361_reg_write(dev, 0x0100, 0x6F); // Max Digital Gain + status = ad9361_reg_write(dev, 0x0104, 0x2F); // ADC Small Overload Threshold + status = ad9361_reg_write(dev, 0x0105, 0x3A); // ADC Large Overload Threshold + status = ad9361_reg_write(dev, 0x0107, 0x2B); // Small LMT Overload Threshold + status = ad9361_reg_write(dev, 0x0108, 0x31); // Large LMT Overload Threshold + status = ad9361_reg_write(dev, 0x0109, 0x00); // Rx1 Full/LMT Gain Index + status = ad9361_reg_write(dev, 0x010A, 0x58); // Rx1 LPF Gain Index + status = ad9361_reg_write(dev, 0x010B, 0x00); // Rx1 Digital Gain Index + status = ad9361_reg_write(dev, 0x010C, 0x00); // Rx2 Full/LMT Gain Index + status = ad9361_reg_write(dev, 0x010D, 0x18); // Rx2 LPF Gain Index + status = ad9361_reg_write(dev, 0x010E, 0x00); // Rx2 Digital Gain Index + status = ad9361_reg_write(dev, 0x0114, 0x30); // Low Power Threshold + status = ad9361_reg_write(dev, 0x011A, 0x27); // Initial LMT Gain Limit + status = ad9361_reg_write(dev, 0x0081, 0x00); // Tx Symbol Gain Control +//************************************************************ +// RX Baseband Filter Tuning (Real BW: 7.500000 MHz) 3dB Filter +// Corner @ 10.500000 MHz) +//************************************************************ + status = ad9361_reg_write(dev, 0x01FB, 0x07); // RX Freq Corner (MHz) + status = ad9361_reg_write(dev, 0x01FC, 0x40); // RX Freq Corner (Khz) + status = ad9361_reg_write(dev, 0x01F8, 0x0D); // Rx BBF Tune Divider[7:0] + status = ad9361_reg_write(dev, 0x01F9, 0x1E); // RX BBF Tune Divider[8] + + status = ad9361_reg_write(dev, 0x01D5, 0x3F); // Set Rx Mix LO CM + status = ad9361_reg_write(dev, 0x01C0, 0x03); // Set GM common mode + status = ad9361_reg_write(dev, 0x01E2, 0x02); // Enable Rx1 Filter Tuner + status = ad9361_reg_write(dev, 0x01E3, 0x02); // Enable Rx2 Filter Tuner + status = ad9361_reg_write(dev, 0x0016, 0x80); // Start RX Filter Tune + + // Wait for RX filter to tune, Max Cal Time: 6.884 us (Done when 0x016[7]==0) + time_out_cnt = 0; + do{ + status |= ad9361_reg_read(dev, 0x0016, &value); + mdelay(1);// Wait 1ms + time_out_cnt++; + } while((value & 0x80) != 0x00 && time_out_cnt <= AD9361_TIMEOUT_TH); + + status = ad9361_reg_write(dev, 0x01E2, 0x03); // Disable Rx Filter Tuner (Rx1) + status = ad9361_reg_write(dev, 0x01E3, 0x03); // Disable Rx Filter Tuner (Rx2) +//************************************************************ +// TX Baseband Filter Tuning (Real BW: 7.500000 MHz) 3dB Filter +// Corner @ 12.000000 MHz) +//************************************************************ + status = ad9361_reg_write(dev, 0x00D6, 0x0B); // TX BBF Tune Divider[7:0] + status = ad9361_reg_write(dev, 0x00D7, 0x1E); // TX BBF Tune Divider[8] + + status = ad9361_reg_write(dev, 0x00CA, 0x22); // Enable Tx Filter Tuner + status = ad9361_reg_write(dev, 0x0016, 0x40); // Start Tx Filter Tune + + // Wait for TX filter to tune, Max Cal Time: 3.390 us (Done when 0x016[6]==0) + time_out_cnt = 0; + do{ + status |= ad9361_reg_read(dev, 0x0016, &value); + mdelay(1);// Wait 1ms + time_out_cnt++; + } while((value & 0x40) != 0x00 && time_out_cnt <= AD9361_TIMEOUT_TH); + + status = ad9361_reg_write(dev, 0x00CA, 0x26); // Disable Tx Filter Tuner (Both Channels) +//************************************************************ +// RX TIA Setup: Setup values scale based on RxBBF calibration +// results. See information in Calibration Guide. +//************************************************************ + status = ad9361_reg_write(dev, 0x01DB, 0x60); // Set TIA selcc[2:0] + status = ad9361_reg_write(dev, 0x01DD, 0x00); // Set RX TIA1 C MSB[6:0] + status = ad9361_reg_write(dev, 0x01DF, 0x00); // Set RX TIA2 C MSB[6:0] + status = ad9361_reg_write(dev, 0x01DC, 0x72); // Set RX TIA1 C LSB[5:0] + status = ad9361_reg_write(dev, 0x01DE, 0x72); // Set RX TIA2 C LSB[5:0] + +//************************************************************ +// TX Secondary Filter Calibration Setup: Real Bandwidth +// 7.500000MHz, 3dB Corner @ 37.500000MHz +//************************************************************ + status = ad9361_reg_write(dev, 0x00D2, 0x1E); // TX Secondary Filter PDF Cap cal[5:0] + status = ad9361_reg_write(dev, 0x00D1, 0x0C); // TX Secondary Filter PDF Res cal[3:0] + status = ad9361_reg_write(dev, 0x00D0, 0x56); // Pdampbias + +//************************************************************ +// ADC Setup: Tune ADC Performance based on RX analog filter tune +// corner. Real Bandwidth: 6.982753 MHz, ADC Clock Frequency: +// 288.000000 MHz. The values in registers 0x200 - 0x227 need to be +// calculated using the equations in the Calibration Guide. +//************************************************************ + + status = ad9361_reg_write(dev, 0x0200, 0x00); + status = ad9361_reg_write(dev, 0x0201, 0x00); + status = ad9361_reg_write(dev, 0x0202, 0x00); + status = ad9361_reg_write(dev, 0x0203, 0x24); + status = ad9361_reg_write(dev, 0x0204, 0x24); + status = ad9361_reg_write(dev, 0x0205, 0x00); + status = ad9361_reg_write(dev, 0x0206, 0x00); + status = ad9361_reg_write(dev, 0x0207, 0x7C); + status = ad9361_reg_write(dev, 0x0208, 0x46); + status = ad9361_reg_write(dev, 0x0209, 0x3C); + status = ad9361_reg_write(dev, 0x020A, 0x4C); + status = ad9361_reg_write(dev, 0x020B, 0x2C); + status = ad9361_reg_write(dev, 0x020C, 0x4F); + status = ad9361_reg_write(dev, 0x020D, 0x2A); + status = ad9361_reg_write(dev, 0x020E, 0x00); + status = ad9361_reg_write(dev, 0x020F, 0x7F); + status = ad9361_reg_write(dev, 0x0210, 0x7F); + status = ad9361_reg_write(dev, 0x0211, 0x7F); + status = ad9361_reg_write(dev, 0x0212, 0x4A); + status = ad9361_reg_write(dev, 0x0213, 0x4A); + status = ad9361_reg_write(dev, 0x0214, 0x4A); + status = ad9361_reg_write(dev, 0x0215, 0x4D); + status = ad9361_reg_write(dev, 0x0216, 0x4D); + status = ad9361_reg_write(dev, 0x0217, 0x4D); + status = ad9361_reg_write(dev, 0x0218, 0x2E); + status = ad9361_reg_write(dev, 0x0219, 0x9C); + status = ad9361_reg_write(dev, 0x021A, 0x1F); + status = ad9361_reg_write(dev, 0x021B, 0x15); + status = ad9361_reg_write(dev, 0x021C, 0x9C); + status = ad9361_reg_write(dev, 0x021D, 0x1F); + status = ad9361_reg_write(dev, 0x021E, 0x15); + status = ad9361_reg_write(dev, 0x021F, 0x9C); + status = ad9361_reg_write(dev, 0x0220, 0x1F); + status = ad9361_reg_write(dev, 0x0221, 0x2A); + status = ad9361_reg_write(dev, 0x0222, 0x2A); + status = ad9361_reg_write(dev, 0x0223, 0x40); + status = ad9361_reg_write(dev, 0x0224, 0x40); + status = ad9361_reg_write(dev, 0x0225, 0x2C); + status = ad9361_reg_write(dev, 0x0226, 0x00); + status = ad9361_reg_write(dev, 0x0227, 0x00); +//************************************************************ +// Setup and Run BB DC and RF DC Offset Calibrations +//************************************************************ + status = ad9361_reg_write(dev, 0x0193, 0x3F); + status = ad9361_reg_write(dev, 0x0190, 0x0F); // Set BBDC tracking shift M value, only applies when BB DC tracking enabled + status = ad9361_reg_write(dev, 0x0194, 0x01); // BBDC Cal setting + status = ad9361_reg_write(dev, 0x0016, 0x01); // Start BBDC offset cal + + // BBDC Max Cal Time: 8416.667 us. Cal done when 0x016[0]==0 + time_out_cnt = 0; + do{ + status |= ad9361_reg_read(dev, 0x0016, &value); + mdelay(1);// Wait 1ms + time_out_cnt++; + } while((value & 0x01) != 0x00 && time_out_cnt <= AD9361_TIMEOUT_TH); + + status = ad9361_reg_write(dev, 0x0185, 0x20); // Set RF DC offset Wait Count + status = ad9361_reg_write(dev, 0x0186, 0x32); // Set RF DC Offset Count[7:0] + status = ad9361_reg_write(dev, 0x0187, 0x24); // Settings for RF DC cal + status = ad9361_reg_write(dev, 0x018B, 0x83); // Settings for RF DC cal + status = ad9361_reg_write(dev, 0x0188, 0x05); // Settings for RF DC cal + status = ad9361_reg_write(dev, 0x0189, 0x30); // Settings for RF DC cal + status = ad9361_reg_write(dev, 0x0016, 0x02); // Start RFDC offset cal + + // RFDC Max Cal Time: 114511.250 us + time_out_cnt = 0; + do{ + status |= ad9361_reg_read(dev, 0x0016, &value); + mdelay(1);// Wait 1ms + time_out_cnt++; + } while((value & 0x01) != 0x00 && time_out_cnt <= AD9361_TIMEOUT_TH); + +//************************************************************ +// Tx Quadrature Calibration Settings +//************************************************************ + status = ad9361_reg_write(dev, 0x00A0, 0x15); // Set TxQuadcal NCO frequency + status = ad9361_reg_write(dev, 0x00A3, 0x00); // Set TxQuadcal NCO frequency (Only update bits [7:6]) + status = ad9361_reg_write(dev, 0x00A1, 0x7B); // Tx Quad Cal Configuration, Phase and Gain Cal Enable + status = ad9361_reg_write(dev, 0x00A9, 0xFF); // Set Tx Quad Cal Count + status = ad9361_reg_write(dev, 0x00A2, 0x7F); // Set Tx Quad Cal Kexp + status = ad9361_reg_write(dev, 0x00A5, 0x01); // Set Tx Quad Cal Magnitude Threshhold + status = ad9361_reg_write(dev, 0x00A6, 0x01); // Set Tx Quad Cal Magnitude Threshhold + status = ad9361_reg_write(dev, 0x00AA, 0x28); // Set Tx Quad Cal Gain Table index + status = ad9361_reg_write(dev, 0x00A4, 0xF0); // Set Tx Quad Cal Settle Count + status = ad9361_reg_write(dev, 0x00AE, 0x04); // Set Tx Quad Cal LPF Gain index incase Split table mode used + + status = ad9361_reg_write(dev, 0x0169, 0xC0); // Disable Rx Quadrature Calibration before Running Tx Quadrature Calibration + status = ad9361_reg_write(dev, 0x0016, 0x10); // Start Tx Quad cal + + // Wait for cal to complete (Done when 0x016[4]==0) + time_out_cnt = 0; + do{ + status |= ad9361_reg_read(dev, 0x0016, &value); + mdelay(1);// Wait 1ms + time_out_cnt++; + } while((value & 0x10) != 0x00 && time_out_cnt <= AD9361_TIMEOUT_TH); + + status = ad9361_reg_write(dev, 0x016A, 0x75); // Set Kexp Phase + status = ad9361_reg_write(dev, 0x016B, 0x95); // Set Kexp Amplitude & Prevent Positive Gain Bit + status = ad9361_reg_write(dev, 0x0169, 0xCF); // Enable Rx Quadrature Calibration Tracking + status = ad9361_reg_write(dev, 0x018B, 0xAD); // Enable BB and RF DC Tracking Calibrations + status = ad9361_reg_write(dev, 0x0012, 0x02); // Cals done, Set PPORT Config + status = ad9361_reg_write(dev, 0x0013, 0x01); // Set ENSM FDD/TDD bit + status = ad9361_reg_write(dev, 0x0015, 0x0C); // Set Dual Synth Mode, FDD External Control bits properly + +//************************************************************ +// Set Tx Attenuation: Tx1: 0.00 dB, Tx2: 0.00 dB +//************************************************************ + status = ad9361_reg_write(dev, 0x0073, 0x00); + status = ad9361_reg_write(dev, 0x0074, 0x00); + status = ad9361_reg_write(dev, 0x0075, 0x00); + status = ad9361_reg_write(dev, 0x0076, 0x00); +//************************************************************ +// Setup RSSI and Power Measurement Duration Registers +//************************************************************ + status = ad9361_reg_write(dev, 0x0150, 0x0E); // RSSI Measurement Duration 0, 1 + status = ad9361_reg_write(dev, 0x0151, 0x00); // RSSI Measurement Duration 2, 3 + status = ad9361_reg_write(dev, 0x0152, 0xFF); // RSSI Weighted Multiplier 0 + status = ad9361_reg_write(dev, 0x0153, 0x00); // RSSI Weighted Multiplier 1 + status = ad9361_reg_write(dev, 0x0154, 0x00); // RSSI Weighted Multiplier 2 + status = ad9361_reg_write(dev, 0x0155, 0x00); // RSSI Weighted Multiplier 3 + status = ad9361_reg_write(dev, 0x0156, 0x00); // RSSI Delay + status = ad9361_reg_write(dev, 0x0157, 0x00); // RSSI Wait + status = ad9361_reg_write(dev, 0x0158, 0x0D); // RSSI Mode Select + status = ad9361_reg_write(dev, 0x015C, 0x67); // Power Measurement Duration + +//************************************************************ +// Enable External LO & External VCO Buffer +//************************************************************ + status |= ad9361_reg_write(dev, 0x0005, 0x07); + status |= ad9361_reg_write(dev, 0x0057, 0x1C); + + return status; +} diff --git a/df_datalink_sp/src/dev_profile/dev_profile.h b/df_datalink_sp/src/dev_profile/dev_profile.h new file mode 100644 index 0000000..38684fb --- /dev/null +++ b/df_datalink_sp/src/dev_profile/dev_profile.h @@ -0,0 +1,30 @@ +#ifndef _DEV_PROFILE_H_ +#define _DEV_PROFILE_H_ + +#include "spi.h" +#include "i2c.h" +#include "delay.h" +#include "irq.h" +#include "error.h" +#include "../drivers/rf-transceiver/ad9361/ad9361_api.h" +#include "../drivers/rf-transceiver/ad9361_reg/ad9361_reg.h" +#include "../drivers/frequency/hmc7044/hmc7044.h" +#include "../drivers/adc/ad9694/ad9694.h" +#include "../config/app_config.h" + +// device parameters +extern struct irq_init_param intc_init_param; +extern struct timer_init_param scutimer_init_param; +extern struct global_timer_init_param globaltimer_init_param; + +// HMC7044 +extern struct hmc7044_init_param hmc7044_default_init_param; + +// AD9361 +extern AD9361_InitParam ad9361_default_init_param; +extern AD9361_RXFIRConfig rx_fir_config; +extern AD9361_TXFIRConfig tx_fir_config; +extern struct ad9361_reg_init_param ad9361_1_reg_default_init_param; +extern struct ad9361_reg_init_param ad9361_2_reg_default_init_param; +uint32_t ad9361_reg_config(struct ad9361_reg_dev *dev); +#endif /* SRC_DEV_PROFILE_H_ */ diff --git a/df_datalink_sp/src/dev_profile/global_timer_profile.c b/df_datalink_sp/src/dev_profile/global_timer_profile.c new file mode 100644 index 0000000..78fab27 --- /dev/null +++ b/df_datalink_sp/src/dev_profile/global_timer_profile.c @@ -0,0 +1,11 @@ +#include "dev_profile.h" +#include "global_timer.h" +#include "../config/app_config.h" + +struct global_timer_init_param globaltimer_init_param = { + .base_addr = GLOBAL_TIMER_BASEADDR, + .id = GLOBAL_TIMER_DEVICE_ID, + .freq_hz = GLOBAL_TIMER_CLK_HZ, + .load_value = 0x0000000000000000 +}; + diff --git a/df_datalink_sp/src/dev_profile/hmc7044_profile.c b/df_datalink_sp/src/dev_profile/hmc7044_profile.c new file mode 100644 index 0000000..2d24d46 --- /dev/null +++ b/df_datalink_sp/src/dev_profile/hmc7044_profile.c @@ -0,0 +1,132 @@ +#include "dev_profile.h" +#include "../config/app_config.h" +#include "../drivers/platform/xilinx_gpio.h" +#include "../drivers/axi_core/spi_engine/spi_engine.h" +#include "../drivers/frequency/hmc7044/hmc7044.h" + + +static struct spi_engine_init_param spi_engine_param = { + .ref_clk_hz = HMC7044_SPI_ENGINE_REF_CLK, + .type = SPI_ENGINE, + .spi_engine_baseaddr = HMC7044_SPI_ENGINE_BASEADDR, + .cs_delay = HMC7044_SPI_ENGINE_CS_DELAY, + .data_width = HMC7044_SPI_ENGINE_DATA_WIDTH +}; + +//static struct xil_gpio_init_param xil_gpio_param = { +// .type = GPIO_PS, +// .device_id = AD9361_GPIO_DEVICE_ID +//}; + +// hmc7044 spi settings +static struct spi_init_param hmc7044_spi_init_param = { + .device_id = HMC7044_SPI_DEVICE_ID, + .max_speed_hz = HMC7044_SPI_ENGINE_MAX_SPEED, + .mode = SPI_MODE_4, + .chip_select = HMC7044_SPI_CS_HMC7044, + .platform_ops = &spi_eng_platform_ops, + .extra = &spi_engine_param +}; + +// hmc7044 channel specifications +struct hmc7044_chan_spec hmc7044_chan_spec[4] = { + /* AD9361_XTAL */ + { + .disable = 0, + .num = 3, + .divider = 100, + .coarse_delay = 0, + .fine_delay = 0, + .high_performance_mode_dis = true, + .start_up_mode_dynamic_enable = false, + .dynamic_driver_enable = false, + .output_control0_rb4_enable = true, + .force_mute_enable = false, + .driver_mode = CML, + .driver_impedance = INTERNAL_100OHM_PER_PIN, + .out_mux_mode = CHANNEL_DIV + }, + /* FPGA_DAC_LOGIC_CLK */ + { + .disable = 0, + .num = 4, + .divider = 10, + .coarse_delay = 0, + .fine_delay = 0, + .high_performance_mode_dis = true, + .start_up_mode_dynamic_enable = false, + .dynamic_driver_enable = false, + .output_control0_rb4_enable = true, + .force_mute_enable = false, + .driver_mode = CML, + .driver_impedance = INTERNAL_100OHM_PER_PIN, + .out_mux_mode = CHANNEL_DIV + }, + /* B_AD9361_XTAL */ + { + .disable = 0, + .num = 12, + .divider = 100, + .coarse_delay = 0, + .fine_delay = 0, + .high_performance_mode_dis = false, + .start_up_mode_dynamic_enable = false, + .dynamic_driver_enable = false, + .output_control0_rb4_enable = true, + .force_mute_enable = false, + .driver_mode = CML, + .driver_impedance = INTERNAL_100OHM_PER_PIN, + .out_mux_mode = CHANNEL_DIV + }, + /* AD9361_RX_EXT_LO */ + { + .disable = 0, + .num = 13, + .divider = 10, + .coarse_delay = 0, + .fine_delay = 0, + .high_performance_mode_dis = false, + .start_up_mode_dynamic_enable = false, + .dynamic_driver_enable = false, + .output_control0_rb4_enable = true, + .force_mute_enable = false, + .driver_mode = CML, + .driver_impedance = INTERNAL_100OHM_PER_PIN, + .out_mux_mode = CHANNEL_DIV + }, +}; + +// hmc7044 default configurations +struct hmc7044_init_param hmc7044_default_init_param = { + .spi_init = &hmc7044_spi_init_param, + .clkin_freq = {0, 100000000, 0, 0}, + .vcxo_freq = 100000000, + .pll2_freq = 2500000000, + .pll1_loop_bw = 200, + .sysref_timer_div = 1536, + .in_buf_mode = { + BUFFER_DISABLE, + ENABLE_AC_COUPLE | ENABLE_INTERNAL_TERM | BUFFER_ENABLE, + BUFFER_DISABLE, + BUFFER_DISABLE, + ENABLE_AC_COUPLE | ENABLE_INTERNAL_TERM | BUFFER_ENABLE + }, + .gpi_ctrl = { + GPI_DISABLE, + GPI_DISABLE, + CHIP_SLEEP_MODE, + PULSE_GEN_REQUSET + }, + .gpo_ctrl = { + PLL1_LOCK_DETECT | GPO_CMOS_MODE, + PLL2_LOCK_DETECT | GPO_CMOS_MODE, + GPO_DISABLE, + GPO_DISABLE + }, + .num_channels = 4, + .pll1_ref_prio_ctrl = 0xE4, + .sync_pin_mode = SYNC_MULTICHIP, + .high_performance_mode_clock_dist_en = false, + .pulse_gen_mode = PULSE_ONE, + .channels = hmc7044_chan_spec +}; diff --git a/df_datalink_sp/src/dev_profile/intc_profile.c b/df_datalink_sp/src/dev_profile/intc_profile.c new file mode 100644 index 0000000..47dc70a --- /dev/null +++ b/df_datalink_sp/src/dev_profile/intc_profile.c @@ -0,0 +1,13 @@ +#include "dev_profile.h" +#include "irq.h" +#include "../config/app_config.h" +#include "../drivers/platform/xilinx_irq.h" +struct xil_irq_init_param xil_intc_init_param = { + .type = IRQ_PS +}; + +struct irq_init_param intc_init_param = { + .irq_ctrl_id = INTC_DEVICE_ID, + .platform_ops = &xil_irq_ops, + .extra = &xil_intc_init_param +}; diff --git a/df_datalink_sp/src/dev_profile/timer_profile.c b/df_datalink_sp/src/dev_profile/timer_profile.c new file mode 100644 index 0000000..53aac51 --- /dev/null +++ b/df_datalink_sp/src/dev_profile/timer_profile.c @@ -0,0 +1,17 @@ +#include "dev_profile.h" +#include "timer.h" +#include "../config/app_config.h" +#include "../drivers/platform/xilinx_timer.h" + +struct xil_timer_init_param xil_scutimer_init_param = { + .active_tmr = 0, + .type = TIMER_PS +}; + +struct timer_init_param scutimer_init_param = { + .id = SCUTIMER_DEVICE_ID, + .freq_hz = SCU_TIMER_CLK_HZ, + .ticks_count = (SCU_TIMER_CLK_HZ/10), //update log every 100ms + .platform_ops = &xil_timer_ops, + .extra = &xil_scutimer_init_param +}; diff --git a/df_datalink_sp/src/drivers/adc/ad9694/ad9694.c b/df_datalink_sp/src/drivers/adc/ad9694/ad9694.c new file mode 100644 index 0000000..336ea4b --- /dev/null +++ b/df_datalink_sp/src/drivers/adc/ad9694/ad9694.c @@ -0,0 +1,128 @@ +/***************************************************************************//** + * @file ad9694.c + * @brief Implementation of AD9680 Driver. + * @author DBogdan (dragos.bogdan@analog.com) + ******************************************************************************** + * Copyright 2014-2016(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *******************************************************************************/ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ +#include +#include +#include "ad9694.h" +#include "../../../include/error.h" + +/***************************************************************************//** + * @brief ad9694_read + *******************************************************************************/ +int32_t ad9694_read(struct ad9694_dev *dev, + uint16_t reg_addr, + uint8_t *reg_data) +{ + uint8_t tx_buf[2]; + uint8_t rx_buf[1]; + int32_t ret; + + tx_buf[0] = 0x80 | (reg_addr >> 8); + tx_buf[1] = reg_addr & 0xFF; + + + ret = spi_write_and_read_3wire(dev->spi_desc, + tx_buf, rx_buf, 2, 1); + + *reg_data = rx_buf[0]; + + return ret; +} + +/***************************************************************************//** + * @brief ad9694_write + *******************************************************************************/ +int32_t ad9694_write(struct ad9694_dev *dev, + uint16_t reg_addr, + uint8_t reg_data) +{ + uint8_t buf[3]; + + int32_t ret; + + buf[0] = reg_addr >> 8; + buf[1] = reg_addr & 0xFF; + buf[2] = reg_data; + + ret = spi_write_and_read_3wire(dev->spi_desc, + buf, NULL, 3, 0); + return ret; +} + +/***************************************************************************//** + * @brief ad9694_init + *******************************************************************************/ +int32_t ad9694_init(struct ad9694_dev **device, + const struct ad9694_init_param *init_param) +{ + int ret = SUCCESS; + struct ad9694_dev *dev; + + dev = (struct ad9694_dev *)malloc(sizeof(*dev)); + if (!dev) + return FAILURE; + + /* SPI */ + ret = spi_init(&dev->spi_desc, init_param->spi_init); + + *device = dev; + + return ret; +} + +/***************************************************************************//** + * @brief Free the resources allocated by ad9694_setup(). + * + * @param dev - The device structure. + * + * @return SUCCESS in case of success, negative error code otherwise. +*******************************************************************************/ +int32_t ad9694_remove(struct ad9694_dev *dev) +{ + int32_t ret; + + ret = spi_remove(dev->spi_desc); + + free(dev); + + return ret; +} diff --git a/df_datalink_sp/src/drivers/adc/ad9694/ad9694.h b/df_datalink_sp/src/drivers/adc/ad9694/ad9694.h new file mode 100644 index 0000000..3c4446a --- /dev/null +++ b/df_datalink_sp/src/drivers/adc/ad9694/ad9694.h @@ -0,0 +1,231 @@ +/***************************************************************************//** + * @file ad9694.h + * @brief Header file of AD9694 Driver. + * @author DBogdan (dragos.bogdan@analog.com) + ******************************************************************************** + * Copyright 2014-2016(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *******************************************************************************/ +#ifndef AD9694_H_ +#define AD9694_H_ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ +#include +#include "delay.h" +#include "spi.h" + +/******************************************************************************/ +/********************** Macros and Constants Definitions **********************/ +/******************************************************************************/ +#define AD9694_REG_GLOBAL_MAP_SPI_CONF_A 0x0000 +#define AD9694_REG_GLOBAL_MAP_SPI_CONF_B 0x0001 +#define AD9694_REG_CH_MAP_CHIP_CONF 0x0002 +#define AD9694_REG_PAIR_MAP_CHIP_TYPE 0x0003 +#define AD9694_REG_PAIR_MAP_CHIP_ID_LSB 0x0004 +#define AD9694_REG_PAIR_MAP_CHIP_GRADE 0x0006 +#define AD9694_REG_PAIR_MAP_DEV_INDEX 0x0008 +#define AD9694_REG_GLOBAL_MAP_PAIR_INDEX 0x0009 +#define AD9694_REG_PAIR_MAP_SCRATCH_PAD 0x000A +#define AD9694_REG_PAIR_MAP_SPI_REVISION 0x000B +#define AD9694_REG_PAIR_MAP_VENDOR_ID_LSB 0x000C +#define AD9694_REG_PAIR_MAP_VENDOR_ID_MSB 0x000D +#define AD9694_REG_CH_MAP_CHIP_PD_PIN 0x003F +#define AD9694_REG_PAIR_MAP_CHIP_PIN_CTRL_1 0x0040 +#define AD9694_REG_PAIR_MAP_CLK_DIV_CTRL 0x0108 +#define AD9694_REG_CH_MAP_CLK_DIV_PHASE 0x0109 +#define AD9694_REG_PAIR_MAP_CLK_DIV_SYSREF_CTRL 0x010A +#define AD9694_REG_PAIR_MAP_CLK_DELAY_CTRL 0x0110 +#define AD9694_REG_CH_MAP_CLK_SUPER_FINE_DELAY 0x0111 +#define AD9694_REG_CH_MAP_CLK_FINE_DELAY 0x0112 +#define AD9694_REG_CLK_DETN_CTRL 0x011A +#define AD9694_REG_PAIR_MAP_CLK_STAT 0x011B +#define AD9694_REG_CLK_DCS_CTRL_1 0x011C +#define AD9694_REG_CLK_DCS_CTRL_2 0x011E +#define AD9694_REG_CLK_DCS_CTRL_3 0x011F +#define AD9694_REG_PAIR_MAP_SYSREF_CTRL_1 0x0120 +#define AD9694_REG_PAIR_MAP_SYSREF_CTRL_2 0x0121 +#define AD9694_REG_PAIR_MAP_SYSREF_CTRL_4 0x0123 +#define AD9694_REG_PAIR_MAP_SYSREF_STAT_1 0x0128 +#define AD9694_REG_PAIR_MAP_SYSREF_STAT_2 0x0129 +#define AD9694_REG_PAIR_MAP_SYSREF_STAT_3 0x012A +#define AD9694_REG_PAIR_MAP_CHIP_SYNC 0x01FF +#define AD9694_REG_PAIR_MAP_CHIP_MODE 0x0200 +#define AD9694_REG_PAIR_MAP_CHIP_DEC_RATIO 0x0201 +#define AD9694_REG_CH_MAP_CUSTOM_OFFSET 0x0228 +#define AD9694_REG_CH_MAP_FD_CTRL 0x0245 +#define AD9694_REG_CH_MAP_FD_UT_LSB 0x0247 +#define AD9694_REG_CH_MAP_FD_UT_MSB 0x0248 +#define AD9694_REG_CH_MAP_FD_LT_LSB 0x0249 +#define AD9694_REG_CH_MAP_FD_LT_MSB 0x024A +#define AD9694_REG_CH_MAP_FD_DWELL_TIME_LSB 0x024B +#define AD9694_REG_CH_MAP_FD_DWELL_TIME_MSB 0x024C +#define AD9694_REG_PAIR_MAP_SIG_MON_SYNC_CTRL 0x026F +#define AD9694_REG_CH_MAP_SIG_MON_CTRL 0x0270 +#define AD9694_REG_CH_MAP_SIG_MON_PERIOD_0 0x0271 +#define AD9694_REG_CH_MAP_SIG_MON_PERIOD_1 0x0272 +#define AD9694_REG_CH_MAP_SIG_MON_PERIOD_2 0x0273 +#define AD9694_REG_CH_MAP_SIG_MON_STAT_CTRL 0x0274 +#define AD9694_REG_CH_MAP_SIG_MON_STAT_0 0x0275 +#define AD9694_REG_CH_MAP_SIG_MON_STAT_1 0x0276 +#define AD9694_REG_CH_MAP_SIG_MON_STAT_2 0x0277 +#define AD9694_REG_CH_MAP_SIG_MON_STAT_FRAME_CNT 0x0278 +#define AD9694_REG_CH_MAP_SIG_MON_SERIAL_FRAMER_CTRL 0x0279 +#define AD9694_REG_SPORT_OVER_JESD204B_INPUT_SEL 0x027A +#define AD9694_REG_PAIR_MAP_DDC_SYNC_CTRL 0x0300 +#define AD9694_REG_PAIR_MAP_DDC_0_CTRL 0x0310 +#define AD9694_REG_PAIR_MAP_DDC_0_INPUT_SEL 0x0311 +#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_INC_0 0x0314 +#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_INC_1 0x0315 +#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_INC_2 0x0316 +#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_INC_3 0x0317 +#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_INC_4 0x0318 +#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_INC_5 0x031A +#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_OFFSET_0 0x031D +#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_OFFSET_1 0x031E +#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_OFFSET_2 0x031F +#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_OFFSET_3 0x0320 +#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_OFFSET_4 0x0321 +#define AD9694_REG_PAIR_MAP_DDC_0_PHASE_OFFSET_5 0x0322 +#define AD9694_REG_PAIR_MAP_DDC_0_TEST_ENABLE 0x0327 +#define AD9694_REG_PAIR_MAP_DDC_1_CTRL 0x0330 +#define AD9694_REG_PAIR_MAP_DDC_1_INPUT_SEL 0x0331 +#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_INC_0 0x0334 +#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_INC_1 0x0335 +#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_INC_2 0x0336 +#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_INC_3 0x0337 +#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_INC_4 0x0338 +#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_INC_5 0x033A +#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_OFFSET_0 0x033D +#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_OFFSET_1 0x033E +#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_OFFSET_2 0x033F +#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_OFFSET_3 0x0340 +#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_OFFSET_4 0x0341 +#define AD9694_REG_PAIR_MAP_DDC_1_PHASE_OFFSET_5 0x0342 +#define AD9694_REG_PAIR_MAP_DDC_1_TEST_ENABLE 0x0347 +#define AD9694_REG_CH_MAP_TEST_MODE_CTRL 0x0550 +#define AD9694_REG_PAIR_MAP_USER_PATTERN_1_LSB 0x0551 +#define AD9694_REG_PAIR_MAP_USER_PATTERN_1_MSB 0x0552 +#define AD9694_REG_PAIR_MAP_USER_PATTERN_2_LSB 0x0553 +#define AD9694_REG_PAIR_MAP_USER_PATTERN_2_MSB 0x0554 +#define AD9694_REG_PAIR_MAP_USER_PATTERN_3_LSB 0x0555 +#define AD9694_REG_PAIR_MAP_USER_PATTERN_3_MSB 0x0556 +#define AD9694_REG_PAIR_MAP_USER_PATTERN_4_LSB 0x0557 +#define AD9694_REG_PAIR_MAP_USER_PATTERN_4_MSB 0x0558 +#define AD9694_REG_PAIR_MAP_OUTPUT_CTRL_MODE_0 0x0559 +#define AD9694_REG_PAIR_MAP_OUTPUT_CTRL_MODE_1 0x055A +#define AD9694_REG_PAIR_MAP_OUTPUT_SAMPLE_MODE 0x0561 +#define AD9694_REG_PAIR_MAP_OUTPUT_CH_SEL 0x0564 +#define AD9694_REG_JESD204B_MAP_PLL_CTRL 0x056E +#define AD9694_REG_JESD204B_MAP_PLL_STAT 0x056F +#define AD9694_REG_JESD204B_MAP_JTX_QUICK_CONF 0x0570 +#define AD9694_REG_JESD204B_MAP_JTX_LINK_CTRL_1 0x0571 +#define AD9694_REG_JESD204B_MAP_JTX_LINK_CTRL_2 0x0572 +#define AD9694_REG_JESD204B_MAP_JTX_LINK_CTRL_3 0x0573 +#define AD9694_REG_JESD204B_MAP_JTX_LINK_CTRL_4 0x0574 +#define AD9694_REG_JESD204B_MAP_JTX_LMFC_OFFSET 0x0578 +#define AD9694_REG_JESD204B_MAP_JTX_DID_CONF 0x0580 +#define AD9694_REG_JESD204B_MAP_JTX_BID_CONF 0x0581 +#define AD9694_REG_JESD204B_MAP_JTX_LID_0_CONF 0x0583 +#define AD9694_REG_JESD204B_MAP_JTX_LID_1_CONF 0x0585 +#define AD9694_REG_JESD204B_MAP_JTX_SCR_L_CONF 0x058B +#define AD9694_REG_JESD204B_MAP_JTX_F_CONF 0x058C +#define AD9694_REG_JESD204B_MAP_JTX_K_CONF 0x058D +#define AD9694_REG_JESD204B_MAP_JTX_M_CONF 0x058E +#define AD9694_REG_JESD204B_MAP_JTX_CS_N_CONF 0x058F +#define AD9694_REG_JESD204B_MAP_JTX_SUBCLASS_CONF 0x0590 +#define AD9694_REG_JESD204B_MAP_JTX_S_CONF 0x0591 +#define AD9694_REG_JESD204B_MAP_JTX_HD_CF_CONF 0x0592 +#define AD9694_REG_JESD204B_MAP_JTX_CHECKSUM_0_CONF 0x05A0 +#define AD9694_REG_JESD204B_MAP_JTX_CHECKSUM_1_CONF 0x05A1 +#define AD9694_REG_SERDOUTX0_SERDOUTX1_LANE_PD 0x05B0 +#define AD9694_REG_JESD204B_MAP_JTX_LANE_ASSIGN_1 0x05B2 +#define AD9694_REG_JESD204B_MAP_JTX_LANE_ASSIGN_2 0x05B3 +#define AD9694_REG_JESD204B_MAP_SERD_ADJUST_0 0x05C0 +#define AD9694_REG_JESD204B_MAP_SERD_ADJUST_1 0x05C1 +#define AD9694_REG_JESD204B_SER_PE_SEL_LANE_0 0x05C4 +#define AD9694_REG_JESD204B_SER_PE_SEL_LANE_1 0x05C6 +#define AD9694_REG_LARGE_DITHER_CTRL 0x0922 +#define AD9694_REG_PLL_CAL 0x1222 +#define AD9694_REG_JESD204B_STARTUP_CIRCUIT_RST 0x1228 +#define AD9694_REG_PLL_LOSS_OF_LOCK_CTRL 0x1262 +#define AD9694_REG_DC_OFFSET_CAL_CTRL 0x0701 +#define AD9694_REG_DC_OFFSET_CAL_CTRL_2 0x073B +#define AD9694_REG_PAIR_MAP_VREF_CTRL 0x18A6 +#define AD9694_REG_EXT_VCM_BUF_CTRL_1 0x18E0 +#define AD9694_REG_EXT_VCM_BUF_CTRL_2 0x18E1 +#define AD9694_REG_EXT_VCM_BUF_CTRL_3 0x18E2 +#define AD9694_REG_EXT_VCM_BUF_CTRL 0x18E3 +#define AD9694_REG_TEMP_DIODE_EXPORT 0x18E6 +#define AD9694_REG_CH_MAP_ANALOG_INPUT_CTRL 0x1908 +#define AD9694_REG_CH_MAP_INPUT_FULLSCALE_RANGE 0x1910 +#define AD9694_REG_CH_MAP_BUF_CTRL_1 0x1A4C +#define AD9694_REG_CH_MAP_BUF_CTRL_2 0x1A4D + +/******************************************************************************/ +/*************************** Types Declarations *******************************/ +/******************************************************************************/ +struct ad9694_dev { + /* SPI */ + struct spi_desc *spi_desc; +}; + +struct ad9694_init_param { + /* SPI */ + struct spi_init_param *spi_init; +}; + +struct ad9694_config { + uint16_t addr; + uint8_t value; +}; + +/******************************************************************************/ +/************************ Functions Declarations ******************************/ +/******************************************************************************/ + +int32_t ad9694_read(struct ad9694_dev *dev, + uint16_t reg_addr, + uint8_t *reg_data); + +int32_t ad9694_write(struct ad9694_dev *dev, + uint16_t reg_addr, + uint8_t reg_data); + +int32_t ad9694_init(struct ad9694_dev **device, + const struct ad9694_init_param *init_param); + +int32_t ad9694_remove(struct ad9694_dev *dev); + +#endif diff --git a/df_datalink_sp/src/drivers/api/gpio.c b/df_datalink_sp/src/drivers/api/gpio.c new file mode 100644 index 0000000..5b37137 --- /dev/null +++ b/df_datalink_sp/src/drivers/api/gpio.c @@ -0,0 +1,241 @@ +/***************************************************************************//** + * @file gpio.c + * @brief Implementation of the GPIO Interface + * @author Antoniu Miclaus (antoniu.miclaus@analog.com) +******************************************************************************** + * Copyright 2020(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ + +#include +#include "gpio.h" +#include +#include "error.h" + +/******************************************************************************/ +/************************ Functions Definitions *******************************/ +/******************************************************************************/ + +/** + * @brief Obtain the GPIO decriptor. + * @param desc - The GPIO descriptor. + * @param param - GPIO Initialization parameters. + * @return 0 in case of success, -1 otherwise. + */ +int32_t gpio_get(struct gpio_desc **desc, + const struct gpio_init_param *param) +{ + int32_t ret; + + if (!param || !param->platform_ops) + return -EINVAL; + + if (!param->platform_ops->gpio_ops_get) + return -ENOSYS; + + ret = param->platform_ops->gpio_ops_get(desc, param); + if (ret) + return ret; + + (*desc)->platform_ops = param->platform_ops; + + return 0; +} + +/** + * @brief Get the value of an optional GPIO. + * @param desc - The GPIO descriptor. + * @param param - GPIO Initialization parameters. + * @return 0 in case of success, -1 otherwise. + */ +int32_t gpio_get_optional(struct gpio_desc **desc, + const struct gpio_init_param *param) +{ + int32_t ret; + + if (!param || (param->number == -1)) { + *desc = NULL; + return 0; + } + + if (!param->platform_ops) + return -EINVAL; + + if (!param->platform_ops->gpio_ops_get_optional) + return -ENOSYS; + + ret = param->platform_ops->gpio_ops_get_optional(desc, param); + if (ret) + return ret; + + (*desc)->platform_ops = param->platform_ops; + + return 0; +} +/** + * @brief Free the resources allocated by gpio_get(). + * @param desc - The GPIO descriptor. + * @return 0 in case of success, -1 otherwise. + */ +int32_t gpio_remove(struct gpio_desc *desc) +{ + if (desc) { + if (!desc->platform_ops) + return -EINVAL; + + if (!desc->platform_ops->gpio_ops_remove) + return -ENOSYS; + + return desc->platform_ops->gpio_ops_remove(desc); + } + + return 0; +} + +/** + * @brief Enable the input direction of the specified GPIO. + * @param desc - The GPIO descriptor. + * @return 0 in case of success, -1 otherwise. + */ +int32_t gpio_direction_input(struct gpio_desc *desc) +{ + if (desc) { + if (!desc->platform_ops) + return -EINVAL; + + if (!desc->platform_ops->gpio_ops_direction_input) + return -ENOSYS; + + return desc->platform_ops->gpio_ops_direction_input(desc); + } + + return 0; +} + +/** + * @brief Enable the output direction of the specified GPIO. + * @param desc - The GPIO descriptor. + * @param value - The value. + * Example: GPIO_HIGH + * GPIO_LOW + * @return 0 in case of success, -1 otherwise. + */ +int32_t gpio_direction_output(struct gpio_desc *desc, + uint8_t value) +{ + if (desc) { + if (!desc->platform_ops) + return -EINVAL; + + if (!desc->platform_ops->gpio_ops_direction_output) + return -ENOSYS; + + return desc->platform_ops-> + gpio_ops_direction_output(desc, value); + } + + return 0; +} + +/** + * @brief Get the direction of the specified GPIO. + * @param desc - The GPIO descriptor. + * @param direction - The direction. + * Example: GPIO_OUT + * GPIO_IN + * @return 0 in case of success, -1 otherwise. + */ +int32_t gpio_get_direction(struct gpio_desc *desc, + uint8_t *direction) +{ + if (desc) { + if (!desc->platform_ops) + return -EINVAL; + + if (!desc->platform_ops->gpio_ops_get_direction) + return -ENOSYS; + + return desc->platform_ops-> + gpio_ops_get_direction(desc, direction); + } + + return 0; +} + +/** + * @brief Set the value of the specified GPIO. + * @param desc - The GPIO descriptor. + * @param value - The value. + * Example: GPIO_HIGH + * GPIO_LOW + * @return 0 in case of success, -1 otherwise. + */ +int32_t gpio_set_value(struct gpio_desc *desc, + uint8_t value) +{ + if (desc) { + if (!desc->platform_ops) + return -EINVAL; + + if (!desc->platform_ops->gpio_ops_set_value) + return -ENOSYS; + + return desc->platform_ops->gpio_ops_set_value(desc, value); + } + + return 0; +} + +/** + * @brief Get the value of the specified GPIO. + * @param desc - The GPIO descriptor. + * @param value - The value. + * Example: GPIO_HIGH + * GPIO_LOW + * @return 0 in case of success, -1 otherwise. + */ +int32_t gpio_get_value(struct gpio_desc *desc, + uint8_t *value) +{ + if (desc) { + if (!desc->platform_ops) + return -EINVAL; + + if (!desc->platform_ops->gpio_ops_set_value) + return -ENOSYS; + + return desc->platform_ops->gpio_ops_get_value(desc, value); + } + + return 0; +} diff --git a/df_datalink_sp/src/drivers/api/i2c.c b/df_datalink_sp/src/drivers/api/i2c.c new file mode 100644 index 0000000..149e7cd --- /dev/null +++ b/df_datalink_sp/src/drivers/api/i2c.c @@ -0,0 +1,135 @@ +/***************************************************************************//** + * @file i2c.c + * @brief Implementation of the I2C Interface + * @author Antoniu Miclaus (antoniu.miclaus@analog.com) +******************************************************************************** + * Copyright 2020(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ + +#include +#include "i2c.h" +#include +#include "error.h" + +/** + * @brief Initialize the I2C communication peripheral. + * @param desc - The I2C descriptor. + * @param param - The structure that contains the I2C parameters. + * @return 0 in case of success, -1 otherwise. + */ +int32_t i2c_init(struct i2c_desc **desc, + const struct i2c_init_param *param) +{ + int32_t ret; + + if (!param || !param->platform_ops) + return -EINVAL; + + if (!param->platform_ops->i2c_ops_init) + return -ENOSYS; + + ret = param->platform_ops->i2c_ops_init(desc, param); + if (ret) + return ret; + + (*desc)->platform_ops = param->platform_ops; + + return 0; +} + +/** + * @brief Free the resources allocated by i2c_init(). + * @param desc - The I2C descriptor. + * @return 0 in case of success, -1 otherwise. + */ +int32_t i2c_remove(struct i2c_desc *desc) +{ + if (!desc || !desc->platform_ops) + return -EINVAL; + + if (!desc->platform_ops->i2c_ops_remove) + return -ENOSYS; + + return desc->platform_ops->i2c_ops_remove(desc); +} + +/** + * @brief I2C Write data to slave device. + * @param desc - The I2C descriptor. + * @param data - The buffer with the transmitted/received data. + * @param bytes_number - Number of bytes to write. + * @param stop_bit - Stop conditional control. + * Example: 0 - A stop condition will not be generated. + * 1 - A stop condition will be generated. + * @return 0 in case of success, -1 otherwise. + */ +int32_t i2c_write(struct i2c_desc *desc, + uint8_t *data, + uint8_t bytes_number, + uint8_t stop_bit) +{ + if (!desc || !desc->platform_ops) + return -EINVAL; + + if (!desc->platform_ops->i2c_ops_write) + return -ENOSYS; + + return desc->platform_ops->i2c_ops_write(desc, data, bytes_number, + stop_bit); +} + +/** + * @brief I2C Read data from slave device. + * @param desc - The i2c descriptor. + * @param data - The buffer with the transmitted/received data. + * @param bytes_number - Number of bytes to read. + * @param stop_bit - Stop conditional control. + * Example: 0 - A stop condition will not be generated. + * 1 - A stop condition will be generated. + * @return 0 in case of success, -1 otherwise. + */ +int32_t i2c_read(struct i2c_desc *desc, + uint8_t *data, + uint8_t bytes_number, + uint8_t stop_bit) +{ + if (!desc || !desc->platform_ops) + return -EINVAL; + + if (!desc->platform_ops->i2c_ops_read) + return -ENOSYS; + + return desc->platform_ops->i2c_ops_read(desc, data, bytes_number, + stop_bit); +} diff --git a/df_datalink_sp/src/drivers/api/irq.c b/df_datalink_sp/src/drivers/api/irq.c new file mode 100644 index 0000000..9162366 --- /dev/null +++ b/df_datalink_sp/src/drivers/api/irq.c @@ -0,0 +1,229 @@ +/***************************************************************************//** + * @file irq.c + * @brief Implementation of the IRQ Interface + * @author Andrei Porumb (andrei.porumb@analog.com) +******************************************************************************** + * Copyright 2021(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ + +#include +#include +#include "irq.h" +#include "error.h" + +/** + * @brief Initialize the IRQ interrupts. + * @param desc - The IRQ descriptor. + * @param param - The structure that contains the IRQ parameters. + * @return 0 in case of success, -1 otherwise. + */ +int32_t irq_ctrl_init(struct irq_ctrl_desc **desc, + const struct irq_init_param *param) +{ + int32_t ret; + + if (!param || !param->platform_ops) + return -EINVAL; + + if (!param->platform_ops->init) + return -ENOSYS; + + ret = param->platform_ops->init(desc, param); + if (ret) + return ret; + + (*desc)->platform_ops = param->platform_ops; + + return 0; +} + +/** + * @brief Free the resources allocated by irq_ctrl_init(). + * @param desc - The SPI descriptor. + * @return 0 in case of success, -1 otherwise. + */ +int32_t irq_ctrl_remove(struct irq_ctrl_desc *desc) +{ + if (!desc || !desc->platform_ops) + return -EINVAL; + + if (!desc->platform_ops->remove) + return -ENOSYS; + + return desc->platform_ops->remove(desc); +} + +/** + * @brief Register a callback to handle the irq events. + * @param desc - The IRQ controller descriptor. + * @param irq_id - Interrupt identifier. + * @param callback - Callback descriptor - platform specific type. + * @return SUCCESS in case of success, FAILURE otherwise. + */ +int32_t irq_register_callback(struct irq_ctrl_desc *desc, + uint32_t irq_id, + struct callback_desc *callback) +{ + if (!desc || !desc->platform_ops) + return -EINVAL; + + if (!desc->platform_ops->register_callback) + return -ENOSYS; + + return desc->platform_ops->register_callback(desc, irq_id, callback); +} + +/** + * @brief Unregisters a generic IRQ handling function. + * @param desc - The IRQ controller descriptor. + * @param irq_id - Interrupt identifier. + * @param callback - Callback descriptor - platform specific type. + * @return SUCCESS in case of success, FAILURE otherwise. + */ +int32_t irq_unregister_callback(struct irq_ctrl_desc *desc, + uint32_t irq_id, + struct callback_desc *callback) +{ + if (!desc || !desc->platform_ops) + return -EINVAL; + + if (!desc->platform_ops->unregister_callback) + return -ENOSYS; + + return desc->platform_ops->unregister_callback(desc, irq_id, callback); +} + +/** + * @brief Enable global interrupts. + * @return 0 in case of success, -1 otherwise. + */ +int32_t irq_global_enable(struct irq_ctrl_desc *desc) +{ + if (!desc || !desc->platform_ops) + return -EINVAL; + + if (!desc->platform_ops->global_enable) + return -ENOSYS; + + return desc->platform_ops->global_enable(desc); +} + +/** + * @brief Disable global interrupts. + * @return 0 in case of success, -1 otherwise. + */ +int32_t irq_global_disable(struct irq_ctrl_desc *desc) +{ + if (!desc || !desc->platform_ops) + return -EINVAL; + + if (!desc->platform_ops->global_disable) + return -ENOSYS; + + return desc->platform_ops->global_disable(desc); +} + +/** + * @brief Set interrupt trigger level. + * @param desc - The IRQ controller descriptor. + * @param irq_id - Interrupt identifier. + * @param trig - New trigger level for the interrupt. + * @return 0 in case of success, -1 otherwise. + */ +int32_t irq_trigger_level_set(struct irq_ctrl_desc *desc, + uint32_t irq_id, + enum irq_trig_level trig) +{ + if (!desc || !desc->platform_ops) + return -EINVAL; + + if(!desc->platform_ops->trigger_level_set) + return -ENOSYS; + + return desc->platform_ops->trigger_level_set(desc, irq_id, trig); +} + +/** + * @brief Enable specific interrupt. + * @param desc - The IRQ controller descriptor. + * @param irq_id - Interrupt identifier. + * @return 0 in case of success, -1 otherwise. + */ +int32_t irq_enable(struct irq_ctrl_desc *desc, uint32_t irq_id) +{ + if (!desc || !desc->platform_ops) + return -EINVAL; + + if (!desc->platform_ops->enable) + return -ENOSYS; + + return desc->platform_ops->enable(desc, irq_id); +} + +/** + * @brief Disable specific interrupt. + * @param desc - The IRQ controller descriptor. + * @param irq_id - Interrupt identifier. + * @return 0 in case of success, -1 otherwise. + */ +int32_t irq_disable(struct irq_ctrl_desc *desc, uint32_t irq_id) +{ + if (!desc || !desc->platform_ops) + return -EINVAL; + + if (!desc->platform_ops->disable) + return -ENOSYS; + + return desc->platform_ops->disable(desc, irq_id); +} + +/** + * @brief Set the priority for an interrupt. + * @param desc - The IRQ controller descriptor. + * @param irq_id - Interrupt identifier. + * @param priority_level - The priority level of the interrupt. + * @return 0 in case of success, negative errno error codes. + */ +int32_t irq_set_priority(struct irq_ctrl_desc *desc, + uint32_t irq_id, + uint32_t priority_level) +{ + if (!desc || !desc->platform_ops) + return -EINVAL; + + if (!desc->platform_ops->set_priority) + return -ENOSYS; + + return desc->platform_ops->set_priority(desc, irq_id, priority_level); +} diff --git a/df_datalink_sp/src/drivers/api/spi.c b/df_datalink_sp/src/drivers/api/spi.c new file mode 100644 index 0000000..954f669 --- /dev/null +++ b/df_datalink_sp/src/drivers/api/spi.c @@ -0,0 +1,161 @@ +/***************************************************************************//** + * @file spi.c + * @brief Implementation of the SPI Interface + * @author Antoniu Miclaus (antoniu.miclaus@analog.com) +******************************************************************************** + * Copyright 2020(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ + +#include +#include "spi.h" +#include +#include "error.h" + +/** + * @brief Initialize the SPI communication peripheral. + * @param desc - The SPI descriptor. + * @param param - The structure that contains the SPI parameters. + * @return 0 in case of success, -1 otherwise. + */ +int32_t spi_init(struct spi_desc **desc, + const struct spi_init_param *param) +{ + int32_t ret; + + if (!param || !param->platform_ops) + return -EINVAL; + + if (!param->platform_ops->init) + return -ENOSYS; + + ret = param->platform_ops->init(desc, param); + if (ret) + return ret; + + (*desc)->platform_ops = param->platform_ops; + (*desc)->parent = param->parent; + + return 0; +} + +/** + * @brief Free the resources allocated by spi_init(). + * @param desc - The SPI descriptor. + * @return 0 in case of success, -1 otherwise. + */ +int32_t spi_remove(struct spi_desc *desc) +{ + if (!desc || !desc->platform_ops) + return -EINVAL; + + if (!desc->platform_ops->remove) + return -ENOSYS; + + return desc->platform_ops->remove(desc); +} + +/** + * @brief Write and read data to/from SPI. + * @param desc - The SPI descriptor. + * @param data - The buffer with the transmitted/received data. + * @param bytes_number - Number of bytes to write/read. + * @return 0 in case of success, -1 otherwise. + */ +int32_t spi_write_and_read(struct spi_desc *desc, + uint8_t *data, + uint16_t bytes_number) +{ + if (!desc || !desc->platform_ops) + return -EINVAL; + + if (!desc->platform_ops->write_and_read) + return -ENOSYS; + + return desc->platform_ops->write_and_read(desc, data, bytes_number); +} + +/** + * @brief Write and read data to/from SPI in 3 wire mode. + * @param desc - The SPI descriptor. + * @param write_data - The buffer with the transmitted data. + * @param read_data - The buffer with the received data. + * @param write_bytes_number - Number of bytes to write. + * @param read_bytes_number - Number of bytes to read. + * @return SUCCESS in case of success, FAILURE otherwise. + */ +int32_t spi_write_and_read_3wire(struct spi_desc *desc, + uint8_t *write_data, + uint8_t *read_data, + uint16_t write_bytes_number, + uint16_t read_bytes_number) +{ + if (!desc || !desc->platform_ops) + return -EINVAL; + + if (!desc->platform_ops->write_and_read_3wire) + return -ENOSYS; + return desc->platform_ops->write_and_read_3wire(desc, write_data, read_data, + write_bytes_number, read_bytes_number); +} +/** + * @brief Iterate over head list and send all spi messages + * @param desc - The SPI descriptor. + * @param msgs - Array of messages. + * @param len - Number of messages in the array. + * @return 0 in case of success, negativ error code otherwise. + */ +int32_t spi_transfer(struct spi_desc *desc, + struct spi_msg *msgs, + uint32_t len) +{ + int32_t ret; + uint32_t i; + + if (!desc || !desc->platform_ops) + return -EINVAL; + + if (desc->platform_ops->transfer) + return desc->platform_ops->transfer(desc, msgs, len); + + for (i = 0; i < len; i++) { + if (msgs[i].rx_buff != msgs[i].tx_buff || !msgs[i].tx_buff) + return -EINVAL; + ret = spi_write_and_read(desc, msgs[i].rx_buff, + msgs[i].bytes_number); + if (IS_ERR_VALUE(ret)) + return ret; + } + + return 0; +} diff --git a/df_datalink_sp/src/drivers/api/timer.c b/df_datalink_sp/src/drivers/api/timer.c new file mode 100644 index 0000000..c9aae42 --- /dev/null +++ b/df_datalink_sp/src/drivers/api/timer.c @@ -0,0 +1,211 @@ +/***************************************************************************//** +* @file timer.c +* @brief Implementation of the timer Interface +* @author RBolboac (ramona.bolboaca@analog.com) +******************************************************************************** +* Copyright 2022(c) Analog Devices, Inc. +* +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* - Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* - Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in +* the documentation and/or other materials provided with the +* distribution. +* - Neither the name of Analog Devices, Inc. nor the names of its +* contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* - The use of this software may or may not infringe the patent rights +* of one or more patent holders. This license does not release you +* from the requirement that you obtain separate licenses from these +* patent holders to use this software. +* - Use of the software either in source or binary form, must be run +* on or directly connected to an Analog Devices Inc. component. +* +* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY +* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ +#include "error.h" +#include "timer.h" + +/******************************************************************************/ +/************************ Functions Definitions *******************************/ +/******************************************************************************/ +/** + * @brief Initialize hardware timer and the handler structure associated with + * it. + * @param [out] desc - Pointer to the reference of the device handler. + * @param [in] param - Initialization structure. + * @return 0 in case of success, negative error code otherwise + */ +int32_t timer_init(struct timer_desc **desc, + struct timer_init_param *param) +{ + int32_t ret; + + if (!param || !param->platform_ops) + return -EINVAL; + + if (!param->platform_ops->init) + return -ENOSYS; + + ret = param->platform_ops->init(desc, param); + if (ret) + return ret; + + (*desc)->platform_ops = param->platform_ops; + + return 0; +} + +/** + * @brief Free the memory allocated by timer_init(). + * @param [in] desc - Pointer to the device handler. + * @return 0 in case of success, negative error code otherwise + */ +int32_t timer_remove(struct timer_desc *desc) +{ + if (!desc || !desc->platform_ops) + return -EINVAL; + + if (!desc->platform_ops->remove) + return -ENOSYS; + + return desc->platform_ops->remove(desc); +} + +/** + * @brief Start a timer. + * @param [in] desc - Pointer to the device handler. + * @return 0 in case of success, negative error code otherwise + */ +int32_t timer_start(struct timer_desc *desc) +{ + if (!desc || !desc->platform_ops) + return -EINVAL; + + if (!desc->platform_ops->start) + return -ENOSYS; + + return desc->platform_ops->start(desc); +} + +/** + * @brief Stop a timer from counting. + * @param [in] desc - Pointer to the device handler. + * @return 0 in case of success, negative error code otherwise + */ +int32_t timer_stop(struct timer_desc *desc) +{ + if (!desc || !desc->platform_ops) + return -EINVAL; + + if (!desc->platform_ops->stop) + return -ENOSYS; + + return desc->platform_ops->stop(desc); +} + +/** + * @brief Get the value of the counter register for the timer. + * @param [in] desc - Pointer to the device handler. + * @param [out] counter - Pointer to the counter value. + * @return 0 in case of success, error code otherwise. + */ +int32_t timer_counter_get(struct timer_desc *desc, + uint32_t *counter) +{ + if (!desc || !desc->platform_ops || !counter) + return -EINVAL; + + if (!desc->platform_ops->counter_get) + return -ENOSYS; + + return desc->platform_ops->counter_get(desc, counter); +} + +/** + * @brief Set the timer counter register value. + * @param [in] desc - Pointer to the device handler. + * @param [in] new_val - The new value of the counter register. + * @return 0 in case of success, error code otherwise. + */ +int32_t timer_counter_set(struct timer_desc *desc, uint32_t new_val) +{ + if (!desc || !desc->platform_ops) + return -EINVAL; + + if (!desc->platform_ops->counter_set) + return -ENOSYS; + + return desc->platform_ops->counter_set(desc, new_val); +} + +/** + * @brief Get the timer clock frequency. + * @param [in] desc - Pointer to the device handler. + * @param [out] freq_hz - The value in Hz of the timer clock. + * @return 0 in case of success, error code otherwise. + */ +int32_t timer_count_clk_get(struct timer_desc *desc, + uint32_t *freq_hz) +{ + if (!desc || !desc->platform_ops || !freq_hz) + return -EINVAL; + + if (!desc->platform_ops->count_clk_get) + return -ENOSYS; + + return desc->platform_ops->count_clk_get(desc, freq_hz); +} + +/** + * @brief Set the timer clock frequency. + * @param [in] desc - Pointer to the device handler. + * @param [in] freq_hz - The value in Hz of the new timer clock. + * @return 0 in case of success, error code otherwise. + */ +int32_t timer_count_clk_set(struct timer_desc *desc, + uint32_t freq_hz) +{ + if (!desc || !desc->platform_ops) + return -EINVAL; + + if (!desc->platform_ops->count_clk_set) + return -ENOSYS; + + return desc->platform_ops->count_clk_set(desc, freq_hz); +} + +/** + * @brief Get the elapsed time in nsec for the timer. + * @param [in] desc - Pointer to the device handler. + * @param [in] elapsed_time - The elapsed time in nsec. + * @return 0 in case of success, error code otherwise. + */ +int32_t timer_get_elapsed_time_nsec(struct timer_desc *desc, + uint64_t *elapsed_time) +{ + if (!desc || !desc->platform_ops) + return -EINVAL; + + if (!desc->platform_ops->get_elapsed_time_nsec) + return -ENOSYS; + + return desc->platform_ops->get_elapsed_time_nsec(desc, elapsed_time); +} diff --git a/df_datalink_sp/src/drivers/api/trng.c b/df_datalink_sp/src/drivers/api/trng.c new file mode 100644 index 0000000..1f3827a --- /dev/null +++ b/df_datalink_sp/src/drivers/api/trng.c @@ -0,0 +1,111 @@ +/***************************************************************************//** + * @file trng.c + * @brief Implementation of the TRNG Interface + * @author Antoniu Miclaus (antoniu.miclaus@analog.com) +******************************************************************************** + * Copyright 2023(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ +#include +#include "trng.h" +#include +#include "error.h" + +/******************************************************************************/ +/************************ Functions Definitions *******************************/ +/******************************************************************************/ + +/** + * @brief Initialize the TRNG. + * @param desc - The TRNG descriptor. + * @param param - The structure that contains the TRNG parameters. + * @return 0 in case of success, -1 otherwise. + */ +int trng_init(struct trng_desc **desc, + const struct trng_init_param *param) +{ + int ret; + + if (!param || !param->platform_ops) + return -EINVAL; + + if (!param->platform_ops->init) + return -ENOSYS; + + ret = param->platform_ops->init(desc, param); + if (ret) + return ret; + + (*desc)->platform_ops = param->platform_ops; + + return 0; +} + +/** + * @brief Free the resources allocated by trng_init(). + * @param desc - The TRNG descriptor. + * @return 0 in case of success, -1 otherwise. + */ +int trng_remove(struct trng_desc *desc) +{ + if (!desc || !desc->platform_ops) + return -EINVAL; + + if (!desc->platform_ops->remove) + return -ENOSYS; + + return desc->platform_ops->remove(desc); +} + +/** + * @brief Fill buffer with rng data. + * @param desc - The TRNG descriptor. + * @param buff - Buffer to be filled + * @param len - Size of the buffer + * @return 0 in case of success, -1 otherwise. + */ +int trng_fill_buffer(struct trng_desc *desc, uint8_t *buff, + uint32_t len) +{ + if (!desc || !desc->platform_ops) + return -EINVAL; + + if (!desc->platform_ops->fill_buffer) + return -ENOSYS; + + return desc->platform_ops->fill_buffer(desc, buff, len); +} diff --git a/df_datalink_sp/src/drivers/axi_core/axi_dmac/axi_dmac.c b/df_datalink_sp/src/drivers/axi_core/axi_dmac/axi_dmac.c new file mode 100644 index 0000000..885fc74 --- /dev/null +++ b/df_datalink_sp/src/drivers/axi_core/axi_dmac/axi_dmac.c @@ -0,0 +1,547 @@ +/******************************************************************************* + * @file axi_dmac.c + * @brief Driver for the Analog Devices AXI-DMAC core. + * @author DBogdan (dragos.bogdan@analog.com) +******************************************************************************** + * Copyright 2018(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ +#include +#include +#include +#include +#include "axi_io.h" +#include "error.h" +#include "delay.h" +#include "axi_dmac.h" + +/******************************************************************************* + * @brief ISR for dev to mem DMA transfer. It computes the next transfer params, + * if any, and sets the transfer structure fields accordingly. + * + * @param instance - the instance that triggered the ISR. + * + * @return None. +*******************************************************************************/ +void axi_dmac_dev_to_mem_isr(void *instance) +{ + struct axi_dmac *dmac = (struct axi_dmac *)instance; + uint32_t burst_size; + uint32_t reg_val; + + /* Get interrupt sources and clear interrupts. */ + axi_dmac_read(dmac, AXI_DMAC_REG_IRQ_PENDING, ®_val); + axi_dmac_write(dmac, AXI_DMAC_REG_IRQ_PENDING, reg_val); + + if (reg_val & AXI_DMAC_IRQ_SOT) { + if (dmac->remaining_size) { + /* See if remaining size is bigger than max transfer size and + * set burst size. */ + if (dmac->remaining_size > dmac->max_length) { + burst_size = dmac->max_length; + } else { + burst_size = dmac->remaining_size - 1; + } + + /* The current transfer was started; set up the new one. */ + axi_dmac_write(dmac, AXI_DMAC_REG_DEST_ADDRESS, dmac->next_dest_addr); + axi_dmac_write(dmac, AXI_DMAC_REG_DEST_STRIDE, 0x0); + axi_dmac_write(dmac, AXI_DMAC_REG_X_LENGTH, burst_size); + axi_dmac_write(dmac, AXI_DMAC_REG_Y_LENGTH, 0x0); + + /* Compute size of the next transfer. */ + dmac->remaining_size = dmac->remaining_size - (burst_size + 1); + /* Address must advance with +1 since the DMAC writes X_LENGTH+1. */ + dmac->next_dest_addr = dmac->next_dest_addr + (burst_size + 1); + + /* Trigger the next transfer. */ + axi_dmac_write(dmac, AXI_DMAC_REG_TRANSFER_SUBMIT, AXI_DMAC_TRANSFER_SUBMIT); + } + } + if (reg_val & AXI_DMAC_IRQ_EOT) { + if (!dmac->remaining_size) { + dmac->transfer.transfer_done = true; + dmac->next_dest_addr = 0; + } + } +} + +/******************************************************************************* + * @brief ISR for mem DMA to dev transfer. It computes the next transfer params, + * if any, and sets the transfer structure fields accordingly. + * + * @param instance - the instance that triggered the ISR. + * + * @return None. +*******************************************************************************/ +void axi_dmac_mem_to_dev_isr(void *instance) +{ + struct axi_dmac *dmac = (struct axi_dmac *)instance; + uint32_t burst_size; + uint32_t reg_val; + + /* Get interrupt sources and clear interrupts. */ + axi_dmac_read(dmac, AXI_DMAC_REG_IRQ_PENDING, ®_val); + axi_dmac_write(dmac, AXI_DMAC_REG_IRQ_PENDING, reg_val); + + if (reg_val & AXI_DMAC_IRQ_SOT) { + if ((dmac->transfer.cyclic == CYCLIC) && + (dmac->next_src_addr >= (dmac->init_addr + dmac->transfer.size - 1))) { + dmac->remaining_size = dmac->transfer.size; + dmac->next_src_addr = dmac->init_addr; + } + + if (dmac->remaining_size) { + /** See if remaining size is bigger than max transfer size and + * set burst size. */ + if (dmac->remaining_size > dmac->max_length) { + burst_size = dmac->max_length; + } else { + burst_size = dmac->remaining_size - 1; + } + + /* The current transfer was started; set up the new one. */ + axi_dmac_write(dmac, AXI_DMAC_REG_SRC_ADDRESS, dmac->next_src_addr); + axi_dmac_write(dmac, AXI_DMAC_REG_SRC_STRIDE, 0x0); + axi_dmac_write(dmac, AXI_DMAC_REG_X_LENGTH, burst_size); + axi_dmac_write(dmac, AXI_DMAC_REG_Y_LENGTH, 0x0); + + /* Compute parameters for the next transfer. */ + dmac->remaining_size = dmac->remaining_size - (burst_size + 1); + /* Address must advance with +1 since the DMAC writes X_LENGTH+1. */ + dmac->next_src_addr = dmac->next_src_addr + (burst_size + 1); + + /* Trigger the current transfer */ + axi_dmac_write(dmac, AXI_DMAC_REG_TRANSFER_SUBMIT, AXI_DMAC_TRANSFER_SUBMIT); + } + } + if (reg_val & AXI_DMAC_IRQ_EOT) { + if ((!dmac->remaining_size) && (dmac->transfer.cyclic != CYCLIC)) { + dmac->transfer.transfer_done = true; + dmac->next_src_addr = 0; + } + } +} + +/******************************************************************************* + * @brief ISR for mem DMA to mem DMA transfer. It computes the next transfer + * params, if any, and sets the transfer structure fields accordingly. + * + * @param instance - the instance that triggered the ISR. + * + * @return None. +*******************************************************************************/ +void axi_dmac_mem_to_mem_isr(void *instance) +{ + struct axi_dmac *dmac = (struct axi_dmac *)instance; + uint32_t burst_size; + uint32_t reg_val; + + /* Get interrupt sources and clear interrupts. */ + axi_dmac_read(dmac, AXI_DMAC_REG_IRQ_PENDING, ®_val); + axi_dmac_write(dmac, AXI_DMAC_REG_IRQ_PENDING, reg_val); + + if (reg_val & AXI_DMAC_IRQ_SOT) { + if (dmac->remaining_size) { + /** See if remaining size is bigger than max transfer size and + * set burst size. */ + if (dmac->remaining_size > dmac->max_length) { + burst_size = dmac->max_length; + } else { + burst_size = dmac->remaining_size - 1; + } + + /* The current transfer was started; set up the new one. */ + axi_dmac_write(dmac, AXI_DMAC_REG_SRC_ADDRESS, dmac->next_src_addr); + axi_dmac_write(dmac, AXI_DMAC_REG_SRC_STRIDE, 0x0); + axi_dmac_write(dmac, AXI_DMAC_REG_DEST_ADDRESS, dmac->next_dest_addr); + axi_dmac_write(dmac, AXI_DMAC_REG_DEST_STRIDE, 0x0); + axi_dmac_write(dmac, AXI_DMAC_REG_X_LENGTH, burst_size); + axi_dmac_write(dmac, AXI_DMAC_REG_Y_LENGTH, 0x0); + + /* Compute parameters for the next transfer. */ + dmac->remaining_size = dmac->remaining_size - (burst_size + 1); + /* Address must advance with +1 since the DMAC writes X_LENGTH+1. */ + dmac->next_src_addr = dmac->next_src_addr + (burst_size + 1); + dmac->next_dest_addr = dmac->next_dest_addr + (burst_size + 1); + + /* If transfer finished advance src address so that transfer_done can be set*/ + if (!dmac->remaining_size) { + dmac->next_src_addr = dmac->next_src_addr + (burst_size + 1); + } + + /* Trigger the current transfer */ + axi_dmac_write(dmac, AXI_DMAC_REG_TRANSFER_SUBMIT, AXI_DMAC_TRANSFER_SUBMIT); + } + } + if (reg_val & AXI_DMAC_IRQ_EOT) { + if (!dmac->remaining_size) { + if(dmac->next_src_addr > (dmac->init_addr + dmac->transfer.size)) { + dmac->transfer.transfer_done = true; + dmac->next_src_addr = 0; + dmac->next_dest_addr = 0; + } + } + } +} + +/******************************************************************************* + * @brief Wrapper for AXI IO through UIO/devmem read function. + * + * @param dmac - DMAC istance containing UIO index (/dev/uioX)/base address. + * @param reg_addr - Address to read from. + * @param reg_data - Location where read data will be stored. + * + * @return 0 - success. +*******************************************************************************/ +int32_t axi_dmac_read(struct axi_dmac *dmac, + uint32_t reg_addr, + uint32_t *reg_data) +{ + axi_io_read(dmac->base, reg_addr, reg_data); + + return 0; +} + +/******************************************************************************* + * @brief Wrapper for AXI IO through UIO/devmem wrrite function. + * + * @param dmac - DMAC istance containing UIO index (/dev/uioX)/base address. + * @param reg_addr - Address to write to. + * @param reg_data - Data to be written. + * + * @return 0 - success. +*******************************************************************************/ +int32_t axi_dmac_write(struct axi_dmac *dmac, + uint32_t reg_addr, + uint32_t reg_data) +{ + axi_io_write(dmac->base, reg_addr, reg_data); + + return 0; +} + +/******************************************************************************* + * @brief Get transfer status (value of dmac->transfer.transfer_done flag). + * + * @note This function should not be used if DMA IRQ is not used. + * + * @param dmac - DMAC istance. + * @param rdy - Transfer status (0 - not ready, 1 - ready). + * + * @return 0 - success. +*******************************************************************************/ +int32_t axi_dmac_is_transfer_ready(struct axi_dmac *dmac, bool *rdy) +{ + *rdy = dmac->transfer.transfer_done; + + return 0; +} + +/******************************************************************************* + * @brief Get DMAC capabilities. + * + * @param dmac - DMAC istance. + * + * @return 0 for success, -1 in case of failure. +*******************************************************************************/ +static int32_t axi_dmac_detect_caps(struct axi_dmac *dmac) +{ + uint32_t reg_val, initial_reg_val = 0; + uint32_t src_mem_mapped = 0; + uint32_t dest_mem_mapped = 0; + + dmac->max_length = -1; + dmac->direction = INVALID_DIR; + + /* Check if HW cyclic possible */ + axi_dmac_read(dmac, AXI_DMAC_REG_FLAGS, &initial_reg_val); + axi_dmac_write(dmac, AXI_DMAC_REG_FLAGS, DMA_CYCLIC); + axi_dmac_read(dmac, AXI_DMAC_REG_FLAGS, ®_val); + if (reg_val == DMA_CYCLIC) + dmac->hw_cyclic = true; + /* Restore initial value for AXI_DMAC_REG_FLAGS register */ + axi_dmac_write(dmac, AXI_DMAC_REG_FLAGS, initial_reg_val); + + /* Get maximum burst size and set value. */ + axi_dmac_write(dmac, AXI_DMAC_REG_X_LENGTH, dmac->max_length); + axi_dmac_read(dmac, AXI_DMAC_REG_X_LENGTH, &dmac->max_length); + + /* Get transfer direction and set value. */ + axi_dmac_write(dmac, AXI_DMAC_REG_DEST_ADDRESS, 0xffffffff); + axi_dmac_read(dmac, AXI_DMAC_REG_DEST_ADDRESS, &dest_mem_mapped); + axi_dmac_write(dmac, AXI_DMAC_REG_SRC_ADDRESS, 0xffffffff); + axi_dmac_read(dmac, AXI_DMAC_REG_SRC_ADDRESS, &src_mem_mapped); + + if (dest_mem_mapped && !src_mem_mapped) { + dmac->direction = DMA_DEV_TO_MEM; + } else if (!dest_mem_mapped && src_mem_mapped) { + dmac->direction = DMA_MEM_TO_DEV; + } else if (dest_mem_mapped && src_mem_mapped) { + dmac->direction = DMA_MEM_TO_MEM; + } else { + printf("Destination and source memory-mapped interfaces not supported.\n"); + return -1; + } + return 0; +} + +/******************************************************************************* + * @brief Get transfer status (value of dmac->transfer.transfer_done flag). + * + * @param dmac_core - DMAC istance. + * @param init - Structure containing initializing data. + * + * @return 0 for success, -1 in case of failure. +*******************************************************************************/ +int32_t axi_dmac_init(struct axi_dmac **dmac_core, + const struct axi_dmac_init *init) +{ + struct axi_dmac *dmac; + + dmac = (struct axi_dmac *)calloc(1, sizeof(*dmac)); + if (!dmac) + return -1; + + dmac->name = init->name; + dmac->base = init->base; + dmac->irq_option = init->irq_option; + + *dmac_core = dmac; + + int32_t status = axi_dmac_detect_caps(*dmac_core); + if (status < 0) + return -1; + + return 0; +} + +/******************************************************************************* + * @brief Remove the DMAC instance. + * + * @param dmac - DMAC istance. + * + * @return 0 for success, -1 in case of failure. +*******************************************************************************/ +int32_t axi_dmac_remove(struct axi_dmac *dmac) +{ + if (!dmac) + return -1; + + free(dmac); + + return 0; +} + +/******************************************************************************* + * @brief Start a DMA transfer. + * + * @param dmac - DMAC istance. + * @param dma_transfer - Structure containing transfer details. + * + * @return 0 for success, -1 in case of failure. +*******************************************************************************/ +int32_t axi_dmac_transfer_start(struct axi_dmac *dmac, + struct axi_dma_transfer *dma_transfer) +{ + uint32_t reg_val, burst_size; + + if (dma_transfer->size == 0) + return 0; /* Nothing to do. */ + + /* Set current transfer parameters. */ + dmac->transfer.size = dma_transfer->size; + dmac->transfer.cyclic = dma_transfer->cyclic; + dmac->transfer.dest_addr = dma_transfer->dest_addr; + dmac->transfer.src_addr = dma_transfer->src_addr; + + dmac->remaining_size = dma_transfer->size; + dmac->next_dest_addr = dma_transfer->dest_addr; + dmac->next_src_addr = dma_transfer->src_addr; + + /* If HW cyclic transfer selected and not available, show error */ + /* HW cyclic transfer available only for MEM to DEV transfers. */ + if ((!dmac->hw_cyclic) && (dma_transfer->cyclic == CYCLIC)) { + printf("Transfer mode not supported!\n"); + return -1; + } + + /* Cyclic transfers not possible for DEV_TO_MEM and MEM_TO_MEM transmissions. */ + if ((dmac->direction == DMA_DEV_TO_MEM) + || (dmac->direction == DMA_MEM_TO_MEM)) { + if (dma_transfer->cyclic == CYCLIC) { + printf("Transfer mode not supported!\n"); + return -1; + } + } + + /* Cyclic transfers set to HW or SW depending on size for MEM to DEV. */ + if ((dmac->direction == DMA_MEM_TO_DEV) && (dmac->transfer.cyclic == CYCLIC)) { + if ((dmac->remaining_size - 1) <= dmac->max_length) { + if (dmac->hw_cyclic) { + axi_dmac_read(dmac, AXI_DMAC_REG_FLAGS, ®_val); + reg_val = reg_val | DMA_CYCLIC; + axi_dmac_write(dmac, AXI_DMAC_REG_FLAGS, reg_val); + } + } else { + axi_dmac_read(dmac, AXI_DMAC_REG_FLAGS, ®_val); + reg_val = reg_val & ~DMA_CYCLIC; + axi_dmac_write(dmac, AXI_DMAC_REG_FLAGS, reg_val); + } + } + + /* Enable DMA if not already enabled. */ + axi_dmac_read(dmac, AXI_DMAC_REG_CTRL, ®_val); + if (!(reg_val & AXI_DMAC_CTRL_ENABLE)) { + axi_dmac_write(dmac, AXI_DMAC_REG_CTRL, 0x0); + axi_dmac_write(dmac, AXI_DMAC_REG_CTRL, AXI_DMAC_CTRL_ENABLE); + axi_dmac_write(dmac, AXI_DMAC_REG_IRQ_MASK, 0x0); + } + + axi_dmac_read(dmac, AXI_DMAC_REG_TRANSFER_SUBMIT, ®_val); + /* If we don't have a start of transfer then start compute + * values and trigger next transfer. */ + if (!(reg_val & AXI_DMAC_QUEUE_FULL)) { + switch (dmac->direction) { + case DMA_DEV_TO_MEM: + dmac->init_addr = dmac->next_dest_addr; + axi_dmac_write(dmac, AXI_DMAC_REG_DEST_ADDRESS, dmac->next_dest_addr); + axi_dmac_write(dmac, AXI_DMAC_REG_DEST_STRIDE, 0x0); + break; + case DMA_MEM_TO_DEV: + dmac->init_addr = dmac->next_src_addr; + axi_dmac_write(dmac, AXI_DMAC_REG_SRC_ADDRESS, dmac->next_src_addr); + axi_dmac_write(dmac, AXI_DMAC_REG_SRC_STRIDE, 0x0); + break; + case DMA_MEM_TO_MEM: + dmac->init_addr = dmac->next_src_addr; + axi_dmac_write(dmac, AXI_DMAC_REG_DEST_ADDRESS, dmac->next_dest_addr); + axi_dmac_write(dmac, AXI_DMAC_REG_DEST_STRIDE, 0x0); + axi_dmac_write(dmac, AXI_DMAC_REG_SRC_ADDRESS, dmac->next_src_addr); + axi_dmac_write(dmac, AXI_DMAC_REG_SRC_STRIDE, 0x0); + break; + default: + return -1; /* Other directions are not supported yet. */ + } + + /* Compute the burst size. */ + if (dmac->remaining_size > dmac->max_length) { + burst_size = dmac->max_length; + } else { + burst_size = dmac->remaining_size - 1; + } + + /* Compute next address (src or dest, or both, depending on type of transfer). */ + switch (dmac->direction) { + case DMA_DEV_TO_MEM: + dmac->next_dest_addr = dmac->next_dest_addr + (burst_size + 1); + break; + case DMA_MEM_TO_DEV: + dmac->next_src_addr = dmac->next_src_addr + (burst_size + 1); + break; + case DMA_MEM_TO_MEM: + dmac->next_dest_addr = dmac->next_dest_addr + (burst_size + 1); + dmac->next_src_addr = dmac->next_src_addr + (burst_size + 1); + break; + default: + return -1; + } + + /* Compute remaining size. */ + dmac->remaining_size = dmac->remaining_size - (burst_size + 1); + + /* Specify the length of the transfer and trigger transfer. */ + axi_dmac_write(dmac, AXI_DMAC_REG_X_LENGTH, burst_size); + axi_dmac_write(dmac, AXI_DMAC_REG_Y_LENGTH, 0x0); + axi_dmac_write(dmac, AXI_DMAC_REG_TRANSFER_SUBMIT, AXI_DMAC_TRANSFER_SUBMIT); + } else { + return -1; + } + + return 0; +} + +/******************************************************************************* + * @brief Wait for DMA transfer to be completed. + * + * @param dmac - DMAC istance. + * @param timeout_ms - Number of ms to wait for completion of transfer. + * + * @return 0 for success, -1 in case trasnfer not completed in specified time. +*******************************************************************************/ +int32_t axi_dmac_transfer_wait_completion(struct axi_dmac *dmac, + uint32_t timeout_ms) +{ + uint32_t timeout = 0; + uint32_t reg_val = 0; + + if (dmac->irq_option == IRQ_ENABLED) { + while (!dmac->transfer.transfer_done) { + timeout++; + mdelay(1); + if (timeout == timeout_ms) { + printf("Error transferring data using DMA.\n"); + return -1; + } + } + } else if (dmac->irq_option == IRQ_DISABLED) { + axi_dmac_read(dmac, AXI_DMAC_REG_IRQ_PENDING, ®_val); + while (reg_val != (AXI_DMAC_IRQ_SOT | AXI_DMAC_IRQ_EOT)) { + timeout++; + mdelay(1); + if (timeout == timeout_ms) { + printf("Error transferring data using DMA.\n"); + return -1; + } + axi_dmac_read(dmac, AXI_DMAC_REG_IRQ_PENDING, ®_val); + } + } + + return 0; +} + +/******************************************************************************* + * @brief Stop a DMA transfer. + * + * @param dmac - DMAC istance. + * + * @return None +*******************************************************************************/ +void axi_dmac_transfer_stop(struct axi_dmac *dmac) +{ + axi_dmac_write(dmac, AXI_DMAC_REG_CTRL, AXI_DMAC_CTRL_DISABLE); +} diff --git a/df_datalink_sp/src/drivers/axi_core/axi_dmac/axi_dmac.h b/df_datalink_sp/src/drivers/axi_core/axi_dmac/axi_dmac.h new file mode 100644 index 0000000..6092a5b --- /dev/null +++ b/df_datalink_sp/src/drivers/axi_core/axi_dmac/axi_dmac.h @@ -0,0 +1,156 @@ +/***************************************************************************//** + * @file axi_dmac.h + * @brief Driver for the Analog Devices AXI-DMAC core. + * @author DBogdan (dragos.bogdan@analog.com) +******************************************************************************** + * Copyright 2018(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ +#ifndef AXI_DMAC_H_ +#define AXI_DMAC_H_ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ +#include +#include "util.h" + +/******************************************************************************/ +/********************** Macros and Constants Definitions **********************/ +/******************************************************************************/ +#define AXI_DMAC_REG_IRQ_MASK 0x80 +#define AXI_DMAC_REG_IRQ_PENDING 0x84 +#define AXI_DMAC_IRQ_SOT BIT(0) +#define AXI_DMAC_IRQ_EOT BIT(1) + +#define AXI_DMAC_REG_INTF_DESC 0x010 +#define AXI_DMAC_DMA_TYPE_DEST GENMASK(5,4) +#define AXI_DMAC_DMA_TYPE_SRC GENMASK(13,12) +//Define macro for src and dest + +#define AXI_DMAC_REG_CTRL 0x400 +#define AXI_DMAC_CTRL_ENABLE BIT(0) +#define AXI_DMAC_CTRL_DISABLE 0u +#define AXI_DMAC_CTRL_PAUSE BIT(1) + +#define AXI_DMAC_REG_TRANSFER_ID 0x404 +#define AXI_DMAC_REG_TRANSFER_SUBMIT 0x408 +#define AXI_DMAC_TRANSFER_SUBMIT BIT(0) +#define AXI_DMAC_QUEUE_FULL BIT(0) +#define AXI_DMAC_REG_FLAGS 0x40c +#define AXI_DMAC_REG_DEST_ADDRESS 0x410 +#define AXI_DMAC_REG_SRC_ADDRESS 0x414 +#define AXI_DMAC_REG_X_LENGTH 0x418 +#define AXI_DMAC_REG_Y_LENGTH 0x41c +#define AXI_DMAC_REG_DEST_STRIDE 0x420 +#define AXI_DMAC_REG_SRC_STRIDE 0x424 +#define AXI_DMAC_REG_TRANSFER_DONE 0x428 + +/******************************************************************************/ +/*************************** Types Declarations *******************************/ +/******************************************************************************/ +enum use_irq { + IRQ_DISABLED = 0, + IRQ_ENABLED = 1 +}; + +enum dma_direction { + INVALID_DIR = 0, + DMA_DEV_TO_MEM = 1, + DMA_MEM_TO_DEV = 2, + DMA_MEM_TO_MEM = 3 +}; + +enum dma_flags { + DMA_CYCLIC = 1, + DMA_LAST = 2, + DMA_PARTIAL_REPORTING_EN = 4 +}; + +// Could be transformed to a bool +enum cyclic_transfer { + NO = 0, + CYCLIC = 1 +}; + +struct axi_dma_transfer { + uint32_t size; + volatile bool transfer_done; + enum cyclic_transfer cyclic; + uint32_t src_addr; + uint32_t dest_addr; +}; + +struct axi_dmac { + const char *name; + uint32_t base; + enum use_irq irq_option; + enum dma_direction direction; + bool hw_cyclic; + uint32_t max_length; + volatile struct axi_dma_transfer transfer; + //Current sub-transfer properties + uint32_t init_addr; + uint32_t remaining_size; + uint32_t next_src_addr; + uint32_t next_dest_addr; +}; + +struct axi_dmac_init { + const char *name; + uint32_t base; + enum use_irq irq_option; +}; + +/******************************************************************************/ +/************************ Functions Declarations ******************************/ +/******************************************************************************/ +void axi_dmac_dev_to_mem_isr(void *instance); +void axi_dmac_mem_to_dev_isr(void *instance); +void axi_dmac_mem_to_mem_isr(void *instance); +void axi_dmac_write_isr(void *instance); +int32_t axi_dmac_read(struct axi_dmac *dmac, uint32_t reg_addr, + uint32_t *reg_data); +int32_t axi_dmac_write(struct axi_dmac *dmac, uint32_t reg_addr, + uint32_t reg_data); +int32_t axi_dmac_is_transfer_ready(struct axi_dmac *dmac, bool *rdy); +int32_t axi_dmac_init(struct axi_dmac **adc_core, + const struct axi_dmac_init *init); +int32_t axi_dmac_remove(struct axi_dmac *dmac); +int32_t axi_dmac_transfer_start(struct axi_dmac *dmac, + struct axi_dma_transfer *dma_transfer); +int32_t axi_dmac_transfer_wait_completion(struct axi_dmac *dmac, + uint32_t timeout_ms); +void axi_dmac_transfer_stop(struct axi_dmac *dmac); + +#endif diff --git a/df_datalink_sp/src/drivers/axi_core/spi_engine/spi_engine.c b/df_datalink_sp/src/drivers/axi_core/spi_engine/spi_engine.c new file mode 100644 index 0000000..7e299c3 --- /dev/null +++ b/df_datalink_sp/src/drivers/axi_core/spi_engine/spi_engine.c @@ -0,0 +1,997 @@ +/******************************************************************************* + * @file spi_engine.c + * @brief Core implementation of the SPI Engine Driver. + * @author Sergiu Cuciurean (sergiu.cuciurean@analog.com) +******************************************************************************** + * Copyright 2019(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +/* In debug mode the printf function used in displaying the messages is causing +significant delays */ +//#define DEBUG_LEVEL 2 + +#include +#include +#include +#include +#include +#include + +#include "axi_io.h" +#include "error.h" +#include "spi_engine.h" + +/** + * @brief Spi engine platform specific SPI platform ops structure + */ +const struct spi_platform_ops spi_eng_platform_ops = { + .init = &spi_engine_init, + .write_and_read = &spi_engine_write_and_read, + .write_and_read_3wire = &spi_engine_write_and_read_3wire, + .remove = &spi_engine_remove +}; + +/******************************************************************************/ +/***************************** Static variables *******************************/ +/******************************************************************************/ + +/** + * @brief Static variable used to sync transfers + * + */ +static uint8_t _sync_id = 0x01; + +/******************************************************************************/ +/************************** Functions Implementation **************************/ +/******************************************************************************/ + +/** + * @brief Write SPI Engine's axi registers + * + * @param desc Decriptor containing SPI Engine's parameters + * @param reg_addr The address of the SPI Engine's axi register where the data + * will be written + * @param reg_data Data that will be written + * @return int32_t This function allways returns SUCCESS + */ +int32_t spi_engine_write(struct spi_engine_desc *desc, + uint32_t reg_addr, + uint32_t reg_data) +{ + axi_io_write(desc->spi_engine_baseaddr, reg_addr, reg_data); + + return SUCCESS; +} + +/** + * @brief Read SPI Engine's axi registers + * + * @param desc Decriptor containing SPI Engine's parameters + * @param reg_addr The address of the SPI Engine's axi register from where the + * data where the data will be read + * @param reg_data Pointer where the read that will be stored + * @return int32_t This function allways returns SUCCESS + */ +int32_t spi_engine_read(struct spi_engine_desc *desc, + uint32_t reg_addr, + uint32_t *reg_data) +{ + axi_io_read(desc->spi_engine_baseaddr, reg_addr, reg_data); + return SUCCESS; +} + +/** + * @brief Set width of the transferred word over SPI + * + * @param desc Decriptor containing SPI interface parameters + * @param data_width The desired data width + * The supported values are: + * - 8 + * - 16 + * - 24 + * - 32 + */ +int32_t spi_engine_set_transfer_width(struct spi_desc *desc, + uint8_t data_width) +{ + struct spi_engine_desc *desc_extra; + + desc_extra = desc->extra; + + if (data_width > desc_extra->max_data_width) + desc_extra->data_width = desc_extra->max_data_width; + else + desc_extra->data_width = data_width; + + return SUCCESS; +} + +/** + * @brief Set SPI engine clock frequency + * + * @param desc Decriptor containing SPI Engine's parameters + * @param speed_hz SPI engine transfer speed + */ +void spi_engine_set_speed(struct spi_desc *desc, + uint32_t speed_hz) +{ + struct spi_engine_desc *desc_extra; + + desc_extra = desc->extra; + + desc_extra->clk_div = desc_extra->ref_clk_hz / + (2 * speed_hz) - 1; +} + +/** + * @brief Set the number of words transferred in a single transaction + * + * @param desc Decriptor containing SPI Engine's parameters + * @param bytes_number The number of bytes to be converted + * @return uint8_t A number of words in which bytes_number can be grouped + */ +static uint8_t spi_get_words_number(struct spi_engine_desc *desc, + uint8_t bytes_number) +{ + uint8_t xfer_word_len; + uint8_t words_number; + + xfer_word_len = desc->data_width / 8; + words_number = bytes_number / xfer_word_len; + + if ((bytes_number % xfer_word_len) != 0) + words_number++; + + return words_number; +} + +/** + * @brief Get the word length in bytes + * + * @param desc Decriptor containing SPI Engine's parameters + * @return uint8_t Number of bytes that fit in one word + */ +static uint8_t spi_get_word_length(struct spi_engine_desc *desc) +{ + uint8_t word_length; + + word_length = desc->data_width / 8; + + return word_length; +} + +/** + * @brief Compute the prescaler used to set the sleep period. + * + * @param desc Decriptor containing SPI interface parameters + * @param sleep_time_ns The amount of time where the transfer hangs + * @param sleep_div Clock prescaler + * @return int32_t This function allways returns SUCCESS + */ +static int32_t spi_get_sleep_div(struct spi_desc *desc, + uint32_t sleep_time_ns, + uint32_t *sleep_div) +{ + struct spi_engine_desc *eng_desc; + + eng_desc = desc->extra; + + /* + * Engine Wiki: + * + * The frequency of the SCLK signal is derived from the + * module clock frequency using the following formula: + * f_sclk = f_clk / ((div + 1) * 2) + */ + + *sleep_div = (desc->max_speed_hz / 1000000 * sleep_time_ns / 1000) / + ((eng_desc->clk_div + 1) * 2) - 1; + + return SUCCESS; +} + +/** + * @brief Create a new commands queue used in a spi transfer + * + * @param fifo Command buffer, usually used in fifo mode + * @param cmd Command with which the buffer will be initiated + * @return int32_t Failure if the memory allocation failed + */ +static int32_t spi_engine_queue_new_cmd(struct spi_engine_cmd_queue **fifo, + uint32_t cmd) +{ + struct spi_engine_cmd_queue *local_fifo; + + local_fifo = (spi_engine_cmd_queue*)malloc(sizeof(*local_fifo)); + + if(!local_fifo) + return FAILURE; + + local_fifo->cmd = cmd; + local_fifo->next = NULL; + *fifo = local_fifo; + + return SUCCESS; +} + +/** + * @brief Add a command at the end of an existing queue + * + * @param fifo Command buffer, usually used in fifo mode + * @param cmd Command to be added + */ +static void spi_engine_queue_add_cmd(struct spi_engine_cmd_queue **fifo, + uint32_t cmd) +{ + struct spi_engine_cmd_queue *to_add = NULL; + struct spi_engine_cmd_queue *local_fifo; + + local_fifo = *fifo; + while (local_fifo->next != NULL) { + // Get the last element + local_fifo = local_fifo->next; + } + + // Create a new element + spi_engine_queue_new_cmd(&to_add, cmd); + // Add as the next element + local_fifo->next = to_add; +} + +/** + * @brief Add a command at the beginning of an existing queue + * + * @param fifo Command buffer, usually used in fifo mode + * @param cmd Command to be added + */ +static void spi_engine_queue_append_cmd(struct spi_engine_cmd_queue **fifo, + uint32_t cmd) +{ + struct spi_engine_cmd_queue *to_add = NULL; + + // Create a new element + spi_engine_queue_new_cmd(&to_add, cmd); + // Interchange the addresses + to_add->next = *fifo; + *fifo = to_add; +} + + +/** + * @brief Get the command from the beginning of the queue + * + * @param fifo Command buffer, usually used in fifo mode + * @param cmd Value of the command that was extracted + * @return int32_t Return FAILURE if the queue is empty + */ +static int32_t spi_engine_queue_get_cmd(struct spi_engine_cmd_queue **fifo, + uint32_t *cmd) +{ + struct spi_engine_cmd_queue *local_fifo; + + if (!*fifo) + return FAILURE; + + local_fifo = *fifo; + *cmd = local_fifo->cmd; + if ((*fifo)->next) { + *fifo = local_fifo->next; + free(local_fifo); + } else { + free(*fifo); + *fifo = NULL; + } + + return SUCCESS; +} + +/** + * @brief Free the memory allocated by a queue + * + * @param fifo The queue that needs it's memory freed + * @return int32_t This function always returns SUCCESS + */ +static int32_t spi_engine_queue_free(struct spi_engine_cmd_queue **fifo) +{ + if(*fifo && (*fifo)->next) + spi_engine_queue_free(&(*fifo)->next); + if((*fifo) != NULL) { + free(*fifo); + *fifo = NULL; + } + + return SUCCESS; +} + +/** + * @brief Write the SPI engine's command fifo + * + * @param desc Decriptor containing SPI Engine's parameters + * @param cmd The command that will be written + * @return int32_t Returns FAILURE if the the axi transfer failed + */ +static int32_t spi_engine_write_cmd_reg(struct spi_engine_desc *desc, + uint32_t cmd) +{ + int32_t ret; + + /* Check if offload is enabled */ + if(desc->offload_config & (OFFLOAD_TX_EN | OFFLOAD_RX_EN)) { + ret = spi_engine_write(desc, + SPI_ENGINE_REG_OFFLOAD_CMD_MEM(0), + cmd); + + } else { + ret = spi_engine_write(desc, + SPI_ENGINE_REG_CMD_FIFO, + cmd); + } + + return ret; +} + +/** + * @brief Write a transfer command to the SPI engine's command fifo + * + * @param desc Decriptor containing SPI Engine's parameters + * @param read_write Read/Write operation flag + * @param bytes_number Number of bytes to transfer + * @return int32_t This function always returns SUCCESS + */ +static int32_t spi_engine_transfer(struct spi_engine_desc *desc, + uint8_t read_write, + uint8_t bytes_number) +{ + uint8_t words_number; + + words_number = spi_get_words_number(desc, bytes_number); + + desc->offload_tx_len += words_number; + + /* + * Engine Wiki: + * + * https://wiki.analog.com/resources/fpga/peripherals/spi_engine + * + * The words number is zero based + */ + + spi_engine_write_cmd_reg(desc, + SPI_ENGINE_CMD_TRANSFER(read_write, + words_number - 1)); + + return SUCCESS; +} + +/** + * @brief Change the state of the chip select port + * + * @param desc Decriptor containing SPI interface parameters + * @param assert Chip select state. + * The supported values are : + * -true (HIGH) + * -false (LOW) + */ +static void spi_engine_set_cs(struct spi_desc *desc, + bool assert) +{ + uint8_t mask; + struct spi_engine_desc *eng_desc; + + eng_desc = desc->extra; + + mask = 0xFF; + /* Switch the state only of the selected chip select */ + if (!assert) + mask ^= BIT(desc->chip_select); + + spi_engine_write_cmd_reg(eng_desc, + SPI_ENGINE_CMD_ASSERT(eng_desc->cs_delay, + mask)); +} + +/** + * @brief Add a delay between the engine commands + * + * @param desc Decriptor containing SPI interface parameters + * @param sleep_time_ns Number of nanoseconds to sleep between commands + */ +static void spi_gen_sleep_ns(struct spi_desc *desc, + uint32_t sleep_time_ns) +{ + uint32_t sleep_div; + struct spi_engine_desc *eng_desc; + + eng_desc = desc->extra; + + spi_get_sleep_div(desc, sleep_time_ns, &sleep_div); + + spi_engine_write_cmd_reg(eng_desc, SPI_ENGINE_CMD_SLEEP(sleep_div)); +} + +/** + * @brief Spi engine command interpreter + * + * @param desc Decriptor containing SPI interface parameters + * @param cmd Command to send to the engine + * @return int32_t - SUCCESS if the command is transferred + * - FAILURE if the command format is invalid + */ +static int32_t spi_engine_write_cmd(struct spi_desc *desc, + uint32_t cmd) +{ + uint8_t engine_command; + uint8_t parameter; + uint8_t modifier; + struct spi_engine_desc *desc_extra; + + desc_extra = desc->extra; + + engine_command = (cmd >> 12) & 0x0F; + modifier = (cmd >> 8) & 0x0F; + parameter = cmd & 0xFF; + + switch(engine_command) { + case SPI_ENGINE_INST_TRANSFER: + spi_engine_transfer(desc_extra, modifier, parameter); + break; + + case SPI_ENGINE_INST_ASSERT: + if(parameter == 0xFF) { + /* Set the CS HIGH */ + spi_engine_set_cs(desc, true); + } else if(parameter == 0x00) { + /* Set the CS LOW */ + spi_engine_set_cs(desc, false); + } + break; + + /* The SYNC and SLEEP commands got the same value but different + modifier */ + case SPI_ENGINE_INST_SYNC_SLEEP: + /* SYNC instruction */ + if(modifier == 0x00) { + spi_engine_write_cmd_reg(desc_extra, cmd); + } else if(modifier == 0x01) { + spi_gen_sleep_ns(desc, parameter); + } + break; + case SPI_ENGINE_INST_CONFIG: + spi_engine_write_cmd_reg(desc_extra, cmd); + + break; + + default: + + return FAILURE; + } + + return SUCCESS; +} + +/** + * @brief Prepare the command queue before sending it to the engine + * + * @param desc Decriptor containing SPI interface parameters + * @param msg Structure used to store the transfer messages + * @return int32_t This function always returns SUCCESS + */ +static int32_t spi_engine_compile_message(struct spi_desc *desc, + struct spi_engine_msg *msg) +{ + struct spi_engine_desc *desc_extra; + + desc_extra = desc->extra; + + /* Configure the prescaler */ + spi_engine_queue_append_cmd(&msg->cmds, + SPI_ENGINE_CMD_CONFIG( + SPI_ENGINE_CMD_REG_CLK_DIV, + desc_extra->clk_div)); + + /* Set the data transfer length */ + spi_engine_queue_append_cmd(&msg->cmds, + SPI_ENGINE_CMD_CONFIG( + SPI_ENGINE_CMD_DATA_TRANSFER_LEN, + desc_extra->data_width)); + /* + * Configure the spi mode : + * - 3 wire + * - CPOL + * - CPHA + */ + spi_engine_queue_append_cmd(&msg->cmds, + SPI_ENGINE_CMD_CONFIG( + SPI_ENGINE_CMD_REG_CONFIG, + desc->mode)); + + /* Add a sync command to signal that the transfer has finished */ + spi_engine_queue_add_cmd(&msg->cmds, SPI_ENGINE_CMD_SYNC(_sync_id)); + + return SUCCESS; +} + +/** + * @brief Initiate a spi transfer (Blocking) + * + * @param desc Decriptor containing SPI interface parameters + * @param msg Structure used to store the transfer messages + * @return int32_t - SUCCESS if the transfer finished + * - FAILURE if the memory allocation failed + */ +static int32_t spi_engine_transfer_message(struct spi_desc *desc, + struct spi_engine_msg *msg) +{ + uint32_t i; + uint32_t data; + uint32_t sync_id; + bool offload_en; + struct spi_engine_desc *desc_extra; + + desc_extra = desc->extra; + + spi_engine_compile_message(desc, msg); + + offload_en = (desc_extra->offload_config & OFFLOAD_TX_EN) | + (desc_extra->offload_config & OFFLOAD_RX_EN); + + /* Write the command fifo buffer */ + while(msg->cmds != NULL) { + spi_engine_queue_get_cmd(&msg->cmds, &data); + spi_engine_write_cmd(desc, data); + } + + /* Write a number of tx_length WORDS on the SDO line */ + if(offload_en) { + for(i = 0; i < desc_extra->offload_tx_len; i++) + spi_engine_write(desc_extra, + SPI_ENGINE_REG_OFFLOAD_SDO_MEM(0), + msg->tx_buf[i]); + + } else { + if(msg->tx_buf != NULL){ + for(i = 0; i < msg->tx_length; i++) + spi_engine_write(desc_extra, + SPI_ENGINE_REG_SDO_DATA_FIFO, + msg->tx_buf[i]); + } + do { + spi_engine_read(desc_extra, + SPI_ENGINE_REG_SYNC_ID, + &sync_id); + } + /* Wait for the end sync signal */ + while(sync_id != _sync_id); + _sync_id++; + + /* Read a number of rx_length WORDS from the SDI line and store + them */ + for(i = 0; i < msg->rx_length; i++) { + spi_engine_read(desc_extra, + SPI_ENGINE_REG_SDI_DATA_FIFO, + &data); + /* Store the rx data if rx buffer valid, flush sdi_fifo if + rx buffer is invalid.*/ + if(msg->rx_buf != NULL){ + msg->rx_buf[i] = data; + } + } + } + + return SUCCESS; +} + +/** + * @brief Initialize the spi engine + * + * @param desc Decriptor containing SPI interface parameters + * @param param Structure containing the spi init parameters + * @return int32_t - SUCCESS if the transfer finished + * - FAILURE if the memory allocation failed + */ +int32_t spi_engine_init(struct spi_desc **desc, + const struct spi_init_param *param) +{ + uint32_t data_width; + uint32_t spi_engine_version; + struct spi_engine_desc *eng_desc; + struct spi_engine_init_param *spi_engine_init; + + if (!param) { + return FAILURE; + } + + *desc = malloc(sizeof(**desc)); + if(! *desc) { + free(*desc); + return FAILURE; + } + + eng_desc = (struct spi_engine_desc*)malloc(sizeof(*eng_desc)); + + if (!eng_desc) + return FAILURE; + + spi_engine_init = param->extra; + + (*desc)->max_speed_hz = param->max_speed_hz; + (*desc)->chip_select = param->chip_select; + (*desc)->mode = param->mode; + (*desc)->extra = eng_desc; + + eng_desc->offload_config = OFFLOAD_DISABLED; + eng_desc->spi_engine_baseaddr = spi_engine_init->spi_engine_baseaddr; + eng_desc->type = spi_engine_init->type; + eng_desc->cs_delay = spi_engine_init->cs_delay; + eng_desc->ref_clk_hz = spi_engine_init->ref_clk_hz; + eng_desc->clk_div = eng_desc->ref_clk_hz / + (2 * param->max_speed_hz) - 1; + + /* Perform a reset */ + spi_engine_write(eng_desc, SPI_ENGINE_REG_RESET, 0x01); + usleep(1000); + spi_engine_write(eng_desc, SPI_ENGINE_REG_RESET, 0x00); + + /* Get current data width */ + spi_engine_read(eng_desc, SPI_ENGINE_REG_DATA_WIDTH, &data_width); + eng_desc->max_data_width = data_width; + + spi_engine_set_transfer_width(*desc, spi_engine_init->data_width); + + /* Get spi engine version */ + spi_engine_read(eng_desc, SPI_ENGINE_REG_VERSION, &spi_engine_version); + + printf("Spi engine v%"PRIu32".%"PRIu32".%"PRIu32" successfully initialized.\n", + (spi_engine_version >> 16), + ((spi_engine_version >> 8) & 0xFF), + (spi_engine_version & 0xFF)); + + return SUCCESS; +} + +/** + * @brief Write/read on the spi interface in 4-wire mode (full-duplex) + * + * @param desc Decriptor containing SPI interface parameters + * @param data Pointer to data buffer + * @param bytes_number Number of bytes to transfer + * @return int32_t - SUCCESS if the transfer finished + * - FAILURE if the memory allocation or transfer failed + */ +int32_t spi_engine_write_and_read(struct spi_desc *desc, + uint8_t *data, + uint16_t bytes_number) +{ + uint8_t i; + uint8_t word_len; + uint8_t words_number; + int32_t ret; + struct spi_engine_msg msg; + struct spi_engine_desc *desc_extra; + + desc_extra = desc->extra; + + /* If we want to access SPI interface and SPI engine offload module was + * activated, we need to disable it + * This is set in spi_engine_offload_init() */ + desc_extra->offload_config = OFFLOAD_DISABLED; + /* This is set in spi_engine_offload_transfer() */ + spi_engine_write(desc_extra, SPI_ENGINE_REG_OFFLOAD_CTRL(0), 0); + + words_number = spi_get_words_number(desc_extra, bytes_number); + + msg.cmds = (spi_engine_cmd_queue*)malloc(sizeof(*msg.cmds)); + if (!msg.cmds) + return FAILURE; + + msg.tx_buf =(uint32_t*)calloc(words_number, sizeof(msg.tx_buf[0])); + msg.rx_buf =(uint32_t*)calloc(words_number, sizeof(msg.rx_buf[0])); + msg.tx_length = words_number; + msg.rx_length = words_number; + + /* Get the length of transferred word */ + word_len = spi_get_word_length(desc_extra); + + /* Make sure the CS is HIGH before starting a transaction */ + msg.cmds->next = NULL; + msg.cmds->cmd = CS_HIGH; + // Assert select. + spi_engine_queue_add_cmd(&msg.cmds, CS_LOW); + // add read/write command + spi_engine_queue_add_cmd(&msg.cmds, WRITE_READ(bytes_number)); + // Disable select. + spi_engine_queue_add_cmd(&msg.cmds, CS_HIGH); + + /* Pack the bytes into engine WORDS */ + for (int i = 0; i < bytes_number; i++) + msg.tx_buf[i / word_len] |= data[i] << (desc_extra->data_width- + (i % word_len + 1) * 8); + + ret = spi_engine_transfer_message(desc, &msg); + + for (int i = 0; i < bytes_number; i++) + data[i] = msg.rx_buf[(i) / word_len] >> + (desc_extra->data_width - + ((i) % word_len + 1) * 8); + + spi_engine_queue_free(&msg.cmds); + free(msg.tx_buf); + free(msg.rx_buf); + + return ret; +} + +/** + * @brief Write and read on the spi interface in 3-wire mode (half-duplex) + * + * @param desc Decriptor containing SPI interface parameters + * @param data Pointer to data buffer + * @param bytes_number Number of bytes to transfer + * @return int32_t - SUCCESS if the transfer finished + * - FAILURE if the memory allocation or transfer failed + */ +int32_t spi_engine_write_and_read_3wire(struct spi_desc *desc, + uint8_t *write_data, + uint8_t *read_data, + uint16_t write_bytes_number, + uint16_t read_bytes_number) +{ + uint8_t word_len; + uint8_t wr_words_number; + uint8_t rd_words_number; + int32_t ret; + struct spi_engine_msg msg; + struct spi_engine_desc *desc_extra; + + desc_extra = desc->extra; + + /* If we want to access SPI interface and SPI engine offload module was + * activated, we need to disable it + * This is set in spi_engine_offload_init() */ + desc_extra->offload_config = OFFLOAD_DISABLED; + /* This is set in spi_engine_offload_transfer() */ + spi_engine_write(desc_extra, SPI_ENGINE_REG_OFFLOAD_CTRL(0), 0); + + wr_words_number = spi_get_words_number(desc_extra, write_bytes_number); + rd_words_number = spi_get_words_number(desc_extra, read_bytes_number); + + msg.cmds = (spi_engine_cmd_queue*)malloc(sizeof(*msg.cmds)); + if (!msg.cmds) + return FAILURE; + + msg.tx_buf =(wr_words_number>0)?(uint32_t*)calloc(wr_words_number, sizeof(msg.tx_buf[0])):NULL; + msg.rx_buf =(rd_words_number>0)?(uint32_t*)calloc(rd_words_number, sizeof(msg.rx_buf[0])):NULL; + msg.tx_length = wr_words_number; + msg.rx_length = rd_words_number; + + /* Get the length of transferred word */ + word_len = spi_get_word_length(desc_extra); + + /* Make sure the CS is HIGH before starting a transaction */ + msg.cmds->next = NULL; + msg.cmds->cmd = CS_HIGH; + + // Assert select. + spi_engine_queue_add_cmd(&msg.cmds, CS_LOW); + + // add read/write command + if(write_bytes_number > 0) + spi_engine_queue_add_cmd(&msg.cmds, WRITE(write_bytes_number)); + if(read_bytes_number > 0) + spi_engine_queue_add_cmd(&msg.cmds, READ(read_bytes_number)); + + // Disable select. + spi_engine_queue_add_cmd(&msg.cmds, CS_HIGH); + + /* Pack the bytes into engine WORDS */ + for (int i = 0; i < write_bytes_number; i++) + msg.tx_buf[i / word_len] |= write_data[i] << (desc_extra->data_width- + (i % word_len + 1) * 8); + + ret = spi_engine_transfer_message(desc, &msg); + + for (int i = 0; i < read_bytes_number; i++) + read_data[i] = msg.rx_buf[(i) / word_len] >> + (desc_extra->data_width - + ((i) % word_len + 1) * 8); + + spi_engine_queue_free(&msg.cmds); + free(msg.tx_buf); + free(msg.rx_buf); + + return ret; +} + +/** + * @brief Initialize the SPI engine's offload module + * + * @param desc Decriptor containing SPI interface parameters + * @param param Structure containing the offload init parameters + * @return int32_t This function always returns SUCCESS + */ +int32_t spi_engine_offload_init(struct spi_desc *desc, + const struct spi_engine_offload_init_param *param) +{ + struct spi_engine_desc *eng_desc; + struct axi_dmac_init dmac_init; + + eng_desc = desc->extra; + + eng_desc->offload_config = param->offload_config; + + if(!(param->dma_flags)) { + eng_desc->cyclic = CYCLIC; + } else { + if((*(param->dma_flags)) & DMA_CYCLIC) + eng_desc->cyclic = CYCLIC; + else + eng_desc->cyclic = NO; + } + + + if(param->offload_config & OFFLOAD_TX_EN) { + dmac_init.name = "DAC DMAC"; + dmac_init.base = param->tx_dma_baseaddr; + axi_dmac_init(&eng_desc->offload_tx_dma, &dmac_init); + if(!eng_desc->offload_tx_dma) + return FAILURE; + } + if(param->offload_config & OFFLOAD_RX_EN) { + dmac_init.name = "ADC DMAC"; + dmac_init.base = param->rx_dma_baseaddr; + axi_dmac_init(&eng_desc->offload_rx_dma, &dmac_init); + if(!eng_desc->offload_rx_dma) + return FAILURE; + } + + return SUCCESS; +} + +/** + * @brief Initiate a SPI transfer in offload mode + * + * @param desc Decriptor containing SPI interface parameters + * @param msg Offload message that get's to be transferred + * @param no_samples Number of time the messages will be transferred + * @return int32_t This function always returns SUCCESS + */ +int32_t spi_engine_offload_transfer(struct spi_desc *desc, + struct spi_engine_offload_message msg, + uint32_t no_samples) +{ + struct spi_engine_msg transfer; + struct spi_engine_desc *eng_desc; + uint32_t i; + uint8_t word_length; + + eng_desc = desc->extra; + + /* Check if offload is disabled */ + if(!((eng_desc->offload_config & OFFLOAD_TX_EN) | + (eng_desc->offload_config & OFFLOAD_RX_EN))) + return FAILURE; + + spi_engine_write(eng_desc, SPI_ENGINE_REG_OFFLOAD_RESET(0), 1); + spi_engine_write(eng_desc, SPI_ENGINE_REG_OFFLOAD_RESET(0), 0); + + eng_desc->offload_tx_len = 0; + eng_desc->offload_rx_len = 0; + + transfer.cmds = (spi_engine_cmd_queue*)malloc(sizeof(*transfer.cmds)); + + if (!transfer.cmds) + return -1; + + transfer.tx_buf = msg.commands_data; + + /* Load the commands into the message */ + transfer.cmds->next = NULL; + transfer.cmds->cmd = msg.commands[0]; + i = 1; + while(i < msg.no_commands) { + spi_engine_queue_add_cmd(&transfer.cmds, msg.commands[i++]); + + } + + spi_engine_transfer_message(desc, &transfer); + + /* Start transfer */ + spi_engine_write(eng_desc, SPI_ENGINE_REG_OFFLOAD_CTRL(0), 0x0001); + + word_length = spi_get_word_length(eng_desc); + if(eng_desc->offload_config & OFFLOAD_TX_EN) { + struct axi_dma_transfer tx_transfer = { + // Number of bytes to write/read + .size = word_length * eng_desc->offload_tx_len * no_samples, + // Transfer done flag + .transfer_done = 0, + // Signal transfer mode + .cyclic = eng_desc->cyclic, + // Address of data source + .src_addr = (uintptr_t)msg.tx_addr, + // Address of data destination + .dest_addr = 0 + }; + axi_dmac_transfer_start(eng_desc->offload_tx_dma, &tx_transfer); + } + + if(eng_desc->offload_config & OFFLOAD_RX_EN) { + struct axi_dma_transfer rx_transfer = { + // Number of bytes to write/read + .size = word_length * eng_desc->offload_tx_len * no_samples, + // Transfer done flag + .transfer_done = 0, + // Signal transfer mode + .cyclic = NO, + // Address of data source + .src_addr = 0, + // Address of data destination + .dest_addr = (uintptr_t)msg.rx_addr + }; + axi_dmac_transfer_start(eng_desc->offload_rx_dma, &rx_transfer); + axi_dmac_transfer_wait_completion(eng_desc->offload_rx_dma, 500); + } + + usleep(1000); + + spi_engine_queue_free(&transfer.cmds); + + return SUCCESS; +} + +/** + * @brief Free the resources allocated by spi_init(). + * + * @param desc Decriptor containing SPI interface parameters + * @return int32_t This function allways returns SUCCESS + */ +int32_t spi_engine_remove(struct spi_desc *desc) +{ + struct spi_engine_desc *eng_desc; + + eng_desc = desc->extra; + + if(eng_desc->offload_config & OFFLOAD_TX_EN) + axi_dmac_remove(eng_desc->offload_tx_dma); + if(eng_desc->offload_config & OFFLOAD_RX_EN) + axi_dmac_remove(eng_desc->offload_rx_dma); + free(desc->extra); + free(desc); + + return SUCCESS; +} diff --git a/df_datalink_sp/src/drivers/axi_core/spi_engine/spi_engine.h b/df_datalink_sp/src/drivers/axi_core/spi_engine/spi_engine.h new file mode 100644 index 0000000..9e6887e --- /dev/null +++ b/df_datalink_sp/src/drivers/axi_core/spi_engine/spi_engine.h @@ -0,0 +1,229 @@ +/******************************************************************************* + * @file spi_engine.h + * @brief Header file of SPI Engine core features. + * @author Sergiu Cuciurean (sergiu.cuciurean@analog.com) +******************************************************************************** + * Copyright 2019(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ + +#ifndef SPI_ENGINE_H +#define SPI_ENGINE_H + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include + +#include "spi_engine_private.h" +#include "../axi_dmac/axi_dmac.h" +#include "../../platform/xilinx_spi.h" + +/******************************************************************************/ +/********************** Macros and Constants Definitions **********************/ +/******************************************************************************/ + +#define OFFLOAD_DISABLED 0x00 +#define OFFLOAD_TX_EN BIT(0) +#define OFFLOAD_RX_EN BIT(1) +#define OFFLOAD_TX_RX_EN OFFLOAD_TX_EN | OFFLOAD_RX_EN + +#define SPI_ENGINE_MSG_QUEUE_END 0xFFFFFFFF + +/* Spi engine commands */ +#define WRITE(no_bytes) ((SPI_ENGINE_INST_TRANSFER << 12) |\ + (SPI_ENGINE_INSTRUCTION_TRANSFER_W << 8) | no_bytes) + +#define READ(no_bytes) ((SPI_ENGINE_INST_TRANSFER << 12) |\ + (SPI_ENGINE_INSTRUCTION_TRANSFER_R << 8) | no_bytes) + +#define WRITE_READ(no_bytes) ((SPI_ENGINE_INST_TRANSFER << 12) |\ + (SPI_ENGINE_INSTRUCTION_TRANSFER_RW << 8) | no_bytes) + +#define SLEEP(time) SPI_ENGINE_CMD_SLEEP(time & 0xF) + +/* The delay and chip select parmeters are passed over the engine descriptor +and will be used inside the function call */ +#define CS_HIGH SPI_ENGINE_CMD_ASSERT(0x01, 0xFF) +#define CS_LOW SPI_ENGINE_CMD_ASSERT(0x01, 0x00) + +/******************************************************************************/ +/*************************** Types Declarations *******************************/ +/******************************************************************************/ + +/** + * @struct spi_engine_init_param + * @brief Structure containing the init parameters needed by the SPI engine + */ +struct spi_engine_init_param { + /** SPI engine reference clock */ + uint32_t ref_clk_hz; + /** Type of implementation */ + enum xil_spi_type type; + /** Base address where the HDL core is situated */ + uint32_t spi_engine_baseaddr; + /** Delay between the CS toggle and the start of SCLK */ + uint32_t cs_delay; + /** Data with of one SPI transfer ( in bits ) */ + uint8_t data_width; +}; + + +/** + * @struct spi_engine_desc + * @brief Structure representing an SPI engine device + */ +struct spi_engine_desc { + /** SPI engine reference clock */ + uint32_t ref_clk_hz; + /** Type of implementation */ + enum xil_spi_type type; + /** Pointer to a DMAC used in transmission */ + struct axi_dmac *offload_tx_dma; + /** Pointer to a DMAC used in reception */ + struct axi_dmac *offload_rx_dma; + /** Transfer mode for Tx DMAC */ + enum cyclic_transfer cyclic; + /** Offload's module transfer direction : TX, RX or both */ + uint8_t offload_config; + /** Number of words that the module has to send */ + uint8_t offload_tx_len; + /** Number of words that the module has to receive */ + uint8_t offload_rx_len; + /** Base address where the HDL core is situated */ + uint32_t spi_engine_baseaddr; + /** Base address where the RX DMAC core is situated */ + uint32_t rx_dma_baseaddr; + /** Base address where the TX DMAC core is situated */ + uint32_t tx_dma_baseaddr; + /** Delay between the CS toggle and the start of SCLK */ + uint8_t cs_delay; + /** Clock divider used in transmission delays */ + uint32_t clk_div; + /** Data with of one SPI transfer ( in bits ) */ + uint8_t data_width; + /** The maximum data width supported by the engine */ + uint8_t max_data_width; +}; + + +/** + * @struct spi_engine_offload_init_param + * @brief Structure containing the init parameters needed by the offload module + */ +struct spi_engine_offload_init_param { + /** Base address where the RX DMAC core is situated */ + uint32_t rx_dma_baseaddr; + /** Base address where the TX DMAC core is situated */ + uint32_t tx_dma_baseaddr; + /** DMAC flags - if not initialized, the default value is DMA_CYCLIC */ + uint32_t *dma_flags; + /** Offload's module transfer direction : TX, RX or both */ + uint8_t offload_config; +}; + +/** + * @struct spi_engine_offload_message + * @brief Structure representing an offload message + */ +struct spi_engine_offload_message { + /** Pointer to the SPI engine commands buffer that will be sent. + * The available commands can be found at: + * https://wiki.analog.com/resources/fpga/peripherals/spi_engine/ + */ + uint32_t *commands; + /** Length of the SPI engine commands buffer */ + uint32_t no_commands; + /** Pointer of the data that will be sent over spi */ + uint32_t *commands_data; + /** The address where the data that will be transmitted is situated */ + uint32_t tx_addr; + /** The address where the data that will be received is situated */ + uint32_t rx_addr; +}; + +/******************************************************************************/ +/************************ Functions Declarations ******************************/ +/******************************************************************************/ + +/** + * @brief Spi engine platform specific SPI platform ops structure + */ +extern const struct spi_platform_ops xil_spi_ops; + +/* Write SPI Engine's axi registers */ +int32_t spi_engine_write(struct spi_engine_desc *desc, + uint32_t reg_addr, + uint32_t reg_data); + +/* Read SPI Engine's axi registers */ +int32_t spi_engine_read(struct spi_engine_desc *desc, + uint32_t reg_addr, + uint32_t *reg_data); +/* Initialize the SPI engine device */ +int32_t spi_engine_init(struct spi_desc **desc, + const struct spi_init_param *param); + +/* Write and read data over SPI using the SPI engine */ +int32_t spi_engine_write_and_read(struct spi_desc *desc, + uint8_t *data, + uint16_t bytes_number); + +/* Write and read data over SPI using the SPI engine in 3-wire mode */ +int32_t spi_engine_write_and_read_3wire(struct spi_desc *desc, + uint8_t *write_data, + uint8_t *read_data, + uint16_t write_bytes_number, + uint16_t read_bytes_number); +/* Free the resources used by the SPI engine device */ +int32_t spi_engine_remove(struct spi_desc *desc); + +/* Initialize the SPI engine offload module */ +int32_t spi_engine_offload_init(struct spi_desc *desc, + const struct spi_engine_offload_init_param *param); + +/* Write and read data over SPI using the offload module */ +int32_t spi_engine_offload_transfer(struct spi_desc *desc, + struct spi_engine_offload_message msg, + uint32_t no_samples); + +/* Set SPI transfer width */ +int32_t spi_engine_set_transfer_width(struct spi_desc *desc, + uint8_t data_wdith); + +/* Set SPI transfer speed */ +void spi_engine_set_speed(struct spi_desc *desc, + uint32_t speed_hz); + +#endif // SPI_ENGINE_H diff --git a/df_datalink_sp/src/drivers/axi_core/spi_engine/spi_engine_private.h b/df_datalink_sp/src/drivers/axi_core/spi_engine/spi_engine_private.h new file mode 100644 index 0000000..571a847 --- /dev/null +++ b/df_datalink_sp/src/drivers/axi_core/spi_engine/spi_engine_private.h @@ -0,0 +1,154 @@ +/******************************************************************************* + * @file spi_engine_private.h + * @brief Private definitions of the SPI Engine + * @author Sergiu Cuciurean (sergiu.cuciurean@analog.com) +******************************************************************************** + * Copyright 2019(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ + +#ifndef SPI_ENGINE_PRIVATE_H +#define SPI_ENGINE_PRIVATE_H + +#include +#include + +#include "spi.h" +#include "util.h" + +/******************************************************************************/ +/*************************** Spi Engine registers *****************************/ +/******************************************************************************/ + +#define SPI_ENGINE_REG_VERSION 0x00 +#define SPI_ENGINE_REG_DATA_WIDTH 0x0C +#define SPI_ENGINE_REG_RESET 0x40 +#define SPI_ENGINE_REG_INT_ENABLE 0x80 +#define SPI_ENGINE_REG_INT_PENDING 0x84 +#define SPI_ENGINE_REG_INT_SOURCE 0x88 +#define SPI_ENGINE_REG_SYNC_ID 0xC0 +#define SPI_ENGINE_REG_CMD_FIFO_ROOM 0xD0 +#define SPI_ENGINE_REG_SDO_FIFO_ROOM 0xD4 +#define SPI_ENGINE_REG_SDI_FIFO_LEVEL 0xD8 +#define SPI_ENGINE_REG_CMD_FIFO 0xE0 +#define SPI_ENGINE_REG_SDO_DATA_FIFO 0xE4 +#define SPI_ENGINE_REG_SDI_DATA_FIFO 0xE8 +#define SPI_ENGINE_REG_SDI_DATA_FIFO_PEEK 0xEC + +/******************************************************************************/ +/************************ Spi Engine register parameters **********************/ +/******************************************************************************/ + +#define SPI_ENGINE_INST_TRANSFER 0x00 +#define SPI_ENGINE_INST_ASSERT 0x01 +#define SPI_ENGINE_INST_CONFIG 0x02 +#define SPI_ENGINE_INST_SYNC_SLEEP 0x03 +#define SPI_ENGINE_INST_MISC 0x03 +#define SPI_ENGINE_CMD_REG_CLK_DIV 0x00 +#define SPI_ENGINE_CMD_REG_CONFIG 0x01 +#define SPI_ENGINE_CMD_DATA_TRANSFER_LEN 0x02 +#define SPI_ENGINE_MISC_SYNC 0x00 +#define SPI_ENGINE_MISC_SLEEP 0x01 +#define SPI_ENGINE_SYNC_TRANSFER_BEGIN BIT(1) +#define SPI_ENGINE_SYNC_TRANSFER_END BIT(2) +#define SPI_ENGINE_INT_CMD_ALMOST_EMPTY BIT(0) +#define SPI_ENGINE_INT_SDO_ALMOST_EMPTY BIT(1) +#define SPI_ENGINE_INT_SDI_ALMOST_FULL BIT(2) +#define SPI_ENGINE_INT_SYNC BIT(3) +#define SPI_ENGINE_OFFLOAD_CTRL_ENABLE BIT(0) +#define SPI_ENGINE_OFFLOAD_STATUS_ENABLED BIT(0) +#define SPI_ENGINE_CONFIG_CPHA BIT(0) +#define SPI_ENGINE_CONFIG_CPOL BIT(1) +#define SPI_ENGINE_CONFIG_3WIRE BIT(2) +#define SPI_ENGINE_VERSION_MAJOR(x) ((x >> 16) & 0xff) +#define SPI_ENGINE_VERSION_MINOR(x) ((x >> 8) & 0xff) +#define SPI_ENGINE_VERSION_PATCH(x) (x & 0xff) + +/******************************************************************************/ +/**************************** Spi Engine commands *****************************/ +/******************************************************************************/ + +#define SPI_ENGINE_INSTRUCTION_TRANSFER_W 0x01 +#define SPI_ENGINE_INSTRUCTION_TRANSFER_R 0x02 +#define SPI_ENGINE_INSTRUCTION_TRANSFER_RW 0x03 + +#define SPI_ENGINE_REG_OFFLOAD_CTRL(x) (0x100 + (0x20 * x)) +#define SPI_ENGINE_REG_OFFLOAD_STATUS(x) (0x104 + (0x20 * x)) +#define SPI_ENGINE_REG_OFFLOAD_RESET(x) (0x108 + (0x20 * x)) +#define SPI_ENGINE_REG_OFFLOAD_CMD_MEM(x) (0x110 + (0x20 * x)) +#define SPI_ENGINE_REG_OFFLOAD_SDO_MEM(x) (0x114 + (0x20 * x)) + +#define SPI_ENGINE_CMD(inst, arg1, arg2) \ + (((inst & 0x03) << 12) | \ + ((arg1 & 0x03) << 8) | arg2 ) + +#define SPI_ENGINE_CMD_TRANSFER(readwrite, n) \ + SPI_ENGINE_CMD(SPI_ENGINE_INST_TRANSFER, \ + (readwrite), (n)) + +#define SPI_ENGINE_CMD_ASSERT(delay, cs) \ + SPI_ENGINE_CMD(SPI_ENGINE_INST_ASSERT, \ + (delay), (cs)) + +#define SPI_ENGINE_CMD_CONFIG(reg, val) \ + SPI_ENGINE_CMD(SPI_ENGINE_INST_CONFIG, \ + (reg), (val)) + +#define SPI_ENGINE_CMD_SLEEP(delay) \ + SPI_ENGINE_CMD(SPI_ENGINE_INST_MISC, \ + SPI_ENGINE_MISC_SLEEP, \ + (delay)) + +#define SPI_ENGINE_CMD_SYNC(id) \ + SPI_ENGINE_CMD(SPI_ENGINE_INST_MISC, \ + SPI_ENGINE_MISC_SYNC, \ + (id)) + +/******************************************************************************/ +/*************************** Types Declarations *******************************/ +/******************************************************************************/ + +typedef struct spi_engine_cmd_queue { + uint32_t cmd; + struct spi_engine_cmd_queue *next; +} spi_engine_cmd_queue; + +typedef struct spi_engine_msg { + uint32_t *tx_buf; + uint32_t *rx_buf; + uint32_t tx_length; + uint32_t rx_length; + struct spi_engine_cmd_queue *cmds; +} spi_engine_msg; + +#endif // SPI_ENGINE_PRIVATE_H diff --git a/df_datalink_sp/src/drivers/frequency/hmc7044/hmc7044.c b/df_datalink_sp/src/drivers/frequency/hmc7044/hmc7044.c new file mode 100644 index 0000000..2574d9a --- /dev/null +++ b/df_datalink_sp/src/drivers/frequency/hmc7044/hmc7044.c @@ -0,0 +1,927 @@ +/***************************************************************************//** + * @file hmc7044.c + * @brief Implementation of HMC7044, HMC7043 Driver. + * @author DBogdan (dragos.bogdan@analog.com) +******************************************************************************** + * Copyright 2018-2020(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ +#include +#include +#include "hmc7044.h" +#include "../../../include/error.h" +#include "../../../include/util.h" + +/******************************************************************************/ +/********************** Macros and Constants Definitions **********************/ +/******************************************************************************/ +#define HMC7044_WRITE (0 << 15) +#define HMC7044_READ (1 << 15) +#define HMC7044_CNT(x) (((x) - 1) << 13) +#define HMC7044_ADDR(x) ((x) & 0xFFF) + +/* Global Control */ +#define HMC7044_REG_SOFT_RESET 0x0000 +#define HMC7044_SOFT_RESET BIT(0) + +#define HMC7044_REG_REQ_MODE_0 0x0001 +#define HMC7044_RESEED_REQ BIT(7) +#define HMC7044_HIGH_PERF_DISTRIB_PATH BIT(6) +#define HMC7044_HIGH_PERF_PLL_VCO BIT(5) +#define HMC7044_FORCE_HOLDOVER BIT(4) +#define HMC7044_MUTE_OUT_DIV BIT(3) +#define HMC7044_PULSE_GEN_REQ BIT(2) +#define HMC7044_RESTART_DIV_FSM BIT(1) +#define HMC7044_SLEEP_MODE BIT(0) + +#define HMC7044_REG_REQ_MODE_1 0x0002 +#define HMC7044_PLL2_AUTOTUNE_TRIG BIT(2) +#define HMC7044_SLIP_REQ BIT(1) + +#define HMC7044_REG_EN_CTRL_0 0x0003 +#define HMC7044_RF_RESEEDER_EN BIT(5) +#define HMC7044_VCO_SEL(x) (((x) & 0x3) << 3) +#define HMC7044_VCO_EXT 0 +#define HMC7044_VCO_HIGH 1 +#define HMC7044_VCO_LOW 2 +#define HMC7044_SYSREF_TIMER_EN BIT(2) +#define HMC7044_PLL2_EN BIT(1) +#define HMC7044_PLL1_EN BIT(0) + +#define HMC7044_REG_EN_CTRL_1 0x0004 +#define HMC7044_SEVEN_PAIRS(x) ((x) & 0x7f) + +#define HMC7044_REG_GLOB_MODE 0x0005 +#define HMC7044_REF_PATH_EN(x) ((x) & 0xf) +#define HMC7044_RFSYNC_EN BIT(4) +#define HMC7044_VCOIN_MODE_EN BIT(5) +#define HMC7044_SYNC_PIN_MODE(x) (((x) & 0x3) << 6) + +/* PLL1 */ +#define HMC7044_REG_CLKIN0_BUF_CTRL 0x000A +#define HMC7044_REG_CLKIN1_BUF_CTRL 0x000B +#define HMC7044_REG_CLKIN2_BUF_CTRL 0x000C +#define HMC7044_REG_CLKIN3_BUF_CTRL 0x000D +#define HMC7044_REG_OSCIN_BUF_CTRL 0x000E + +#define HMC7044_REG_PLL1_REF_PRIO_CTRL 0x0014 + +#define HMC7044_HIGH_Z_EN BIT(4) +#define HMC7044_LVPECL_EN BIT(3) +#define HMC7044_AC_COUPLING_EN BIT(2) +#define HMC7044_100_OHM_EN BIT(1) +#define HMC7044_BUF_EN BIT(0) + +#define HMC7044_REG_CLKIN_PRESCALER(x) (0x001C + (x)) +#define HMC7044_REG_OSCIN_PRESCALER 0x0020 + +#define HMC7044_REG_PLL1_R_LSB 0x0021 +#define HMC7044_R1_LSB(x) ((x) & 0xff) + +#define HMC7044_REG_PLL1_R_MSB 0x0022 +#define HMC7044_R1_MSB(x) (((x) & 0xff00) >> 8) + +#define HMC7044_REG_PLL1_N_LSB 0x0026 +#define HMC7044_N1_LSB(x) ((x) & 0xff) + +#define HMC7044_REG_PLL1_N_MSB 0x0027 +#define HMC7044_N1_MSB(x) (((x) & 0xff00) >> 8) + +#define HMC7044_REG_PLL1_LOCK_DETECT 0x0028 +#define HMC7044_LOCK_DETECT_SLIP BIT(5) +#define HMC7044_LOCK_DETECT_TIMER(x) ((x) & 0x1f) + +/* PLL2 */ +#define HMC7044_REG_PLL2_FREQ_DOUBLER 0x0032 +#define HMC7044_PLL2_FREQ_DOUBLER_DIS BIT(0) + +#define HMC7044_REG_PLL2_R_LSB 0x0033 +#define HMC7044_R2_LSB(x) ((x) & 0xff) + +#define HMC7044_REG_PLL2_R_MSB 0x0034 +#define HMC7044_R2_MSB(x) (((x) & 0xf00) >> 8) + +#define HMC7044_REG_PLL2_N_LSB 0x0035 +#define HMC7044_N2_LSB(x) ((x) & 0xff) + +#define HMC7044_REG_PLL2_N_MSB 0x0036 +#define HMC7044_N2_MSB(x) (((x) & 0xff00) >> 8) + +#define HMC7044_REG_OSCOUT_PATH 0x0039 +#define HMC7044_REG_OSCOUT_DRIVER_0 0x003A +#define HMC7044_REG_OSCOUT_DRIVER_1 0x003B + +/* GPIO/SDATA Control */ +#define HMC7044_REG_GPI_CTRL(x) (0x0046 + (x)) +#define HMC7044_REG_GPI_SEL(x) ((x) & 0xf) + +#define HMC7044_REG_GPO_CTRL(x) (0x0050 + (x)) +#define HMC7044_GPO_SEL(x) (((x) & 0x3f) << 2) +#define HMC7044_GPO_MODE BIT(1) +#define HMC7044_GPO_EN BIT(0) + +/* SYSREF/SYNC Control */ +#define HMC7044_REG_PULSE_GEN 0x005A +#define HMC7044_PULSE_GEN_MODE(x) ((x) & 0x7) + +#define HMC7044_REG_SYNC 0x005B +#define HMC7044_SYNC_RETIME BIT(2) +#define HMC7044_SYNC_THROUGH_PLL2 BIT(1) +#define HMC7044_SYNC_POLARITY BIT(0) + +#define HMC7044_REG_SYSREF_TIMER_LSB 0x005C +#define HMC7044_SYSREF_TIMER_LSB(x) ((x) & 0xff) + +#define HMC7044_REG_SYSREF_TIMER_MSB 0x005D +#define HMC7044_SYSREF_TIMER_MSB(x) (((x) & 0xf00) >> 8) + +#define HMC7044_CLK_INPUT_CTRL 0x0064 +#define HMC7044_LOW_FREQ_INPUT_MODE BIT(0) +#define HMC7044_DIV_2_INPUT_MODE BIT(1) + +/* Status and Alarm readback */ +#define HMC7044_REG_ALARM_READBACK 0x007D +#define HMC7044_REG_PLL1_STATUS 0x0082 + +#define HMC7044_PLL1_FSM_STATE(x) ((x) & 0x7) +#define HMC7044_PLL1_ACTIVE_CLKIN(x) (((x) >> 3) & 0x3) + +#define HMC7044_PLL2_LOCK_DETECT(x) ((x) & 0x1) +#define HMC7044_SYSREF_SYNC_STAT(x) ((x) & 0x2) +#define HMC7044_CLK_OUT_PH_STATUS(x) ((x) & 0x4) +#define HMC7044_PLL1_PLL2_LOCK_STAT(x) ((x) & 0x8) +#define HMC7044_SYNC_REQ_STATUS(x) ((x) & 0x10) + +/* Other Controls */ +#define HMC7044_REG_CLK_OUT_DRV_LOW_PW 0x009F +#define HMC7044_REG_CLK_OUT_DRV_HIGH_PW 0x00A0 +#define HMC7044_REG_PLL1_DELAY 0x00A5 +#define HMC7044_REG_PLL1_HOLDOVER 0x00A8 +#define HMC7044_REG_VTUNE_PRESET 0x00B0 + +/* Clock Distribution */ +#define HMC7044_REG_CH_OUT_CRTL_0(ch) (0x00C8 + 0xA * (ch)) +#define HMC7044_HI_PERF_MODE BIT(7) +#define HMC7044_SYNC_EN BIT(6) +#define HMC7044_CH_EN BIT(0) +#define HMC7044_START_UP_MODE_DYN_EN (BIT(3) | BIT(2)) + +#define HMC7044_REG_CH_OUT_CRTL_1(ch) (0x00C9 + 0xA * (ch)) +#define HMC7044_DIV_LSB(x) ((x) & 0xFF) + +#define HMC7044_REG_CH_OUT_CRTL_2(ch) (0x00CA + 0xA * (ch)) +#define HMC7044_DIV_MSB(x) (((x) >> 8) & 0xFF) + +#define HMC7044_REG_CH_OUT_CRTL_3(ch) (0x00CB + 0xA * (ch)) +#define HMC7044_REG_CH_OUT_CRTL_4(ch) (0x00CC + 0xA * (ch)) +#define HMC7044_REG_CH_OUT_CRTL_5(ch) (0x00CD + 0xA * (ch)) +#define HMC7044_REG_CH_OUT_CRTL_6(ch) (0x00CE + 0xA * (ch)) +#define HMC7044_REG_CH_OUT_CRTL_7(ch) (0x00CF + 0xA * (ch)) + +#define HMC7044_REG_CH_OUT_CRTL_8(ch) (0x00D0 + 0xA * (ch)) +#define HMC7044_DRIVER_MODE(x) (((x) & 0x3) << 3) +#define HMC7044_DRIVER_Z_MODE(x) (((x) & 0x3) << 0) +#define HMC7044_DYN_DRIVER_EN BIT(5) +#define HMC7044_FORCE_MUTE_EN BIT(7) + +#define HMC7044_NUM_CHAN 14 + +#define HMC7044_LOW_VCO_MIN 2150000 +#define HMC7044_LOW_VCO_MAX 2880000 +#define HMC7044_HIGH_VCO_MIN 2650000 +#define HMC7044_HIGH_VCO_MAX 3200000 + +#define HMC7044_RECOMM_LCM_MIN 30000 +#define HMC7044_RECOMM_LCM_MAX 70000 +#define HMC7044_RECOMM_FPD1 10000 + +#define HMC7044_R1_MAX 65535 +#define HMC7044_N1_MAX 65535 + +#define HMC7044_R2_MIN 1 +#define HMC7044_R2_MAX 4095 +#define HMC7044_N2_MIN 8 +#define HMC7044_N2_MAX 65535 + +#define HMC7044_OUT_DIV_MIN 1 +#define HMC7044_OUT_DIV_MAX 4094 + +/******************************************************************************/ +/************************** Functions Implementation **************************/ +/******************************************************************************/ + +/** + * SPI register write to device. + * @param dev - The device structure. + * @param reg - The register address. + * @param val - The register data. + * @return SUCCESS in case of success, negative error code otherwise. + */ +int32_t hmc7044_write(struct hmc7044_dev *dev, + uint16_t reg, + uint8_t val) +{ + uint8_t buf[3]; + uint16_t cmd; + + cmd = HMC7044_WRITE | HMC7044_CNT(1) | HMC7044_ADDR(reg); + buf[0] = cmd >> 8; + buf[1] = cmd & 0xFF; + buf[2] = val; + return spi_write_and_read_3wire(dev->spi_desc, buf, NULL, + ARRAY_SIZE(buf), 0); +} + +/** + * SPI register read from device. + * @param dev - The device structure. + * @param reg - The register address. + * @param val - The register data. + * @return SUCCESS in case of success, negative error code otherwise. + */ + +int32_t hmc7044_read(struct hmc7044_dev *dev, uint16_t reg, uint8_t *val) +{ + uint8_t wr_buf[2]; + uint8_t rd_data[1]; + uint16_t cmd; + int ret; + + cmd = HMC7044_READ | HMC7044_CNT(1) | HMC7044_ADDR(reg); + wr_buf[0] = cmd >> 8; + wr_buf[1] = cmd & 0xFF; + + ret = spi_write_and_read_3wire(dev->spi_desc, wr_buf, rd_data, + ARRAY_SIZE(wr_buf), ARRAY_SIZE(rd_data)); + if (ret != SUCCESS) + return ret; + + *val = rd_data[0]; + + return SUCCESS; +} + +/** + * Calculate the output channel divider. + * @param rate - The desired rate. + * @param parent_rate - The parent rate. + * @return The output divider. + */ +uint32_t hmc7044_calc_out_div(uint32_t rate, + uint32_t parent_rate) +{ + uint32_t div; + + div = DIV_ROUND_CLOSEST(parent_rate, rate); + + /* Supported odd divide ratios are 1, 3, and 5 */ + if ((div != 1) && (div != 3) && (div != 5) && (div % 2)) + div = DIV_ROUND_CLOSEST(parent_rate, rate * 2) * 2; + + div = clamp_t(unsigned int, + div, + HMC7044_OUT_DIV_MIN, + HMC7044_OUT_DIV_MAX); + + return div; +} + +/** + * Recalculate rate corresponding to a channel. + * @param dev - The device structure. + * @param chan_num - Channel number. + * @param rate - Channel rate. + * @return SUCCESS in case of success, negative error code otherwise. + */ +int32_t hmc7044_clk_recalc_rate(struct hmc7044_dev *dev, uint32_t chan_num, + uint64_t *rate) +{ + int i; + struct hmc7044_chan_spec *chan = NULL; + + /* Find the reqested channel number */ + for (i = 0; i < dev->num_channels; i++) { + if (dev->channels[i].num == chan_num) { + chan = &dev->channels[i]; + break; + } + } + if (chan == NULL ) + return FAILURE; + + *rate = dev->pll2_freq / chan->divider; + + return SUCCESS; +} + +/** + * Calculate closest possible rate + * @param dev - The device structure + * @param rate - The desired rate. + * @param rounded_rate - The closest possible rate of desired rate. + * @return SUCCESS in case of success, negative error code otherwise. + */ +int32_t hmc7044_clk_round_rate(struct hmc7044_dev *dev, uint32_t rate, + uint64_t *rounded_rate) +{ + uint32_t div = hmc7044_calc_out_div(rate, dev->pll2_freq); + + *rounded_rate = DIV_ROUND_CLOSEST(dev->pll2_freq, div); + + return SUCCESS; +} + +/** + * Set channel rate. + * @param dev - The device structure. + * @param chan_num - Channel number. + * @param rate - Channel rate. + * @return SUCCESS in case of success, negative error code otherwise. + */ +int32_t hmc7044_clk_set_rate(struct hmc7044_dev *dev, uint32_t chan_num, + uint64_t rate) +{ + uint32_t div; + int32_t ret; + int i; + struct hmc7044_chan_spec *chan = NULL; + + /* Find the reqested channel number */ + for (i = 0; i < dev->num_channels; i++) { + if (dev->channels[i].num == chan_num) { + chan = &dev->channels[i]; + break; + } + } + if (chan == NULL ) + return FAILURE; + + div = hmc7044_calc_out_div(rate, dev->pll2_freq); + chan->divider = div; + + ret = hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_1(chan->num), + HMC7044_DIV_LSB(div)); + if(ret < 0) + return ret; + + return hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_2(chan->num), + HMC7044_DIV_MSB(div)); +} + +/** + * Setup the device. + * @param dev - The device structure. + * @return SUCCESS in case of success, negative error code otherwise. + */ +static int32_t hmc7044_setup(struct hmc7044_dev *dev) +{ + struct hmc7044_chan_spec *chan; + bool high_vco_en; + bool pll2_freq_doubler_en; + uint32_t vcxo_freq, pll2_freq; + uint32_t clkin_freq[4]; + uint32_t lcm_freq; + uint32_t in_prescaler[5]; + uint32_t pll1_lock_detect; + uint32_t n1, r1; + uint32_t pfd1_freq; + uint32_t vco_limit; + uint32_t n2[2], r2[2]; + uint32_t i, ref_en = 0; + + vcxo_freq = dev->vcxo_freq / 1000; + pll2_freq = dev->pll2_freq / 1000; + + lcm_freq = vcxo_freq; + for (i = 0; i < ARRAY_SIZE(clkin_freq); i++) { + if (dev->clkin_freq_ccf[i]) + clkin_freq[i] = dev->clkin_freq_ccf[i] / 1000; + else + clkin_freq[i] = dev->clkin_freq[i] / 1000; + + if (clkin_freq[i]) { + lcm_freq = greatest_common_divisor(clkin_freq[i], lcm_freq); + ref_en |= BIT(i); + } + } + + while (lcm_freq > HMC7044_RECOMM_LCM_MAX) + lcm_freq /= 2; + + for (i = 0; i < ARRAY_SIZE(clkin_freq); i++) { + if (clkin_freq[i]) + in_prescaler[i] = clkin_freq[i] / lcm_freq; + else + in_prescaler[i] = 1; + } + in_prescaler[4] = vcxo_freq / lcm_freq; + + pll1_lock_detect = log_base_2((lcm_freq * 4000) / dev->pll1_loop_bw); + + /* fVCXO / N1 = fLCM / R1 */ + rational_best_approximation(vcxo_freq, lcm_freq, + HMC7044_N1_MAX, HMC7044_R1_MAX, + &n1, &r1); + + pfd1_freq = vcxo_freq / n1; + while ((pfd1_freq > HMC7044_RECOMM_FPD1) && + (n1 <= HMC7044_N1_MAX / 2) && + (r1 <= HMC7044_R1_MAX / 2)) { + pfd1_freq /= 2; + n1 *= 2; + r1 *= 2; + } + + dev->pll1_pfd = pfd1_freq; + + if (pll2_freq < HMC7044_LOW_VCO_MIN || + pll2_freq > HMC7044_HIGH_VCO_MAX) + return FAILURE; + + vco_limit = (HMC7044_LOW_VCO_MAX + HMC7044_HIGH_VCO_MIN) / 2; + if (pll2_freq >= vco_limit) + high_vco_en = true; + else + high_vco_en = false; + + /* fVCO / N2 = fVCXO * doubler / R2 */ + pll2_freq_doubler_en = true; + rational_best_approximation(pll2_freq, vcxo_freq * 2, + HMC7044_N2_MAX, HMC7044_R2_MAX, + &n2[0], &r2[0]); + + if (pll2_freq != vcxo_freq * n2[0] / r2[0]) { + rational_best_approximation(pll2_freq, vcxo_freq, + HMC7044_N2_MAX, HMC7044_R2_MAX, + &n2[1], &r2[1]); + + if (abs((int)pll2_freq - (int)(vcxo_freq * 2 * n2[0] / r2[0])) > + abs((int)pll2_freq - (int)(vcxo_freq * n2[1] / r2[1]))) { + n2[0] = n2[1]; + r2[0] = r2[1]; + pll2_freq_doubler_en = false; + } + } + + while ((n2[0] < HMC7044_N2_MIN) && (r2[0] <= HMC7044_R2_MAX / 2)) { + n2[0] *= 2; + r2[0] *= 2; + } + if (n2[0] < HMC7044_N2_MIN) + return -FAILURE; + + /* Resets all registers to default values */ + hmc7044_write(dev, HMC7044_REG_SOFT_RESET, HMC7044_SOFT_RESET); + mdelay(10); + hmc7044_write(dev, HMC7044_REG_SOFT_RESET, 0); + mdelay(10); + + /* Disable all channels */ + for (i = 0; i < HMC7044_NUM_CHAN; i++) + hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_0(i), 0); + + /* Load the configuration updates (provided by Analog Devices) */ + hmc7044_write(dev, HMC7044_REG_CLK_OUT_DRV_LOW_PW, 0x4d); + hmc7044_write(dev, HMC7044_REG_CLK_OUT_DRV_HIGH_PW, 0xdf); + hmc7044_write(dev, HMC7044_REG_PLL1_DELAY, 0x06); + hmc7044_write(dev, HMC7044_REG_PLL1_HOLDOVER, 0x06); + hmc7044_write(dev, HMC7044_REG_VTUNE_PRESET, 0x04); + + uint8_t rd_back; + hmc7044_read(dev, HMC7044_REG_CLK_OUT_DRV_LOW_PW, &rd_back); + hmc7044_read(dev, HMC7044_REG_CLK_OUT_DRV_HIGH_PW, &rd_back); + hmc7044_read(dev, HMC7044_REG_PLL1_DELAY, &rd_back); + hmc7044_read(dev, HMC7044_REG_PLL1_HOLDOVER, &rd_back); + hmc7044_read(dev, HMC7044_REG_VTUNE_PRESET, &rd_back); + + hmc7044_write(dev, HMC7044_REG_GLOB_MODE, + HMC7044_SYNC_PIN_MODE(dev->sync_pin_mode) | + (dev->clkin0_rfsync_en ? HMC7044_RFSYNC_EN : 0) | + (dev->clkin1_vcoin_en ? HMC7044_VCOIN_MODE_EN : 0) | + HMC7044_REF_PATH_EN(ref_en)); + + /* Program PLL2 */ + + /* Select the VCO range */ + hmc7044_write(dev, HMC7044_REG_EN_CTRL_0, + (dev->rf_reseeder_en ? HMC7044_RF_RESEEDER_EN : 0) | + HMC7044_VCO_SEL(high_vco_en ? + HMC7044_VCO_HIGH : + HMC7044_VCO_LOW) | + HMC7044_SYSREF_TIMER_EN | HMC7044_PLL2_EN | + HMC7044_PLL1_EN); + + /* Program the dividers */ + hmc7044_write(dev, HMC7044_REG_PLL2_R_LSB, + HMC7044_R2_LSB(r2[0])); + hmc7044_write(dev, HMC7044_REG_PLL2_R_MSB, + HMC7044_R2_MSB(r2[0])); + hmc7044_write(dev, HMC7044_REG_PLL2_N_LSB, + HMC7044_N2_LSB(n2[0])); + hmc7044_write(dev, HMC7044_REG_PLL2_N_MSB, + HMC7044_N2_MSB(n2[0])); + + /* Program the reference doubler */ + hmc7044_write(dev, HMC7044_REG_PLL2_FREQ_DOUBLER, + pll2_freq_doubler_en ? 0 : HMC7044_PLL2_FREQ_DOUBLER_DIS); + + /* Program PLL1 */ + + /* Set the lock detect timer threshold */ + hmc7044_write(dev, HMC7044_REG_PLL1_LOCK_DETECT, + HMC7044_LOCK_DETECT_TIMER(pll1_lock_detect)); + + /* Set the LCM */ + for (i = 0; i < ARRAY_SIZE(clkin_freq); i++) { + hmc7044_write(dev, HMC7044_REG_CLKIN_PRESCALER(i), + in_prescaler[i]); + } + hmc7044_write(dev, HMC7044_REG_OSCIN_PRESCALER, + in_prescaler[4]); + + /* Program the dividers */ + hmc7044_write(dev, HMC7044_REG_PLL1_R_LSB, + HMC7044_R2_LSB(r1)); + hmc7044_write(dev, HMC7044_REG_PLL1_R_MSB, + HMC7044_R2_MSB(r1)); + hmc7044_write(dev, HMC7044_REG_PLL1_N_LSB, + HMC7044_N2_LSB(n1)); + hmc7044_write(dev, HMC7044_REG_PLL1_N_MSB, + HMC7044_N2_MSB(n1)); + + hmc7044_write(dev, HMC7044_REG_PLL1_REF_PRIO_CTRL, + dev->pll1_ref_prio_ctrl); + + /* Program the SYSREF timer */ + + /* Set the divide ratio */ + hmc7044_write(dev, HMC7044_REG_SYSREF_TIMER_LSB, + HMC7044_SYSREF_TIMER_LSB(dev->sysref_timer_div)); + hmc7044_write(dev, HMC7044_REG_SYSREF_TIMER_MSB, + HMC7044_SYSREF_TIMER_MSB(dev->sysref_timer_div)); + + /* Set the pulse generator mode configuration */ + hmc7044_write(dev, HMC7044_REG_PULSE_GEN, + HMC7044_PULSE_GEN_MODE(dev->pulse_gen_mode)); + + /* Enable the input buffers */ + hmc7044_write(dev, HMC7044_REG_CLKIN0_BUF_CTRL, + dev->in_buf_mode[0]); + hmc7044_write(dev, HMC7044_REG_CLKIN1_BUF_CTRL, + dev->in_buf_mode[1]); + hmc7044_write(dev, HMC7044_REG_CLKIN2_BUF_CTRL, + dev->in_buf_mode[2]); + hmc7044_write(dev, HMC7044_REG_CLKIN3_BUF_CTRL, + dev->in_buf_mode[3]); + hmc7044_write(dev, HMC7044_REG_OSCIN_BUF_CTRL, + dev->in_buf_mode[4]); + + /* Set GPIOs */ + for (i = 0; i < ARRAY_SIZE(dev->gpi_ctrl); i++) { + hmc7044_write(dev, HMC7044_REG_GPI_CTRL(i), + dev->gpi_ctrl[i]); + } + + for (i = 0; i < ARRAY_SIZE(dev->gpo_ctrl); i++) { + hmc7044_write(dev, HMC7044_REG_GPO_CTRL(i), + dev->gpo_ctrl[i]); + } + + mdelay(10); + + /* Program the output channels */ + for (i = 0; i < dev->num_channels; i++) { + chan = &dev->channels[i]; + if (chan->num >= HMC7044_NUM_CHAN || chan->disable) + continue; + + hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_1(chan->num), + HMC7044_DIV_LSB(chan->divider)); + hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_2(chan->num), + HMC7044_DIV_MSB(chan->divider)); + hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_8(chan->num), + HMC7044_DRIVER_MODE(chan->driver_mode) | + HMC7044_DRIVER_Z_MODE(chan->driver_impedance) | + (chan->dynamic_driver_enable ? + HMC7044_DYN_DRIVER_EN : 0) | + (chan->force_mute_enable ? + HMC7044_FORCE_MUTE_EN : 0)); + + hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_3(chan->num), + chan->fine_delay & 0x1F); + hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_4(chan->num), + chan->coarse_delay & 0x1F); + hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_7(chan->num), + chan->out_mux_mode & 0x3); + + hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_0(chan->num), + (chan->start_up_mode_dynamic_enable ? + HMC7044_START_UP_MODE_DYN_EN : 0) | + (chan->output_control0_rb4_enable ? BIT(4) : 0) | + (chan->high_performance_mode_dis ? + 0 : HMC7044_HI_PERF_MODE) | HMC7044_SYNC_EN | + HMC7044_CH_EN); + } + mdelay(10); + + /* Do a restart to reset the system and initiate calibration */ + hmc7044_write(dev, HMC7044_REG_REQ_MODE_0, + HMC7044_RESTART_DIV_FSM); + mdelay(1); + hmc7044_write(dev, HMC7044_REG_REQ_MODE_0, + (dev->high_performance_mode_clock_dist_en ? + HMC7044_HIGH_PERF_DISTRIB_PATH : 0)); + mdelay(1); + + return SUCCESS; +} + +/** + * Setup the device. + * @param dev - The device structure. + * @return SUCCESS in case of success, negative error code otherwise. + */ +static int32_t hmc7043_setup(struct hmc7044_dev *dev) +{ + struct hmc7044_chan_spec *chan; + uint32_t i; + + if (dev->clkin_freq_ccf[0]) + dev->pll2_freq = dev->clkin_freq_ccf[0]; + else + dev->pll2_freq = dev->clkin_freq[0]; + + if (!dev->pll2_freq) { + printf("%s: Failed to get valid parent rate\n", __func__); + return FAILURE; + } + + /* Resets all registers to default values */ + hmc7044_write(dev, HMC7044_REG_SOFT_RESET, HMC7044_SOFT_RESET); + mdelay(10); + hmc7044_write(dev, HMC7044_REG_SOFT_RESET, 0); + mdelay(10); + + /* Load the configuration updates (provided by Analog Devices) */ + hmc7044_write(dev, HMC7044_REG_CLK_OUT_DRV_LOW_PW, 0x4d); + hmc7044_write(dev, HMC7044_REG_CLK_OUT_DRV_HIGH_PW, 0xdf); + + /* Disable all channels */ + for (i = 0; i < HMC7044_NUM_CHAN; i++) + hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_0(i), 0); + + if (dev->pll2_freq < 1000000000U) + hmc7044_write(dev, HMC7044_CLK_INPUT_CTRL, + HMC7044_LOW_FREQ_INPUT_MODE); + + hmc7044_write(dev, HMC7044_REG_EN_CTRL_0, + (dev->rf_reseeder_en ? HMC7044_RF_RESEEDER_EN : 0) | + HMC7044_SYSREF_TIMER_EN); + + /* Program the SYSREF timer */ + + /* Set the divide ratio */ + hmc7044_write(dev, HMC7044_REG_SYSREF_TIMER_LSB, + HMC7044_SYSREF_TIMER_LSB(dev->sysref_timer_div)); + hmc7044_write(dev, HMC7044_REG_SYSREF_TIMER_MSB, + HMC7044_SYSREF_TIMER_MSB(dev->sysref_timer_div)); + + /* Set the pulse generator mode configuration */ + hmc7044_write(dev, HMC7044_REG_PULSE_GEN, + HMC7044_PULSE_GEN_MODE(dev->pulse_gen_mode)); + + /* Enable the input buffers */ + hmc7044_write(dev, HMC7044_REG_CLKIN0_BUF_CTRL, + dev->in_buf_mode[0]); + hmc7044_write(dev, HMC7044_REG_CLKIN1_BUF_CTRL, + dev->in_buf_mode[1]); + + /* Set GPIOs */ + hmc7044_write(dev, HMC7044_REG_GPI_CTRL(0), + dev->gpi_ctrl[0]); + + hmc7044_write(dev, HMC7044_REG_GPO_CTRL(0), + dev->gpo_ctrl[0]); + + /* Program the output channels */ + for (i = 0; i < dev->num_channels; i++) { + chan = &dev->channels[i]; + + if (chan->num >= HMC7044_NUM_CHAN || chan->disable) + continue; + + hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_1(chan->num), + HMC7044_DIV_LSB(chan->divider)); + hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_2(chan->num), + HMC7044_DIV_MSB(chan->divider)); + hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_8(chan->num), + HMC7044_DRIVER_MODE(chan->driver_mode) | + HMC7044_DRIVER_Z_MODE(chan->driver_impedance) | + (chan->dynamic_driver_enable ? + HMC7044_DYN_DRIVER_EN : 0) | + (chan->force_mute_enable ? + HMC7044_FORCE_MUTE_EN : 0)); + + hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_3(chan->num), + chan->fine_delay & 0x1F); + hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_4(chan->num), + chan->coarse_delay & 0x1F); + hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_7(chan->num), + chan->out_mux_mode & 0x3); + + hmc7044_write(dev, HMC7044_REG_CH_OUT_CRTL_0(chan->num), + (chan->start_up_mode_dynamic_enable ? + HMC7044_START_UP_MODE_DYN_EN : 0) | + (chan->output_control0_rb4_enable ? BIT(4) : 0) | + (chan->high_performance_mode_dis ? + 0 : HMC7044_HI_PERF_MODE) | HMC7044_SYNC_EN | + HMC7044_CH_EN); + } + mdelay(10); + + + /* Do a restart to reset the system and initiate calibration */ + hmc7044_write(dev, HMC7044_REG_REQ_MODE_0, + HMC7044_RESTART_DIV_FSM); + mdelay(1); + hmc7044_write(dev, HMC7044_REG_REQ_MODE_0, + (dev->high_performance_mode_clock_dist_en ? + HMC7044_HIGH_PERF_DISTRIB_PATH : 0)); + mdelay(1); + + return SUCCESS; +} + +/***************************************************************************//** + * @brief hmc7044_reg_init + *******************************************************************************/ +int32_t hmc7044_reg_init(struct hmc7044_dev **device, + const struct hmc7044_init_param *init_param) +{ + int ret = SUCCESS; + struct hmc7044_dev *dev; + + dev = (struct hmc7044_dev *)malloc(sizeof(*dev)); + if (!dev) + return FAILURE; + + /* SPI */ + ret = spi_init(&dev->spi_desc, init_param->spi_init); + + *device = dev; + + return ret; +} + +/** + * Initialize the device. + * @param device - The device structure. + * @param init_param - The structure that contains the device initial + * parameters. + * @return SUCCESS in case of success, negative error code otherwise. + */ +int32_t hmc7044_init(struct hmc7044_dev **device, + const struct hmc7044_init_param *init_param) +{ + struct hmc7044_dev *dev; + int32_t ret; + unsigned int i; + + dev = (struct hmc7044_dev *)malloc(sizeof(*dev)); + if (!dev) + return FAILURE; + + ret = spi_init(&dev->spi_desc, init_param->spi_init); + if (ret < 0) + return ret; + + dev->is_hmc7043 = init_param->is_hmc7043; + + dev->clkin_freq[0] = init_param->clkin_freq[0]; + dev->clkin_freq[1] = init_param->clkin_freq[1]; + dev->clkin_freq[2] = init_param->clkin_freq[2]; + dev->clkin_freq[3] = init_param->clkin_freq[3]; + + dev->clkin_freq_ccf[0] = init_param->clkin_freq_ccf[0]; + dev->clkin_freq_ccf[1] = init_param->clkin_freq_ccf[1]; + dev->clkin_freq_ccf[2] = init_param->clkin_freq_ccf[2]; + dev->clkin_freq_ccf[3] = init_param->clkin_freq_ccf[3]; + + dev->vcxo_freq = init_param->vcxo_freq; + dev->pll1_pfd = init_param->pll1_pfd; + dev->pll2_freq = init_param->pll2_freq; + dev->pll1_loop_bw = init_param->pll1_loop_bw; + + dev->sysref_timer_div = init_param->sysref_timer_div; + dev->pll1_ref_prio_ctrl = init_param->pll1_ref_prio_ctrl; + dev->clkin0_rfsync_en = init_param->clkin0_rfsync_en; + dev->clkin1_vcoin_en = init_param->clkin1_vcoin_en; + dev->high_performance_mode_clock_dist_en = + init_param->high_performance_mode_clock_dist_en; + dev->rf_reseeder_en = !init_param->rf_reseeder_disable; + dev->sync_pin_mode = init_param->sync_pin_mode; + dev->pulse_gen_mode = init_param->pulse_gen_mode; + + dev->in_buf_mode[0] = init_param->in_buf_mode[0]; + dev->in_buf_mode[1] = init_param->in_buf_mode[1]; + dev->in_buf_mode[2] = init_param->in_buf_mode[2]; + dev->in_buf_mode[3] = init_param->in_buf_mode[3]; + dev->in_buf_mode[4] = init_param->in_buf_mode[4]; + + dev->gpi_ctrl[0] = init_param->gpi_ctrl[0]; + dev->gpi_ctrl[1] = init_param->gpi_ctrl[1]; + dev->gpi_ctrl[2] = init_param->gpi_ctrl[2]; + dev->gpi_ctrl[3] = init_param->gpi_ctrl[3]; + + dev->gpo_ctrl[0] = init_param->gpo_ctrl[0]; + dev->gpo_ctrl[1] = init_param->gpo_ctrl[1]; + dev->gpo_ctrl[2] = init_param->gpo_ctrl[2]; + dev->gpo_ctrl[3] = init_param->gpo_ctrl[3]; + + dev->num_channels = init_param->num_channels; + dev->channels = (struct hmc7044_chan_spec *) + malloc(sizeof(*dev->channels) * dev->num_channels); + + for (i = 0; i < dev->num_channels; i++) { + dev->channels[i].num = init_param->channels[i].num; + dev->channels[i].disable = init_param->channels[i].disable; + dev->channels[i].divider = init_param->channels[i].divider; + dev->channels[i].driver_mode = + init_param->channels[i].driver_mode; + dev->channels[i].high_performance_mode_dis = + init_param->channels[i].high_performance_mode_dis; + dev->channels[i].start_up_mode_dynamic_enable = + init_param->channels[i].start_up_mode_dynamic_enable; + dev->channels[i].dynamic_driver_enable = + init_param->channels[i].dynamic_driver_enable; + dev->channels[i].output_control0_rb4_enable = + init_param->channels[i].output_control0_rb4_enable; + dev->channels[i].force_mute_enable = + init_param->channels[i].force_mute_enable; + dev->channels[i].driver_impedance = + init_param->channels[i].driver_impedance; + dev->channels[i].coarse_delay = + init_param->channels[i].coarse_delay; + dev->channels[i].fine_delay = + init_param->channels[i].fine_delay; + dev->channels[i].out_mux_mode = + init_param->channels[i].out_mux_mode; + } + + *device = dev; + + if (!dev->is_hmc7043) + return hmc7044_setup(dev); + else + return hmc7043_setup(dev); +} + +/** + * Remove the device - release resources. + * @param device - The device structure. + * @return SUCCESS in case of success, negative error code otherwise. + */ +int32_t hmc7044_remove(struct hmc7044_dev *device) +{ + int32_t ret; + + ret = spi_remove(device->spi_desc); + free(device->channels); + free(device); + + return ret; +} diff --git a/df_datalink_sp/src/drivers/frequency/hmc7044/hmc7044.h b/df_datalink_sp/src/drivers/frequency/hmc7044/hmc7044.h new file mode 100644 index 0000000..a178975 --- /dev/null +++ b/df_datalink_sp/src/drivers/frequency/hmc7044/hmc7044.h @@ -0,0 +1,276 @@ +/***************************************************************************//** + * @file hmc7044.h + * @brief Header file of HMC7044, HMC7043 Driver. + * @author DBogdan (dragos.bogdan@analog.com) +******************************************************************************** + * Copyright 2018-2020(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ +#ifndef HMC7044_H_ +#define HMC7044_H_ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ +#include +#include +#include "delay.h" +#include "spi.h" + +/******************************************************************************/ +/*************************** Types Declarations *******************************/ +/******************************************************************************/ +// Enum to select SYNC pin configuration with respect to PLL2 (0x0005) +typedef enum +{ + SYNC_DISABLED = 0, + SYNC_MULTICHIP = 1, + SYNC_PULSE_GEN = 2, + SYNC_ALARM = 3 +} hmc7044SyncPinModeSelect_t; + +// Enum to select input buffer mode (0x000A, 0x000B, 0x000C, 0x000D, 0x000E) +typedef enum +{ + BUFFER_ENABLE = (1) << 0, + BUFFER_DISABLE = (0) << 0, + ENABLE_INTERNAL_TERM = (1) << 1, + ENABLE_AC_COUPLE = (1) << 2, + ENABLE_LVPECL = (1) << 3, + ENABLE_HIGH_Z = (1) << 4 +} hmc7044InputBufferMode_t; + +// Enum to select output driver mode (0x003A, 0x003B, 0x00D0, 0x00DA, 0x00E4, +// 0x00EE, 0x00F8, 0x0102, 0x010C, 0x0116, 0x0120, 0x012A, 0x0134, 0x013E, +// 0x0148, 0x0152) +typedef enum +{ + CML = 0, + LVPECL = 1, + LVDS = 2, + CMOS = 3 +} hmc7044DriverMode_t; + +// Enum to select the GPIx functionality. (0x0046, 0x0047, 0x0048, 0x0049) +typedef enum +{ + GPI_ENABLE = (1) << 0, + GPI_DISABLE = (0) << 0, + FORCE_PLL1_HOLDOVER = (0x01) << 1 | GPI_ENABLE, + SELECT_PLL1_REF_BIT1 = (0x02) << 1 | GPI_ENABLE, + SELECT_PLL1_REF_BIT2 = (0x03) << 1 | GPI_ENABLE, + CHIP_SLEEP_MODE = (0x04) << 1 | GPI_ENABLE, + MUTE_REQUSET = (0x05) << 1 | GPI_ENABLE, + SELECT_INTERNAL_VCO_TYPE = (0x06) << 1 | GPI_ENABLE, + SELECT_HI_PERF_MODE = (0x07) << 1 | GPI_ENABLE, + PULSE_GEN_REQUSET = (0x08) << 1 | GPI_ENABLE, + RESEED_REQUEST = (0x09) << 1 | GPI_ENABLE, + RESTART_REQUSET = (0x0A) << 1 | GPI_ENABLE, + FORCE_FANOUT_MODE = (0x0B) << 1 | GPI_ENABLE, + SLIP_REQUEST = (0x0D) << 1 | GPI_ENABLE, +} hmc7044GPIControl_t; + +// Enum to select the GPOx functionality. (0x0050, 0x0051, 0x0052, 0x0053) +typedef enum +{ + GPO_ENABLE = (1) << 0, + GPO_DISABLE = (0) << 0, + GPO_CMOS_MODE = (1) << 1, + GPO_OPEN_DRAIN_MODE = (0) << 1, + ALARM_SIGNAL = (0x00) << 3 | GPO_ENABLE, + SPI_SDATA = (0x01) << 3 | GPO_ENABLE, + CLKIN3_SIGNAL_LOSS = (0x02) << 3 | GPO_ENABLE, + CLKIN2_SIGNAL_LOSS = (0x03) << 3 | GPO_ENABLE, + CLKIN1_SIGNAL_LOSS = (0x04) << 3 | GPO_ENABLE, + CLKIN0_SIGNAL_LOSS = (0x05) << 3 | GPO_ENABLE, + PLL1_HOLDOVER_ENABLE = (0x06) << 3 | GPO_ENABLE, + PLL1_LOCK_DETECT = (0x07) << 3 | GPO_ENABLE, + PLL1_ACQUIRING_LOCK = (0x08) << 3 | GPO_ENABLE, + PLL1_NEAR_CLOCK_ACQ_STAT = (0x09) << 3 | GPO_ENABLE, + PLL2_LOCK_DETECT = (0x0A) << 3 | GPO_ENABLE, + PLL2_SYSREF_SYNC = (0x0B) << 3 | GPO_ENABLE, + CLOCK_OUTPUT_PHASE_STAT = (0x0C) << 3 | GPO_ENABLE, + PLL1_PLL2_LOCKED = (0x0D) << 3 | GPO_ENABLE, + SYNC_REQUSRT_STAT = (0x0E) << 3 | GPO_ENABLE, + PLL1_ACTIVE_CLKIN0 = (0x0F) << 3 | GPO_ENABLE, + PLL1_ACTIVE_CLKIN1 = (0x10) << 3 | GPO_ENABLE, + PLL1_HOLDOVER_IN_RANGE_STAT = (0x11) << 3 | GPO_ENABLE, + PLL1_HOLDOVER_IN_STAT = (0x12) << 3 | GPO_ENABLE, + PLL1_VCXO_STAT = (0x13) << 3 | GPO_ENABLE, + PLL1_ACTIVE_CLKINx_STAT = (0x14) << 3 | GPO_ENABLE, + PLL1_FSM_BIT0 = (0x15) << 3 | GPO_ENABLE, + PLL1_FSM_BIT1 = (0x16) << 3 | GPO_ENABLE, + PLL1_FSM_BIT2 = (0x17) << 3 | GPO_ENABLE, + PLL1_HOLDOVER_EXIT_PHASE_BIT0 = (0x18) << 3 | GPO_ENABLE, + PLL1_HOLDOVER_EXIT_PHASE_BIT1 = (0x19) << 3 | GPO_ENABLE, + CHANNEL_OUTPUT_FSM_BUSY = (0x1A) << 3 | GPO_ENABLE, + SYSREF_FSM_STAT_BIT0 = (0x1B) << 3 | GPO_ENABLE, + SYSREF_FSM_STAT_BIT1 = (0x1C) << 3 | GPO_ENABLE, + SYSREF_FSM_STAT_BIT2 = (0x1D) << 3 | GPO_ENABLE, + SYSREF_FSM_STAT_BIT3 = (0x1E) << 3 | GPO_ENABLE, + FORCE_LOGIC_1 = (0x1F) << 3 | GPO_ENABLE, + FORCE_LOGIC_0 = (0x20) << 3 | GPO_ENABLE, + PLL1_HOLDOVER_AVG_VALUE_BIT0 = (0x27) << 3 | GPO_ENABLE, + PLL1_HOLDOVER_AVG_VALUE_BIT1 = (0x28) << 3 | GPO_ENABLE, + PLL1_HOLDOVER_AVG_VALUE_BIT2 = (0x29) << 3 | GPO_ENABLE, + PLL1_HOLDOVER_AVG_VALUE_BIT3 = (0x2A) << 3 | GPO_ENABLE, + PLL1_HOLDOVER_CURR_VALUE_BIT0 = (0x2B) << 3 | GPO_ENABLE, + PLL1_HOLDOVER_CURR_VALUE_BIT1 = (0x2C) << 3 | GPO_ENABLE, + PLL1_HOLDOVER_CURR_VALUE_BIT2 = (0x2D) << 3 | GPO_ENABLE, + PLL1_HOLDOVER_CURR_VALUE_BIT3 = (0x2E) << 3 | GPO_ENABLE +} hmc7044GPOControl_t; + +// Enum to select output channel (0x00CF, 0x00D9, 0x00E3, 0x00ED, 0x00F7, +// 0x0101, 0x010B, 0x0115, 0x011F, 0x0129, 0x0133, 0x013D, 0x0147, 0x0151 +typedef enum +{ + CHANNEL_DIV = 0, + ANALOG_DELAY = 1, + OTHER_CHANNEL = 2, + VCO_CLOCK = 3 +} hmc7044OutputMuxSelect_t; + +// Enum to select output driver impedance selection for CML mode (0x00D0, +// 0x00DA, 0x00E4, 0x00EE, 0x00F8, 0x0102, 0x010C, 0x0116, 0x0120, 0x012A, +// 0x0134, 0x013E, 0x0148, 0x0152) +typedef enum +{ + INTERNAL_RES_DISABLE = 0, + INTERNAL_100OHM_PER_PIN = 1, +// INTERNAL_RES_RESERVED = 2, + INTERNAL_50OHM_PER_PIN = 3 +} hmc7044DriverImpedance_t; + +// Enum to select pulse generator mode (0x005A) +typedef enum +{ + PULSE_LEVEL_SENSITIVE = 0, + PULSE_ONE = 1, + PULSE_TWO = 2, + PULSE_FOUR = 3, + PULSE_EIGHT = 4, + PULSE_SIXTEEN = 5, +// PULSE_SIXTEEN = 6, + PULSE_CONTINOUS = 7 +} hmc7044SyncPulseGenControl_t; + +struct hmc7044_chan_spec { + unsigned int num; + bool disable; + bool high_performance_mode_dis; + bool start_up_mode_dynamic_enable; + bool dynamic_driver_enable; + bool output_control0_rb4_enable; + bool force_mute_enable; + unsigned int divider; + unsigned int coarse_delay; + unsigned int fine_delay; + hmc7044DriverMode_t driver_mode; + hmc7044DriverImpedance_t driver_impedance; + hmc7044OutputMuxSelect_t out_mux_mode; +}; + +struct hmc7044_config { + uint16_t addr; + uint8_t value; +}; + +struct hmc7044_dev { + struct spi_desc *spi_desc; + bool is_hmc7043; + uint32_t clkin_freq[4]; + uint32_t clkin_freq_ccf[4]; + uint32_t vcxo_freq; + uint32_t pll1_pfd; + uint32_t pll2_freq; + uint32_t pll1_loop_bw; + uint32_t sysref_timer_div; + unsigned int pll1_ref_prio_ctrl; + bool clkin0_rfsync_en; + bool clkin1_vcoin_en; + bool high_performance_mode_clock_dist_en; + bool rf_reseeder_en; + hmc7044SyncPinModeSelect_t sync_pin_mode; + hmc7044SyncPulseGenControl_t pulse_gen_mode; + uint32_t in_buf_mode[5]; + uint32_t gpi_ctrl[4]; + uint32_t gpo_ctrl[4]; + uint32_t num_channels; + struct hmc7044_chan_spec *channels; +}; + +struct hmc7044_init_param { + struct spi_init_param *spi_init; + bool is_hmc7043; + uint32_t clkin_freq[4]; + uint32_t clkin_freq_ccf[4]; + uint32_t vcxo_freq; + uint32_t pll1_pfd; + uint32_t pll2_freq; + uint32_t pll1_loop_bw; + uint32_t sysref_timer_div; + unsigned int pll1_ref_prio_ctrl; + bool clkin0_rfsync_en; + bool clkin1_vcoin_en; + bool high_performance_mode_clock_dist_en; + bool rf_reseeder_disable; + hmc7044SyncPinModeSelect_t sync_pin_mode; + hmc7044SyncPulseGenControl_t pulse_gen_mode; + uint32_t in_buf_mode[5]; + uint32_t gpi_ctrl[4]; + uint32_t gpo_ctrl[4]; + uint32_t num_channels; + struct hmc7044_chan_spec *channels; +}; + +/******************************************************************************/ +/************************ Functions Declarations ******************************/ +/******************************************************************************/ +/* Initialize the device. */ +int32_t hmc7044_reg_init(struct hmc7044_dev **device, + const struct hmc7044_init_param *init_param); +int32_t hmc7044_init(struct hmc7044_dev **device, + const struct hmc7044_init_param *init_param); +/* Remove the device. */ +int32_t hmc7044_remove(struct hmc7044_dev *device); +int32_t hmc7044_write(struct hmc7044_dev *dev, + uint16_t reg, uint8_t val); +int32_t hmc7044_read(struct hmc7044_dev *dev, uint16_t reg, uint8_t *val); +int32_t hmc7044_clk_recalc_rate(struct hmc7044_dev *dev, uint32_t chan_num, + uint64_t *rate); +int32_t hmc7044_clk_round_rate(struct hmc7044_dev *dev, uint32_t rate, + uint64_t *rounded_rate); +int32_t hmc7044_clk_set_rate(struct hmc7044_dev *dev, uint32_t chan_num, + uint64_t rate); + +#endif // HMC7044_H_ diff --git a/df_datalink_sp/src/drivers/platform/xilinx_axi_io.c b/df_datalink_sp/src/drivers/platform/xilinx_axi_io.c new file mode 100644 index 0000000..5c33838 --- /dev/null +++ b/df_datalink_sp/src/drivers/platform/xilinx_axi_io.c @@ -0,0 +1,79 @@ +/***************************************************************************//** + * @file xilinx/xilinx_axi_io.c + * @brief Implementation of Xilinx AXI IO. + * @author Antoniu Miclaus (antoniu.miclaus@analog.com) +******************************************************************************** + * Copyright 2019(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include +#include "error.h" +#include "axi_io.h" + +/******************************************************************************/ +/************************ Functions Definitions *******************************/ +/******************************************************************************/ + +/** + * @brief AXI IO Xilinx specific read function. + * @param base - Base address + * @param offset - Address offset + * @param data - variable where returned data is stored + * @return 0 in case of success, -1 otherwise. + */ +int32_t axi_io_read(uint32_t base, uint32_t offset, uint32_t *data) +{ + *data = Xil_In32(base + offset); + + return 0; +} + +/** + * @brief AXI IO Xilinx specific write function. + * @param base - Base address + * @param offset - Address offset + * @param data - data to be written. + * @return 0 in case of success, -1 otherwise. + */ +int32_t axi_io_write(uint32_t base, uint32_t offset, uint32_t data) +{ + Xil_Out32(base + offset, data); + + return 0; +} + diff --git a/df_datalink_sp/src/drivers/platform/xilinx_delay.c b/df_datalink_sp/src/drivers/platform/xilinx_delay.c new file mode 100644 index 0000000..3c320f6 --- /dev/null +++ b/df_datalink_sp/src/drivers/platform/xilinx_delay.c @@ -0,0 +1,100 @@ +/***************************************************************************//** + * @file xilinx/xilinx_delay.c + * @brief Implementation of Xilinx Delay Functions. + * @author Antoniu Miclaus (antoniu.miclaus@analog.com) +******************************************************************************** + * Copyright 2019(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include "delay.h" +#include +#ifdef _XPARAMETERS_PS_H_ +#include "util.h" +#include "xtime_l.h" +#endif + +/******************************************************************************/ +/************************ Functions Definitions *******************************/ +/******************************************************************************/ + +/** + * @brief Generate microseconds delay. + * @param usecs - Delay in microseconds. + * @return None. + */ +void udelay(uint32_t usecs) +{ +#ifdef _XPARAMETERS_PS_H_ + usleep(usecs); +#else + usleep_MB(usecs); +#endif +} + +/** + * @brief Generate miliseconds delay. + * @param msecs - Delay in miliseconds. + * @return None. + */ +void mdelay(uint32_t msecs) +{ +#ifdef _XPARAMETERS_PS_H_ + usleep(msecs * 1000); +#else + usleep_MB(msecs * 1000); +#endif +} + +/** + * @brief Get current time. + * @return Current time structure from system start (seconds, microseconds). + */ +struct time get_time(void) +{ + struct time t = {0, 0}; +#ifdef _XPARAMETERS_PS_H_ + unsigned long long Xtime_Global; + uint32_t rem; + + XTime_GetTime(&Xtime_Global); + t.s = div_u64_rem(Xtime_Global, COUNTS_PER_SECOND, &rem); + t.us = div_u64((uint64_t)rem * 1000000, COUNTS_PER_SECOND); +#endif + + return t; +} diff --git a/df_datalink_sp/src/drivers/platform/xilinx_gpio.c b/df_datalink_sp/src/drivers/platform/xilinx_gpio.c new file mode 100644 index 0000000..274399d --- /dev/null +++ b/df_datalink_sp/src/drivers/platform/xilinx_gpio.c @@ -0,0 +1,464 @@ +/***************************************************************************//** + * @file xilinx/xilinx_gpio.c + * @brief Implementation of Xilinx GPIO Generic Driver. + * @author Antoniu Miclaus (antoniu.miclaus@analog.com) +******************************************************************************** + * Copyright 2019(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include + +#include +#ifdef XPAR_XGPIO_NUM_INSTANCES +#include +#endif +#ifdef XPAR_XGPIOPS_NUM_INSTANCES +#include +#endif + +#include "error.h" +#include "gpio.h" +#include "xilinx_gpio.h" + +/******************************************************************************/ +/************************ Functions Definitions *******************************/ +/******************************************************************************/ + +/** + * @brief Prepare the GPIO decriptor. + * @param desc - The GPIO descriptor. + * @param param - The structure that contains the GPIO parameters. + * @return 0 in case of success, -1 otherwise. + */ +int32_t _gpio_init(struct gpio_desc *desc, + const struct gpio_init_param *param) +{ + int32_t ret; + struct xil_gpio_desc *xdesc; + struct xil_gpio_init_param *xinit; + + ret = -1; + + xdesc = desc->extra; + xinit = param->extra; + + xdesc->type = xinit->type; + desc->number = param->number; + + switch (xinit->type) { + case GPIO_PL: +#ifdef XGPIO_H + xdesc->instance = (XGpio *)malloc(sizeof(XGpio)); + if(!xdesc->instance) + goto pl_error; + + xdesc->config = XGpio_LookupConfig(xinit->device_id); + if(xdesc->config == NULL) + goto pl_error; + + ret = XGpio_CfgInitialize(xdesc->instance, + xdesc->config, + ((XGpio_Config*)xdesc->config) + ->BaseAddress); + if(ret < 0) + goto pl_error; + + break; +pl_error: + free(xdesc->instance); +#endif + goto error; + case GPIO_PS: +#ifdef XGPIOPS_H + xdesc->instance = (XGpioPs *)malloc(sizeof(XGpioPs)); + if(!xdesc->instance) + goto ps_error; + + xdesc->config = XGpioPs_LookupConfig(xinit->device_id); + if(xdesc->config == NULL) + goto ps_error; + + ret = XGpioPs_CfgInitialize(xdesc->instance, + xdesc->config, + ((XGpioPs_Config*)xdesc->config)->BaseAddr); + if(ret < 0) + goto ps_error; + break; +ps_error: + free(xdesc->instance); +#endif + goto error; +error: + default: + return -1; + } + + return 0; +} + +/** + * @brief Obtain the GPIO decriptor. + * @param desc - The GPIO descriptor. + * @param param - GPIO initialization parameters + * @return 0 in case of success, -1 otherwise. + */ +int32_t xil_gpio_get(struct gpio_desc **desc, + const struct gpio_init_param *param) +{ + struct gpio_desc *descriptor; + struct xil_gpio_desc *extra; + int32_t ret; + + descriptor = (struct gpio_desc *)malloc(sizeof(*descriptor)); + extra = (struct xil_gpio_desc*)malloc(sizeof(*extra)); + + if (!descriptor || !extra) + return -1; + + descriptor->extra = extra; + ret = _gpio_init(descriptor, param); + + if(ret != 0) + goto error; + + *desc = descriptor; + + return 0; +error: + free(extra); + free(descriptor); + + return -1; +} + +/** + * @brief Get the value of an optional GPIO. + * @param desc - The GPIO descriptor. + * @param param - GPIO Initialization parameters. + * @return 0 in case of success, -1 otherwise. + */ +int32_t xil_gpio_get_optional(struct gpio_desc **desc, + const struct gpio_init_param *param) +{ + if(param == NULL) { + *desc = NULL; + return 0; + } + + return xil_gpio_get(desc, param); +} + +/** + * @brief Free the resources allocated by gpio_get(). + * @param desc - The GPIO descriptor. + * @return 0 in case of success, -1 otherwise. + */ +int32_t xil_gpio_remove(struct gpio_desc *desc) +{ + if (desc != NULL) { + free(((struct xil_gpio_desc *)(desc->extra))->instance); + free(desc->extra); + free(desc); + } + + return 0; +} + +/** + * @brief Enable the input direction of the specified GPIO. + * @param desc - The GPIO descriptor. + * @return 0 in case of success, -1 otherwise. + */ +int32_t xil_gpio_direction_input(struct gpio_desc *desc) +{ + struct xil_gpio_desc *extra; +#ifdef XGPIO_H + uint8_t pin = desc->number; + uint32_t channel = 1; + uint32_t config = 0; +#endif + extra = desc->extra; + + switch (extra->type) { + case GPIO_PL: +#ifdef XGPIO_H + /* We assume that pin 32 is the first pin from channel 2 */ + if (pin >= 32) { + channel = 2; + pin -= 32; + } + + config = XGpio_GetDataDirection((XGpio *)extra->instance, + channel); + config |= (1 << pin); + XGpio_SetDataDirection((XGpio *)extra->instance, + channel, + config); +#endif + break; + case GPIO_PS: +#ifdef XGPIOPS_H + XGpioPs_SetDirectionPin(extra->instance, + desc->number, + GPIO_IN); +#endif + break; + default: + return -1; + } + + return 0; +} + +/** + * @brief Enable the output direction of the specified GPIO. + * @param desc - The GPIO descriptor. + * @param value - The value. + * Example: GPIO_HIGH + * GPIO_LOW + * @return 0 in case of success, -1 otherwise. + */ +int32_t xil_gpio_direction_output(struct gpio_desc *desc, + uint8_t value) +{ + struct xil_gpio_desc *extra; +#ifdef XGPIO_H + uint8_t pin = desc->number; + uint8_t channel; + uint32_t reg_val; +#endif + extra = desc->extra; + + switch (extra->type) { + case GPIO_PL: +#ifdef XGPIO_H + if (pin >= 32) { + channel = 2; + pin -= 32; + } else + channel = 1; + + reg_val = XGpio_GetDataDirection(extra->instance, + channel); + reg_val &= ~(1 << pin); + XGpio_SetDataDirection(extra->instance, + channel, + reg_val); + reg_val = XGpio_DiscreteRead(extra->instance, + channel); + if(value) + reg_val |= (1 << pin); + else + reg_val &= ~(1 << pin); + XGpio_DiscreteWrite(extra->instance, + channel, + reg_val); +#endif + break; + case GPIO_PS: +#ifdef XGPIOPS_H + XGpioPs_SetDirectionPin(extra->instance, + desc->number, + GPIO_OUT); + XGpioPs_SetOutputEnablePin(extra->instance, + desc->number, + GPIO_OUT); + XGpioPs_WritePin(extra->instance, + desc->number, + value); +#endif + break; + default: + return -1; + } + + return 0; +} + +/** + * @brief Get the direction of the specified GPIO. + * @param desc - The GPIO descriptor. + * @param direction - The direction. + * Example: GPIO_OUT + * GPIO_IN + * @return 0 in case of success, -1 otherwise. + */ +int32_t xil_gpio_get_direction(struct gpio_desc *desc, + uint8_t *direction) +{ + if (!desc) + return -1; + + struct xil_gpio_desc *extra; + uint8_t pin = desc->number; + +#ifdef XGPIO_H + uint8_t channel; +#endif + extra = desc->extra; + + switch (extra->type) { + case GPIO_PL: +#ifdef XGPIO_H + if (pin >= 32) { + channel = 2; + pin -= 32; + } else + channel = 1; + *direction = ((XGpio_GetDataDirection(extra->instance, + channel) >> pin) & 0x1) ^ 0x1; +#endif + break; + case GPIO_PS: +#ifdef XGPIOPS_H + *direction = XGpioPs_GetDirectionPin(extra->instance, pin); +#endif + break; + default: + return -1; + } + + return 0; +} + +/** + * @brief Set the value of the specified GPIO. + * @param desc - The GPIO descriptor. + * @param value - The value. + * Example: GPIO_HIGH + * GPIO_LOW + * @return 0 in case of success, -1 otherwise. + */ +int32_t xil_gpio_set_value(struct gpio_desc *desc, + uint8_t value) +{ + struct xil_gpio_desc *extra; +#ifdef XGPIO_H + uint8_t pin = desc->number; + uint8_t channel; + uint32_t reg_val; +#endif + extra = desc->extra; + + switch (extra->type) { + case GPIO_PL: +#ifdef XGPIO_H + if (pin >= 32) { + channel = 2; + pin -= 32; + } else + channel = 1; + + reg_val = XGpio_DiscreteRead(extra->instance, channel); + if(value) + reg_val |= (1 << pin); + else + reg_val &= ~(1 << pin); + XGpio_DiscreteWrite(extra->instance, channel, reg_val); +#endif + break; + case GPIO_PS: +#ifdef XGPIOPS_H + XGpioPs_WritePin(extra->instance, desc->number, value); +#endif + break; + default: + return -1; + } + + return 0; +} + +/** + * @brief Get the value of the specified GPIO. + * @param desc - The GPIO descriptor. + * @param value - The value. + * Example: GPIO_HIGH + * GPIO_LOW + * @return 0 in case of success, -1 otherwise. + */ +int32_t xil_gpio_get_value(struct gpio_desc *desc, + uint8_t *value) +{ + if (!desc) + return -1; + + struct xil_gpio_desc *extra; + uint8_t pin = desc->number; + +#ifdef XGPIO_H + uint8_t channel; +#endif + extra = desc->extra; + + switch (extra->type) { + case GPIO_PL: +#ifdef XGPIO_H + if (pin >= 32) { + channel = 2; + pin -= 32; + } else + channel = 1; + *value = (XGpio_DiscreteRead(extra->instance, channel) >> pin) & 0x01; +#endif + break; + case GPIO_PS: +#ifdef XGPIOPS_H + *value = XGpioPs_ReadPin(extra->instance, pin); +#endif + break; + default: + return -1; + } + + return 0; +} + +/** + * @brief Xilinx platform specific GPIO platform ops structure + */ +const struct gpio_platform_ops xil_gpio_ops = { + .gpio_ops_get = &xil_gpio_get, + .gpio_ops_get_optional = &xil_gpio_get_optional, + .gpio_ops_remove = &xil_gpio_remove, + .gpio_ops_direction_input = &xil_gpio_direction_input, + .gpio_ops_direction_output = &xil_gpio_direction_output, + .gpio_ops_get_direction = &xil_gpio_get_direction, + .gpio_ops_set_value = &xil_gpio_set_value, + .gpio_ops_get_value = &xil_gpio_get_value, +}; diff --git a/df_datalink_sp/src/drivers/platform/xilinx_gpio.h b/df_datalink_sp/src/drivers/platform/xilinx_gpio.h new file mode 100644 index 0000000..041a1d6 --- /dev/null +++ b/df_datalink_sp/src/drivers/platform/xilinx_gpio.h @@ -0,0 +1,95 @@ +/******************************************************************************* + * @file xilinx/xilinx_gpio.h + * @brief Header containing extra types used in the gpio driver + * @author scuciurean (sergiu.cuciurean@analog.com) +******************************************************************************** + * Copyright 2019(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ + +#ifndef XILINX_GPIO_H_ +#define XILINX_GPIO_H_ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include +#include + +/******************************************************************************/ +/*************************** Types Declarations *******************************/ +/******************************************************************************/ + +/** + * @enum xil_gpio_type + * @brief Xilinx platform architecture sections + */ +enum xil_gpio_type { + /** Programmable Logic */ + GPIO_PL, + /** Processing System */ + GPIO_PS +}; + +/** + * @struct xil_gpio_init_param + * @brief Structure holding the initialization parameters for Xilinx platform + * specific GPIO parameters. + */ +struct xil_gpio_init_param { + /** Xilinx architecture */ + enum xil_gpio_type type; + /** Device ID */ + uint32_t device_id; +}; + +/** + * @struct xil_gpio_desc + * @brief Xilinx platform specific GPIO descriptor + */ +struct xil_gpio_desc { + /** Xilinx architecture */ + enum xil_gpio_type type; + /** Xilinx GPIO configuration */ + void *config; + /** Xilinx GPIO Instance */ + void *instance; +}; + +/** + * @brief Xilinx platform specific gpio platform ops structure + */ +extern const struct gpio_platform_ops xil_gpio_ops; + +#endif diff --git a/df_datalink_sp/src/drivers/platform/xilinx_gpio_irq.c b/df_datalink_sp/src/drivers/platform/xilinx_gpio_irq.c new file mode 100644 index 0000000..f153c2a --- /dev/null +++ b/df_datalink_sp/src/drivers/platform/xilinx_gpio_irq.c @@ -0,0 +1,360 @@ +/***************************************************************************//** + * @file xilinx/xilinx_gpio_irq.c + * @brief Implementation of Xilinx GPIO IRQ Generic Driver. + * @author Porumb Andrei (andrei.porumb@analog.com) +******************************************************************************** + * Copyright 2021(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include +#include "xparameters.h" +#include "error.h" +#include "xilinx_gpio_irq.h" +#include "util.h" +#include "list.h" +#include "irq.h" + +/******************************************************************************/ +/************************ Functions Definitions *******************************/ +/******************************************************************************/ + +/** + * @brief Comparing function used by list. + * @param desc_a - Compared item + * @param desc_b - Reference item + * @return - 0 if items match + */ +static int32_t call_cmp(struct xil_callback_desc *desc_a, + struct xil_callback_desc *desc_b) +{ + return desc_a->pin_nb - desc_b->pin_nb; +} + +/** + * @brief Function called when GPIO IRQ occurs. + * @param param - GPIO IRQ desc's extra field + * @return - None. + */ +static void xil_gpio_irq_handler(struct xil_gpio_irq_desc *param) +{ + int32_t status = 0; + int32_t pin_nb; + struct xil_callback_desc *callback_desc; + + status = iterator_move_to_idx(param->it, 0); + while(!status) { + iterator_read(param->it, &callback_desc); + status = iterator_move(param->it, 1); + if(XGpioPs_IntrGetStatusPin(¶m->my_Gpio, callback_desc->pin_nb)) + callback_desc->triggered = true; + } + + status = iterator_move_to_idx(param->it, 0); + while(!status) { + iterator_read(param->it, &callback_desc); + status = iterator_move(param->it, 1); + if(callback_desc->triggered == true) { + callback_desc->triggered = false; + XGpioPs_IntrDisablePin(¶m->my_Gpio, callback_desc->pin_nb); + XGpioPs_IntrClearPin(¶m->my_Gpio, callback_desc->pin_nb); + callback_desc->callback.legacy_callback(callback_desc->callback.ctx, 0U, NULL); + if(callback_desc->enabled) + XGpioPs_IntrEnablePin(¶m->my_Gpio, callback_desc->pin_nb); + } + } +} + +/** + * @brief Disable specific GPIO IRQ pin. + * @param desc - The GPIO IRQ controller descriptor. + * @param irq_id - Pin number. + * @return 0 in case of success, -1 otherwise. + */ +int32_t xil_gpio_irq_disable(struct irq_ctrl_desc *desc, uint32_t irq_id) +{ + int32_t status; + struct xil_gpio_irq_desc *extra; + struct xil_callback_desc *callback_desc; + + extra = desc->extra; + + status = iterator_move_to_idx(extra->it, 0); + while(!status) { + iterator_read(extra->it, &callback_desc); + status = iterator_move(extra->it, 1); + if(callback_desc->pin_nb == irq_id) { + callback_desc->enabled = false; + break; + } + } + + XGpioPs_IntrDisablePin(&extra->my_Gpio, irq_id); + + return 0; +} + +/** + * @brief Initialize the GPIO IRQ controller. + * @param desc - The GPIO IRQ controller descriptor. + * @param param - The GPIO IRQ controller initial parameters. + * irq_ctrl_id from irq_init_param is the interrupt id for the parent controller + * @return 0 in case of success, -1 otherwise. + */ +int32_t xil_gpio_irq_ctrl_init(struct irq_ctrl_desc **desc, + const struct irq_init_param *param) +{ + int32_t i; + int32_t status; + struct irq_ctrl_desc *ldesc; + static XGpioPs_Config *GPIO_Config; + struct xil_gpio_irq_desc *xil_desc; + struct xil_gpio_irq_init_param *xil_ip; + struct callback_desc callback; + + xil_desc = (struct xil_gpio_irq_desc *)calloc(1, sizeof(*xil_desc)); + if(!xil_desc) + return -ENOMEM; + + ldesc = (struct irq_ctrl_desc *)calloc(1, sizeof(*ldesc)); + if(!ldesc) { + free(xil_desc); + return -ENOMEM; + } + + xil_ip = param->extra; + GPIO_Config = XGpioPs_LookupConfig(xil_ip->gpio_device_id); + status = XGpioPs_CfgInitialize(&xil_desc->my_Gpio, GPIO_Config, + GPIO_Config->BaseAddr); + if(status) + goto error_desc; + + ldesc->extra = xil_desc; + xil_desc->parent_desc = xil_ip->parent_desc; + + status = list_init(&xil_desc->callback_list, LIST_DEFAULT, + call_cmp); + if(status) + goto error_list; + + status = iterator_init(&xil_desc->it, xil_desc->callback_list, 0); + if(status) { + iterator_remove(xil_desc->it); + goto error_list; + } + + ldesc->irq_ctrl_id = param->irq_ctrl_id; + status = irq_trigger_level_set(xil_desc->parent_desc, ldesc->irq_ctrl_id, + IRQ_EDGE_RISING); + if(status) + goto error_op; + + status = irq_enable(xil_desc->parent_desc, ldesc->irq_ctrl_id); + if(status) + goto error_op; + + callback.legacy_callback = &xil_gpio_irq_handler; + callback.ctx = ldesc->extra; + status = irq_register_callback(xil_desc->parent_desc, ldesc->irq_ctrl_id, + &callback); + if(status) + goto error_op; + + *desc = ldesc; + + return 0; + +error_op: + iterator_remove(xil_desc->it); +error_list: + list_remove(xil_desc->callback_list); +error_desc: + free(xil_desc); + free(ldesc); + return status; +} + +/** + * @brief Set GPIO interrupt trigger level. + * @param desc - The GPIO IRQ controller descriptor. + * @param irq_id - Pin number. + * @param trig - New trigger level for the GPIO interrupt. + * @return 0 in case of success, -1 otherwise. + */ +int32_t xil_gpio_irq_trigger_level_set(struct irq_ctrl_desc *desc, + uint32_t irq_id, + enum irq_trig_level trig) +{ + static const int32_t trig_level[5] = {XGPIOPS_IRQ_TYPE_LEVEL_LOW, + XGPIOPS_IRQ_TYPE_LEVEL_HIGH, + XGPIOPS_IRQ_TYPE_EDGE_FALLING, + XGPIOPS_IRQ_TYPE_EDGE_RISING, + XGPIOPS_IRQ_TYPE_EDGE_BOTH + }; + struct xil_gpio_irq_desc *extra; + + extra = desc->extra; + XGpioPs_SetIntrTypePin(&extra->my_Gpio, irq_id, trig_level[trig]); + + return 0; +} + +/** + * @brief Register pin specific GPIO interrupt. + * @param desc - The GPIO IRQ controller descriptor. + * @param irq_id - Pin number. + * @param callback_desc - Callback. + * @return 0 in case of success, -1 otherwise. + */ +int32_t xil_gpio_irq_register_callback(struct irq_ctrl_desc *desc, + uint32_t irq_id, + struct callback_desc *callback_desc) +{ + struct xil_callback_desc *dev_callback; + struct xil_gpio_irq_desc *extra; + + dev_callback = (struct xil_callback_desc *)calloc(1, + sizeof(*dev_callback)); + if(!dev_callback) + return -1; + + dev_callback->pin_nb = irq_id; + dev_callback->callback.legacy_callback = callback_desc->legacy_callback; + dev_callback->callback.ctx = callback_desc->ctx; + dev_callback->triggered = false; + + extra = desc->extra; + XGpioPs_SetDirectionPin(&extra->my_Gpio, irq_id, 0); + list_add_last(extra->callback_list, dev_callback); + + return 0; +} + +/** + * @brief Unregister pin specific GPIO interrupt. + * @param desc - The GPIO IRQ controller descriptor. + * @param irq_id - Pin number. + * @param cb - Callback descriptor. + * @return 0 in case of success, -1 otherwise. + */ +int32_t xil_gpio_irq_unregister_callback(struct irq_ctrl_desc *desc, + uint32_t irq_id, struct callback_desc *cb) +{ + int32_t status; + struct xil_gpio_irq_desc *extra; + struct xil_callback_desc *dev_callback; + struct xil_callback_desc search_callback; + + extra = desc->extra; + search_callback.pin_nb = irq_id; + status = list_get_find(extra->callback_list, &dev_callback, + &search_callback); + if(status) + return -ENXIO; + + free(dev_callback); + + return 0; +} + +/** + * @brief Enable specific GPIO IRQ pin. + * @param desc - The GPIO IRQ controller descriptor. + * @param irq_id - Pin number. + * @return 0 in case of success, -1 otherwise. + */ +int32_t xil_gpio_irq_enable(struct irq_ctrl_desc *desc, uint32_t irq_id) +{ + int32_t status; + struct xil_gpio_irq_desc *extra; + struct xil_callback_desc *callback_desc; + + extra = desc->extra; + + status = iterator_move_to_idx(extra->it, 0); + while(!status) { + iterator_read(extra->it, &callback_desc); + status = iterator_move(extra->it, 1); + if(callback_desc->pin_nb == irq_id) { + callback_desc->enabled = true; + XGpioPs_IntrClearPin(&extra->my_Gpio, irq_id); + break; + } + } + + XGpioPs_IntrEnablePin(&extra->my_Gpio, irq_id); + + return 0; +} + +/** + * @brief Remove the GPIO IRQ controller. + * @param desc - The GPIO IRQ controller descriptor. + * @return 0 in case of success, -1 otherwise. + */ +int32_t xil_gpio_irq_ctrl_remove(struct irq_ctrl_desc *desc) +{ + struct xil_gpio_irq_desc *extra; + struct xil_callback_desc *callback_desc; + + if (!desc) + return -EINVAL; + + extra = desc->extra; + while (0 == list_get_first(extra->callback_list, &callback_desc)) + free(callback_desc); + + iterator_remove(extra->it); + list_remove(extra->callback_list); + free(extra); + free(desc); + + return 0; +} + +/** + * @brief Xilinx platform specific GPIO IRQ platform ops structure + */ +const struct irq_platform_ops xil_gpio_irq_ops = { + .init = &xil_gpio_irq_ctrl_init, + .enable = &xil_gpio_irq_enable, + .disable = &xil_gpio_irq_disable, + .trigger_level_set = &xil_gpio_irq_trigger_level_set, + .register_callback = &xil_gpio_irq_register_callback, + .unregister_callback = xil_gpio_irq_unregister_callback, + .remove = &xil_gpio_irq_ctrl_remove +}; diff --git a/df_datalink_sp/src/drivers/platform/xilinx_gpio_irq.h b/df_datalink_sp/src/drivers/platform/xilinx_gpio_irq.h new file mode 100644 index 0000000..c0c8348 --- /dev/null +++ b/df_datalink_sp/src/drivers/platform/xilinx_gpio_irq.h @@ -0,0 +1,92 @@ +/***************************************************************************//** + * @file xilinx_gpio_irq.h + * @brief Implementation of Xilinx GPIO IRQ Generic Driver. + * @author Porumb Andrei (andrei.porumb@analog.com) +******************************************************************************** + * Copyright 2021(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ + +#ifndef XILINX_GPIO_IRQ_H_ +#define XILINX_GPIO_IRQ_H_ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include "stdbool.h" +#include "list.h" +#include "xgpiops.h" +#include "irq.h" + +/******************************************************************************/ +/*************************** Types Declarations *******************************/ +/******************************************************************************/ +/** + * @struct xil_callback_desc + * @brief Structure holding callback parameters for each pin + */ +struct xil_callback_desc { + int32_t pin_nb; + struct callback_desc callback; + bool triggered; + bool enabled; +}; + +/** + * @struct xil_gpio_irq_init_param + * @brief Structure holding the initialization parameters for Xilinx platform + * specific GPIO IRQ parameters. + */ +struct xil_gpio_irq_init_param { + struct irq_ctrl_desc *parent_desc; + int32_t gpio_device_id; +}; + +/** + * @struct xil_gpio_irq_desc + * @brief Xilinx platform specific GPIO IRQ descriptor + */ +struct xil_gpio_irq_desc { + struct irq_ctrl_desc *parent_desc; + XGpioPs my_Gpio; + struct list_desc *callback_list; + struct iterator *it; +}; + +/** + * @brief Xilinx specific GPIO IRQ platform ops structure + */ +extern const struct irq_platform_ops xil_gpio_irq_ops; + +#endif diff --git a/df_datalink_sp/src/drivers/platform/xilinx_i2c.c b/df_datalink_sp/src/drivers/platform/xilinx_i2c.c new file mode 100644 index 0000000..de4ecb4 --- /dev/null +++ b/df_datalink_sp/src/drivers/platform/xilinx_i2c.c @@ -0,0 +1,514 @@ +/***************************************************************************//** + * @file xilinx/xilinx_i2c.c + * @brief Implementation of Xilinx I2C Generic Driver. + * @author Antoniu Miclaus (antoniu.miclaus@analog.com) +******************************************************************************** + * Copyright 2019(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include + +#include +#ifdef XPAR_XIIC_NUM_INSTANCES +#include +#endif +#ifdef XPAR_XIICPS_NUM_INSTANCES +#include +#endif + +#include "error.h" +#include "i2c.h" +#include "xilinx_i2c.h" +#include "list.h" + +/******************************************************************************/ +/*************************** Types Declarations *******************************/ +/******************************************************************************/ + +static struct list_desc *pl_list = NULL; +static struct iterator *pl_it = NULL; + +#ifdef XIICPS_H +static struct list_desc *ps_list = NULL; +static struct iterator *ps_it = NULL; +#endif /* XIICPS_H */ + +/** + * @struct inst_table_item + * @brief Table item for I2C cores already started. + */ +struct inst_table_item { + /** Instance the BSP driver uses for this core. */ + void *instance; + /** Core ID in BSP. */ + uint32_t device_id; + /** Number of ADI driver instances running on this core. */ + uint32_t inst_no; +}; + +#ifdef XPAR_XIICPS_NUM_INSTANCES +/** Save the current state of the bitrate to not change it each time */ +static uint32_t ps_last_bitrate = 0; +#endif + +/** + * @brief Xilinx platform specific I2C platform ops structure + */ +const struct i2c_platform_ops xil_i2c_ops = { + .i2c_ops_init = &xil_i2c_init, + .i2c_ops_write = &xil_i2c_write, + .i2c_ops_read = &xil_i2c_read, + .i2c_ops_remove = &xil_i2c_remove +}; + +/******************************************************************************/ +/************************ Functions Definitions *******************************/ +/******************************************************************************/ + +/** + * @brief Compare two I2C cores by ID. + * @param el1 - First I2C core to compare. + * @param el2 - Second I2C core to compare. + * @return \ref 0 if the two cores have the same ID, + * \ref difference between the first and the second IDs otherwise. + */ +static int32_t xil_i2c_cmp(void *el1, void *el2) +{ + struct inst_table_item *sel1 = el1, *sel2 = el2; + + return (sel1->device_id - sel2->device_id); +} + +/** + * @brief Configure slave address and bitrate if needed + * @param desc - Descriptor of the I2C device + * @return 0 in case of success, -1 otherwise. + */ +static int32_t xil_i2c_set_transmission_config(struct i2c_desc *desc) +{ + struct xil_i2c_desc *xil_i2c_desc = desc->extra; +#ifdef XIICPS_H + int32_t ret; +#endif + + switch (xil_i2c_desc->type) { + case IIC_PL: +#ifdef XIIC_H + break; +#endif + return -1; + case IIC_PS: +#ifdef XIICPS_H + if (desc->max_speed_hz != ps_last_bitrate) { + ret = XIicPs_SetSClk(xil_i2c_desc->instance, desc->max_speed_hz); + if (ret != XST_SUCCESS) + return -1; + ps_last_bitrate = desc->max_speed_hz; + } + break; +#endif + return -1; + default: + + return -1; + } + + return 0; +} + +/** + * @brief Initialize the I2C communication peripheral. + * @param desc - The I2C descriptor. + * @param param - The structure that contains the I2C parameters. + * @return 0 in case of success, -1 otherwise. + */ +int32_t xil_i2c_init(struct i2c_desc **desc, + const struct i2c_init_param *param) +{ + int32_t ret; + struct i2c_desc *idesc; + struct xil_i2c_desc *xdesc; + struct xil_i2c_init_param *xinit; + + idesc = (struct i2c_desc *)malloc(sizeof(*idesc)); + xdesc = (struct xil_i2c_desc *)malloc(sizeof(*xdesc)); + + if(!idesc || !xdesc) + goto error; + + idesc->max_speed_hz = param->max_speed_hz; + idesc->slave_address = param->slave_address; + xinit = param->extra; + + idesc->extra = xdesc; + xdesc->type = xinit->type; + xdesc->device_id = xinit->device_id; + switch (xinit->type) { + case IIC_PL: +#ifdef XIIC_H + ; /** Intentional empty statement */ + struct inst_table_item tab_check_pl; + struct inst_table_item *temp_el_pl; + + if (!pl_list) + list_init(&pl_list, LIST_DEFAULT, xil_i2c_cmp); + if (!pl_it) + iterator_init(&pl_it, pl_list, true); + + tab_check_pl.device_id = xdesc->device_id; + + if (!IS_ERR_VALUE(list_read_find(pl_list, (void **)&temp_el_pl, + &tab_check_pl))) { + xdesc->instance = temp_el_pl->instance; + temp_el_pl->inst_no++; + break; + } + + xdesc->instance = (XIic *)malloc(sizeof(XIic)); + if(!xdesc->instance) + goto pl_error; + + xdesc->config = XIic_LookupConfig(xinit->device_id); + if(xdesc->config == NULL) + goto pl_error; + + ret = XIic_CfgInitialize(xdesc->instance, + xdesc->config, + ((XIic_Config*)xdesc->config) + ->BaseAddress); + if(ret != 0) + goto pl_error; + + ret = XIic_Start(xdesc->instance); + if(ret != 0) + goto pl_error; + + ret = XIic_SetAddress(xdesc->instance, + XII_ADDR_TO_SEND_TYPE, + param->slave_address); + if(ret != 0) + goto pl_error; + + ret = XIic_SelfTest(xdesc->instance); + if(ret < 0) + goto pl_error; + + ret = XIic_SetGpOutput(xdesc->instance, 1); + if(ret < 0) + goto pl_error; + + temp_el_pl = (struct inst_table_item*)calloc(1, sizeof(*temp_el_pl)); + temp_el_pl->device_id = xinit->device_id; + temp_el_pl->inst_no = 1; + temp_el_pl->instance = xdesc->instance; + pl_list->push(pl_list, temp_el_pl); + + break; +pl_error: + free(xdesc->instance); +#endif + goto error; + case IIC_PS: +#ifdef XIICPS_H + ; /** Intentional empty statement */ + struct inst_table_item tab_check_ps; + struct inst_table_item *temp_el_ps; + + if (!pl_list) + list_init(&ps_list, LIST_DEFAULT, xil_i2c_cmp); + if (!pl_it) + iterator_init(&ps_it, ps_list, true); + + tab_check_ps.device_id = xdesc->device_id; + + if (!IS_ERR_VALUE(list_read_find(ps_list, + (void **)&temp_el_ps, + &tab_check_ps))) { + xdesc->instance = temp_el_ps->instance; + temp_el_ps->inst_no++; + break; + } + + xdesc->instance = (XIicPs *)malloc(sizeof(XIicPs)); + if(!xdesc->instance) + goto ps_error; + + xdesc->config = XIicPs_LookupConfig(xinit->device_id); + if(xdesc->config == NULL) + goto ps_error; + + ret = XIicPs_CfgInitialize(xdesc->instance, + xdesc->config, + ((XIicPs_Config*)xdesc->config) + ->BaseAddress); + if(ret != 0) + goto ps_error; + + XIicPs_SetSClk(xdesc->instance, param->max_speed_hz); + + temp_el_ps = (struct inst_table_item*)calloc(1, sizeof(*temp_el_ps)); + temp_el_ps->device_id = xinit->device_id; + temp_el_ps->inst_no = 1; + temp_el_ps->instance = xdesc->instance; + ps_list->push(ps_list, temp_el_ps); + + break; +ps_error: + free(xdesc->instance); +#endif + goto error; + + default: + goto error; + break; + } + + *desc = idesc; + + return 0; + +error: + free(idesc); + free(xdesc); + + return -1; +} + +/** + * @brief Free the resources allocated by i2c_init(). + * @param desc - The I2C descriptor. + * @return 0 in case of success, -1 otherwise. + */ +int32_t xil_i2c_remove(struct i2c_desc *desc) +{ + struct xil_i2c_desc *xdesc; + int32_t ret; + + xdesc = desc->extra; + + switch (xdesc->type) { + case IIC_PL: +#ifdef XIIC_H + ; /** Intentional empty statement */ + struct inst_table_item tab_check_pl; + struct inst_table_item *temp_el_pl; + tab_check_pl.device_id = xdesc->device_id; + ret = iterator_find(pl_it, &tab_check_pl); + if (ret != 0) + goto error; + iterator_read(pl_it, (void **)&temp_el_pl); + temp_el_pl->inst_no--; + if (temp_el_pl->inst_no != 0) + break; + + ret = XIic_Stop(((XIic *)xdesc->instance)); + + if(ret != 0) + goto error; + + /** Remove list element */ + iterator_get(pl_it, (void **)&temp_el_pl); + free(temp_el_pl); + break; +#endif + goto error; + case IIC_PS: +#ifdef XIICPS_H + ; /** Intentional empty statement */ + struct inst_table_item tab_check_ps; + struct inst_table_item *temp_el_ps; + tab_check_ps.device_id = xdesc->device_id; + ret = iterator_find(ps_it, &tab_check_ps); + if (ret != 0) + goto error; + iterator_read(ps_it, (void **)&temp_el_ps); + temp_el_ps->inst_no--; + if (temp_el_ps->inst_no != 0) + break; + + /** Remove list element */ + iterator_get(ps_it, (void **)&temp_el_ps); + free(temp_el_ps); + break; +#endif + /* Intended fallthrough */ +error: + default: + + return -1; + } + + free(desc->extra); + free(desc); + + return 0; +} + +/** + * @brief Write data to a slave device. + * @param desc - The I2C descriptor. + * @param data - Buffer that stores the transmission data. + * @param bytes_number - Number of bytes to write. + * @param stop_bit - Stop condition control. + * Example: 0 - A stop condition will not be generated; + * 1 - A stop condition will be generated. + * @return 0 in case of success, -1 otherwise. + */ +int32_t xil_i2c_write(struct i2c_desc *desc, + uint8_t *data, + uint8_t bytes_number, + uint8_t stop_bit) +{ + struct xil_i2c_desc *xdesc; + int32_t ret; + + xdesc = desc->extra; + + switch (xdesc->type) { + case IIC_PL: +#ifdef XIIC_H + ret = xil_i2c_set_transmission_config(desc); + if (ret != 0) + return -1; + + XIic_Send(((XIic*)xdesc->instance)->BaseAddress, + desc->slave_address, + data, + bytes_number, + stop_bit ? XIIC_STOP : XIIC_REPEATED_START); + break; +#endif + goto error; + case IIC_PS: +#ifdef XIICPS_H + ret = xil_i2c_set_transmission_config(desc); + if (ret != 0) + return -1; + + ret = XIicPs_SetOptions(xdesc->instance, + stop_bit ? 0 : XIICPS_REP_START_OPTION); + if(ret != 0) + goto error; + + XIicPs_MasterSend(xdesc->instance, + data, + bytes_number, + desc->slave_address); + if(ret != 0) + goto error; + + break; +#endif + /* Intended fallthrough */ +error: + default: + + return -1; + } + + return 0; +} + +/** + * @brief Read data from a slave device. + * @param desc - The I2C descriptor. + * @param data - Buffer that will store the received data. + * @param bytes_number - Number of bytes to read. + * @param stop_bit - Stop condition control. + * Example: 0 - A stop condition will not be generated; + * 1 - A stop condition will be generated. + * @return 0 in case of success, -1 otherwise. + */ +int32_t xil_i2c_read(struct i2c_desc *desc, + uint8_t *data, + uint8_t bytes_number, + uint8_t stop_bit) +{ + struct xil_i2c_desc *xdesc; + int32_t ret; + + xdesc = desc->extra; + + switch (xdesc->type) { + case IIC_PL: +#ifdef XIIC_H + ret = xil_i2c_set_transmission_config(desc); + if (ret != 0) + return -1; + + ret = XIic_Recv(((XIic*)xdesc->instance)->BaseAddress, + desc->slave_address, + data, + bytes_number, + stop_bit ? XIIC_STOP : XIIC_REPEATED_START); + if(ret != bytes_number) + goto error; + + break; +#endif + goto error; + case IIC_PS: +#ifdef XIICPS_H + ret = xil_i2c_set_transmission_config(desc); + if (ret != 0) + return -1; + + ret = XIicPs_SetOptions(xdesc->instance, + stop_bit ? 0 : XIICPS_REP_START_OPTION); + if(ret != 0) + goto error; + + XIicPs_MasterRecv(xdesc->instance, + data, + bytes_number, + desc->slave_address); + if(ret != 0) + goto error; + + break; +#endif + /* Intended fallthrough */ +error: + default: + return -1; + + break; + } + + return 0; +} diff --git a/df_datalink_sp/src/drivers/platform/xilinx_i2c.h b/df_datalink_sp/src/drivers/platform/xilinx_i2c.h new file mode 100644 index 0000000..b091318 --- /dev/null +++ b/df_datalink_sp/src/drivers/platform/xilinx_i2c.h @@ -0,0 +1,115 @@ +/******************************************************************************* + * @file xilinx/xilinx_i2c.h + * @brief Header containing types used in the i2c driver. + * @author scuciurean (sergiu.cuciurean@analog.com) +******************************************************************************** + * Copyright 2019(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ + +#ifndef XILINX_I2C_H_ +#define XILINX_I2C_H_ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include + +/******************************************************************************/ +/*************************** Types Declarations *******************************/ +/******************************************************************************/ + +/** + * @enum xil_i2c_type + * @brief Xilinx platform architecture sections + */ +enum xil_i2c_type { + /** Programmable Logic */ + IIC_PL, + /** Processing System */ + IIC_PS +}; + +/** + * @struct xil_i2c_init + * @brief Structure holding the initialization parameters for Xilinx platform + * specific I2C parameters. + */ +struct xil_i2c_init_param { + /** Xilinx architecture */ + enum xil_i2c_type type; + /** Device ID */ + uint32_t device_id; +}; + +/** + * @struct xil_i2c_desc + * @brief Xilinx platform specific I2C descriptor + */ +struct xil_i2c_desc { + /** Xilinx architecture */ + enum xil_i2c_type type; + /** Device ID */ + uint32_t device_id; + /** Xilinx I2C configuration */ + void *config; + /** Xilinx I2C Instance */ + void *instance; +}; + +/** + * @brief Xilinx platform specific i2c platform ops structure + */ +extern const struct i2c_platform_ops xil_i2c_ops; + +/******************************************************************************/ +/************************ Functions Declarations ******************************/ +/******************************************************************************/ + +/* Initialize the I2C communication peripheral. */ +int32_t xil_i2c_init(struct i2c_desc **desc, + const struct i2c_init_param *param); + +/* Free the resources allocated by i2c_init(). */ +int32_t xil_i2c_remove(struct i2c_desc *desc); + +/* I2C Write data */ +int32_t xil_i2c_write(struct i2c_desc *desc, uint8_t *data, + uint8_t bytes_number, uint8_t stop_bit); + +/* I2C Read data. */ +int32_t xil_i2c_read(struct i2c_desc *desc, uint8_t *data, + uint8_t bytes_number, uint8_t stop_bit); + +#endif // XILINX_I2C_H_ diff --git a/df_datalink_sp/src/drivers/platform/xilinx_irq.c b/df_datalink_sp/src/drivers/platform/xilinx_irq.c new file mode 100644 index 0000000..8ecb1fa --- /dev/null +++ b/df_datalink_sp/src/drivers/platform/xilinx_irq.c @@ -0,0 +1,433 @@ +/***************************************************************************//** + * @file xilinx/xilinx_irq.c + * @brief Implementation of Xilinx IRQ Generic Driver. + * @author Cristian Pop (cristian.pop@analog.com) +******************************************************************************** + * Copyright 2019(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include +#include +#include "error.h" +#include "irq.h" +#include "xilinx_irq.h" +#ifdef XPAR_XSCUGIC_NUM_INSTANCES +#include +#endif +#ifdef XPAR_XINTC_NUM_INSTANCES +#include +#endif +#ifdef XPAR_XTMRCTR_NUM_INSTANCES +#include +#endif + +/******************************************************************************/ +/************************ Functions Definitions *******************************/ +/******************************************************************************/ + +/** + * @brief Initialize the IRQ interrupts. + * @param desc - The IRQ controller descriptor. + * @param param - The structure that contains the IRQ parameters. + * @return 0 in case of success, -1 otherwise. + */ +int32_t xil_irq_ctrl_init(struct irq_ctrl_desc **desc, + const struct irq_init_param *param) +{ + int32_t status; + struct irq_ctrl_desc *descriptor; + struct xil_irq_desc *xil_dev; +#ifdef XSCUGIC_H + void *config; +#endif + + descriptor = (struct irq_ctrl_desc *)calloc(1, sizeof *descriptor); + if(!descriptor) + return -1; + xil_dev = (struct xil_irq_desc *)calloc(1, sizeof *xil_dev); + if(!xil_dev) { + free(descriptor); + return -1; + } + + Xil_ExceptionInit(); + + descriptor->irq_ctrl_id = param->irq_ctrl_id; + descriptor->extra = xil_dev; + xil_dev->type = ((struct xil_irq_init_param *)param->extra)->type; + + switch(xil_dev->type) { + case IRQ_PS: +#ifdef XSCUGIC_H + xil_dev->instance = calloc(1, sizeof(XScuGic)); + if(!xil_dev->instance) + goto error; + + config = XScuGic_LookupConfig(descriptor->irq_ctrl_id); + if(!config) + goto ps_error; + + status = XScuGic_CfgInitialize(xil_dev->instance, config, + ((XScuGic_Config *)config)->CpuBaseAddress); + if (status != 0) + goto ps_error; + + Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, + (Xil_ExceptionHandler)XScuGic_InterruptHandler, + xil_dev->instance); + + break; +ps_error: + free(xil_dev->instance); +#endif + goto error; + case IRQ_PL: +#ifdef XINTC_H + xil_dev->instance = calloc(1, sizeof(XIntc)); + if(!xil_dev->instance) + goto error; + + status = XIntc_Initialize(xil_dev->instance, descriptor->irq_ctrl_id); + if(status != 0) + goto pl_error; + + status = XIntc_Start(xil_dev->instance, XIN_REAL_MODE); + if(status != 0) + goto pl_error; + + break; +pl_error: + free(xil_dev->instance); +#endif + goto error; + default: + goto error; + + break; + } + + *desc = descriptor; + + return 0; + +error: + free(xil_dev); + free(descriptor); + + return -1; +} + +/** + * @brief Enable global interrupts. + * @return 0 in case of success, -1 otherwise. + */ +int32_t xil_irq_global_enable(struct irq_ctrl_desc *desc) +{ + /* Enable interrupts */ + Xil_ExceptionEnable(); + + return 0; +} + +/** + * @brief Disable global interrupts. + * @return 0 in case of success, -1 otherwise. + */ +int32_t xil_irq_global_disable(struct irq_ctrl_desc *desc) +{ + /* Disable interrupts */ + Xil_ExceptionDisable(); + + return 0; +} + +/** + * @brief Enable specific interrupt. + * @param desc - The IRQ controller descriptor. + * @param irq_id - Interrupt identifier. + * @return 0 in case of success, -1 otherwise. + */ +int32_t xil_irq_enable(struct irq_ctrl_desc *desc, uint32_t irq_id) +{ + struct xil_irq_desc *xil_dev = desc->extra; + + switch(xil_dev->type) { + case IRQ_PS: +#ifdef XSCUGIC_H + XScuGic_Enable(xil_dev->instance, irq_id); +#endif + break; + case IRQ_PL: +#ifdef XINTC_H + XIntc_Enable(xil_dev->instance, irq_id); +#endif + break; + default: + + return -1; + } + + return 0; +} + +/** + * @brief Disable specific interrupt. + * @param desc - The IRQ controller descriptor. + * @param irq_id - Interrupt identifier. + * @return 0 in case of success, -1 otherwise. + */ +int32_t xil_irq_disable(struct irq_ctrl_desc *desc, uint32_t irq_id) +{ + struct xil_irq_desc *xil_dev = desc->extra; + + switch(xil_dev->type) { + case IRQ_PS: +#ifdef XSCUGIC_H + XScuGic_Disable(xil_dev->instance, irq_id); +#endif + break; + case IRQ_PL: +#ifdef XINTC_H + XIntc_Disable(xil_dev->instance, irq_id); +#endif + break; + default: + + return -1; + } + + return 0; +} + +/** + * @brief Register a callback to handle the irq events. + * @param desc - The IRQ controller descriptor. + * @param irq_id - Interrupt identifier. + * @param callback_desc - Callback descriptor + * @return 0 in case of success, -1 otherwise. + */ +int32_t xil_irq_register_callback(struct irq_ctrl_desc *desc, + uint32_t irq_id, + struct callback_desc *callback_desc) +{ + struct xil_irq_desc *xil_dev = desc->extra; + + switch(xil_dev->type) { + case IRQ_PS: +#ifdef XSCUGIC_H + return XScuGic_Connect(xil_dev->instance, irq_id, + (Xil_InterruptHandler) callback_desc->callback, + callback_desc->ctx); +#endif + break; + case IRQ_PL: +#ifdef XINTC_H + if (irq_id == XPAR_AXI_INTC_AXI_TIMER_INTERRUPT_INTR) { + int32_t ret; + + ret = XIntc_Connect(xil_dev->instance, irq_id, + XTmrCtr_InterruptHandler, callback_desc->legacy_config); + if (IS_ERR_VALUE(ret)) + return -1; + XTmrCtr_SetHandler(callback_desc->legacy_config, + (XTmrCtr_Handler)callback_desc->callback, + callback_desc->ctx); + + return 0; + } + return XIntc_Connect(xil_dev->instance, irq_id, + (XInterruptHandler) callback_desc->callback, + callback_desc->ctx); +#endif + break; + default: + break; + } + + return -1; +} + +/** + * @brief Set interrupt trigger level. + * @param desc - The IRQ controller descriptor. + * @param irq_id - Interrupt identifier. + * @param trig - New trigger level for the interrupt. + * @return 0 in case of success, -1 otherwise. + */ +int32_t xil_irq_trigger_level_set(struct irq_ctrl_desc *desc, + uint32_t irq_id, + enum irq_trig_level trig) +{ + struct xil_irq_desc *xil_dev = desc->extra; + + if(trig == IRQ_EDGE_BOTH) + return -EINVAL; + + switch(xil_dev->type) { + case IRQ_PS: +#ifdef XSCUGIC_H + ; + uint8_t priority, trigger; + + XScuGic_GetPriorityTriggerType(xil_dev->instance, irq_id, &priority, + &trigger); + trigger = trig; + XScuGic_SetPriorityTriggerType(xil_dev->instance, irq_id, priority, + trigger); + + return 0; +#endif + break; + case IRQ_PL: +#ifdef XINTC_H + /* Interrupt trigger determined in hardware. TODO: verify */ + return 0; +#endif + break; + default: + break; + } + + return -1; +} + +/** + * @brief Set interrupt trigger level. + * @param desc - The IRQ controller descriptor. + * @param irq_id - Interrupt identifier. + * @param priority_level - New priority level for the interrupt. + * @return 0 in case of success, -1 otherwise. + */ +int32_t xil_irq_set_priority(struct irq_ctrl_desc *desc, + uint32_t irq_id, + uint32_t priority_level) +{ + struct xil_irq_desc *xil_dev = desc->extra; + + if(priority_level % 8 != 0) + return -EINVAL; + + switch(xil_dev->type) { + case IRQ_PS: +#ifdef XSCUGIC_H + ; + uint8_t priority, trigger; + + XScuGic_GetPriorityTriggerType(xil_dev->instance, irq_id, &priority, + &trigger); + priority = priority_level; + XScuGic_SetPriorityTriggerType(xil_dev->instance, irq_id, priority, + trigger); + + return 0; +#endif + break; + case IRQ_PL: +#ifdef XINTC_H + /* Interrupt priority level determined in hardware. TODO: verify */ + return 0; +#endif + break; + default: + break; + } + + return -1; +} + +/** + * @brief Unregisters a generic IRQ handling function. + * @param desc - The IRQ controller descriptor. + * @param irq_id - Interrupt identifier. + * @param cb - Callback descriptor. + * @return 0 in case of success, -1 otherwise. + */ +int32_t xil_irq_unregister_callback(struct irq_ctrl_desc *desc, + uint32_t irq_id, struct callback_desc *cb) +{ + struct xil_irq_desc *xil_dev = desc->extra; + + switch(xil_dev->type) { + case IRQ_PS: +#ifdef XSCUGIC_H + XScuGic_Disconnect(xil_dev->instance, irq_id); +#endif + break; + case IRQ_PL: +#ifdef XINTC_H + XIntc_Disconnect(xil_dev->instance, irq_id); +#endif + break; + default: + + return -1; + } + + return 0; +} + +/** + * @brief Free the resources allocated by irq_ctrl_init(). + * @param desc - The IRQ control descriptor. + * @return 0 in case of success, -1 otherwise. + */ +int32_t xil_irq_ctrl_remove(struct irq_ctrl_desc *desc) +{ + struct xil_irq_desc *xil_dev = desc->extra; + free(xil_dev->instance); + free(desc->extra); + free(desc); + + return 0; +} + +/** + * @brief Xilinx platform specific IRQ platform ops structure + */ +const struct irq_platform_ops xil_irq_ops = { + .init = &xil_irq_ctrl_init, + .register_callback = &xil_irq_register_callback, + .unregister_callback = &xil_irq_unregister_callback, + .global_enable = &xil_irq_global_enable, + .global_disable = &xil_irq_global_disable, + .trigger_level_set = &xil_irq_trigger_level_set, + .set_priority = &xil_irq_set_priority, + .enable = &xil_irq_enable, + .disable = &xil_irq_disable, + .remove = &xil_irq_ctrl_remove +}; diff --git a/df_datalink_sp/src/drivers/platform/xilinx_irq.h b/df_datalink_sp/src/drivers/platform/xilinx_irq.h new file mode 100644 index 0000000..386b233 --- /dev/null +++ b/df_datalink_sp/src/drivers/platform/xilinx_irq.h @@ -0,0 +1,91 @@ +/******************************************************************************* + * @file xilinx_irq.h + * @brief Header containing types used in the irq driver. + * @author Cristian Pop (cristian.pop@analog.com) +******************************************************************************** + * Copyright 2019(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ + +#ifndef XILINX_IRQ_H_ +#define XILINX_IRQ_H_ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include +#include "irq.h" + +/******************************************************************************/ +/*************************** Types Declarations *******************************/ +/******************************************************************************/ + +/** + * @enum xil_irq_type + * @brief Xilinx platform architecture sections + */ +enum xil_irq_type { + /** Programmable Logic */ + IRQ_PL, + /** Processing System */ + IRQ_PS +}; + +/** + * @struct xil_irq_init_param + * @brief Structure holding the initialization parameters for Xilinx platform + * specific IRQ parameters. + */ +struct xil_irq_init_param { + /** Xilinx architecture */ + enum xil_irq_type type; +}; + +/** + * @struct xil_irq_desc + * @brief Xilinx platform specific IRQ descriptor + */ +struct xil_irq_desc { + /** Xilinx architecture */ + enum xil_irq_type type; + /** Xilinx IRQ Instance */ + void *instance; +}; + +/** + * @brief Xilinx specific IRQ platform ops structure + */ +extern const struct irq_platform_ops xil_irq_ops; + +#endif diff --git a/df_datalink_sp/src/drivers/platform/xilinx_spi.c b/df_datalink_sp/src/drivers/platform/xilinx_spi.c new file mode 100644 index 0000000..832ea91 --- /dev/null +++ b/df_datalink_sp/src/drivers/platform/xilinx_spi.c @@ -0,0 +1,462 @@ +/***************************************************************************//** + * @file xilinx/xilinx_spi.c + * @brief Implementation of Xilinx SPI Generic Driver. + * @author Antoniu Miclaus (antoniu.miclaus@analog.com) +******************************************************************************** + * Copyright 2019(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include + +#include +#ifdef XPAR_XSPI_NUM_INSTANCES +#include +#endif +#ifdef XPAR_XSPIPS_NUM_INSTANCES +#include +#endif + +#include "error.h" +#include "spi.h" +#include "xilinx_spi.h" + +#if defined(PLATFORM_ZYNQ) +#define SPI_CLK_FREQ_HZ(dev) (XPAR_PS7_SPI_ ## dev ## _SPI_CLK_FREQ_HZ) +#define SPI_NUM_INSTANCES XPAR_XSPIPS_NUM_INSTANCES +#elif defined(PLATFORM_ZYNQMP) +#define SPI_CLK_FREQ_HZ(dev) (XPAR_PSU_SPI_ ## dev ## _SPI_CLK_FREQ_HZ) +#define SPI_NUM_INSTANCES XPAR_XSPIPS_NUM_INSTANCES +#else +#define SPI_NUM_INSTANCES 0 +#endif + +#warning SPI delays are not supported on the xilinx platform + +/******************************************************************************/ +/************************ Functions Definitions *******************************/ +/******************************************************************************/ + +/** + * @brief Initialize the hardware SPI peripherial + * + * @param xdesc Platform specific SPI descriptor + * @param xinit Platform specific SPI init param + * @return int32_t -1 if the device couldn't be found or configured + */ +static int32_t spi_init_pl(struct spi_desc *desc, + const struct spi_init_param *param) +{ +#ifdef XSPI_H + int32_t ret; + struct xil_spi_desc *xdesc; + struct xil_spi_init_param *xinit; + + xdesc = (struct xil_spi_desc*)malloc(sizeof(struct xil_spi_desc)); + if(!xdesc) { + free(xdesc); + return -1; + } + + desc->extra = xdesc; + xinit = param->extra; + xdesc->type = xinit->type; + xdesc->flags = xinit->flags; + + xdesc->instance = (XSpi*)calloc(1, sizeof(XSpi)); + if(!xdesc->instance) + goto pl_error; + + xdesc->config = XSpi_LookupConfig(param->device_id); + if(xdesc->config == NULL) + goto pl_error; + + ret = XSpi_CfgInitialize(xdesc->instance, + xdesc->config, + ((XSpi_Config*)xdesc->config) + ->BaseAddress); + if(ret != 0) + goto pl_error; + + ret = XSpi_Initialize(xdesc->instance, param->device_id); + if (ret != 0) + goto pl_error; + + ret = XSpi_SetOptions(xdesc->instance, + XSP_MASTER_OPTION | + ((desc->mode & SPI_CPOL) ? + XSP_CLK_ACTIVE_LOW_OPTION : 0) | + ((desc->mode & SPI_CPHA) ? + XSP_CLK_PHASE_1_OPTION : 0)); + if (ret != 0) + goto pl_error; + + ret = XSpi_Start(xdesc->instance); + if (ret != 0) + goto pl_error; + + XSpi_IntrGlobalDisable((XSpi *)(xdesc->instance)); + + return 0; + +pl_error: + free(xdesc->instance); + free(xdesc); +#endif + return -1; +} + +/** + * @brief Initialize the hardware SPI peripherial + * + * @param xdesc Platform specific SPI descriptor + * @param xinit Platform specific SPI init param + * @return int32_t -1 if the device couldn't be found or configured + */ +static int32_t spi_init_ps(struct spi_desc *desc, + const struct spi_init_param *param) +{ +#ifdef XSPIPS_H + int32_t ret; + struct xil_spi_desc *xdesc; + struct xil_spi_init_param *xinit; + const uint32_t prescaler_default = XSPIPS_CLK_PRESCALE_64; + const uint32_t prescaler_min = XSPIPS_CLK_PRESCALE_4; + const uint32_t prescaler_max = XSPIPS_CLK_PRESCALE_256; + uint32_t prescaler = 0u; + uint32_t input_clock = 0u; + + xdesc = (struct xil_spi_desc*)malloc(sizeof(struct xil_spi_desc)); + if(!xdesc) { + free(xdesc); + return -1; + } + + desc->extra = xdesc; + xinit = param->extra; + xdesc->type = xinit->type; + xdesc->flags = xinit->flags; + + xdesc->instance = (XSpiPs*)malloc(sizeof(XSpiPs)); + if(!xdesc->instance) + goto ps_error; + + xdesc->config = XSpiPs_LookupConfig(param->device_id); + if(xdesc->config == NULL) + goto ps_error; + + ret = XSpiPs_CfgInitialize(xdesc->instance, + xdesc->config, + ((XSpiPs_Config*)xdesc->config) + ->BaseAddress); + if(ret != 0) + goto ps_error; + + switch (param->device_id) { +#if (SPI_NUM_INSTANCES >= 1) + case 0: + input_clock = SPI_CLK_FREQ_HZ(0); + break; +#endif +#if (SPI_NUM_INSTANCES >= 2) + case 1: + input_clock = SPI_CLK_FREQ_HZ(1); + break; +#endif + default: + goto ps_error; + }; + + if (desc->max_speed_hz != 0u) { + uint32_t div = input_clock / desc->max_speed_hz; + uint32_t rem = input_clock % desc->max_speed_hz; + uint32_t po2 = !(div & (div - 1)) && !rem; + + // find the power of two just higher than div and + // store the exponent in prescaler + while(div) { + prescaler += 1; + div >>= 1u; + } + + // this exponent - 1 is needed because of the way + // xilinx stores it into registers + if (prescaler) + prescaler -= 1; + + // this exponent - 1 is needed when initial div was + // precisely a power of two + if (prescaler && po2) + prescaler -= 1; + + if (prescaler < prescaler_min) + prescaler = prescaler_min; + + if (prescaler > prescaler_max) + prescaler = prescaler_max; + } else + prescaler = prescaler_default; + + ret = XSpiPs_SetClkPrescaler(xdesc->instance, prescaler); + + if(ret != 0) + goto ps_error; + + return 0; + +ps_error: + free(xdesc->instance); + free(xdesc); +#endif + return -1; +} + +/** + * @brief Initialize the SPI communication peripheral. + * @param desc - The SPI descriptor. + * @param param - The structure that contains the SPI parameters. + * @return 0 in case of success, -1 otherwise. + */ +int32_t xil_spi_init(struct spi_desc **desc, + const struct spi_init_param *param) +{ + int32_t ret; + enum xil_spi_type *spi_type; + + if (!param) { + return -1; + } + + *desc = malloc(sizeof(**desc)); + if(! *desc) { + free(*desc); + return -1; + } + + spi_type = param->extra; + + if(!spi_type) + goto init_error; + + (*desc)->max_speed_hz = param->max_speed_hz; + (*desc)->mode = param->mode; + (*desc)->bit_order = param->bit_order; + (*desc)->chip_select = param->chip_select; + + switch (*spi_type) { + case SPI_PL: + ret = spi_init_pl(*desc, param); + break; + case SPI_PS: + ret = spi_init_ps(*desc, param); + break; + + default: + goto init_error; + break; + } + + if (ret != 0) { +init_error: + free(*desc); + + return -1; + } + + return ret; +} + +/** + * @brief Free the resources allocated by spi_init(). + * @param desc - The SPI descriptor. + * @return 0 in case of success, -1 otherwise. + */ +int32_t xil_spi_remove(struct spi_desc *desc) +{ +#ifdef XSPI_H + int32_t ret; +#endif + struct xil_spi_desc *xdesc = NULL; + enum xil_spi_type *spi_type; + + spi_type = desc->extra; + + if(!spi_type) + return -1; + + switch (*spi_type ) { + case SPI_PL: +#ifdef XSPI_H + xdesc = desc->extra; + + if(!xdesc) + return -1; + + ret = XSpi_Stop((XSpi *)(xdesc->instance)); + if(ret != 0) + goto error; +#endif + break; + case SPI_PS: +#ifdef XSPIPS_H + xdesc = desc->extra; + + if(!xdesc) + return -1; +#endif + break; + + /* Intended fallthrough */ +#ifdef XSPI_H +error: +#endif + default: + return -1; + } + + if(xdesc) + free(xdesc->instance); + free(desc->extra); + free(desc); + + return 0; +} + +/** + * @brief Write and read data to/from SPI. + * @param desc - The SPI descriptor. + * @param data - The buffer with the transmitted/received data. + * @param bytes_number - Number of bytes to write/read. + * @return 0 in case of success, -1 otherwise. + */ +int32_t xil_spi_write_and_read(struct spi_desc *desc, + uint8_t *data, + uint16_t bytes_number) +{ + int32_t ret; +#ifdef XSPI_H + uint32_t ctrl_reg; +#endif + struct xil_spi_desc *xdesc; + enum xil_spi_type *spi_type; + + ret = -1; + + spi_type = desc->extra; + + if(!spi_type) + return -1; + + xdesc = desc->extra; + + switch (*spi_type) { + case SPI_PL: +#ifdef XSPI_H + ret = XSpi_SetOptions(xdesc->instance, + XSP_MASTER_OPTION | + ((desc->mode & SPI_CPOL) ? + XSP_CLK_ACTIVE_LOW_OPTION : 0) | + ((desc->mode & SPI_CPHA) ? + XSP_CLK_PHASE_1_OPTION : 0)); + if (ret != 0) + goto error; + + ctrl_reg = XSpi_GetControlReg(((XSpi*)xdesc->instance)); + if (desc->bit_order == SPI_BIT_ORDER_LSB_FIRST) + ctrl_reg |= XSP_CR_LSB_MSB_FIRST_MASK; + else + ctrl_reg &= ~ XSP_CR_LSB_MSB_FIRST_MASK; + XSpi_SetControlReg(((XSpi*)xdesc->instance), ctrl_reg); + + ret = XSpi_SetSlaveSelect(xdesc->instance, + 0x01 << desc->chip_select); + if (ret != 0) + goto error; + + ret = XSpi_Transfer(xdesc->instance, + data, + data, + bytes_number); + if (ret != 0) + goto error; +#endif + break; + case SPI_PS: +#ifdef XSPIPS_H + ret = XSpiPs_SetOptions(xdesc->instance, + XSPIPS_MASTER_OPTION | + ((xdesc->flags & SPI_CS_DECODE) ? + XSPIPS_DECODE_SSELECT_OPTION : 0) | + XSPIPS_FORCE_SSELECT_OPTION | + ((desc->mode & SPI_CPOL) ? + XSPIPS_CLK_ACTIVE_LOW_OPTION : 0) | + ((desc->mode & SPI_CPHA) ? + XSPIPS_CLK_PHASE_1_OPTION : 0)); + if (ret != 0) + goto error; + + ret = XSpiPs_SetSlaveSelect(xdesc->instance, + desc->chip_select); + if (ret != 0) + goto error; + ret = XSpiPs_PolledTransfer(xdesc->instance, + data, + data, + bytes_number); + if (ret != 0) + goto error; + ret = XSpiPs_SetSlaveSelect(xdesc->instance, SPI_DEASSERT_CURRENT_SS); + if (ret != 0) + goto error; +#endif + break; +error: + default: + return -1; + } + + return ret; +} + +/** + * @brief Xilinx platform specific SPI platform ops structure + */ +const struct spi_platform_ops xil_spi_ops = { + .init = &xil_spi_init, + .write_and_read = &xil_spi_write_and_read, + .remove = &xil_spi_remove +}; diff --git a/df_datalink_sp/src/drivers/platform/xilinx_spi.h b/df_datalink_sp/src/drivers/platform/xilinx_spi.h new file mode 100644 index 0000000..fc42c7b --- /dev/null +++ b/df_datalink_sp/src/drivers/platform/xilinx_spi.h @@ -0,0 +1,115 @@ +/******************************************************************************* + * @file xilinx/xilinx_spi.h + * @brief Header containing extra types used in the spi driver. + * @author scuciurean (sergiu.cuciurean@analog.com) +******************************************************************************** + * Copyright 2019(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ +#ifndef XILINX_SPI_H_ +#define XILINX_SPI_H_ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include +#include "spi.h" + +/******************************************************************************/ +/********************** Macros and Constants Definitions **********************/ +/******************************************************************************/ + +#define SPI_CS_DECODE 0x01 +#define SPI_DEASSERT_CURRENT_SS 0x0F + +/******************************************************************************/ +/*************************** Types Declarations *******************************/ +/******************************************************************************/ + +/** + * @enum xil_spi_type + * @brief Xilinx platform architecture sections + */ +enum xil_spi_type { + /** Programmable Logic */ + SPI_PL, + /** Processing System */ + SPI_PS, + /** SPI Engine */ + SPI_ENGINE +}; + +/** + * @struct xil_spi_init_param + * @brief Structure holding the initialization parameters for Xilinx platform + * specific SPI parameters when using xil_spi_ops. + */ +struct xil_spi_init_param { + /** Xilinx architecture */ + enum xil_spi_type type; + /** SPI flags */ + uint32_t flags; +}; + +/** + * @struct xil_spi_desc + * @brief Xilinx platform specific SPI descriptor + */ +struct xil_spi_desc { + /** Xilinx architecture */ + enum xil_spi_type type; + /** SPI flags */ + uint32_t flags; + /** SPI configuration */ + void *config; + /** SPI instance */ + void *instance; +}; + +/** + * @brief SPI engine platform ops structure + */ +extern const struct spi_platform_ops spi_eng_platform_ops; + +/** + * @brief Xilinx specific SPI platform ops structure + */ +extern const struct spi_platform_ops xil_spi_ops; + +/** + * @brief Xilinx SPI PS register functions. No extra param needed + */ +extern const struct spi_platform_ops xil_spi_pl_ops; + +#endif // XILINX_SPI_H_ diff --git a/df_datalink_sp/src/drivers/platform/xilinx_spi_pl.c b/df_datalink_sp/src/drivers/platform/xilinx_spi_pl.c new file mode 100644 index 0000000..270cc29 --- /dev/null +++ b/df_datalink_sp/src/drivers/platform/xilinx_spi_pl.c @@ -0,0 +1,533 @@ +/******************************************************************************* + * @file xilinx/xilinx_spi_pl.c + * @brief Driver for spi pl device using registers + * @author Mihail Chindris (mihail.chindris@analog.com) +******************************************************************************** + * Copyright 2021(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ + +#include + +#ifdef XPAR_XSPI_NUM_INSTANCES + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include +#include +#include +#include "spi.h" +#include "error.h" +#include "delay.h" +#include "util.h" +#include "alloc.h" + +/******************************************************************************/ +/********************** Macros and Constants Definitions **********************/ +/******************************************************************************/ + +#define XPS_TYPE_WRITE 0x1 +#define XPS_TYPE_READ 0x2 +#define XSP_DEFAULT_SR_VALUE 0x25 +#define XSP_DUMMY_DATA 0xFF + +/* + * Used to store current spi device configuration in order to not update it for + * each spi transaction if not needed. + */ +static struct spi_desc g_spi_desc[XPAR_XSPI_NUM_INSTANCES]; + +/******************************************************************************/ +/*************************** Types Declarations *******************************/ +/******************************************************************************/ + +/* Xilinx PL spi specific data */ +struct xspi_desc { + uint32_t base_addr; + uint32_t disable_slaves_mask; + uint32_t fifo_depth; + uint8_t cs_asserted; +}; + +/* Structure used to iterate over SPI messages */ +struct msg_iter { + struct spi_msg *msgs; + uint32_t len; + uint32_t i; + uint32_t buff_i; + uint8_t is_wr; +}; + +/******************************************************************************/ +/************************ Functions Definitions *******************************/ +/******************************************************************************/ + +/* Read device register */ +static inline uint32_t _read(struct xspi_desc *xdesc, uint32_t reg) +{ + return Xil_In32(xdesc->base_addr + reg); +} + +/* Write device register */ +static inline void _write(struct xspi_desc *xdesc, uint32_t reg, uint32_t val) +{ + Xil_Out32(xdesc->base_addr + reg, val); +} + +/* Update device register. Only bits set to 1 in mask will be modified */ +static inline void _wr_mask(struct xspi_desc *xdesc, uint32_t reg, + uint32_t val, uint32_t mask) +{ + uint32_t tmp; + + tmp = _read(xdesc, reg); + tmp &= ~mask; + tmp |= val & mask; + _write(xdesc, reg, tmp); +} + +/* Update spi device configuration if needed */ +static void _update_mode(struct spi_desc *desc) +{ + uint32_t val; + uint32_t mask; + + if (desc->mode == g_spi_desc[desc->device_id].mode && + desc->bit_order == g_spi_desc[desc->device_id].bit_order) + return ; + + /* Update mode */ + val = desc->mode | SPI_CPOL ? XSP_CR_CLK_POLARITY_MASK : 0; + val |= desc->mode | SPI_CPHA ? XSP_CR_CLK_PHASE_MASK : 0; + mask = XSP_CR_CLK_POLARITY_MASK | XSP_CR_CLK_PHASE_MASK; + + val |= desc->bit_order == SPI_BIT_ORDER_LSB_FIRST ? + XSP_CR_LSB_MSB_FIRST_MASK : 0; + mask |= XSP_CR_LSB_MSB_FIRST_MASK; + + _wr_mask(desc->extra, XSP_CR_OFFSET, val, mask); + g_spi_desc[desc->device_id] = *desc; +} + +/* Configure SPI PL device */ +static int32_t _xil_spi_init_dev(struct xspi_desc *xdesc) +{ + uint32_t val; + + /* Software reset */ + _write(xdesc, XSP_SRR_OFFSET, XSP_SRR_RESET_MASK); + mdelay(1); + + /* Check if success reset */ + val = _read(xdesc, XSP_SR_OFFSET); + if (val != XSP_DEFAULT_SR_VALUE) + return -ENODEV; + + /* Disable interrupts. Drivers only works with pooled mode */ + _write(xdesc, XSP_IIER_OFFSET, 0); + + /* Deasert chip selects */ + _write(xdesc, XSP_SSR_OFFSET, 0xFFFFFFFF); + + /* Get fifo depth */ + while (!(_read(xdesc, XSP_SR_OFFSET) & XSP_SR_TX_FULL_MASK)) + _write(xdesc, XSP_DTR_OFFSET, XSP_DUMMY_DATA); + xdesc->fifo_depth = _read(xdesc, XSP_TFO_OFFSET) + 1; + + /* Configure spi device */ + val = XSP_CR_ENABLE_MASK | + XSP_CR_MANUAL_SS_MASK | + XSP_CR_TXFIFO_RESET_MASK | + XSP_CR_RXFIFO_RESET_MASK | + XSP_CR_MASTER_MODE_MASK | + XSP_CR_TRANS_INHIBIT_MASK; + + _write(xdesc, XSP_CR_OFFSET, val); + + return 0; +} + +/* Initialize spi_desc structure and device */ +static int32_t xil_spi_init_pl(struct spi_desc **desc, + const struct spi_init_param *param) +{ + struct spi_desc *ldesc; + struct xspi_desc *xdesc; + int32_t err; + XSpi_Config *cfg; + + if (!desc || !param || param->device_id >= XPAR_XSPI_NUM_INSTANCES) + return -EINVAL; + + cfg = XSpi_LookupConfig(param->device_id); + if (!cfg) + return -EINVAL; + + if (param->chip_select > cfg->NumSlaveBits) + return -EINVAL; + + ldesc = (struct spi_desc *)calloc(1, sizeof(*ldesc)); + if (!ldesc) + return -ENOMEM; + + xdesc = (struct xspi_desc *)calloc(1, sizeof(*xdesc)); + if (!xdesc) { + err = -ENOMEM; + goto error; + } + + ldesc->bit_order = param->bit_order; + ldesc->chip_select = param->chip_select; + ldesc->mode = param->mode; + xdesc->base_addr = cfg->BaseAddress; + xdesc->disable_slaves_mask = (1 << cfg->NumSlaveBits) - 1; + xdesc->cs_asserted = 0; + + err = _xil_spi_init_dev(xdesc); + if (IS_ERR_VALUE(err)) + goto error; + + ldesc->extra = xdesc; + *desc = ldesc; + + return 0; + +error: + free(xdesc); + free(ldesc); + + return err; +} + +/* Remove allocated resources */ +static int32_t xil_spi_remove_pl(struct spi_desc *desc) +{ + if (!desc) + return -EINVAL; + + free(desc->extra); + free(desc); + + return 0; +} + +/* + * Fill fifo until fifo is full or no more data available. + * Return the number of written bytes. + */ +static uint32_t _wr_fifo(struct xspi_desc *xdesc, uint8_t *data, + uint32_t len) +{ + uint32_t i; + uint32_t to_write; + uint32_t tx_available; + + tx_available = xdesc->fifo_depth - _read(xdesc, XSP_TFO_OFFSET); + to_write = min(tx_available, len); + for (i = 0; i < to_write; ++i) + if (data) + _write(xdesc, XSP_DTR_OFFSET, data[i]); + else + _write(xdesc, XSP_DTR_OFFSET, XSP_DUMMY_DATA); + + return to_write; +} + +/* + * Read fifo until fifo is empty or no more buffer available to read into + * Returns the number of read bytes + */ +static uint32_t _rd_fifo(struct xspi_desc *xdesc, uint8_t *data, + uint32_t len) +{ + uint32_t rx_available; + uint32_t to_read; + uint32_t tmp; + uint32_t i; + + tmp = _read(xdesc, XSP_SR_OFFSET); + if (tmp & XSP_SR_RX_EMPTY_MASK) + return 0; + + rx_available = _read(xdesc, XSP_RFO_OFFSET) + 1; + to_read = min(rx_available, len); + for (i = 0; i < to_read; ++i) { + tmp = _read(xdesc, XSP_DRR_OFFSET); + if (data) + data[i] = tmp; + } + + return to_read; +} + +/* If start is 0 stop transfer, else start it. + * CS will be asserted if needed. If different CS othere than the one needed + * is asserted. Deassert it and assert correct one */ +static void _xil_spi_start_transfer(struct spi_desc *desc, uint8_t start) +{ + struct xspi_desc *xdesc; + + xdesc = desc->extra; + if (start) { + if (xdesc->cs_asserted) { + if (desc->chip_select == + g_spi_desc[desc->device_id].chip_select) + return ; + else + /* Stop transfer to start again with new CS */ + _xil_spi_start_transfer(desc, 0); + } + _write(xdesc, XSP_SSR_OFFSET, ~(1 << desc->chip_select)); + _wr_mask(xdesc, XSP_CR_OFFSET, 0, XSP_CR_TRANS_INHIBIT_MASK); + } else { + _wr_mask(xdesc, XSP_CR_OFFSET, XSP_CR_TRANS_INHIBIT_MASK, + XSP_CR_TRANS_INHIBIT_MASK); + _write(xdesc, XSP_SSR_OFFSET, xdesc->disable_slaves_mask); + } + xdesc->cs_asserted = start; +} + + +/* SPI polled transfer */ +static int32_t xil_spi_write_and_read_pl(struct spi_desc *desc, + uint8_t *data, + uint16_t bytes_number) +{ + struct xspi_desc *xdesc; + uint32_t rx; + uint32_t tx; + + if (!desc || !desc->extra) + return -EINVAL; + + xdesc = desc->extra; + _update_mode(desc); + + _xil_spi_start_transfer(desc, 1); + rx = 0; + tx = 0; + while (rx < bytes_number) { + if (tx < bytes_number) + tx += _wr_fifo(xdesc, data + tx, bytes_number - tx); + rx += _rd_fifo(xdesc, data + rx, bytes_number - rx); + } + _xil_spi_start_transfer(desc, 0); + + return 0; +} + +/* Get type of message. It can be READ, WRITE or both */ +static uint32_t _get_msg_type(struct spi_msg *msg) +{ + uint32_t type; + + type = 0; + if (msg->tx_buff) + type |= XPS_TYPE_WRITE; + if (msg->rx_buff) + type |= XPS_TYPE_READ; + + return type; +} + +/* Get information based on current iterator position */ +static void _get_data(struct msg_iter *it, uint8_t **buff, uint32_t *len, + uint32_t *type) +{ + struct spi_msg *msg; + + if (it->i == it->len) { + *len = 0; + return ; + } + + msg = it->msgs + it->i; + if (it->is_wr) + *buff = msg->tx_buff; + else + *buff = msg->rx_buff; + + if (*buff) + *buff += it->buff_i; + + *len = msg->bytes_number - it->buff_i; + if (type) + *type = _get_msg_type(msg); +} + +/* + * Increment iterator position with desired length. + * If the new position has a different message type, new_type will be set to 1 + * If a CS change is needed, cs_change is set + */ +static void _increment_iter(struct msg_iter *it, uint32_t len, + uint8_t *cs_change, uint8_t *new_type) +{ + struct spi_msg *msg; + uint32_t type; + uint32_t extra_len; + + if (!len) + return ; + + *cs_change = 0; + *new_type = 0; + msg = it->msgs + it->i; + if (it->buff_i + len > msg->bytes_number) + extra_len = it->buff_i + len - msg->bytes_number; + else + extra_len = 0; + len -= extra_len; + it->buff_i += len; + if (it->buff_i == msg->bytes_number) { + type = _get_msg_type(msg); + ++it->i; + it->buff_i = 0; + if (cs_change && msg->cs_change) + *cs_change = 1; + if (new_type) + if (it->i == it->len || + type != _get_msg_type(it->msgs + it->i)) + *new_type = 1; + } + if (extra_len) + _increment_iter(it, extra_len, cs_change, new_type); +} + +/* + * SPI polling transfer of multiple messages. + */ +static int32_t xil_spi_transfer_pl(struct spi_desc *desc, + struct spi_msg *msgs, + uint32_t len) + +{ + struct xspi_desc *xdesc; + uint8_t cs_change; + uint8_t new_type; + struct msg_iter rx = {.msgs = msgs, .len = len, .is_wr = 0}; + struct msg_iter tx = {.msgs = msgs, .len = len, .is_wr = 1}; + uint8_t *buff; + uint32_t bytes; + uint32_t type; + /* Bytes to increment rx when only a write transaction is executed */ + uint32_t to_inc_rx; + /* Difference between rx and tx iterators in bytes */ + uint32_t tx_advance; + /* Save bytes sent during a write loop */ + uint32_t tx_sent; + /* Used to loop if need to empty the RX FIFO */ + uint32_t loop; + + if (!desc || !desc->extra) + return -EINVAL; + + xdesc = desc->extra; + _update_mode(desc); + + tx_advance = 0; + to_inc_rx = 0; + buff = NULL; + type = 0; + do { + _xil_spi_start_transfer(desc, 1); + + tx_sent = 0; + /* Writing loop */ + do { + _get_data(&tx, &buff, &bytes, &type); + if (type & XPS_TYPE_READ) + /* + * Do not write more bytes than fifo_depth if + * they haven't been read. + */ + bytes = min(bytes, + xdesc->fifo_depth - tx_advance); + bytes = _wr_fifo(xdesc, buff, bytes); + tx_sent += bytes; + _increment_iter(&tx, bytes, &cs_change, &new_type); + tx_advance += bytes; + } while (!cs_change && !new_type && bytes); + + if (type & XPS_TYPE_READ) { + loop = 1; + /* + * Loop only when no more data to write otherwise read + * only available data. + */ + while (loop) { + if (!new_type) + loop = 0; + _get_data(&rx, &buff, &bytes, NULL); + bytes = _rd_fifo(xdesc, buff, bytes); + _increment_iter(&rx, bytes, &cs_change, &new_type); + tx_advance -= bytes; + if (loop && new_type) + break; + } + } else { + /* Clean RX FIFO if it was only a WRITE message */ + to_inc_rx += tx_sent; + if (new_type) { + /* Wait for TX to be sent */ + while (!(_read(xdesc, XSP_SR_OFFSET) & + XSP_SR_TX_EMPTY_MASK)) + ; + /* Reset fifo. Only write was performed */ + _wr_mask(xdesc, XSP_CR_OFFSET, + XSP_CR_RXFIFO_RESET_MASK, + XSP_CR_RXFIFO_RESET_MASK); + + _increment_iter(&rx, to_inc_rx, NULL, NULL); + tx_advance -= to_inc_rx; + to_inc_rx = 0; + } + } + + if ((cs_change && rx.i != len) || (!cs_change && rx.i == len)) + _xil_spi_start_transfer(desc, 0); + } while (rx.i < len); + + return 0; +} + +const struct spi_platform_ops xil_spi_pl_ops = { + .init = xil_spi_init_pl, + .remove = xil_spi_remove_pl, + .write_and_read = xil_spi_write_and_read_pl, + .transfer = xil_spi_transfer_pl +}; + +#endif // XPAR_XSPI_NUM_INSTANCES diff --git a/df_datalink_sp/src/drivers/platform/xilinx_timer.c b/df_datalink_sp/src/drivers/platform/xilinx_timer.c new file mode 100644 index 0000000..4b1fa85 --- /dev/null +++ b/df_datalink_sp/src/drivers/platform/xilinx_timer.c @@ -0,0 +1,456 @@ +/***************************************************************************//** +* @file xilinx/xilinx_timer.c +* @brief Timer and GIC control module source. +* @author Andrei Drimbarean (andrei.drimbarean@analog.com) +******************************************************************************** +* Copyright 2020(c) Analog Devices, Inc. +* +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* - Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* - Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in +* the documentation and/or other materials provided with the +* distribution. +* - Neither the name of Analog Devices, Inc. nor the names of its +* contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* - The use of this software may or may not infringe the patent rights +* of one or more patent holders. This license does not release you +* from the requirement that you obtain separate licenses from these +* patent holders to use this software. +* - Use of the software either in source or binary form, must be run +* on or directly connected to an Analog Devices Inc. component. +* +* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY +* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include +#include +#include "timer.h" +#include "xilinx_timer.h" +#include "error.h" + +/******************************************************************************/ +/********************** Macros and Constants Definitions **********************/ +/******************************************************************************/ + +#if defined(_XPARAMETERS_PS_H_) +#define CORE_PRIVATE_TIMER_CLOCK (XPAR_CPU_CORTEXA9_CORE_CLOCK_FREQ_HZ / 2) +#endif + +/******************************************************************************/ +/************************ Functions Definitions *******************************/ +/******************************************************************************/ + +/** + * @brief Set the current counter value of the timer. + * @param [in] desc - Pointer to the device handler. + * @param [in] new_val - New value for the timer counter. + * @return 0 in case of success, -1 otherwise + */ +int32_t xilinx_timer_counter_set(struct timer_desc *desc, + uint32_t new_val) +{ + struct xil_timer_desc *xdesc; + + if (!desc) + return -1; + + xdesc = desc->extra; + + switch (xdesc->type) { + case TIMER_PS: +#ifdef XSCUTIMER_H + XScuTimer_LoadTimer((XScuTimer *)xdesc->instance, new_val - 1); + break; +#endif + return -1; + case TIMER_PL: +#ifdef XTMRCTR_H + XTmrCtr_SetResetValue(xdesc->instance, xdesc->active_tmr, new_val); + XTmrCtr_Reset(xdesc->instance, xdesc->active_tmr); + break; +#endif + return -1; + default: + return -1; + } + + return 0; +} + +/** + * @brief Set the timer clock frequency. + * @param [in] desc - Pointer to the device handler. + * @param [in] freq_hz - New timer frequency in hertz. + * @return 0 in case of success, -1 otherwise + */ +int32_t xilinx_timer_count_clk_set(struct timer_desc *desc, + uint32_t freq_hz) +{ + struct xil_timer_desc *xdesc; + + if (!desc || !freq_hz) + return -1; + + xdesc = desc->extra; + + switch (xdesc->type) { + case TIMER_PS: +#ifdef XSCUTIMER_H + ; + uint32_t prescaler = CORE_PRIVATE_TIMER_CLOCK / freq_hz; + if (prescaler == 0 || prescaler >= 256) + return -1; + XScuTimer_SetPrescaler(xdesc->instance, prescaler - 1); + desc->freq_hz = CORE_PRIVATE_TIMER_CLOCK / prescaler; + break; +#endif + return -1; + case TIMER_PL: +#ifdef XTMRCTR_H + (void *)xdesc; + /** Cannot be done. */ +#endif + return -1; + default: + return -1; + } + + return 0; +} + +/** + * @brief Initialize hardware timer and the handler structure associated with + * it. + * @param [out] desc - Pointer to the reference of the device handler. + * @param [in] param - Initialization structure. + * @return 0 in case of success, -1 otherwise + */ +int32_t xilinx_timer_init(struct timer_desc **desc, + const struct timer_init_param *param) +{ + int32_t ret; + struct timer_desc *dev; + struct xil_timer_desc *xdesc; + struct xil_timer_init_param *xinit; + + if (!desc || !param) + return -1; + + xinit = param->extra; + + dev = (struct timer_desc *)calloc(1, sizeof(*dev)); + if(!dev) + return -1; + xdesc = (struct xil_timer_desc *)calloc(1, sizeof(*xdesc)); + if(!xdesc) + goto error_desc; + + dev->id = param->id; + dev->freq_hz = param->freq_hz; + dev->ticks_count = param->ticks_count; + dev->extra = xdesc; + xdesc->active_tmr = xinit->active_tmr; + xdesc->type = xinit->type; + + switch (xdesc->type) { + case TIMER_PS: +#ifdef XSCUTIMER_H + xdesc->config = XScuTimer_LookupConfig(dev->id); + xdesc->instance = calloc(1, sizeof(XScuTimer)); + if (!xdesc->instance) + goto error_xdesc; + ret = XScuTimer_CfgInitialize(xdesc->instance, xdesc->config, + ((XScuTimer_Config *)xdesc->config)->BaseAddr); + if (ret != XST_SUCCESS) { + free(xdesc->instance); + goto error_xdesc; + } + ret = xilinx_timer_count_clk_set(dev, param->freq_hz); + if (IS_ERR_VALUE(ret)) + goto error_xdesc; + + ret = xilinx_timer_counter_set(dev, dev->ticks_count); + if (IS_ERR_VALUE(ret)) + goto error_xdesc; + + XScuTimer_EnableAutoReload((XScuTimer *)xdesc->instance); + XScuTimer_EnableInterrupt((XScuTimer *)xdesc->instance); + break; +#endif + goto error_xdesc; + case TIMER_PL: +#ifdef XTMRCTR_H + xdesc->instance = (XTmrCtr *)calloc(1, sizeof(XTmrCtr)); + if (!xdesc->instance) + return -1; + + xdesc->config = XTmrCtr_LookupConfig(dev->id); + if (!xdesc->config) { + free(xdesc->instance); + goto error_desc; + } + XTmrCtr_CfgInitialize(xdesc->instance, xdesc->config, + ((XTmrCtr_Config *)xdesc->config)->BaseAddress); + ret = XTmrCtr_InitHw(xdesc->instance); + if (ret != 0) { + free(xdesc->instance); + goto error_desc; + } + dev->freq_hz = ((XTmrCtr_Config *)xdesc->config)->SysClockFreqHz; + + ret = XTmrCtr_SelfTest(xdesc->instance, dev->id); + if(ret != 0) + goto error_desc; + XTmrCtr_SetOptions(xdesc->instance, xdesc->active_tmr, + XTC_DOWN_COUNT_OPTION | XTC_INT_MODE_OPTION | + XTC_AUTO_RELOAD_OPTION); + XTmrCtr_SetResetValue(xdesc->instance, xdesc->active_tmr, + dev->ticks_count); + break; +#endif + goto error_xdesc; + default: + goto error_xdesc; + } + + *desc = dev; + + return 0; + +error_xdesc: + free(xdesc); +error_desc: + free(dev); + + return -1; +} + +/** + * @brief Free the memory allocated by timer_setup(). + * @param [in] desc - Pointer to the device handler. + * @return 0 in case of success, -1 otherwise + */ +int32_t xilinx_timer_remove(struct timer_desc *desc) +{ + struct xil_timer_desc *xdesc; + + if(!desc) + return -1; + + xdesc = desc->extra; + + switch (xdesc->type) { + case TIMER_PS: +#ifdef XSCUTIMER_H + XScuTimer_Stop(xdesc->instance); + free(xdesc->instance); + break; +#endif + return -1; + case TIMER_PL: +#ifdef XTMRCTR_H + XTmrCtr_Stop(xdesc->instance, xdesc->active_tmr); + break; +#endif + return -1; + default: + return -1; + } + + free(xdesc); + free(desc); + + return 0; +} + +/** + * @brief Start a timer. + * @param [in] desc - Pointer to the device handler. + * @return 0 in case of success, -1 otherwise + */ +int32_t xilinx_timer_start(struct timer_desc *desc) +{ + struct xil_timer_desc *xdesc; + + if (!desc) + return -1; + + xdesc = desc->extra; + + switch (xdesc->type) { + case TIMER_PS: +#ifdef XSCUTIMER_H + XScuTimer_Start(xdesc->instance); + break; +#endif + return -1; + case TIMER_PL: +#ifdef XTMRCTR_H + XTmrCtr_Start(xdesc->instance, xdesc->active_tmr); + break; +#endif + return -1; + } + + return 0; +} + +/** + * @brief Stop a timer from counting. + * @param [in] desc - Pointer to the device handler. + * @return 0 in case of success, -1 otherwise + */ +int32_t xilinx_timer_stop(struct timer_desc *desc) +{ + struct xil_timer_desc *xdesc; + + if (!desc) + return -1; + + xdesc = desc->extra; + + switch (xdesc->type) { + case TIMER_PS: +#ifdef XSCUTIMER_H + XScuTimer_Stop(xdesc->instance); + break; +#endif + return -1; + case TIMER_PL: +#ifdef XTMRCTR_H + XTmrCtr_Stop(xdesc->instance, xdesc->active_tmr); + break; +#endif + return -1; + default: + return -1; + } + + return 0; +} + +/** + * @brief Get the current counter value of the timer. + * @param [in] desc - Pointer to the device handler. + * @param [out] counter - Pointer to the current counter value. + * @return 0 in case of success, -1 otherwise + */ +int32_t xilinx_timer_counter_get(struct timer_desc *desc, + uint32_t *counter) +{ + struct xil_timer_desc *xdesc; + + if (!desc || !counter) + return -1; + + xdesc = desc->extra; + + switch (xdesc->type) { + case TIMER_PS: +#ifdef XSCUTIMER_H + *counter = XScuTimer_GetCounterValue((XScuTimer *)xdesc->instance); + ++(*counter); + break; +#endif + return -1; + case TIMER_PL: +#ifdef XTMRCTR_H + *counter = XTmrCtr_GetValue(xdesc->instance, xdesc->active_tmr); + break; +#endif + return -1; + default: + *counter = 0; + + return -1; + } + + return 0; +} + + +/** + * @brief Get the timer clock frequency. + * @param [in] desc - Pointer to the device handler. + * @param [out] freq_hz - Pointer to the returned frequency. + * @return 0 in case of success, -1 otherwise + */ +int32_t xilinx_timer_count_clk_get(struct timer_desc *desc, + uint32_t *freq_hz) +{ + struct xil_timer_desc *xdesc; + + if (!desc || !freq_hz) + return -1; + + xdesc = desc->extra; + + switch (xdesc->type) { + case TIMER_PS: +#ifdef XSCUTIMER_H + *freq_hz = desc->freq_hz; + break; +#endif + return -1; + case TIMER_PL: +#ifdef XTMRCTR_H + *freq_hz = ((XTmrCtr_Config *)xdesc->config)->SysClockFreqHz; + break; +#endif + return -1; + default: + *freq_hz = 0; + + return -1; + } + + return 0; +} + + +/** + * @brief Get the elapsed time in nsec for the timer. + * @param [in] desc - Pointer to the device handler. + * @param [in] elapsed_time - The elapsed time in nsec. + * @return -ENOSYS. + */ +int32_t xilinx_timer_get_elapsed_time_nsec(struct timer_desc *desc, + uint64_t *elapsed_time) +{ + /* Function not implemented */ + return -ENOSYS; +} + +/** + * @brief Xilinx platform specific timer platform ops structure + */ +const struct timer_platform_ops xil_timer_ops = { + .init = &xilinx_timer_init, + .start = &xilinx_timer_start, + .stop = &xilinx_timer_stop, + .counter_get = &xilinx_timer_counter_get, + .counter_set = &xilinx_timer_counter_set, + .count_clk_get = &xilinx_timer_count_clk_get, + .count_clk_set = &xilinx_timer_count_clk_set, + .get_elapsed_time_nsec = &xilinx_timer_get_elapsed_time_nsec, + .remove = &xilinx_timer_remove +}; diff --git a/df_datalink_sp/src/drivers/platform/xilinx_timer.h b/df_datalink_sp/src/drivers/platform/xilinx_timer.h new file mode 100644 index 0000000..7f5ff87 --- /dev/null +++ b/df_datalink_sp/src/drivers/platform/xilinx_timer.h @@ -0,0 +1,101 @@ +/***************************************************************************//** +* @file xilinx_timer.h +* @brief Timer control module header. +* @author Andrei Drimbarean (andrei.drimbarean@analog.com) +******************************************************************************** +* Copyright 2020(c) Analog Devices, Inc. +* +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* - Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* - Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in +* the documentation and/or other materials provided with the +* distribution. +* - Neither the name of Analog Devices, Inc. nor the names of its +* contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* - The use of this software may or may not infringe the patent rights +* of one or more patent holders. This license does not release you +* from the requirement that you obtain separate licenses from these +* patent holders to use this software. +* - Use of the software either in source or binary form, must be run +* on or directly connected to an Analog Devices Inc. component. +* +* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY +* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ + +#ifndef XILINX_TIMER_H_ +#define XILINX_TIMER_H_ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include +#ifdef XPAR_XSCUTIMER_NUM_INSTANCES +#include +#endif +#ifdef XPAR_XTMRCTR_NUM_INSTANCES +#include +#endif + +/******************************************************************************/ +/*************************** Types Declarations *******************************/ +/******************************************************************************/ + +/** + * @enum xil_timer_type + * @brief Xilinx platform architecture sections + */ +enum xil_timer_type { + /** Programmable Logic */ + TIMER_PL, + /** Processing System */ + TIMER_PS +}; + +/** + * @struct xil_timer_desc + * @brief Xilinx specific timer descriptor + */ +struct xil_timer_desc { + /** Pointer to the BSP driver handler */ + void *instance; + /** Pointer to the BSP driver configuration handler */ + void *config; + /** Timer used from the PL 3-timer core */ + uint8_t active_tmr; + /** Platform selection parameter */ + enum xil_timer_type type; +}; + +/** + * @struct xil_timer_init_param + * @brief Xilinx specific timer initialization structure + */ +struct xil_timer_init_param { + /** Timer used from the PL 3-timer core */ + uint8_t active_tmr; + /** Platform selection parameter */ + enum xil_timer_type type; +}; + +/** + * @brief Xilinx platform specific timer platform ops structure + */ +extern const struct timer_platform_ops xil_timer_ops; + +#endif /* XILINX_TIMER_H_ */ diff --git a/df_datalink_sp/src/drivers/rf-transceiver/ad9361/ad9361.c b/df_datalink_sp/src/drivers/rf-transceiver/ad9361/ad9361.c new file mode 100644 index 0000000..0305df3 --- /dev/null +++ b/df_datalink_sp/src/drivers/rf-transceiver/ad9361/ad9361.c @@ -0,0 +1,7475 @@ +/***************************************************************************//** + * @file ad9361.c + * @brief Implementation of AD9361 Driver. +******************************************************************************** + * Copyright 2014-2015(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ +#include +#include +#include +#include +#include +#include +#include "ad9361.h" +#include "ad9361_util.h" +#include "spi.h" +#include "gpio.h" +#include "delay.h" +#include "util.h" +#include "../../../config/app_config.h" + +#define diff_abs(x, y) ((x) > (y) ? (x - y) : (y - x)) + +#define NO_GAIN_TABLE ((uint32_t)-1) + +/* Used for static code size optimization: please see app_config.h */ +const bool has_split_gt = HAVE_SPLIT_GAIN_TABLE; +const bool have_tdd_tables = HAVE_TDD_SYNTH_TABLE; + +#define SYNTH_LUT_SIZE 53 + +static const struct SynthLUT SynthLUT_FDD[LUT_FTDD_ENT][SYNTH_LUT_SIZE] = { + { + {12605, 13, 1, 4, 2, 15, 12, 7, 14, 6, 14, 5, 15}, /* 40 MHz */ + {12245, 13, 1, 4, 2, 15, 12, 7, 14, 6, 14, 5, 15}, + {11906, 13, 1, 4, 2, 15, 12, 7, 15, 6, 14, 5, 15}, + {11588, 13, 1, 4, 2, 15, 12, 8, 15, 6, 14, 5, 15}, + {11288, 13, 1, 4, 2, 15, 12, 8, 15, 6, 14, 5, 15}, + {11007, 13, 1, 4, 2, 15, 12, 9, 15, 6, 14, 5, 15}, + {10742, 13, 1, 4, 2, 15, 12, 9, 15, 6, 14, 5, 15}, + {10492, 13, 1, 6, 2, 15, 12, 10, 15, 6, 14, 5, 15}, + {10258, 13, 1, 6, 2, 15, 12, 10, 15, 6, 14, 5, 15}, + {10036, 13, 1, 6, 2, 15, 12, 11, 15, 6, 14, 5, 15}, + {9827, 13, 1, 6, 2, 14, 12, 11, 15, 6, 14, 5, 15}, + {9631, 13, 1, 6, 2, 13, 12, 12, 15, 6, 14, 5, 15}, + {9445, 13, 1, 6, 2, 12, 12, 12, 15, 6, 14, 5, 15}, + {9269, 13, 1, 6, 2, 12, 12, 13, 15, 6, 14, 5, 15}, + {9103, 13, 1, 6, 2, 12, 12, 13, 15, 6, 14, 5, 15}, + {8946, 13, 1, 6, 2, 12, 12, 14, 15, 6, 14, 5, 15}, + {8797, 12, 1, 7, 2, 12, 12, 13, 15, 6, 14, 5, 15}, + {8655, 12, 1, 7, 2, 12, 12, 14, 15, 6, 14, 5, 15}, + {8520, 12, 1, 7, 2, 12, 12, 14, 15, 6, 14, 5, 15}, + {8392, 12, 1, 7, 2, 12, 12, 15, 15, 6, 14, 5, 15}, + {8269, 12, 1, 7, 2, 12, 12, 15, 15, 6, 14, 5, 15}, + {8153, 12, 1, 7, 2, 12, 12, 16, 15, 6, 14, 5, 15}, + {8041, 12, 1, 7, 2, 13, 12, 16, 15, 6, 14, 5, 15}, + {7934, 11, 1, 7, 2, 12, 12, 16, 15, 6, 14, 5, 15}, + {7831, 11, 1, 7, 2, 12, 12, 16, 15, 6, 14, 5, 15}, + {7733, 10, 1, 7, 3, 13, 12, 16, 15, 6, 14, 5, 15}, + {7638, 10, 1, 7, 2, 12, 12, 16, 15, 6, 14, 5, 15}, + {7547, 10, 1, 7, 2, 12, 12, 17, 15, 6, 14, 5, 15}, + {7459, 10, 1, 7, 2, 12, 12, 17, 15, 6, 14, 5, 15}, + {7374, 10, 2, 7, 3, 14, 13, 14, 15, 6, 14, 5, 15}, + {7291, 10, 2, 7, 3, 14, 13, 14, 15, 6, 14, 5, 15}, + {7212, 10, 2, 7, 3, 14, 13, 14, 15, 6, 14, 5, 15}, + {7135, 10, 2, 7, 3, 14, 13, 15, 15, 7, 14, 5, 15}, + {7061, 10, 2, 7, 3, 14, 13, 15, 15, 6, 14, 5, 15}, + {6988, 10, 1, 7, 3, 12, 14, 20, 15, 6, 14, 5, 15}, + {6918, 9, 2, 7, 3, 14, 13, 15, 15, 6, 14, 5, 15}, + {6850, 9, 2, 7, 3, 14, 13, 15, 15, 6, 14, 5, 15}, + {6784, 9, 2, 7, 2, 13, 13, 15, 15, 6, 14, 5, 15}, + {6720, 9, 2, 7, 2, 13, 13, 16, 15, 6, 14, 5, 15}, + {6658, 8, 2, 7, 3, 14, 13, 15, 15, 6, 14, 5, 15}, + {6597, 8, 2, 7, 2, 13, 13, 15, 15, 6, 14, 5, 15}, + {6539, 8, 2, 7, 2, 13, 13, 15, 15, 6, 14, 5, 15}, + {6482, 8, 2, 7, 2, 13, 13, 16, 15, 6, 14, 5, 15}, + {6427, 7, 2, 7, 3, 14, 13, 15, 15, 6, 14, 5, 15}, + {6373, 7, 2, 7, 3, 15, 13, 15, 15, 6, 14, 5, 15}, + {6321, 7, 2, 7, 3, 15, 13, 15, 15, 6, 14, 5, 15}, + {6270, 7, 2, 7, 3, 15, 13, 16, 15, 6, 14, 5, 15}, + {6222, 7, 2, 7, 3, 15, 13, 16, 15, 6, 14, 5, 15}, + {6174, 6, 2, 7, 3, 15, 13, 15, 15, 6, 14, 5, 15}, + {6128, 6, 2, 7, 3, 15, 13, 15, 15, 6, 14, 5, 15}, + {6083, 6, 2, 7, 3, 15, 13, 16, 15, 6, 14, 5, 15}, + {6040, 6, 2, 7, 3, 15, 13, 16, 15, 6, 14, 5, 15}, + {5997, 6, 2, 7, 3, 15, 13, 16, 15, 6, 14, 5, 15}, + }, { + {12605, 13, 1, 4, 2, 15, 12, 13, 15, 12, 12, 5, 14}, /* 60 MHz */ + {12245, 13, 1, 4, 2, 15, 12, 13, 15, 12, 12, 5, 14}, + {11906, 13, 1, 4, 2, 15, 12, 13, 15, 13, 12, 5, 13}, + {11588, 13, 1, 4, 2, 15, 12, 14, 15, 13, 12, 5, 13}, + {11288, 13, 1, 5, 2, 15, 12, 15, 15, 13, 12, 5, 13}, + {11007, 13, 1, 5, 2, 15, 12, 16, 15, 13, 12, 5, 13}, + {10742, 13, 1, 5, 2, 15, 12, 16, 15, 12, 12, 5, 14}, + {10492, 13, 1, 6, 2, 15, 12, 17, 15, 12, 12, 5, 14}, + {10258, 13, 1, 6, 2, 15, 12, 18, 15, 13, 12, 5, 13}, + {10036, 13, 1, 6, 2, 15, 12, 19, 15, 13, 12, 5, 13}, + {9827, 13, 1, 6, 2, 14, 12, 20, 15, 13, 12, 5, 13}, + {9631, 13, 1, 6, 2, 13, 12, 21, 15, 13, 12, 5, 13}, + {9445, 13, 1, 6, 2, 12, 12, 22, 15, 13, 12, 5, 13}, + {9269, 13, 1, 6, 2, 12, 12, 22, 15, 12, 12, 5, 14}, + {9103, 13, 1, 6, 2, 12, 12, 23, 15, 13, 12, 5, 13}, + {8946, 13, 1, 6, 2, 12, 12, 24, 15, 13, 12, 5, 13}, + {8797, 12, 1, 7, 2, 12, 12, 24, 15, 13, 12, 5, 13}, + {8655, 12, 1, 7, 2, 12, 12, 25, 15, 13, 12, 5, 13}, + {8520, 12, 1, 7, 2, 12, 12, 25, 15, 13, 12, 5, 13}, + {8392, 12, 1, 7, 2, 12, 12, 26, 15, 13, 12, 5, 13}, + {8269, 12, 1, 7, 2, 12, 12, 27, 15, 13, 12, 5, 13}, + {8153, 12, 1, 7, 2, 12, 12, 28, 15, 13, 12, 5, 13}, + {8041, 12, 1, 7, 2, 13, 12, 29, 15, 13, 12, 5, 13}, + {7934, 11, 1, 7, 2, 12, 12, 28, 15, 13, 12, 5, 13}, + {7831, 11, 1, 7, 2, 12, 12, 29, 15, 13, 12, 5, 13}, + {7733, 10, 1, 7, 3, 13, 12, 28, 15, 13, 12, 5, 13}, + {7638, 10, 1, 7, 2, 12, 12, 29, 15, 13, 12, 5, 13}, + {7547, 10, 1, 7, 2, 12, 12, 29, 15, 13, 12, 5, 13}, + {7459, 10, 1, 7, 2, 12, 12, 30, 15, 13, 12, 5, 13}, + {7374, 10, 2, 7, 3, 14, 13, 24, 15, 13, 12, 5, 13}, + {7291, 10, 2, 7, 3, 14, 13, 25, 15, 13, 12, 5, 13}, + {7212, 10, 2, 7, 3, 14, 13, 25, 15, 13, 12, 5, 13}, + {7135, 10, 2, 7, 3, 14, 13, 26, 15, 13, 12, 5, 13}, + {7061, 10, 2, 7, 3, 14, 13, 26, 15, 13, 12, 5, 13}, + {6988, 10, 1, 7, 3, 12, 14, 35, 15, 13, 12, 5, 13}, + {6918, 9, 1, 7, 3, 12, 14, 33, 15, 13, 12, 5, 13}, + {6850, 9, 1, 7, 3, 12, 14, 34, 15, 13, 12, 5, 13}, + {6784, 9, 1, 7, 2, 11, 14, 35, 15, 13, 12, 5, 13}, + {6720, 9, 1, 7, 2, 11, 14, 35, 15, 13, 12, 5, 13}, + {6658, 8, 2, 7, 3, 15, 13, 26, 15, 13, 12, 5, 13}, + {6597, 8, 2, 7, 2, 15, 13, 27, 15, 13, 12, 5, 13}, + {6539, 8, 2, 7, 2, 15, 13, 27, 15, 13, 12, 5, 13}, + {6482, 8, 2, 7, 2, 15, 13, 28, 15, 13, 12, 5, 13}, + {6427, 7, 2, 7, 3, 14, 13, 27, 15, 13, 12, 5, 13}, + {6373, 7, 2, 7, 3, 15, 13, 27, 15, 13, 12, 5, 13}, + {6321, 7, 2, 7, 3, 15, 13, 27, 15, 13, 12, 5, 13}, + {6270, 7, 2, 7, 3, 15, 13, 28, 15, 13, 12, 5, 13}, + {6222, 7, 2, 7, 3, 15, 13, 28, 15, 13, 12, 5, 13}, + {6174, 6, 2, 7, 3, 15, 13, 27, 15, 13, 12, 5, 13}, + {6128, 6, 2, 7, 3, 15, 13, 27, 15, 13, 12, 5, 13}, + {6083, 6, 2, 7, 3, 15, 13, 28, 15, 13, 12, 5, 13}, + {6040, 6, 2, 7, 3, 15, 13, 28, 15, 13, 12, 5, 13}, + {5997, 6, 2, 7, 3, 15, 13, 29, 15, 13, 12, 5, 13}, + }, { + {12605, 13, 1, 4, 2, 15, 12, 7, 15, 6, 13, 5, 14}, /* 80 MHz */ + {12245, 13, 1, 4, 2, 15, 12, 7, 15, 6, 13, 5, 14}, + {11906, 13, 1, 4, 2, 15, 12, 7, 15, 6, 13, 5, 14}, + {11588, 13, 1, 4, 2, 15, 12, 7, 14, 6, 14, 4, 14}, + {11288, 13, 1, 4, 2, 15, 12, 8, 15, 6, 13, 5, 14}, + {11007, 13, 1, 4, 2, 15, 12, 8, 14, 6, 13, 5, 14}, + {10742, 13, 1, 4, 2, 15, 12, 9, 15, 6, 13, 5, 14}, + {10492, 13, 1, 6, 2, 15, 12, 9, 14, 6, 13, 5, 14}, + {10258, 13, 1, 6, 2, 15, 12, 10, 15, 6, 13, 5, 14}, + {10036, 13, 1, 6, 2, 15, 12, 10, 15, 6, 13, 5, 14}, + {9827, 13, 1, 6, 2, 14, 12, 11, 15, 6, 13, 5, 14}, + {9631, 13, 1, 6, 2, 13, 12, 11, 15, 6, 13, 5, 14}, + {9445, 13, 1, 6, 2, 12, 12, 12, 15, 6, 13, 5, 14}, + {9269, 13, 1, 6, 2, 12, 12, 12, 15, 6, 13, 5, 14}, + {9103, 13, 1, 6, 2, 12, 12, 13, 15, 6, 13, 5, 14}, + {8946, 13, 1, 6, 2, 12, 12, 13, 15, 6, 13, 5, 14}, + {8797, 12, 1, 7, 2, 12, 12, 13, 15, 6, 13, 5, 14}, + {8655, 12, 1, 7, 2, 12, 12, 14, 15, 6, 13, 5, 14}, + {8520, 12, 1, 7, 2, 12, 12, 14, 15, 6, 13, 5, 14}, + {8392, 12, 1, 7, 2, 12, 12, 15, 15, 7, 13, 5, 14}, + {8269, 12, 1, 7, 2, 12, 12, 15, 15, 6, 13, 5, 14}, + {8153, 12, 1, 7, 2, 12, 12, 15, 15, 6, 13, 5, 14}, + {8041, 12, 1, 7, 2, 13, 12, 16, 15, 6, 13, 5, 14}, + {7934, 11, 1, 7, 2, 12, 12, 15, 15, 6, 13, 5, 14}, + {7831, 11, 1, 7, 2, 12, 12, 16, 15, 6, 13, 5, 14}, + {7733, 10, 1, 7, 3, 13, 12, 15, 15, 6, 13, 5, 14}, + {7638, 10, 1, 7, 2, 12, 12, 16, 15, 6, 13, 5, 14}, + {7547, 10, 1, 7, 2, 12, 12, 16, 15, 6, 13, 5, 14}, + {7459, 10, 1, 7, 2, 12, 12, 17, 15, 6, 13, 5, 14}, + {7374, 10, 2, 7, 3, 14, 13, 13, 15, 6, 13, 5, 14}, + {7291, 10, 2, 7, 3, 14, 13, 14, 15, 6, 13, 5, 14}, + {7212, 10, 2, 7, 3, 14, 13, 14, 15, 6, 13, 5, 14}, + {7135, 10, 2, 7, 3, 14, 13, 14, 15, 6, 13, 5, 14}, + {7061, 10, 2, 7, 3, 14, 13, 15, 15, 6, 13, 5, 14}, + {6988, 10, 1, 7, 3, 12, 14, 19, 15, 6, 13, 5, 14}, + {6918, 9, 2, 7, 3, 14, 13, 14, 15, 6, 13, 5, 14}, + {6850, 9, 2, 7, 3, 14, 13, 15, 15, 6, 13, 5, 14}, + {6784, 9, 2, 7, 2, 13, 13, 15, 15, 6, 13, 5, 14}, + {6720, 9, 2, 7, 2, 13, 13, 15, 15, 6, 13, 5, 14}, + {6658, 8, 2, 7, 3, 14, 13, 15, 15, 6, 13, 5, 14}, + {6597, 8, 2, 7, 2, 13, 13, 15, 15, 6, 13, 5, 14}, + {6539, 8, 2, 7, 2, 13, 13, 15, 15, 6, 13, 5, 14}, + {6482, 8, 2, 7, 2, 13, 13, 15, 15, 6, 13, 5, 14}, + {6427, 7, 2, 7, 3, 14, 13, 15, 15, 6, 13, 5, 14}, + {6373, 7, 2, 7, 3, 15, 13, 15, 15, 6, 13, 5, 14}, + {6321, 7, 2, 7, 3, 15, 13, 15, 15, 6, 13, 5, 14}, + {6270, 7, 2, 7, 3, 15, 13, 15, 15, 6, 13, 5, 14}, + {6222, 7, 2, 7, 3, 15, 13, 16, 15, 6, 13, 5, 14}, + {6174, 6, 2, 7, 3, 15, 13, 15, 15, 6, 13, 5, 14}, + {6128, 6, 2, 7, 3, 15, 13, 15, 15, 6, 13, 5, 14}, + {6083, 6, 2, 7, 3, 15, 13, 15, 15, 6, 13, 5, 14}, + {6040, 6, 2, 7, 3, 15, 13, 16, 15, 6, 13, 5, 14}, + {5997, 6, 2, 7, 3, 15, 13, 16, 15, 6, 13, 5, 14}, + } +}; + +static const struct SynthLUT SynthLUT_TDD[LUT_FTDD_ENT][SYNTH_LUT_SIZE] = { + { + {12605, 13, 1, 4, 2, 15, 12, 27, 12, 15, 12, 4, 13}, /* 40 MHz */ + {12245, 13, 1, 4, 2, 15, 12, 27, 12, 15, 12, 4, 13}, + {11906, 13, 1, 4, 2, 15, 12, 26, 11, 15, 12, 4, 13}, + {11588, 13, 1, 4, 2, 15, 12, 28, 12, 15, 12, 4, 13}, + {11288, 13, 1, 4, 2, 15, 12, 30, 12, 15, 12, 4, 13}, + {11007, 13, 1, 4, 2, 15, 12, 32, 12, 15, 12, 4, 13}, + {10742, 13, 1, 4, 2, 15, 12, 33, 12, 15, 12, 4, 13}, + {10492, 13, 1, 6, 2, 15, 12, 35, 12, 15, 12, 4, 13}, + {10258, 13, 1, 6, 2, 15, 12, 37, 12, 15, 12, 4, 13}, + {10036, 13, 1, 6, 2, 15, 12, 38, 12, 15, 12, 4, 13}, + {9827, 13, 1, 6, 2, 14, 12, 40, 12, 15, 12, 4, 13}, + {9631, 13, 1, 6, 2, 13, 12, 42, 12, 15, 12, 4, 13}, + {9445, 13, 1, 6, 2, 12, 12, 44, 12, 15, 12, 4, 13}, + {9269, 13, 1, 6, 2, 12, 12, 45, 12, 15, 12, 4, 13}, + {9103, 13, 1, 6, 2, 12, 12, 47, 12, 15, 12, 4, 13}, + {8946, 13, 1, 6, 2, 12, 12, 49, 12, 15, 12, 4, 13}, + {8797, 12, 1, 7, 2, 12, 12, 48, 12, 15, 12, 4, 13}, + {8655, 12, 1, 7, 2, 12, 12, 50, 12, 15, 12, 4, 13}, + {8520, 12, 1, 7, 2, 12, 12, 51, 12, 15, 12, 4, 13}, + {8392, 12, 1, 7, 2, 12, 12, 53, 12, 15, 12, 4, 13}, + {8269, 12, 1, 7, 2, 12, 12, 55, 12, 15, 12, 4, 13}, + {8153, 12, 1, 7, 2, 12, 12, 56, 12, 15, 12, 4, 13}, + {8041, 12, 1, 7, 2, 13, 12, 58, 12, 15, 12, 4, 13}, + {7934, 11, 1, 7, 2, 12, 12, 57, 12, 15, 12, 4, 13}, + {7831, 11, 1, 7, 2, 12, 12, 58, 12, 15, 12, 4, 13}, + {7733, 10, 1, 7, 3, 13, 12, 56, 12, 15, 12, 4, 13}, + {7638, 10, 1, 7, 2, 12, 12, 58, 12, 15, 12, 4, 13}, + {7547, 10, 1, 7, 2, 12, 12, 59, 12, 15, 12, 4, 13}, + {7459, 10, 1, 7, 2, 12, 12, 61, 12, 15, 12, 4, 13}, + {7374, 10, 2, 7, 3, 14, 13, 49, 12, 15, 12, 4, 13}, + {7291, 10, 2, 7, 3, 14, 13, 50, 12, 15, 12, 4, 13}, + {7212, 10, 2, 7, 3, 14, 13, 51, 12, 15, 12, 4, 13}, + {7135, 10, 2, 7, 3, 14, 13, 52, 12, 15, 12, 4, 13}, + {7061, 10, 2, 7, 3, 14, 13, 53, 12, 15, 12, 4, 13}, + {6988, 10, 1, 7, 3, 12, 14, 63, 11, 14, 12, 3, 13}, + {6918, 9, 2, 7, 3, 14, 13, 52, 12, 15, 12, 4, 13}, + {6850, 9, 2, 7, 3, 14, 13, 53, 12, 15, 12, 4, 13}, + {6784, 9, 2, 7, 2, 13, 13, 54, 12, 15, 12, 4, 13}, + {6720, 9, 2, 7, 2, 13, 13, 56, 12, 15, 12, 4, 13}, + {6658, 8, 2, 7, 3, 14, 13, 53, 12, 15, 12, 4, 13}, + {6597, 8, 2, 7, 2, 13, 13, 54, 12, 15, 12, 4, 13}, + {6539, 8, 2, 7, 2, 13, 13, 55, 12, 15, 12, 4, 13}, + {6482, 8, 2, 7, 2, 13, 13, 56, 12, 15, 12, 4, 13}, + {6427, 7, 2, 7, 3, 14, 13, 54, 12, 15, 12, 4, 13}, + {6373, 7, 2, 7, 3, 15, 13, 54, 12, 15, 12, 4, 13}, + {6321, 7, 2, 7, 3, 15, 13, 55, 12, 15, 12, 4, 13}, + {6270, 7, 2, 7, 3, 15, 13, 56, 12, 15, 12, 4, 13}, + {6222, 7, 2, 7, 3, 15, 13, 57, 12, 15, 12, 4, 13}, + {6174, 6, 2, 7, 3, 15, 13, 54, 12, 15, 12, 4, 13}, + {6128, 6, 2, 7, 3, 15, 13, 55, 12, 15, 12, 4, 13}, + {6083, 6, 2, 7, 3, 15, 13, 56, 12, 15, 12, 4, 13}, + {6040, 6, 2, 7, 3, 15, 13, 57, 12, 15, 12, 4, 13}, + {5997, 6, 2, 7, 3, 15, 13, 58, 12, 15, 12, 4, 13}, + }, { + {12605, 13, 1, 4, 2, 15, 12, 26, 11, 15, 11, 4, 13}, /* 60 MHz */ + {12245, 13, 1, 4, 2, 15, 12, 26, 11, 15, 11, 4, 13}, + {11906, 13, 1, 4, 2, 15, 12, 26, 12, 15, 11, 4, 12}, + {11588, 13, 1, 4, 2, 15, 12, 30, 12, 15, 11, 4, 12}, + {11288, 13, 1, 4, 2, 15, 12, 32, 12, 15, 10, 4, 12}, + {11007, 13, 1, 4, 2, 15, 12, 31, 12, 15, 11, 4, 12}, + {10742, 13, 1, 4, 2, 15, 12, 33, 12, 15, 10, 4, 12}, + {10492, 13, 1, 6, 2, 15, 12, 37, 12, 15, 10, 4, 12}, + {10258, 13, 1, 6, 2, 15, 12, 38, 12, 15, 11, 4, 13}, + {10036, 13, 1, 6, 2, 15, 12, 38, 12, 15, 10, 4, 12}, + {9827, 13, 1, 6, 2, 14, 12, 42, 12, 15, 11, 4, 12}, + {9631, 13, 1, 6, 2, 13, 12, 41, 12, 15, 11, 4, 12}, + {9445, 13, 1, 6, 2, 12, 12, 45, 12, 15, 11, 4, 12}, + {9269, 13, 1, 6, 2, 12, 12, 47, 12, 15, 11, 4, 12}, + {9103, 13, 1, 6, 2, 12, 12, 46, 12, 15, 11, 4, 12}, + {8946, 13, 1, 6, 2, 12, 12, 48, 12, 15, 10, 4, 12}, + {8797, 12, 1, 7, 2, 12, 12, 49, 12, 15, 11, 4, 13}, + {8655, 12, 1, 7, 2, 12, 12, 51, 12, 15, 11, 4, 12}, + {8520, 12, 1, 7, 2, 12, 12, 50, 12, 15, 11, 4, 12}, + {8392, 12, 1, 7, 2, 12, 12, 52, 12, 15, 10, 4, 12}, + {8269, 12, 1, 7, 2, 12, 12, 56, 12, 15, 10, 4, 12}, + {8153, 12, 1, 7, 2, 12, 12, 55, 12, 15, 11, 4, 12}, + {8041, 12, 1, 7, 2, 13, 12, 57, 12, 15, 10, 4, 12}, + {7934, 11, 1, 7, 2, 12, 12, 55, 12, 15, 11, 4, 12}, + {7831, 11, 1, 7, 2, 12, 12, 57, 12, 15, 10, 4, 12}, + {7733, 10, 1, 7, 3, 13, 12, 55, 12, 15, 11, 4, 12}, + {7638, 10, 1, 7, 2, 12, 12, 59, 12, 15, 10, 4, 12}, + {7547, 10, 1, 7, 2, 12, 12, 60, 12, 15, 11, 4, 12}, + {7459, 10, 1, 7, 2, 12, 12, 48, 12, 15, 11, 4, 12}, + {7374, 10, 2, 7, 3, 14, 13, 47, 12, 15, 11, 4, 13}, + {7291, 10, 2, 7, 3, 14, 13, 49, 12, 15, 10, 4, 12}, + {7212, 10, 2, 7, 3, 14, 13, 50, 12, 15, 10, 4, 12}, + {7135, 10, 2, 7, 3, 14, 13, 52, 12, 15, 11, 4, 13}, + {7061, 10, 2, 7, 3, 14, 13, 52, 12, 15, 11, 4, 12}, + {6988, 10, 1, 7, 3, 12, 14, 63, 11, 15, 11, 4, 13}, + {6918, 9, 1, 7, 3, 12, 14, 63, 11, 15, 11, 4, 13}, + {6850, 9, 1, 7, 3, 12, 14, 63, 11, 15, 11, 4, 13}, + {6784, 9, 1, 7, 2, 11, 14, 63, 11, 15, 11, 4, 13}, + {6720, 9, 1, 7, 2, 11, 14, 63, 11, 14, 11, 3, 13}, + {6658, 8, 1, 7, 3, 12, 14, 63, 11, 15, 11, 4, 13}, + {6597, 8, 1, 7, 2, 11, 14, 63, 11, 14, 11, 3, 13}, + {6539, 8, 1, 7, 2, 11, 14, 63, 10, 14, 11, 3, 13}, + {6482, 8, 1, 7, 2, 11, 14, 63, 10, 14, 11, 3, 13}, + {6427, 7, 2, 7, 3, 14, 13, 54, 12, 15, 10, 4, 12}, + {6373, 7, 2, 7, 3, 15, 13, 53, 12, 15, 11, 4, 12}, + {6321, 7, 2, 7, 3, 15, 13, 54, 12, 15, 11, 4, 12}, + {6270, 7, 2, 7, 3, 15, 13, 55, 12, 15, 11, 4, 12}, + {6222, 7, 2, 7, 3, 15, 13, 56, 12, 15, 11, 4, 12}, + {6174, 6, 2, 7, 3, 15, 13, 53, 12, 15, 11, 4, 12}, + {6128, 6, 2, 7, 3, 15, 13, 55, 12, 15, 11, 4, 12}, + {6083, 6, 2, 7, 3, 15, 13, 55, 12, 15, 10, 4, 12}, + {6040, 6, 2, 7, 3, 15, 13, 56, 12, 15, 10, 4, 12}, + {5997, 6, 2, 7, 3, 15, 13, 57, 12, 15, 10, 4, 12}, + }, { + {12605, 13, 1, 4, 2, 15, 12, 21, 12, 15, 11, 4, 13}, /* 80 MHz */ + {12245, 13, 1, 4, 2, 15, 12, 21, 12, 15, 11, 4, 13}, + {11906, 13, 1, 4, 2, 15, 12, 20, 11, 15, 11, 4, 13}, + {11588, 13, 1, 4, 2, 15, 12, 22, 12, 15, 11, 4, 12}, + {11288, 13, 1, 5, 2, 15, 12, 23, 12, 15, 11, 4, 13}, + {11007, 13, 1, 5, 2, 15, 12, 25, 12, 15, 10, 4, 12}, + {10742, 13, 1, 5, 2, 15, 12, 26, 12, 15, 11, 4, 13}, + {10492, 13, 1, 6, 2, 15, 12, 27, 11, 15, 11, 4, 13}, + {10258, 13, 1, 6, 2, 15, 12, 29, 12, 15, 10, 4, 12}, + {10036, 13, 1, 6, 2, 15, 12, 30, 12, 15, 11, 4, 12}, + {9827, 13, 1, 6, 2, 14, 12, 31, 12, 15, 11, 4, 13}, + {9631, 13, 1, 6, 2, 13, 12, 33, 12, 15, 10, 4, 12}, + {9445, 13, 1, 6, 2, 12, 12, 34, 12, 15, 11, 4, 12}, + {9269, 13, 1, 6, 2, 12, 12, 35, 12, 15, 11, 4, 13}, + {9103, 13, 1, 6, 2, 12, 12, 37, 12, 15, 10, 4, 12}, + {8946, 13, 1, 6, 2, 12, 12, 38, 12, 15, 11, 4, 12}, + {8797, 12, 1, 7, 2, 12, 12, 37, 12, 15, 11, 4, 13}, + {8655, 12, 1, 7, 2, 12, 12, 39, 12, 15, 11, 4, 12}, + {8520, 12, 1, 7, 2, 12, 12, 40, 12, 15, 11, 4, 12}, + {8392, 12, 1, 7, 2, 12, 12, 41, 12, 15, 11, 4, 13}, + {8269, 12, 1, 7, 2, 12, 12, 43, 12, 15, 10, 4, 12}, + {8153, 12, 1, 7, 2, 12, 12, 44, 12, 15, 11, 4, 12}, + {8041, 12, 1, 7, 2, 13, 12, 45, 12, 15, 11, 4, 12}, + {7934, 11, 1, 7, 2, 12, 12, 44, 12, 15, 11, 4, 12}, + {7831, 11, 1, 7, 2, 12, 12, 45, 12, 15, 11, 4, 13}, + {7733, 10, 1, 7, 3, 13, 12, 44, 12, 15, 11, 4, 12}, + {7638, 10, 1, 7, 2, 12, 12, 45, 12, 15, 11, 4, 12}, + {7547, 10, 1, 7, 2, 12, 12, 46, 12, 15, 11, 4, 12}, + {7459, 10, 1, 7, 2, 12, 12, 47, 12, 15, 11, 4, 13}, + {7374, 10, 2, 7, 3, 14, 13, 38, 12, 15, 11, 4, 12}, + {7291, 10, 2, 7, 3, 14, 13, 39, 12, 15, 10, 4, 12}, + {7212, 10, 2, 7, 3, 14, 13, 40, 12, 15, 10, 4, 12}, + {7135, 10, 2, 7, 3, 14, 13, 41, 12, 15, 10, 4, 12}, + {7061, 10, 2, 7, 3, 14, 13, 41, 12, 15, 11, 4, 13}, + {6988, 10, 1, 7, 3, 12, 14, 54, 12, 15, 11, 4, 12}, + {6918, 9, 2, 7, 3, 14, 13, 41, 12, 15, 10, 4, 12}, + {6850, 9, 2, 7, 3, 14, 13, 42, 12, 15, 10, 4, 12}, + {6784, 9, 2, 7, 2, 13, 13, 42, 12, 15, 11, 4, 13}, + {6720, 9, 2, 7, 2, 13, 13, 43, 12, 15, 11, 4, 13}, + {6658, 8, 2, 7, 3, 14, 13, 41, 12, 15, 11, 4, 13}, + {6597, 8, 2, 7, 2, 13, 13, 42, 12, 15, 11, 4, 12}, + {6539, 8, 2, 7, 2, 13, 13, 43, 12, 15, 11, 4, 12}, + {6482, 8, 2, 7, 2, 13, 13, 44, 12, 15, 11, 4, 12}, + {6427, 7, 2, 7, 3, 14, 13, 42, 12, 15, 10, 4, 12}, + {6373, 7, 2, 7, 3, 15, 13, 42, 12, 15, 11, 4, 13}, + {6321, 7, 2, 7, 3, 15, 13, 43, 12, 15, 11, 4, 12}, + {6270, 7, 2, 7, 3, 15, 13, 44, 12, 15, 11, 4, 12}, + {6222, 7, 2, 7, 3, 15, 13, 45, 12, 15, 10, 4, 12}, + {6174, 6, 2, 7, 3, 15, 13, 42, 12, 15, 11, 4, 13}, + {6128, 6, 2, 7, 3, 15, 13, 43, 12, 15, 11, 4, 12}, + {6083, 6, 2, 7, 3, 15, 13, 44, 12, 15, 10, 4, 12}, + {6040, 6, 2, 7, 3, 15, 13, 44, 12, 15, 11, 4, 13}, + {5997, 6, 2, 7, 3, 15, 13, 45, 12, 15, 11, 4, 12}, + } +}; + +/* Rx Gain Tables */ + +#define SIZE_FULL_TABLE 77 + +static const uint8_t full_gain_table[RXGAIN_TBLS_END][SIZE_FULL_TABLE][3] = { + { /* 800 MHz */ + {0x00, 0x00, 0x20}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, + {0x00, 0x01, 0x00}, {0x00, 0x02, 0x00}, {0x00, 0x03, 0x00}, + {0x00, 0x04, 0x00}, {0x00, 0x05, 0x00}, {0x01, 0x03, 0x20}, + {0x01, 0x04, 0x00}, {0x01, 0x05, 0x00}, {0x01, 0x06, 0x00}, + {0x01, 0x07, 0x00}, {0x01, 0x08, 0x00}, {0x01, 0x09, 0x00}, + {0x01, 0x0A, 0x00}, {0x01, 0x0B, 0x00}, {0x01, 0x0C, 0x00}, + {0x01, 0x0D, 0x00}, {0x01, 0x0E, 0x00}, {0x02, 0x09, 0x20}, + {0x02, 0x0A, 0x00}, {0x02, 0x0B, 0x00}, {0x02, 0x0C, 0x00}, + {0x02, 0x0D, 0x00}, {0x02, 0x0E, 0x00}, {0x02, 0x0F, 0x00}, + {0x02, 0x10, 0x00}, {0x02, 0x2B, 0x20}, {0x02, 0x2C, 0x00}, + {0x04, 0x28, 0x20}, {0x04, 0x29, 0x00}, {0x04, 0x2A, 0x00}, + {0x04, 0x2B, 0x00}, {0x24, 0x20, 0x20}, {0x24, 0x21, 0x00}, + {0x44, 0x20, 0x20}, {0x44, 0x21, 0x00}, {0x44, 0x22, 0x00}, + {0x44, 0x23, 0x00}, {0x44, 0x24, 0x00}, {0x44, 0x25, 0x00}, + {0x44, 0x26, 0x00}, {0x44, 0x27, 0x00}, {0x44, 0x28, 0x00}, + {0x44, 0x29, 0x00}, {0x44, 0x2A, 0x00}, {0x44, 0x2B, 0x00}, + {0x44, 0x2C, 0x00}, {0x44, 0x2D, 0x00}, {0x44, 0x2E, 0x00}, + {0x44, 0x2F, 0x00}, {0x44, 0x30, 0x00}, {0x44, 0x31, 0x00}, + {0x44, 0x32, 0x00}, {0x64, 0x2E, 0x20}, {0x64, 0x2F, 0x00}, + {0x64, 0x30, 0x00}, {0x64, 0x31, 0x00}, {0x64, 0x32, 0x00}, + {0x64, 0x33, 0x00}, {0x64, 0x34, 0x00}, {0x64, 0x35, 0x00}, + {0x64, 0x36, 0x00}, {0x64, 0x37, 0x00}, {0x64, 0x38, 0x00}, + {0x65, 0x38, 0x20}, {0x66, 0x38, 0x20}, {0x67, 0x38, 0x20}, + {0x68, 0x38, 0x20}, {0x69, 0x38, 0x20}, {0x6A, 0x38, 0x20}, + {0x6B, 0x38, 0x20}, {0x6C, 0x38, 0x20}, {0x6D, 0x38, 0x20}, + {0x6E, 0x38, 0x20}, {0x6F, 0x38, 0x20} + },{ /* 2300 MHz */ + {0x00, 0x00, 0x20}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, + {0x00, 0x01, 0x00}, {0x00, 0x02, 0x00}, {0x00, 0x03, 0x00}, + {0x00, 0x04, 0x00}, {0x00, 0x05, 0x00}, {0x01, 0x03, 0x20}, + {0x01, 0x04, 0x00}, {0x01, 0x05, 0x00}, {0x01, 0x06, 0x00}, + {0x01, 0x07, 0x00}, {0x01, 0x08, 0x00}, {0x01, 0x09, 0x00}, + {0x01, 0x0A, 0x00}, {0x01, 0x0B, 0x00}, {0x01, 0x0C, 0x00}, + {0x01, 0x0D, 0x00}, {0x01, 0x0E, 0x00}, {0x02, 0x09, 0x20}, + {0x02, 0x0A, 0x00}, {0x02, 0x0B, 0x00}, {0x02, 0x0C, 0x00}, + {0x02, 0x0D, 0x00}, {0x02, 0x0E, 0x00}, {0x02, 0x0F, 0x00}, + {0x02, 0x10, 0x00}, {0x02, 0x2B, 0x20}, {0x02, 0x2C, 0x00}, + {0x04, 0x27, 0x20}, {0x04, 0x28, 0x00}, {0x04, 0x29, 0x00}, + {0x04, 0x2A, 0x00}, {0x04, 0x2B, 0x00}, {0x24, 0x21, 0x20}, + {0x24, 0x22, 0x00}, {0x44, 0x20, 0x20}, {0x44, 0x21, 0x00}, + {0x44, 0x22, 0x00}, {0x44, 0x23, 0x00}, {0x44, 0x24, 0x00}, + {0x44, 0x25, 0x00}, {0x44, 0x26, 0x00}, {0x44, 0x27, 0x00}, + {0x44, 0x28, 0x00}, {0x44, 0x29, 0x00}, {0x44, 0x2A, 0x00}, + {0x44, 0x2B, 0x00}, {0x44, 0x2C, 0x00}, {0x44, 0x2D, 0x00}, + {0x44, 0x2E, 0x00}, {0x44, 0x2F, 0x00}, {0x44, 0x30, 0x00}, + {0x44, 0x31, 0x00}, {0x64, 0x2E, 0x20}, {0x64, 0x2F, 0x00}, + {0x64, 0x30, 0x00}, {0x64, 0x31, 0x00}, {0x64, 0x32, 0x00}, + {0x64, 0x33, 0x00}, {0x64, 0x34, 0x00}, {0x64, 0x35, 0x00}, + {0x64, 0x36, 0x00}, {0x64, 0x37, 0x00}, {0x64, 0x38, 0x00}, + {0x65, 0x38, 0x20}, {0x66, 0x38, 0x20}, {0x67, 0x38, 0x20}, + {0x68, 0x38, 0x20}, {0x69, 0x38, 0x20}, {0x6A, 0x38, 0x20}, + {0x6B, 0x38, 0x20}, {0x6C, 0x38, 0x20}, {0x6D, 0x38, 0x20}, + {0x6E, 0x38, 0x20}, {0x6F, 0x38, 0x20}, + },{ /* 5500 MHz */ + {0x00, 0x00, 0x20}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00, 0x01, 0x00}, + {0x00, 0x02, 0x00}, {0x00, 0x03, 0x00}, {0x01, 0x01, 0x20}, + {0x01, 0x02, 0x00}, {0x01, 0x03, 0x00}, {0x01, 0x04, 0x20}, + {0x01, 0x05, 0x00}, {0x01, 0x06, 0x00}, {0x01, 0x07, 0x00}, + {0x01, 0x08, 0x00}, {0x01, 0x09, 0x00}, {0x01, 0x0A, 0x00}, + {0x01, 0x0B, 0x00}, {0x01, 0x0C, 0x00}, {0x02, 0x08, 0x20}, + {0x02, 0x09, 0x00}, {0x02, 0x0A, 0x00}, {0x02, 0x0B, 0x20}, + {0x02, 0x0C, 0x00}, {0x02, 0x0D, 0x00}, {0x02, 0x0E, 0x00}, + {0x02, 0x0F, 0x00}, {0x02, 0x2A, 0x20}, {0x02, 0x2B, 0x00}, + {0x04, 0x27, 0x20}, {0x04, 0x28, 0x00}, {0x04, 0x29, 0x00}, + {0x04, 0x2A, 0x00}, {0x04, 0x2B, 0x00}, {0x04, 0x2C, 0x00}, + {0x04, 0x2D, 0x00}, {0x24, 0x20, 0x20}, {0x24, 0x21, 0x00}, + {0x24, 0x22, 0x00}, {0x44, 0x20, 0x20}, {0x44, 0x21, 0x00}, + {0x44, 0x22, 0x00}, {0x44, 0x23, 0x00}, {0x44, 0x24, 0x00}, + {0x44, 0x25, 0x00}, {0x44, 0x26, 0x00}, {0x44, 0x27, 0x00}, + {0x44, 0x28, 0x00}, {0x44, 0x29, 0x00}, {0x44, 0x2A, 0x00}, + {0x44, 0x2B, 0x00}, {0x44, 0x2C, 0x00}, {0x44, 0x2D, 0x00}, + {0x44, 0x2E, 0x00}, {0x64, 0x2E, 0x20}, {0x64, 0x2F, 0x00}, + {0x64, 0x30, 0x00}, {0x64, 0x31, 0x00}, {0x64, 0x32, 0x00}, + {0x64, 0x33, 0x00}, {0x64, 0x34, 0x00}, {0x64, 0x35, 0x00}, + {0x64, 0x36, 0x00}, {0x64, 0x37, 0x00}, {0x64, 0x38, 0x00}, + {0x65, 0x38, 0x20}, {0x66, 0x38, 0x20}, {0x67, 0x38, 0x20}, + {0x68, 0x38, 0x20}, {0x69, 0x38, 0x20}, {0x6A, 0x38, 0x20}, + {0x6B, 0x38, 0x20}, {0x6C, 0x38, 0x20}, {0x6D, 0x38, 0x20}, + {0x6E, 0x38, 0x20}, {0x6F, 0x38, 0x20} + } +}; + +static const int8_t full_gain_table_abs_gain[RXGAIN_TBLS_END][SIZE_FULL_TABLE] = { + { /* 800 MHz */ + -1, -1, -1, 0, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73 + }, { /* 2300 MHz */ + -3, -3, -3, -2, -1, 0, 1, 2, + 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, 71 + }, { /* 5500 MHz */ + -10, -10, -10, -10, -10, -9, -8, -7, + -6, -5, -4, -3, -2, -1, 0, 1, + 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62 + } +}; + +#define SIZE_SPLIT_TABLE 41 + +#if HAVE_SPLIT_GAIN_TABLE +static const uint8_t split_gain_table[RXGAIN_TBLS_END][SIZE_SPLIT_TABLE][3] = { + { /* 800 MHz */ + {0x00, 0x18, 0x20}, {0x00, 0x18, 0x00}, {0x00, 0x18, 0x00}, + {0x00, 0x18, 0x00}, {0x00, 0x18, 0x00}, {0x00, 0x18, 0x00}, + {0x00, 0x18, 0x20}, {0x01, 0x18, 0x20}, {0x02, 0x18, 0x20}, + {0x04, 0x18, 0x20}, {0x04, 0x38, 0x20}, {0x05, 0x38, 0x20}, + {0x06, 0x38, 0x20}, {0x07, 0x38, 0x20}, {0x08, 0x38, 0x20}, + {0x09, 0x38, 0x20}, {0x0A, 0x38, 0x20}, {0x0B, 0x38, 0x20}, + {0x0C, 0x38, 0x20}, {0x0D, 0x38, 0x20}, {0x0E, 0x38, 0x20}, + {0x0F, 0x38, 0x20}, {0x24, 0x38, 0x20}, {0x25, 0x38, 0x20}, + {0x44, 0x38, 0x20}, {0x45, 0x38, 0x20}, {0x46, 0x38, 0x20}, + {0x47, 0x38, 0x20}, {0x48, 0x38, 0x20}, {0x64, 0x38, 0x20}, + {0x65, 0x38, 0x20}, {0x66, 0x38, 0x20}, {0x67, 0x38, 0x20}, + {0x68, 0x38, 0x20}, {0x69, 0x38, 0x20}, {0x6A, 0x38, 0x20}, + {0x6B, 0x38, 0x20}, {0x6C, 0x38, 0x20}, {0x6D, 0x38, 0x20}, + {0x6E, 0x38, 0x20}, {0x6F, 0x38, 0x20}, + },{ /* 2300 MHz */ + {0x00, 0x18, 0x20}, {0x00, 0x18, 0x00}, {0x00, 0x18, 0x00}, + {0x00, 0x18, 0x00}, {0x00, 0x18, 0x00}, {0x00, 0x18, 0x00}, + {0x00, 0x18, 0x00}, {0x00, 0x18, 0x20}, {0x01, 0x18, 0x20}, + {0x02, 0x18, 0x20}, {0x04, 0x18, 0x20}, {0x04, 0x38, 0x20}, + {0x05, 0x38, 0x20}, {0x06, 0x38, 0x20}, {0x07, 0x38, 0x20}, + {0x08, 0x38, 0x20}, {0x09, 0x38, 0x20}, {0x0A, 0x38, 0x20}, + {0x0B, 0x38, 0x20}, {0x0C, 0x38, 0x20}, {0x0D, 0x38, 0x20}, + {0x0E, 0x38, 0x20}, {0x0F, 0x38, 0x20}, {0x25, 0x38, 0x20}, + {0x26, 0x38, 0x20}, {0x44, 0x38, 0x20}, {0x45, 0x38, 0x20}, + {0x46, 0x38, 0x20}, {0x47, 0x38, 0x20}, {0x64, 0x38, 0x20}, + {0x65, 0x38, 0x20}, {0x66, 0x38, 0x20}, {0x67, 0x38, 0x20}, + {0x68, 0x38, 0x20}, {0x69, 0x38, 0x20}, {0x6A, 0x38, 0x20}, + {0x6B, 0x38, 0x20}, {0x6C, 0x38, 0x20}, {0x6D, 0x38, 0x20}, + {0x6E, 0x38, 0x20}, {0x6F, 0x38, 0x20}, + },{ /* 5500 MHz */ + {0x00, 0x18, 0x20}, {0x00, 0x18, 0x00}, {0x00, 0x18, 0x00}, + {0x00, 0x18, 0x00}, {0x00, 0x18, 0x00}, {0x00, 0x18, 0x00}, + {0x00, 0x18, 0x00}, {0x00, 0x18, 0x00}, {0x00, 0x18, 0x00}, + {0x00, 0x18, 0x00}, {0x01, 0x18, 0x20}, {0x02, 0x18, 0x20}, + {0x04, 0x18, 0x20}, {0x04, 0x38, 0x20}, {0x05, 0x38, 0x20}, + {0x06, 0x38, 0x20}, {0x07, 0x38, 0x20}, {0x08, 0x38, 0x20}, + {0x09, 0x38, 0x20}, {0x0A, 0x38, 0x20}, {0x0B, 0x38, 0x20}, + {0x0C, 0x38, 0x20}, {0x0D, 0x38, 0x20}, {0x0E, 0x38, 0x20}, + {0x0F, 0x38, 0x20}, {0x62, 0x38, 0x20}, {0x25, 0x38, 0x20}, + {0x26, 0x38, 0x20}, {0x44, 0x38, 0x20}, {0x64, 0x38, 0x20}, + {0x65, 0x38, 0x20}, {0x66, 0x38, 0x20}, {0x67, 0x38, 0x20}, + {0x68, 0x38, 0x20}, {0x69, 0x38, 0x20}, {0x6A, 0x38, 0x20}, + {0x6B, 0x38, 0x20}, {0x6C, 0x38, 0x20}, {0x6D, 0x38, 0x20}, + {0x6E, 0x38, 0x20}, {0x6F, 0x38, 0x20}, + } +}; + +static const uint8_t +split_gain_table_abs_gain[RXGAIN_TBLS_END][SIZE_SPLIT_TABLE] = { + { /* 800 MHz */ + -1, -1, -1, -1, -1, -1, -1, 2, + 8, 13, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, + 49 + }, { /* 2300 MHz */ + -3, -3, -3, -3, -3, -3, -3, -3, + 0, 6, 12, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, + 47 + }, { /* 5500 MHz */ + -10, -10, -10, -10, -10, -10, -10, -10, + -10, -10, -7, -2, 3, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, + 20, 22, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, + 38 + } +}; +#endif + +struct gain_table_info ad9361_adi_gt_info[] = { + { + .start = 0, + .end = 1300000000ULL, + .max_index = SIZE_FULL_TABLE, + .abs_gain_tbl = (int8_t *) &full_gain_table_abs_gain[TBL_200_1300_MHZ], + .tab = (uint8_t (*)[3]) full_gain_table[TBL_200_1300_MHZ], + },{ + .start = 1300000000ULL, + .end = 4000000000ULL, + .max_index = SIZE_FULL_TABLE, + .abs_gain_tbl = (int8_t *) &full_gain_table_abs_gain[TBL_1300_4000_MHZ], + .tab = (uint8_t (*)[3]) full_gain_table[TBL_1300_4000_MHZ], + },{ + .start = 4000000000ULL, + .end = 6000000000ULL, + .max_index = SIZE_FULL_TABLE, + .abs_gain_tbl = (int8_t *) &full_gain_table_abs_gain[TBL_4000_6000_MHZ], + .tab = (uint8_t (*)[3]) full_gain_table[TBL_4000_6000_MHZ], +#if HAVE_SPLIT_GAIN_TABLE + },{ + .start = 0, + .end = 1300000000ULL, + .max_index = SIZE_SPLIT_TABLE, + .split_table = 1, + .abs_gain_tbl = (int8_t *) &split_gain_table_abs_gain[TBL_200_1300_MHZ], + .tab = (uint8_t (*)[3]) split_gain_table[TBL_200_1300_MHZ], + },{ + .start = 1300000000ULL, + .end = 4000000000ULL, + .max_index = SIZE_SPLIT_TABLE, + .split_table = 1, + .abs_gain_tbl = (int8_t *) &split_gain_table_abs_gain[TBL_1300_4000_MHZ], + .tab = (uint8_t (*)[3]) split_gain_table[TBL_1300_4000_MHZ], + },{ + .start = 4000000000ULL, + .end = 6000000000ULL, + .max_index = SIZE_SPLIT_TABLE, + .split_table = 1, + .abs_gain_tbl = (int8_t *) &split_gain_table_abs_gain[TBL_4000_6000_MHZ], + .tab = (uint8_t (*)[3]) split_gain_table[TBL_4000_6000_MHZ], +#endif + },{ + .start = 0, + .end = 0, + .max_index = 0, + .split_table = 0, + .abs_gain_tbl = NULL, + .tab = NULL, + }, /* Don't Remove */ +}; + +/* Mixer GM Sub-table */ + +static const uint8_t gm_st_gain[16]= {0x78, 0x74, 0x70, 0x6C, 0x68, 0x64, 0x60, + 0x5C, 0x58, 0x54, 0x50, 0x4C, 0x48, 0x30, 0x18, 0x0}; +static const uint8_t gm_st_ctrl[16]= {0x0, 0xD, 0x15, 0x1B, 0x21, 0x25, 0x29, + 0x2C, 0x2F, 0x31, 0x33, 0x34, 0x35, 0x3A, 0x3D, 0x3E}; + + +static const int8_t lna_table[RXGAIN_TBLS_END][4] = { + {5, 17, 19, 24}, {3, 14, 17, 21}, {-4, 10, 13, 14}}; +static const int8_t tia_table[] = {-6, 0}; +static const int8_t mixer_table[RXGAIN_TBLS_END][16] = { + {0, 3, 9, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25}, + {0, 3, 9, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26}, + {0, 3, 8, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24} +}; + +static const uint32_t gain_step_calib_reg_val[4][5] = { + {0xC0, 0x2E, 0x10, 0x06, 0x00}, // LO Frequency Range: 600 to 1300 MHz + {0xC0, 0x2C, 0x10, 0x06, 0x00}, // LO Frequency Range: 1300 to 3300 MHz + {0xB8, 0x2C, 0x10, 0x06, 0x00}, // LO Frequency Range: 2700 to 4100 MHz + {0xA0, 0x24, 0x10, 0x06, 0x00}, // LO Frequency Range: 4000 to 6000 MHz +}; + +/******************************************************************************/ +/********************** Macros and Constants Definitions **********************/ +/******************************************************************************/ +const char *ad9361_ensm_states[] = { + "sleep", "", "", "", "", "alert", "tx", "tx flush", + "rx", "rx_flush", "fdd", "fdd_flush" +}; + +/** + * SPI multiple bytes register read. + * @param spi + * @param reg The register address. + * @param rbuf The data buffer. + * @param num The number of bytes to read. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_spi_readm(struct spi_desc *spi, uint32_t reg, + uint8_t *rbuf, uint32_t num) +{ + int32_t ret = 0; + uint16_t cmd; + uint8_t *rbuffer; + if (num > MAX_MBYTE_SPI) + return -EINVAL; + + cmd = AD_READ | AD_CNT(num) | AD_ADDR(reg); + rbuffer = malloc(num + 2); + if(!rbuffer) + return -ENOMEM; + rbuffer[0] = cmd >> 8; + rbuffer[1] = cmd & 0xFF; + ret = spi_write_and_read(spi, &rbuffer[0], 2 + num); + + if (ret < 0) + dev_err(&spi->dev, "Read Error %"PRId32, ret); + else + memcpy(rbuf, &rbuffer[2], num); + + free(rbuffer); +#ifdef _DEBUG + { + int32_t i; + for (i = 0; i < num; i++) + dev_dbg(&spi->dev, "%s: reg 0x%"PRIX32" val 0x%X", + __func__, reg--, rbuf[i]); + } +#endif + + return ret; +} + +/** + * SPI register read. + * @param spi + * @param reg The register address. + * @return The register value or negative error code in case of failure. + */ +int32_t ad9361_spi_read(struct spi_desc *spi, uint32_t reg) +{ + uint8_t buf; + int32_t ret; + + ret = ad9361_spi_readm(spi, reg, &buf, 1); + if (ret < 0) + return ret; + + return buf; +} + +/** + * SPI register bits read. + * @param spi + * @param reg The register address. + * @param mask The bits mask. + * @param offset The mask offset. + * @return The bits value or negative error code in case of failure. + */ +static int32_t __ad9361_spi_readf(struct spi_desc *spi, uint32_t reg, + uint32_t mask, uint32_t offset) +{ + uint8_t buf; + int32_t ret; + + if (!mask) + return -EINVAL; + + ret = ad9361_spi_readm(spi, reg, &buf, 1); + if (ret < 0) + return ret; + + buf &= mask; + buf >>= offset; + + return buf; +} + +/** + * SPI register bits read. + * @param spi + * @param reg The register address. + * @param mask The bits mask. + * @return The bits value or negative error code in case of failure. + */ +#define ad9361_spi_readf(spi, reg, mask) \ + __ad9361_spi_readf(spi, reg, mask, find_first_bit(mask)) + +/** + * SPI register write. + * @param spi + * @param reg The register address. + * @param val The value of the register. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_spi_write(struct spi_desc *spi, + uint32_t reg, uint32_t val) +{ + uint8_t buf[3]; + int32_t ret; + uint16_t cmd; + + cmd = AD_WRITE | AD_CNT(1) | AD_ADDR(reg); + buf[0] = cmd >> 8; + buf[1] = cmd & 0xFF; + buf[2] = val; + + ret = spi_write_and_read(spi, buf, 3); + if (ret < 0) { + dev_err(&spi->dev, "Write Error %"PRId32, ret); + return ret; + } + +#ifdef _DEBUG + dev_dbg(&spi->dev, "%s: reg 0x%"PRIX32" val 0x%X", __func__, reg, buf[2]); +#endif + + return 0; +} + +/** + * SPI register bits write. + * @param spi + * @param reg The register address. + * @param mask The bits mask. + * @param offset The mask offset. + * @param val The bits value. + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t __ad9361_spi_writef(struct spi_desc *spi, uint32_t reg, + uint32_t mask, uint32_t offset, uint32_t val) +{ + uint8_t buf; + int32_t ret; + + if (!mask) + return -EINVAL; + + ret = ad9361_spi_readm(spi, reg, &buf, 1); + if (ret < 0) + return ret; + + buf &= ~mask; + buf |= ((val << offset) & mask); + + return ad9361_spi_write(spi, reg, buf); +} + +/** + * SPI register bits write. + * @param spi + * @param reg The register address. + * @param mask The bits mask. + * @param val The bits value. + * @return 0 in case of success, negative error code otherwise. + */ +#define ad9361_spi_writef(spi, reg, mask, val) \ + __ad9361_spi_writef(spi, reg, mask, find_first_bit(mask), val) + +/** + * SPI multiple bytes register write. + * @param spi + * @param reg The register address. + * @param tbuf The data buffer. + * @param num The number of bytes to read. + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t ad9361_spi_writem(struct spi_desc *spi, + uint32_t reg, uint8_t *tbuf, uint32_t num) +{ + uint8_t buf[10]; + int32_t ret; + uint16_t cmd; + + if (num > MAX_MBYTE_SPI) + return -EINVAL; + + cmd = AD_WRITE | AD_CNT(num) | AD_ADDR(reg); + buf[0] = cmd >> 8; + buf[1] = cmd & 0xFF; + +#ifndef ALTERA_PLATFORM + memcpy(&buf[2], tbuf, num); +#else + int32_t i; + for (i = 0; i < num; i++) + buf[2 + i] = tbuf[i]; +#endif + ret = spi_write_and_read(spi, buf, num + 2); + if (ret < 0) { + dev_err(&spi->dev, "Write Error %"PRId32, ret); + return ret; + } + +#ifdef _DEBUG + { + int32_t i; + for (i = 0; i < num; i++) + dev_dbg(&spi->dev, "Reg 0x%"PRIX32" val 0x%X", reg--, tbuf[i]); + } +#endif + + return 0; +} + +/** + * Validate RF BW frequency. + * @param phy The AD9361 state structure. + * @param bw The RF BW frequency. + * @return The validated RF BW frequency. + */ +uint32_t ad9361_validate_rf_bw(struct ad9361_rf_phy *phy, uint32_t bw) +{ + switch (phy->dev_sel) { + case ID_AD9363A: + return clamp_t(uint32_t, bw, 200000UL, 20000000UL); + default: + return clamp_t(uint32_t, bw, 200000UL, 56000000UL); + } +} + +/** + * Validate RF PLL frequency. + * @param phy The AD9361 state structure. + * @param is_tx TX enabled. + * @param freq The RF PLL frequency. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_validate_rfpll(struct ad9361_rf_phy *phy, bool is_tx, + uint64_t freq) +{ + switch (phy->dev_sel) { + case ID_AD9363A: + if (freq > AD9363A_MAX_CARRIER_FREQ_HZ || + freq < AD9363A_MIN_CARRIER_FREQ_HZ) + return -EINVAL; + break; + default: + if (freq > MAX_CARRIER_FREQ_HZ || freq < (is_tx ? + MIN_TX_CARRIER_FREQ_HZ : MIN_RX_CARRIER_FREQ_HZ)) + return -EINVAL; + } + + return 0; +} + +/** + * Find optimal value. + * @param field + * @param size + * @param ret_start + * @return The optimal delay in case of success, negative error code otherwise. + */ +int32_t ad9361_find_opt(uint8_t *field, uint32_t size, uint32_t *ret_start) +{ + int32_t i, cnt = 0, max_cnt = 0, start, max_start = 0; + + for(i = 0, start = -1; i < (int64_t)size; i++) { + if (field[i] == 0) { + if (start == -1) + start = i; + cnt++; + } else { + if (cnt > max_cnt) { + max_cnt = cnt; + max_start = start; + } + start = -1; + cnt = 0; + } + } + + if (cnt > max_cnt) { + max_cnt = cnt; + max_start = start; + } + + *ret_start = max_start; + + return max_cnt; +} + +/** + * Select the channel mapping in 1rx1tx mode. + * @param phy The AD9361 state structure. + * @param tx TX + * @param channel Channel + * @return The channel number. + */ +int32_t ad9361_1rx1tx_channel_map(struct ad9361_rf_phy *phy, bool tx, + int32_t channel) +{ + uint32_t map; + + if (phy->pdata->rx2tx2) + return channel; + + if (tx) + map = phy->pdata->rx1tx1_mode_use_tx_num; + else + map = phy->pdata->rx1tx1_mode_use_rx_num; + + if (map == 2) + return channel + 1; + + return channel; +} + +/** + * AD9361 Device Reset + * @param phy The AD9361 state structure. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_reset(struct ad9361_rf_phy *phy) +{ + if (phy->gpio_desc_resetb) { + gpio_set_value(phy->gpio_desc_resetb, 0); + mdelay(1); + gpio_set_value(phy->gpio_desc_resetb, 1); + mdelay(1); + dev_dbg(&phy->spi->dev, "%s: by GPIO", __func__); + return 0; + } + + /* SPI Soft Reset was removed from the register map, since it doesn't + * work reliably. Without a prober HW reset randomness may happen. + * Please specify a RESET GPIO. + */ + + ad9361_spi_write(phy->spi, REG_SPI_CONF, SOFT_RESET | _SOFT_RESET); + ad9361_spi_write(phy->spi, REG_SPI_CONF, 0x0); + dev_err(&phy->spi->dev, + "%s: by SPI, this may cause unpredicted behavior!", __func__); + + return -ENODEV; +} + +/** + * Enable/disable the desired TX channel. + * @param phy The AD9361 state structure. + * @param tx_if The desired channel number [1, 2]. + * @param enable Enable/disable option. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_en_dis_tx(struct ad9361_rf_phy *phy, uint32_t tx_if, + uint32_t enable) +{ + if ((tx_if & enable) > 1 && AD9364_DEVICE && enable) + return -EINVAL; + + return ad9361_spi_writef(phy->spi, REG_TX_ENABLE_FILTER_CTRL, + TX_CHANNEL_ENABLE(tx_if), enable); +} + +/** + * Enable/disable the desired RX channel. + * @param phy The AD9361 state structure. + * @param rx_if The desired channel number [1, 2]. + * @param enable Enable/disable option. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_en_dis_rx(struct ad9361_rf_phy *phy, uint32_t rx_if, + uint32_t enable) +{ + if ((rx_if & enable) > 1 && AD9364_DEVICE && enable) + return -EINVAL; + + return ad9361_spi_writef(phy->spi, REG_RX_ENABLE_FILTER_CTRL, + RX_CHANNEL_ENABLE(rx_if), enable); +} + +/** + * Loopback works only TX1->RX1 or RX2->RX2. + * @param phy The AD9361 state structure. + * @param enable Enable. + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t ad9361_int_loopback_fix_ch_cross(struct ad9361_rf_phy *phy, + bool enable) +{ + /* Loopback works only TX1->RX1 or RX2->RX2 */ + if (!phy->pdata->rx2tx2 && phy->pdata->rx1tx1_mode_use_rx_num != + phy->pdata->rx1tx1_mode_use_tx_num) + return ad9361_en_dis_tx(phy, TX_1 | TX_2, + enable ? phy->pdata->rx1tx1_mode_use_rx_num : + phy->pdata->rx1tx1_mode_use_tx_num); + + return 0; +} + +/** + * BIST loopback mode. + * @param phy The AD9361 state structure. + * @param mode BIST loopback mode. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_bist_loopback(struct ad9361_rf_phy *phy, int32_t mode) +{ + uint32_t sp_hd, reg; + + dev_dbg(&phy->spi->dev, "%s: mode %"PRId32, __func__, mode); + + reg = ad9361_spi_read(phy->spi, REG_OBSERVE_CONFIG); + + phy->bist_loopback_mode = mode; + + switch (mode) { + case 0: + ad9361_hdl_loopback(phy, false); + ad9361_int_loopback_fix_ch_cross(phy, false); + reg &= ~(DATA_PORT_SP_HD_LOOP_TEST_OE | + DATA_PORT_LOOP_TEST_ENABLE); + return ad9361_spi_write(phy->spi, REG_OBSERVE_CONFIG, reg); + case 1: + /* loopback (AD9361 internal) TX->RX */ + ad9361_hdl_loopback(phy, false); + ad9361_int_loopback_fix_ch_cross(phy, true); + sp_hd = ad9361_spi_read(phy->spi, REG_PARALLEL_PORT_CONF_3); + if ((sp_hd & SINGLE_PORT_MODE) && (sp_hd & HALF_DUPLEX_MODE)) + reg |= DATA_PORT_SP_HD_LOOP_TEST_OE; + else + reg &= ~DATA_PORT_SP_HD_LOOP_TEST_OE; + + reg |= DATA_PORT_LOOP_TEST_ENABLE; + + return ad9361_spi_write(phy->spi, REG_OBSERVE_CONFIG, reg); + case 2: + /* loopback (FPGA internal) RX->TX */ + ad9361_hdl_loopback(phy, true); + ad9361_int_loopback_fix_ch_cross(phy, false); + reg &= ~(DATA_PORT_SP_HD_LOOP_TEST_OE | + DATA_PORT_LOOP_TEST_ENABLE); + return ad9361_spi_write(phy->spi, REG_OBSERVE_CONFIG, reg); + default: + return -EINVAL; + } +} + +/** + * Get BIST loopback mode. + * @param phy The AD9361 state structure. + * @param mode BIST loopback mode. + * @return 0 in case of success, negative error code otherwise. + */ +void ad9361_get_bist_loopback(struct ad9361_rf_phy *phy, int32_t *mode) +{ + *mode = phy->bist_loopback_mode; +} + +/** + * BIST mode. + * @param phy The AD9361 state structure. + * @param mode Bist mode. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_bist_prbs(struct ad9361_rf_phy *phy, enum ad9361_bist_mode mode) +{ + uint32_t reg = 0; + + dev_dbg(&phy->spi->dev, "%s: mode %d", __func__, mode); + + phy->bist_prbs_mode = mode; + + switch (mode) { + case BIST_DISABLE: + reg = 0; + break; + case BIST_INJ_TX: + reg = BIST_CTRL_POINT(0) | BIST_ENABLE; + break; + case BIST_INJ_RX: + reg = BIST_CTRL_POINT(2) | BIST_ENABLE; + break; + }; + + phy->bist_config = reg; + + return ad9361_spi_write(phy->spi, REG_BIST_CONFIG, reg); +} + +/** + * Get BIST mode settings. + * @param phy The AD9361 state structure. + * @param mode Bist mode. + * @return 0 in case of success, negative error code otherwise. + */ +void ad9361_get_bist_prbs(struct ad9361_rf_phy *phy, + enum ad9361_bist_mode *mode) +{ + *mode = phy->bist_prbs_mode; +} + +/** + * BIST tone. + * @param phy The AD9361 state structure. + * @param mode Bist tone mode. + * @param freq_Hz Bist tone frequency. + * @param level_dB Bist tone level. + * @param mask Bist reg mask. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_bist_tone(struct ad9361_rf_phy *phy, + enum ad9361_bist_mode mode, uint32_t freq_Hz, + uint32_t level_dB, uint32_t mask) +{ + uint32_t clk = 0; + uint32_t reg = 0, reg1, reg_mask; + + dev_dbg(&phy->spi->dev, "%s: mode %d", __func__, mode); + + phy->bist_tone_mode = mode; + phy->bist_tone_freq_Hz = freq_Hz; + phy->bist_tone_level_dB = level_dB; + phy->bist_tone_mask = mask; + + switch (mode) { + case BIST_DISABLE: + reg = 0; + break; + case BIST_INJ_TX: + clk = clk_get_rate(phy, phy->ref_clk_scale[TX_SAMPL_CLK]); + reg = BIST_CTRL_POINT(0) | BIST_ENABLE; + break; + case BIST_INJ_RX: + clk = clk_get_rate(phy, phy->ref_clk_scale[RX_SAMPL_CLK]); + reg = BIST_CTRL_POINT(2) | BIST_ENABLE; + break; + }; + + reg |= TONE_PRBS; + reg |= TONE_LEVEL(level_dB / 6); + + if (freq_Hz < 4) { + reg |= TONE_FREQ(freq_Hz); + } else { + if (clk) + reg |= TONE_FREQ(DIV_ROUND_CLOSEST(freq_Hz * 32, clk) - 1); + } + + reg_mask = BIST_MASK_CHANNEL_1_I_DATA | BIST_MASK_CHANNEL_1_Q_DATA | + BIST_MASK_CHANNEL_2_I_DATA | BIST_MASK_CHANNEL_2_Q_DATA; + + reg1 = ((mask << 2) & reg_mask); + ad9361_spi_write(phy->spi, REG_BIST_AND_DATA_PORT_TEST_CONFIG, reg1); + + phy->bist_config = reg; + + return ad9361_spi_write(phy->spi, REG_BIST_CONFIG, reg); +} + +/** + * Get BIST tone settings. + * @param phy The AD9361 state structure. + * @param mode Bist tone mode. + * @param freq_Hz Bist tone frequency. + * @param level_dB Bist tone level. + * @param mask Bist reg mask. + * @return 0 in case of success, negative error code otherwise. + */ +void ad9361_get_bist_tone(struct ad9361_rf_phy *phy, + enum ad9361_bist_mode *mode, uint32_t *freq_Hz, + uint32_t *level_dB, uint32_t *mask) +{ + *mode = phy->bist_tone_mode; + *freq_Hz = phy->bist_tone_freq_Hz; + *level_dB = phy->bist_tone_level_dB; + *mask = phy->bist_tone_mask; +} + +/** + * Check the calibration done bit. + * @param phy The AD9361 state structure. + * @param reg The register address. + * @param mask The bit mask. + * @param done_state The done state [0,1]. + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t ad9361_check_cal_done(struct ad9361_rf_phy *phy, uint32_t reg, + uint32_t mask, uint32_t done_state) +{ + uint32_t timeout = 20000; /* RFDC_CAL can take long */ + uint32_t state; + + do { + state = ad9361_spi_readf(phy->spi, reg, mask); + if (state == done_state) + return 0; + + if (reg == REG_CALIBRATION_CTRL) + udelay(1200); + else + udelay(120); + } while (timeout--); + + dev_err(&phy->spi->dev, "Calibration TIMEOUT (0x%"PRIX32", 0x%"PRIX32")", reg, + mask); + + return -ETIMEDOUT; +} + +/** + * Run an AD9361 calibration and check the calibration done bit. + * @param phy The AD9361 state structure. + * @param mask The calibration bit mask[RX_BB_TUNE_CAL, TX_BB_TUNE_CAL, + * RX_QUAD_CAL, TX_QUAD_CAL, RX_GAIN_STEP_CAL, TXMON_CAL, + * RFDC_CAL, BBDC_CAL]. + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t ad9361_run_calibration(struct ad9361_rf_phy *phy, uint32_t mask) +{ + int32_t ret = ad9361_spi_write(phy->spi, REG_CALIBRATION_CTRL, mask); + if (ret < 0) + return ret; + + dev_dbg(&phy->spi->dev, "%s: CAL Mask 0x%"PRIx32, __func__, mask); + + return ad9361_check_cal_done(phy, REG_CALIBRATION_CTRL, mask, 0); +} + +/** + * Choose the right RX gain table index for the selected frequency. + * @param freq The frequency value [Hz]. + * @return The index to the RX gain table. + */ +static int32_t ad9361_gt_tableindex(struct ad9361_rf_phy *phy, uint64_t freq) +{ + int32_t i; + + for (i = 0; phy->gt_info[i].tab != NULL; i++) { + if ((phy->pdata->split_gt == phy->gt_info[i].split_table) && + (phy->gt_info[i].start < freq) && + (freq <= phy->gt_info[i].end)) { + return i; + } + } + + dev_err(&phy->spi->dev, + "%s: Failed to find suitable gain table (%"PRIu64")", __func__, freq); + + return 0; +} + +/** + * Return the current gain table index. + * @param phy The AD9361 state structure. + * @return The current gain table index or 0 if the table was not chosen. + */ +uint32_t ad9361_gt(struct ad9361_rf_phy *phy) +{ + if (phy->current_table == NO_GAIN_TABLE) { + dev_err(&phy->spi->dev, "%s: ERROR", __func__); + return 0; + } + + return phy->current_table; +} + +/** + * Shift the real frequency value, so it fits type unsigned long + * Note: PLL operates between 47 .. 6000 MHz which is > 2^32. + * @param freq The frequency value [Hz]. + * @return The shifted frequency value. + */ +uint32_t ad9361_to_clk(uint64_t freq) +{ + return (uint32_t)(freq >> 1); +} + +/** + * Shift back the frequency value, so it reflects the real value. + * Note: PLL operates between 47 .. 6000 MHz which is > 2^32. + * @param freq The frequency value [Hz]. + * @return The shifted frequency value. + */ +uint64_t ad9361_from_clk(uint32_t freq) +{ + return ((uint64_t)freq << 1); +} + +/** + * Find the corresponding table index for a specific gain value. + * @param phy The AD9361 state structure. + * @param gain The gain value. + * @return The table index. + */ +static int find_table_index(struct ad9361_rf_phy *phy, int gain) +{ + uint32_t i, nm1, n; + + for (i = 0; i < phy->gt_info[ad9361_gt(phy)].max_index; i++) { + if (phy->gt_info[ad9361_gt(phy)].abs_gain_tbl[i] >= gain) { + nm1 = abs(phy->gt_info[ad9361_gt(phy)].abs_gain_tbl[ + (i > 0) ? i - 1 : i] - gain); + n = abs(phy->gt_info[ad9361_gt(phy)].abs_gain_tbl[i] + - gain); + if (nm1 < n) + return (i > 0) ? i - 1 : i; + else + return i; + } + } + + return -EINVAL; +} + +/** + * Load the gain table for the selected frequency range and receiver. + * @param phy The AD9361 state structure. + * @param freq The frequency value [Hz]. + * @param dest The destination [GT_RX1, GT_RX2]. + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t ad9361_load_gt(struct ad9361_rf_phy *phy, uint64_t freq, + uint32_t dest) +{ + struct spi_desc *spi = phy->spi; + uint8_t (*tab)[3]; + uint32_t band, index_max, i, lna, lpf_tia_mask, set_gain; + int32_t ret, rx1_gain, rx2_gain; + + dev_dbg(&phy->spi->dev, "%s: frequency %"PRIu64, __func__, freq); + + band = ad9361_gt_tableindex(phy, freq); + + dev_dbg(&phy->spi->dev, "%s: frequency %"PRIu64" (band %"PRIu32")", + __func__, freq, band); + + /* check if table is present */ + if (phy->current_table == band) + return 0; + + tab = phy->gt_info[band].tab; + index_max = phy->gt_info[band].max_index; + + ad9361_spi_writef(spi, REG_AGC_CONFIG_2, + AGC_USE_FULL_GAIN_TABLE, !phy->pdata->split_gt); + + ad9361_spi_write(spi, REG_MAX_LMT_FULL_GAIN, + index_max - 1); /* Max Full/LMT Gain Table Index */ + + set_gain = ad9361_spi_readf(spi, REG_RX1_MANUAL_LMT_FULL_GAIN, + RX_FULL_TBL_IDX_MASK); + + if (phy->current_table != NO_GAIN_TABLE) { + rx1_gain = phy->gt_info[phy->current_table].abs_gain_tbl[set_gain]; + } else { + if (set_gain > (index_max - 1)) + set_gain = index_max - 1; + + rx1_gain = phy->gt_info[band].abs_gain_tbl[set_gain]; + } + + set_gain = ad9361_spi_readf(spi, REG_RX2_MANUAL_LMT_FULL_GAIN, + RX_FULL_TBL_IDX_MASK); + + if (phy->current_table != NO_GAIN_TABLE) { + rx2_gain = phy->gt_info[phy->current_table].abs_gain_tbl[set_gain]; + } else { + if (set_gain > (index_max - 1)) + set_gain = index_max - 1; + + rx2_gain = phy->gt_info[band].abs_gain_tbl[set_gain]; + } + + lna = phy->pdata->elna_ctrl.elna_in_gaintable_all_index_en ? + EXT_LNA_CTRL : 0; + + ad9361_spi_write(spi, REG_GAIN_TABLE_CONFIG, START_GAIN_TABLE_CLOCK | + RECEIVER_SELECT(dest)); /* Start Gain Table Clock */ + + /* TX QUAD Calibration */ + if (phy->pdata->split_gt) + lpf_tia_mask = 0x20; + else + lpf_tia_mask = 0x3F; + + phy->tx_quad_lpf_tia_match = -EINVAL; + + for (i = 0; i < index_max; i++) { + ad9361_spi_write(spi, REG_GAIN_TABLE_ADDRESS, i); /* Gain Table Index */ + ad9361_spi_write(spi, REG_GAIN_TABLE_WRITE_DATA1, + tab[i][0] | lna); /* Ext LNA, Int LNA, & Mixer Gain Word */ + ad9361_spi_write(spi, REG_GAIN_TABLE_WRITE_DATA2, + tab[i][1]); /* TIA & LPF Word */ + ad9361_spi_write(spi, REG_GAIN_TABLE_WRITE_DATA3, + tab[i][2]); /* DC Cal bit & Dig Gain Word */ + ad9361_spi_write(spi, REG_GAIN_TABLE_CONFIG, + START_GAIN_TABLE_CLOCK | + WRITE_GAIN_TABLE | + RECEIVER_SELECT(dest)); /* Gain Table Index */ + ad9361_spi_write(spi, REG_GAIN_TABLE_READ_DATA1, + 0); /* Dummy Write to delay 3 ADCCLK/16 cycles */ + ad9361_spi_write(spi, REG_GAIN_TABLE_READ_DATA1, + 0); /* Dummy Write to delay ~1u */ + + if ((tab[i][1] & lpf_tia_mask) == 0x20) + phy->tx_quad_lpf_tia_match = i; + + } + + ad9361_spi_write(spi, REG_GAIN_TABLE_CONFIG, START_GAIN_TABLE_CLOCK | + RECEIVER_SELECT(dest)); /* Clear Write Bit */ + ad9361_spi_write(spi, REG_GAIN_TABLE_READ_DATA1, + 0); /* Dummy Write to delay ~1u */ + ad9361_spi_write(spi, REG_GAIN_TABLE_READ_DATA1, + 0); /* Dummy Write to delay ~1u */ + ad9361_spi_write(spi, REG_GAIN_TABLE_CONFIG, 0); /* Stop Gain Table Clock */ + + phy->current_table = band; + + ret = find_table_index(phy, rx1_gain); + if (ret < 0) + ret = phy->gt_info[band].max_index - 1; + + ad9361_spi_writef(spi, REG_RX1_MANUAL_LMT_FULL_GAIN, + RX_FULL_TBL_IDX_MASK, ret); /* Rx1 Full/LMT Gain Index */ + + ret = find_table_index(phy, rx2_gain); + if (ret < 0) + ret = phy->gt_info[band].max_index - 1; + + ad9361_spi_write(spi, REG_RX2_MANUAL_LMT_FULL_GAIN, + ret); /* Rx2 Full/LMT Gain Index */ + + return 0; +} + +/** + * Setup the external low-noise amplifier (LNA). + * @param phy The AD9361 state structure. + * @param ctrl Pointer to eLNA control structure. + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t ad9361_setup_ext_lna(struct ad9361_rf_phy *phy, + struct elna_control *ctrl) +{ + ad9361_spi_writef(phy->spi, REG_EXTERNAL_LNA_CTRL, EXTERNAL_LNA1_CTRL, + ctrl->elna_1_control_en); + + ad9361_spi_writef(phy->spi, REG_EXTERNAL_LNA_CTRL, EXTERNAL_LNA2_CTRL, + ctrl->elna_2_control_en); + + ad9361_spi_write(phy->spi, REG_EXT_LNA_HIGH_GAIN, + EXT_LNA_HIGH_GAIN(ctrl->gain_mdB / 500)); + + return ad9361_spi_write(phy->spi, REG_EXT_LNA_LOW_GAIN, + EXT_LNA_LOW_GAIN(ctrl->bypass_loss_mdB / 500)); +} + +/** + * Set the clock output mode. + * @param phy The AD9361 state structure. + * @param mode The clock output mode []. + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t ad9361_clkout_control(struct ad9361_rf_phy *phy, + enum ad9361_clkout mode) +{ + if (mode == CLKOUT_DISABLE) + return ad9361_spi_writef(phy->spi, REG_BBPLL, CLKOUT_ENABLE, 0); + + return ad9361_spi_writef(phy->spi, REG_BBPLL, + CLKOUT_ENABLE | CLKOUT_SELECT(~0), + ((mode - 1) << 1) | 0x1); +} + +/** + * Load the Gm Sub Table. + * @param phy The AD9361 state structure. + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t ad9361_load_mixer_gm_subtable(struct ad9361_rf_phy *phy) +{ + int32_t i, addr; + dev_dbg(&phy->spi->dev, "%s", __func__); + + ad9361_spi_write(phy->spi, REG_GM_SUB_TABLE_CONFIG, + START_GM_SUB_TABLE_CLOCK); /* Start Clock */ + + for (i = 0, addr = ARRAY_SIZE(gm_st_ctrl); i < (int64_t)ARRAY_SIZE(gm_st_ctrl); + i++) { + ad9361_spi_write(phy->spi, REG_GM_SUB_TABLE_ADDRESS, + --addr); /* Gain Table Index */ + ad9361_spi_write(phy->spi, REG_GM_SUB_TABLE_BIAS_WRITE, 0); /* Bias */ + ad9361_spi_write(phy->spi, REG_GM_SUB_TABLE_GAIN_WRITE, + gm_st_gain[i]); /* Gain */ + ad9361_spi_write(phy->spi, REG_GM_SUB_TABLE_CTRL_WRITE, + gm_st_ctrl[i]); /* Control */ + ad9361_spi_write(phy->spi, REG_GM_SUB_TABLE_CONFIG, + WRITE_GM_SUB_TABLE | START_GM_SUB_TABLE_CLOCK); /* Write Words */ + ad9361_spi_write(phy->spi, REG_GM_SUB_TABLE_GAIN_READ, 0); /* Dummy Delay */ + ad9361_spi_write(phy->spi, REG_GM_SUB_TABLE_GAIN_READ, 0); /* Dummy Delay */ + } + + ad9361_spi_write(phy->spi, REG_GM_SUB_TABLE_CONFIG, + START_GM_SUB_TABLE_CLOCK); /* Clear Write */ + ad9361_spi_write(phy->spi, REG_GM_SUB_TABLE_GAIN_READ, 0); /* Dummy Delay */ + ad9361_spi_write(phy->spi, REG_GM_SUB_TABLE_GAIN_READ, 0); /* Dummy Delay */ + ad9361_spi_write(phy->spi, REG_GM_SUB_TABLE_CONFIG, 0); /* Stop Clock */ + + return 0; +} + +/** + * Set the attenuation for the selected TX channels. + * @param phy The AD9361 state structure. + * @param atten_mdb Attenuation value [mdB]. + * @param tx1 Set true, the attenuation of the TX1 will be affected. + * @param tx2 Set true, the attenuation of the TX2 will be affected. + * @param immed Set true, an immediate update will take place. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_set_tx_atten(struct ad9361_rf_phy *phy, uint32_t atten_mdb, + bool tx1, bool tx2, bool immed) +{ + uint8_t buf[2]; + int32_t ret = 0; + + dev_dbg(&phy->spi->dev, "%s : attenuation %"PRIu32" mdB tx1=%d tx2=%d", + __func__, atten_mdb, tx1, tx2); + + if (atten_mdb > MAX_TX_ATTENUATION_DB) /* 89.75 dB */ + return -EINVAL; + + atten_mdb /= 250; /* Scale to 0.25dB / LSB */ + + buf[0] = atten_mdb >> 8; + buf[1] = atten_mdb & 0xFF; + + ad9361_spi_writef(phy->spi, REG_TX2_DIG_ATTEN, + IMMEDIATELY_UPDATE_TPC_ATTEN, 0); + + if (tx1) + ret = ad9361_spi_writem(phy->spi, REG_TX1_ATTEN_1, buf, 2); + + if (tx2) + ret = ad9361_spi_writem(phy->spi, REG_TX2_ATTEN_1, buf, 2); + + if (immed) + ad9361_spi_writef(phy->spi, REG_TX2_DIG_ATTEN, + IMMEDIATELY_UPDATE_TPC_ATTEN, 1); + + return ret; +} + +/** + * Get the attenuation for the selected TX channel. + * @param phy The AD9361 state structure. + * @param tx_num The selected channel [1, 2]. + * @return The attenuation value [mdB] or negative error code in case of failure. + */ +int32_t ad9361_get_tx_atten(struct ad9361_rf_phy *phy, uint32_t tx_num) +{ + uint8_t buf[2]; + int32_t ret = 0; + uint32_t code; + + ret = ad9361_spi_readm(phy->spi, (tx_num == 1) ? + REG_TX1_ATTEN_1 : REG_TX2_ATTEN_1, buf, 2); + + if (ret < 0) + return ret; + + code = (buf[0] << 8) | buf[1]; + + code *= 250; + + return code; +} + +/** + * Mute TX. + * @param phy The AD9361 state structure. + * @param state The state - 0 mute; 1 - unmute. + * @return 0 in case of success + */ +int32_t ad9361_tx_mute(struct ad9361_rf_phy *phy, uint32_t state) +{ + int32_t ret; + + if (state) { + phy->tx1_atten_cached = ad9361_get_tx_atten(phy, 1); + phy->tx2_atten_cached = ad9361_get_tx_atten(phy, 2); + + return ad9361_set_tx_atten(phy, 89750, true, true, true); + } else { + if (phy->tx1_atten_cached == phy->tx2_atten_cached) + return ad9361_set_tx_atten(phy, phy->tx1_atten_cached, + true, true, true); + + ret = ad9361_set_tx_atten(phy, phy->tx1_atten_cached, + true, false, true); + ret |= ad9361_set_tx_atten(phy, phy->tx2_atten_cached, + false, true, true); + + return ret; + } +} + +/** + * Choose the right RF VCO table index for the selected frequency. + * @param freq The frequency value [Hz]. + * @return The index from the RF VCO table. + */ +static uint32_t ad9361_rfvco_tableindex(uint32_t freq) +{ + if (freq < 50000000UL) + return LUT_FTDD_40; + + if (freq <= 70000000UL) + return LUT_FTDD_60; + + return LUT_FTDD_80; +} + +/** + * Initialize the RFPLL VCO. + * @param phy The AD9361 state structure. + * @param tx Set true for TX_RFPLL. + * @param vco_freq The VCO frequency [Hz]. + * @param ref_clk The reference clock frequency [Hz]. + * @return 0 in case of success + */ +static int32_t ad9361_rfpll_vco_init(struct ad9361_rf_phy *phy, + bool tx, uint64_t vco_freq, + uint32_t ref_clk) +{ + struct spi_desc *spi = phy->spi; + const struct SynthLUT(*tab); + int32_t i = 0; + uint32_t range, offs = 0; + + range = ad9361_rfvco_tableindex(ref_clk); + + dev_dbg(&phy->spi->dev, + "%s : vco_freq %"PRIu64" : ref_clk %"PRIu32" : range %"PRIu32, + __func__, vco_freq, ref_clk, range); + + do_div(&vco_freq, 1000000UL); /* vco_freq in MHz */ + + if ((phy->pdata->fdd && !phy->pdata->fdd_independent_mode) + && (phy->current_tx_lo_freq != phy->current_rx_lo_freq)) { + tab = &SynthLUT_FDD[range][0]; + if (tx) + phy->current_tx_use_tdd_table = false; + else + phy->current_rx_use_tdd_table = false; + } else { + if (have_tdd_tables) { + tab = &SynthLUT_TDD[range][0]; + if (tx) + phy->current_tx_use_tdd_table = true; + else + phy->current_rx_use_tdd_table = true; + } + } + + if (tx) + offs = REG_TX_VCO_OUTPUT - REG_RX_VCO_OUTPUT; + + while (i < SYNTH_LUT_SIZE && tab[i].VCO_MHz > vco_freq) + i++; + + dev_dbg(&phy->spi->dev, "%s : freq %d MHz : index %"PRId32, + __func__, tab[i].VCO_MHz, i); + + ad9361_spi_write(spi, REG_RX_VCO_OUTPUT + offs, + VCO_OUTPUT_LEVEL(tab[i].VCO_Output_Level) | + PORB_VCO_LOGIC); + ad9361_spi_writef(spi, REG_RX_ALC_VARACTOR + offs, + VCO_VARACTOR(~0), tab[i].VCO_Varactor); + ad9361_spi_write(spi, REG_RX_VCO_BIAS_1 + offs, + VCO_BIAS_REF(tab[i].VCO_Bias_Ref) | + VCO_BIAS_TCF(tab[i].VCO_Bias_Tcf)); + + ad9361_spi_write(spi, REG_RX_FORCE_VCO_TUNE_1 + offs, + VCO_CAL_OFFSET(tab[i].VCO_Cal_Offset)); + ad9361_spi_write(spi, REG_RX_VCO_VARACTOR_CTRL_1 + offs, + VCO_VARACTOR_REFERENCE( + tab[i].VCO_Varactor_Reference)); + + ad9361_spi_write(spi, REG_RX_VCO_CAL_REF + offs, VCO_CAL_REF_TCF(0)); + + ad9361_spi_write(spi, REG_RX_VCO_VARACTOR_CTRL_0 + offs, + VCO_VARACTOR_OFFSET(0) | + VCO_VARACTOR_REFERENCE_TCF(7)); + + ad9361_spi_writef(spi, REG_RX_CP_CURRENT + offs, CHARGE_PUMP_CURRENT(~0), + tab[i].Charge_Pump_Current); + ad9361_spi_write(spi, REG_RX_LOOP_FILTER_1 + offs, + LOOP_FILTER_C2(tab[i].LF_C2) | + LOOP_FILTER_C1(tab[i].LF_C1)); + ad9361_spi_write(spi, REG_RX_LOOP_FILTER_2 + offs, + LOOP_FILTER_R1(tab[i].LF_R1) | + LOOP_FILTER_C3(tab[i].LF_C3)); + ad9361_spi_write(spi, REG_RX_LOOP_FILTER_3 + offs, + LOOP_FILTER_R3(tab[i].LF_R3)); + + return 0; +} + +/** + * Get the current gain in Split Gain Table Mode + * @param phy The AD9361 state structure. + * @param idx_reg Register base address for the selected receiver + * @param rx_gain A rf_rx_gain struct to store the RF gain. + * @return 0 in case of success, + */ +static int32_t ad9361_get_split_table_gain(struct ad9361_rf_phy *phy, + uint32_t idx_reg, + struct rf_rx_gain *rx_gain) +{ + struct spi_desc *spi = phy->spi; + uint32_t val, tbl_addr; + int32_t rc = 0; + + + rx_gain->fgt_lmt_index = ad9361_spi_readf(spi, idx_reg, + FULL_TABLE_GAIN_INDEX(~0)); + tbl_addr = ad9361_spi_read(spi, REG_GAIN_TABLE_ADDRESS); + + ad9361_spi_write(spi, REG_GAIN_TABLE_ADDRESS, rx_gain->fgt_lmt_index); + + val = ad9361_spi_read(spi, REG_GAIN_TABLE_READ_DATA1); + rx_gain->lna_index = TO_LNA_GAIN(val); + rx_gain->mixer_index = TO_MIXER_GM_GAIN(val); + + rx_gain->tia_index = ad9361_spi_readf(spi, REG_GAIN_TABLE_READ_DATA2, TIA_GAIN); + + rx_gain->lmt_gain = lna_table[ad9361_gt(phy) - RXGAIN_TBLS_END][rx_gain->lna_index] + + mixer_table[ad9361_gt(phy) - RXGAIN_TBLS_END][rx_gain->mixer_index] + + tia_table[rx_gain->tia_index]; + + ad9361_spi_write(spi, REG_GAIN_TABLE_ADDRESS, tbl_addr); + + /* Read LPF Index */ + rx_gain->lpf_gain = ad9361_spi_readf(spi, idx_reg + 1, LPF_GAIN_RX(~0)); + + /* Read Digital Gain */ + rx_gain->digital_gain = ad9361_spi_readf(spi, idx_reg + 2, + DIGITAL_GAIN_RX(~0)); + + rx_gain->gain_db = rx_gain->lmt_gain + rx_gain->lpf_gain + + rx_gain->digital_gain; + return rc; +} + +/** + * Get the current gain in Full Gain Table Mode + * @param phy The AD9361 state structure. + * @param idx_reg Register base address for the selected receiver + * @param rx_gain A rf_rx_gain struct to store the RF gain. + * @return 0 in case of success + */ +static int32_t ad9361_get_full_table_gain(struct ad9361_rf_phy *phy, + uint32_t idx_reg, + struct rf_rx_gain *rx_gain) +{ + struct spi_desc *spi = phy->spi; + uint32_t val; + + rx_gain->fgt_lmt_index = val = ad9361_spi_readf(spi, idx_reg, + FULL_TABLE_GAIN_INDEX(~0)); + /* Read Digital Gain */ + rx_gain->digital_gain = ad9361_spi_readf(spi, idx_reg + 2, + DIGITAL_GAIN_RX(~0)); + + rx_gain->gain_db = phy->gt_info[ad9361_gt(phy)].abs_gain_tbl[val]; + + return 0; +} + +/** + * Get current RX gain for the selected channel. + * @param phy The AD9361 state structure. + * @param rx_id The desired channel number (0, 1). + * @param rx_gain A rf_rx_gain struct to store the RF gain. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_get_rx_gain(struct ad9361_rf_phy *phy, + uint32_t rx_id, struct rf_rx_gain *rx_gain) +{ + struct spi_desc *spi = phy->spi; + uint32_t val, idx_reg; + uint8_t gain_ctl_shift, rx_enable_mask; + uint8_t fast_atk_shift; + int32_t rc = 0; + + if (rx_id == 1) { + gain_ctl_shift = RX1_GAIN_CTRL_SHIFT; + idx_reg = REG_GAIN_RX1; + rx_enable_mask = RX_CHANNEL_ENABLE(RX_1); + fast_atk_shift = RX1_FAST_ATK_SHIFT; + + } else if (rx_id == 2) { + gain_ctl_shift = RX2_GAIN_CTRL_SHIFT; + idx_reg = REG_GAIN_RX2; + rx_enable_mask = RX_CHANNEL_ENABLE(RX_2); + fast_atk_shift = RX2_FAST_ATK_SHIFT; + } else { + dev_err(dev, "Unknown Rx path %"PRIu32, rx_id); + rc = -EINVAL; + goto out; + } + + val = ad9361_spi_readf(spi, REG_RX_ENABLE_FILTER_CTRL, rx_enable_mask); + + if (!val) { + dev_dbg(dev, "Rx%"PRIu32" is not enabled", rx_gain->ant); + rc = -EAGAIN; + goto out; + } + + val = ad9361_spi_read(spi, REG_AGC_CONFIG_1); + + val = (val >> gain_ctl_shift) & RX_GAIN_CTL_MASK; + + if (val == RX_GAIN_CTL_AGC_FAST_ATK) { + /* In fast attack mode check whether Fast attack state machine + * has locked gain, if not then we can not read gain. + */ + val = ad9361_spi_read(spi, REG_FAST_ATTACK_STATE); + val = (val >> fast_atk_shift) & FAST_ATK_MASK; + if (val != FAST_ATK_GAIN_LOCKED) { + dev_warn(dev, "Failed to read gain, state m/c at %"PRIx32, + val); + rc = -EAGAIN; + goto out; + } + } + + if (has_split_gt && phy->pdata->split_gt) + rc = ad9361_get_split_table_gain(phy, idx_reg, rx_gain); + else + rc = ad9361_get_full_table_gain(phy, idx_reg, rx_gain); + +out: + return rc; +} + +/** + * Get Enable State Machine (ENSM) state. + * @param phy The AD9361 state structure. + * @return The state. + */ +uint8_t ad9361_ensm_get_state(struct ad9361_rf_phy *phy) +{ + return ad9361_spi_readf(phy->spi, REG_STATE, ENSM_STATE(~0)); +} + +/** + * Force Enable State Machine (ENSM) to the desired state (internally used only). + * @param phy The AD9361 state structure. + * @param ensm_state The ENSM state [ENSM_STATE_SLEEP_WAIT, ENSM_STATE_ALERT, + * ENSM_STATE_TX, ENSM_STATE_TX_FLUSH, ENSM_STATE_RX, + * ENSM_STATE_RX_FLUSH, ENSM_STATE_FDD, ENSM_STATE_FDD_FLUSH]. + * @return None. + */ +void ad9361_ensm_force_state(struct ad9361_rf_phy *phy, uint8_t ensm_state) +{ + struct spi_desc *spi = phy->spi; + uint8_t dev_ensm_state; + int32_t rc, timeout = 10; + uint32_t val; + + dev_ensm_state = ad9361_spi_readf(spi, REG_STATE, ENSM_STATE(~0)); + + phy->prev_ensm_state = dev_ensm_state; + + if (dev_ensm_state == ensm_state) { + dev_dbg(dev, "Nothing to do, device is already in %d state", + ensm_state); + goto out; + } + + dev_dbg(dev, "Device is in %x state, forcing to %x", dev_ensm_state, + ensm_state); + + val = ad9361_spi_read(spi, REG_ENSM_CONFIG_1); + + /* Enable control through SPI writes, and take out from + * Alert + */ + if (val & ENABLE_ENSM_PIN_CTRL) { + val &= ~ENABLE_ENSM_PIN_CTRL; + phy->ensm_pin_ctl_en = true; + } else { + phy->ensm_pin_ctl_en = false; + } + + if (dev_ensm_state) + val &= ~(TO_ALERT); + + switch (ensm_state) { + + case ENSM_STATE_TX: + case ENSM_STATE_FDD: + val |= FORCE_TX_ON; + break; + case ENSM_STATE_RX: + val |= FORCE_RX_ON; + break; + case ENSM_STATE_ALERT: + val &= ~(FORCE_TX_ON | FORCE_RX_ON); + val |= TO_ALERT | FORCE_ALERT_STATE; + break; + default: + dev_err(dev, "No handling for forcing %d ensm state", + ensm_state); + goto out; + } + + ad9361_spi_write(spi, REG_ENSM_CONFIG_1, TO_ALERT | FORCE_ALERT_STATE); + + rc = ad9361_spi_write(spi, REG_ENSM_CONFIG_1, val); + if (rc) { + dev_err(dev, "Failed to write ENSM_CONFIG_1\n"); + goto out; + } + + while (ad9361_ensm_get_state(phy) != ensm_state && --timeout) { + mdelay(1); + } + + if (timeout == 0) + dev_err(dev, "Failed to restore state"); + +out: + return; + +} + +/** + * Restore an Enable State Machine (ENSM) state. + * @param phy The AD9361 state structure. + * @param ensm_state The state. + * @return None. + */ +void ad9361_ensm_restore_state(struct ad9361_rf_phy *phy, uint8_t ensm_state) +{ + struct spi_desc *spi = phy->spi; + int32_t rc; + uint32_t val; + + val = ad9361_spi_read(spi, REG_ENSM_CONFIG_1); + + /* We are restoring state only, so clear State bits first + * which might have set while forcing a particular state + */ + val &= ~(FORCE_TX_ON | FORCE_RX_ON | FORCE_ALERT_STATE); + val |= TO_ALERT; + + switch (ensm_state) { + case ENSM_STATE_TX: + case ENSM_STATE_FDD: + val |= FORCE_TX_ON; + break; + case ENSM_STATE_RX: + val |= FORCE_RX_ON; + break; + case ENSM_STATE_ALERT: + val |= TO_ALERT; + break; + case ENSM_STATE_INVALID: + dev_dbg(dev, "No need to restore, ENSM state wasn't saved"); + return; + default: + dev_dbg(dev, "Could not restore to %d ENSM state", + ensm_state); + return; + } + + ad9361_spi_write(spi, REG_ENSM_CONFIG_1, TO_ALERT | FORCE_ALERT_STATE); + + rc = ad9361_spi_write(spi, REG_ENSM_CONFIG_1, val); + if (rc) { + dev_err(dev, "Failed to write ENSM_CONFIG_1"); + return; + } + + if (phy->ensm_pin_ctl_en) { + val |= ENABLE_ENSM_PIN_CTRL; + rc = ad9361_spi_write(spi, REG_ENSM_CONFIG_1, val); + if (rc) + dev_err(dev, "Failed to write ENSM_CONFIG_1"); + } +} + +/** + * Restore the previous Enable State Machine (ENSM) state. + * @param phy The AD9361 state structure. + * @return None. + */ +void ad9361_ensm_restore_prev_state(struct ad9361_rf_phy *phy) +{ + return ad9361_ensm_restore_state(phy, phy->prev_ensm_state); +} + +/** + * Set gain in Split Gain Table Mode (used only in Manual Gain Control Mode). + * @param phy The AD9361 state structure. + * @param idx_reg Register base address for the selected receiver + * @param rx_gain The rf_rx_gain struct containing the RF gain. + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t set_split_table_gain(struct ad9361_rf_phy *phy, uint32_t idx_reg, + struct rf_rx_gain *rx_gain) +{ + struct spi_desc *spi = phy->spi; + int32_t rc = 0; + + if ((rx_gain->fgt_lmt_index > MAX_LMT_INDEX) || + (rx_gain->lpf_gain > MAX_LPF_GAIN) || + (rx_gain->digital_gain > MAX_DIG_GAIN)) { + dev_err(dev, "LMT_INDEX missing or greater than max value %d", + MAX_LMT_INDEX); + dev_err(dev, "LPF_GAIN missing or greater than max value %d", + MAX_LPF_GAIN); + dev_err(dev, "DIGITAL_GAIN cannot be more than %d", + MAX_DIG_GAIN); + rc = -EINVAL; + goto out; + } + + rc = find_table_index(phy, rx_gain->gain_db); + if (rc < 0) { + dev_err(dev, "Invalid gain %"PRId32", supported range [%d - %d]\n", + rx_gain->gain_db, phy->gt_info[ad9361_gt(phy)]. + abs_gain_tbl[0], + phy->gt_info[ad9361_gt(phy)].abs_gain_tbl + [phy->gt_info[ad9361_gt(phy)].max_index - 1]); + goto out; + } + + rx_gain->fgt_lmt_index = rc; + + rc = ad9361_spi_writef(spi, idx_reg, RX_FULL_TBL_IDX_MASK, + rx_gain->fgt_lmt_index); + if (rc < 0) + goto out; + rc = ad9361_spi_writef(spi, idx_reg + 1, RX_LPF_IDX_MASK, rx_gain->lpf_gain); + if (rc < 0) + goto out; + if (phy->pdata->gain_ctrl.dig_gain_en) { + rc = ad9361_spi_writef(spi, idx_reg + 2, RX_DIGITAL_IDX_MASK, + rx_gain->digital_gain); + } else if (rx_gain->digital_gain > 0) { + dev_err(dev, "Digital gain is disabled and cannot be set"); + } +out: + return rc; +} + +/** + * Set gain in Full Gain Table Mode (used only in Manual Gain Control Mode). + * @param phy The AD9361 state structure. + * @param idx_reg Register base address for the selected receiver + * @param rx_gain The rf_rx_gain struct containing the RF gain. + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t set_full_table_gain(struct ad9361_rf_phy *phy, uint32_t idx_reg, + struct rf_rx_gain *rx_gain) +{ + struct spi_desc *spi = phy->spi; + int rc = 0; + + if (rx_gain->fgt_lmt_index != ((uint32_t)~0) || + rx_gain->lpf_gain != ((uint32_t)~0) || + rx_gain->digital_gain > 0) + dev_dbg(dev, + "Ignoring lmt/lpf/digital gains in Single Table mode"); + + rc = find_table_index(phy, rx_gain->gain_db); + if (rc < 0) { + dev_err(dev, "Invalid gain %"PRId32", supported range [%d - %d]\n", + rx_gain->gain_db, phy->gt_info[ad9361_gt(phy)]. + abs_gain_tbl[0], + phy->gt_info[ad9361_gt(phy)].abs_gain_tbl + [phy->gt_info[ad9361_gt(phy)].max_index - 1]); + goto out; + } + + rc = ad9361_spi_writef(spi, idx_reg, RX_FULL_TBL_IDX_MASK, rc); +out: + return rc; +} + +/** + * Set the RX gain for the selected channel. + * @param phy The AD9361 state structure. + * @param rx_id The desired channel number (0, 1). + * @param rx_gain The rf_rx_gain struct containing the RF gain. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_set_rx_gain(struct ad9361_rf_phy *phy, + uint32_t rx_id, struct rf_rx_gain *rx_gain) +{ + struct spi_desc *spi = phy->spi; + uint32_t val, idx_reg; + uint8_t gain_ctl_shift; + int32_t rc = 0; + + if (rx_id == 1) { + gain_ctl_shift = RX1_GAIN_CTRL_SHIFT; + idx_reg = REG_RX1_MANUAL_LMT_FULL_GAIN; + + } else if (rx_id == 2) { + gain_ctl_shift = RX2_GAIN_CTRL_SHIFT; + idx_reg = REG_RX2_MANUAL_LMT_FULL_GAIN; + } else { + dev_err(dev, "Unknown Rx path %"PRIu32, rx_id); + rc = -EINVAL; + goto out; + + } + + val = ad9361_spi_read(spi, REG_AGC_CONFIG_1); + val = (val >> gain_ctl_shift) & RX_GAIN_CTL_MASK; + + if (val != RX_GAIN_CTL_MGC) { + dev_dbg(dev, "Rx gain can be set in MGC mode only"); + rc = -EOPNOTSUPP; + goto out; + } + + if (has_split_gt && phy->pdata->split_gt) + rc = set_split_table_gain(phy, idx_reg, rx_gain); + else + rc = set_full_table_gain(phy, idx_reg, rx_gain); + + if (rc) { + dev_err(dev, "Unable to write gain tbl idx reg: %"PRIu32, idx_reg); + goto out; + } + +out: + return rc; + +} + +/** + * Update the Gain Control. + * @param phy The AD9361 state structure. + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t ad9361_gc_update(struct ad9361_rf_phy *phy) +{ + struct spi_desc *spi = phy->spi; + uint32_t clkrf; + uint32_t reg, delay_lna, settling_delay, dec_pow_meas_dur; + int32_t ret; + uint32_t fir_div; + + clkrf = clk_get_rate(phy, phy->ref_clk_scale[CLKRF_CLK]); + delay_lna = phy->pdata->elna_ctrl.settling_delay_ns; + + /* + * AGC Attack Delay (us)=ceiling((((0.2+Delay_LNA)*ClkRF+14))/(2*ClkRF))+1 + * ClkRF in MHz, delay in us + */ + + reg = (200 + delay_lna) / 2 + (14000000UL / (clkrf / 500U)); + reg = DIV_ROUND_UP(reg, 1000UL) + + phy->pdata->gain_ctrl.agc_attack_delay_extra_margin_us; + reg = clamp_t(uint8_t, reg, 0U, 31U); + ret = ad9361_spi_writef(spi, REG_AGC_ATTACK_DELAY, + AGC_ATTACK_DELAY(~0), reg); + + /* + * Peak Overload Wait Time (ClkRF cycles)=ceiling((0.1+Delay_LNA) *clkRF+1) + */ + + reg = (delay_lna + 100UL) * (clkrf / 1000UL); + reg = DIV_ROUND_UP(reg, 1000000UL) + 1; + reg = clamp_t(uint8_t, reg, 0U, 31U); + ret |= ad9361_spi_writef(spi, REG_PEAK_WAIT_TIME, + PEAK_OVERLOAD_WAIT_TIME(~0), reg); + + /* + * Settling Delay in 0x111. Applies to all gain control modes: + * 0x111[D4:D0]= ceiling(((0.2+Delay_LNA)*clkRF + dodebug = false;+14)/2) + */ + + reg = (delay_lna + 200UL) * (clkrf / 2000UL); + reg = DIV_ROUND_UP(reg, 1000000UL) + 7; + reg = settling_delay = clamp_t(uint8_t, reg, 0U, 31U); + ret |= ad9361_spi_writef(spi, REG_FAST_CONFIG_2_SETTLING_DELAY, + SETTLING_DELAY(~0), reg); + + /* + * Gain Update Counter [15:0]= round((((time*ClkRF-0x111[D4:D0]*2)-2))/2) + */ + reg = phy->pdata->gain_ctrl.gain_update_interval_us * (clkrf / 1000UL) - + settling_delay * 2000UL - 2000UL; + + reg = DIV_ROUND_CLOSEST(reg, 2000UL); + reg = clamp_t(uint32_t, reg, 0U, 131071UL); + + if (phy->agc_mode[0] == RF_GAIN_FASTATTACK_AGC || + phy->agc_mode[1] == RF_GAIN_FASTATTACK_AGC) { + dec_pow_meas_dur = + phy->pdata->gain_ctrl.f_agc_dec_pow_measuremnt_duration; + } else { + fir_div = DIV_ROUND_CLOSEST(clkrf, + clk_get_rate(phy, phy->ref_clk_scale[RX_SAMPL_CLK])); + dec_pow_meas_dur = phy->pdata->gain_ctrl.dec_pow_measuremnt_duration; + + if (((reg * 2 / fir_div) / dec_pow_meas_dur) < 2) { + dec_pow_meas_dur = reg / fir_div; + } + } + + /* Power Measurement Duration */ + ad9361_spi_writef(spi, REG_DEC_POWER_MEASURE_DURATION_0, + DEC_POWER_MEASUREMENT_DURATION(~0), + ilog2(dec_pow_meas_dur / 16)); + + + ret |= ad9361_spi_writef(spi, REG_DIGITAL_SAT_COUNTER, + DOUBLE_GAIN_COUNTER, reg > 65535); + + if (reg > 65535) + reg /= 2; + + ret |= ad9361_spi_write(spi, REG_GAIN_UPDATE_COUNTER1, reg & 0xFF); + ret |= ad9361_spi_write(spi, REG_GAIN_UPDATE_COUNTER2, reg >> 8); + + /* + * Fast AGC State Wait Time - Energy Detect Count + */ + + reg = DIV_ROUND_CLOSEST(phy->pdata->gain_ctrl.f_agc_state_wait_time_ns * + (clkrf / 1000UL), 1000000UL); + reg = clamp_t(uint32_t, reg, 0U, 31U); + ret |= ad9361_spi_writef(spi, REG_FAST_ENERGY_DETECT_COUNT, + ENERGY_DETECT_COUNT(~0), reg); + + return ret; +} + +/** + * Set the gain control mode. + * @param phy The AD9361 state structure. + * @param gain_ctrl A rf_gain_ctrl struct that contains the the desired + * channel information and the gain control mode. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_set_gain_ctrl_mode(struct ad9361_rf_phy *phy, + struct rf_gain_ctrl *gain_ctrl) +{ + struct spi_desc *spi = phy->spi; + int32_t rc = 0; + uint32_t gain_ctl_shift, mode; + uint8_t val; + + rc = ad9361_spi_readm(spi, REG_AGC_CONFIG_1, &val, 1); + if (rc) { + dev_err(dev, "Unable to read AGC config1 register: %x", + REG_AGC_CONFIG_1); + goto out; + } + + switch (gain_ctrl->mode) { + case RF_GAIN_MGC: + mode = RX_GAIN_CTL_MGC; + break; + case RF_GAIN_FASTATTACK_AGC: + mode = RX_GAIN_CTL_AGC_FAST_ATK; + break; + case RF_GAIN_SLOWATTACK_AGC: + mode = RX_GAIN_CTL_AGC_SLOW_ATK; + break; + case RF_GAIN_HYBRID_AGC: + mode = RX_GAIN_CTL_AGC_SLOW_ATK_HYBD; + break; + default: + rc = -EINVAL; + goto out; + } + + if (gain_ctrl->ant == 1) { + gain_ctl_shift = RX1_GAIN_CTRL_SHIFT; + } else if (gain_ctrl->ant == 2) { + gain_ctl_shift = RX2_GAIN_CTRL_SHIFT; + } else { + dev_err(dev, "Unknown Rx path %"PRIu32, gain_ctrl->ant); + rc = -EINVAL; + goto out; + } + + rc = ad9361_en_dis_rx(phy, gain_ctrl->ant, RX_DISABLE); + if (rc) { + dev_err(dev, "Unable to disable rx%"PRIu32, gain_ctrl->ant); + goto out; + } + + val &= ~(RX_GAIN_CTL_MASK << gain_ctl_shift); + val |= mode << gain_ctl_shift; + if (mode == RX_GAIN_CTL_AGC_SLOW_ATK_HYBD) + val |= SLOW_ATTACK_HYBRID_MODE; + else + val &= ~SLOW_ATTACK_HYBRID_MODE; + + rc = ad9361_spi_write(spi, REG_AGC_CONFIG_1, val); + if (rc) { + dev_err(dev, "Unable to write AGC config1 register: %x", + REG_AGC_CONFIG_1); + goto out; + } + + ad9361_en_dis_rx(phy, gain_ctrl->ant, RX_ENABLE); + rc = ad9361_gc_update(phy); +out: + return rc; +} + +/** + * Get the RSSI. + * @param phy The AD9361 state structure. + * @param rssi A rf_rssi struct to store the RSSI. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_read_rssi(struct ad9361_rf_phy *phy, struct rf_rssi *rssi) +{ + struct spi_desc *spi = phy->spi; + uint8_t reg_val_buf[6]; + int32_t rc; + + rc = ad9361_spi_readm(spi, REG_PREAMBLE_LSB, + reg_val_buf, ARRAY_SIZE(reg_val_buf)); + if (rssi->ant == 1) { + rssi->symbol = RSSI_RESOLUTION * + ((reg_val_buf[5] << RSSI_LSB_SHIFT) + + (reg_val_buf[1] & RSSI_LSB_MASK1)); + rssi->preamble = RSSI_RESOLUTION * + ((reg_val_buf[4] << RSSI_LSB_SHIFT) + + (reg_val_buf[0] & RSSI_LSB_MASK1)); + } else if (rssi->ant == 2) { + rssi->symbol = RSSI_RESOLUTION * + ((reg_val_buf[3] << RSSI_LSB_SHIFT) + + ((reg_val_buf[1] & RSSI_LSB_MASK2) >> 1)); + rssi->preamble = RSSI_RESOLUTION * + ((reg_val_buf[2] << RSSI_LSB_SHIFT) + + ((reg_val_buf[0] & RSSI_LSB_MASK2) >> 1)); + } else + rc = -EFAULT; + + rssi->multiplier = RSSI_MULTIPLIER; + + return rc; +} + +/** + * Setup the RX ADC. + * @param phy The AD9361 state structure. + * @param bbpll_freq The BBPLL frequency [Hz]. + * @param adc_sampl_freq_Hz The ADC sampling frequency [Hz]. + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t ad9361_rx_adc_setup(struct ad9361_rf_phy *phy, + uint32_t bbpll_freq, + uint32_t adc_sampl_freq_Hz) +{ + + uint32_t scale_snr_1e3, maxsnr, sqrt_inv_rc_tconst_1e3, tmp_1e3, + scaled_adc_clk_1e6, inv_scaled_adc_clk_1e3, sqrt_term_1e3, + min_sqrt_term_1e3, bb_bw_Hz; + uint64_t tmp, invrc_tconst_1e6; + uint8_t data[40]; + uint32_t i; + int32_t ret; + + uint8_t c3_msb = ad9361_spi_read(phy->spi, REG_RX_BBF_C3_MSB); + uint8_t c3_lsb = ad9361_spi_read(phy->spi, REG_RX_BBF_C3_LSB); + uint8_t r2346 = ad9361_spi_read(phy->spi, REG_RX_BBF_R2346); + + /* + * BBBW = (BBPLL / RxTuneDiv) * ln(2) / (1.4 * 2PI ) + * We assume ad9361_rx_bb_analog_filter_calib() is always run prior + */ + + tmp = bbpll_freq * 10000ULL; + do_div(&tmp, 126906UL * phy->rxbbf_div); + bb_bw_Hz = tmp; + + dev_dbg(&phy->spi->dev, "%s : BBBW %"PRIu32" : ADCfreq %"PRIu32, + __func__, bb_bw_Hz, adc_sampl_freq_Hz); + + dev_dbg(&phy->spi->dev, "c3_msb 0x%X : c3_lsb 0x%X : r2346 0x%X : ", + c3_msb, c3_lsb, r2346); + + bb_bw_Hz = clamp(bb_bw_Hz, 200000UL, 28000000UL); + + if (adc_sampl_freq_Hz < 80000000) + scale_snr_1e3 = 1000; + else + scale_snr_1e3 = 1585; /* pow(10, scale_snr_dB/10); */ + + if (bb_bw_Hz >= 18000000) { + invrc_tconst_1e6 = (160975ULL * r2346 * + (160 * c3_msb + 10 * c3_lsb + 140) * + (bb_bw_Hz)* (1000 + (10 * (bb_bw_Hz - 18000000) / 1000000))); + + do_div(&invrc_tconst_1e6, 1000UL); + + } else { + invrc_tconst_1e6 = (160975ULL * r2346 * + (160 * c3_msb + 10 * c3_lsb + 140) * + (bb_bw_Hz)); + } + + do_div(&invrc_tconst_1e6, 1000000000UL); + + if (invrc_tconst_1e6 > ULONG_MAX) + dev_err(&phy->spi->dev, "invrc_tconst_1e6 > ULONG_MAX"); + + sqrt_inv_rc_tconst_1e3 = int_sqrt((uint32_t)invrc_tconst_1e6); + maxsnr = 640 / 160; + scaled_adc_clk_1e6 = DIV_ROUND_CLOSEST(adc_sampl_freq_Hz, 640); + inv_scaled_adc_clk_1e3 = DIV_ROUND_CLOSEST(640000000, + DIV_ROUND_CLOSEST(adc_sampl_freq_Hz, 1000)); + tmp_1e3 = DIV_ROUND_CLOSEST(980000 + 20 * max_t(uint32_t, 1000U, + DIV_ROUND_CLOSEST(inv_scaled_adc_clk_1e3, maxsnr)), 1000); + sqrt_term_1e3 = int_sqrt(scaled_adc_clk_1e6); + min_sqrt_term_1e3 = min_t(uint32_t, 1000U, + int_sqrt(maxsnr * scaled_adc_clk_1e6)); + + dev_dbg(&phy->spi->dev, + "invrc_tconst_1e6 %"PRIu64", sqrt_inv_rc_tconst_1e3 %"PRIu32, + invrc_tconst_1e6, sqrt_inv_rc_tconst_1e3); + dev_dbg(&phy->spi->dev, + "scaled_adc_clk_1e6 %"PRIu32", inv_scaled_adc_clk_1e3 %"PRIu32, + scaled_adc_clk_1e6, inv_scaled_adc_clk_1e3); + dev_dbg(&phy->spi->dev, + "tmp_1e3 %"PRIu32", sqrt_term_1e3 %"PRIu32", min_sqrt_term_1e3 %"PRIu32, + tmp_1e3, sqrt_term_1e3, min_sqrt_term_1e3); + + data[0] = 0; + data[1] = 0; + data[2] = 0; + data[3] = 0x24; + data[4] = 0x24; + data[5] = 0; + data[6] = 0; + + tmp = -50000000 + 8ULL * scale_snr_1e3 * sqrt_inv_rc_tconst_1e3 * + min_sqrt_term_1e3; + do_div(&tmp, 100000000UL); + data[7] = min_t(uint64_t, 124U, tmp); + + tmp = (invrc_tconst_1e6 >> 1) + 20 * inv_scaled_adc_clk_1e3 * + data[7] / 80 * 1000ULL; + do_div(&tmp, invrc_tconst_1e6); + data[8] = min_t(uint64_t, 255U, tmp); + + tmp = (-500000 + 77ULL * sqrt_inv_rc_tconst_1e3 * min_sqrt_term_1e3); + do_div(&tmp, 1000000UL); + data[10] = min_t(uint64_t, 127U, tmp); + + data[9] = min_t(uint32_t, 127U, ((800 * data[10]) / 1000)); + tmp = ((invrc_tconst_1e6 >> 1) + (20 * inv_scaled_adc_clk_1e3 * + data[10] * 1000ULL)); + do_div(&tmp, invrc_tconst_1e6 * 77); + data[11] = min_t(uint64_t, 255U, tmp); + data[12] = min_t(uint32_t, 127U, (-500000 + 80 * sqrt_inv_rc_tconst_1e3 * + min_sqrt_term_1e3) / 1000000UL); + + tmp = -3 * (long)(invrc_tconst_1e6 >> 1) + inv_scaled_adc_clk_1e3 * + data[12] * (1000ULL * 20 / 80); + do_div(&tmp, invrc_tconst_1e6); + data[13] = min_t(uint64_t, 255, tmp); + + data[14] = 21 * (inv_scaled_adc_clk_1e3 / 10000); + data[15] = min_t(uint32_t, 127U, (500 + 1025 * data[7]) / 1000); + data[16] = min_t(uint32_t, 127U, (data[15] * tmp_1e3) / 1000); + data[17] = data[15]; + data[18] = min_t(uint32_t, 127U, (500 + 975 * data[10]) / 1000); + data[19] = min_t(uint32_t, 127U, (data[18] * tmp_1e3) / 1000); + data[20] = data[18]; + data[21] = min_t(uint32_t, 127U, (500 + 975 * data[12]) / 1000); + data[22] = min_t(uint32_t, 127, (data[21] * tmp_1e3) / 1000); + data[23] = data[21]; + data[24] = 0x2E; + data[25] = (128 + min_t(uint32_t, 63000U, DIV_ROUND_CLOSEST(63 * + scaled_adc_clk_1e6, 1000)) / 1000); + data[26] = min_t(uint32_t, 63U, 63 * scaled_adc_clk_1e6 / 1000000 * + (920 + 80 * inv_scaled_adc_clk_1e3 / 1000) / 1000); + data[27] = min_t(uint32_t, 63, (32 * sqrt_term_1e3) / 1000); + data[28] = data[25]; + data[29] = data[26]; + data[30] = data[27]; + data[31] = data[25]; + data[32] = data[26]; + data[33] = min_t(uint32_t, 63U, 63 * sqrt_term_1e3 / 1000); + data[34] = min_t(uint32_t, 127U, 64 * sqrt_term_1e3 / 1000); + data[35] = 0x40; + data[36] = 0x40; + data[37] = 0x2C; + data[38] = 0x00; + data[39] = 0x00; + + for (i = 0; i < 40; i++) { + ret = ad9361_spi_write(phy->spi, 0x200 + i, data[i]); + if (ret < 0) + return ret; + } + + return 0; +} + +/** + * Perform a RX TIA calibration. + * @param phy The AD9361 state structure. + * @param bb_bw_Hz The baseband bandwidth [Hz]. + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t ad9361_rx_tia_calib(struct ad9361_rf_phy *phy, uint32_t bb_bw_Hz) +{ + uint32_t Cbbf, R2346; + uint64_t CTIA_fF; + + uint8_t reg1EB = ad9361_spi_read(phy->spi, REG_RX_BBF_C3_MSB); + uint8_t reg1EC = ad9361_spi_read(phy->spi, REG_RX_BBF_C3_LSB); + uint8_t reg1E6 = ad9361_spi_read(phy->spi, REG_RX_BBF_R2346); + uint8_t reg1DB, reg1DF, reg1DD, reg1DC, reg1DE, temp; + + dev_dbg(&phy->spi->dev, "%s : bb_bw_Hz %"PRIu32, + __func__, bb_bw_Hz); + + bb_bw_Hz = clamp(bb_bw_Hz, 200000UL, 20000000UL); + + Cbbf = (reg1EB * 160) + (reg1EC * 10) + 140; /* fF */ + R2346 = 18300 * RX_BBF_R2346(reg1E6); + + CTIA_fF = Cbbf * R2346 * 560ULL; + do_div(&CTIA_fF, 3500000UL); + + if (bb_bw_Hz <= 3000000UL) + reg1DB = 0xE0; + else if (bb_bw_Hz <= 10000000UL) + reg1DB = 0x60; + else + reg1DB = 0x20; + + if (CTIA_fF > 2920ULL) { + reg1DC = 0x40; + reg1DE = 0x40; + temp = min(127U, DIV_ROUND_CLOSEST((uint32_t)CTIA_fF - 400, 320U)); + reg1DD = temp; + reg1DF = temp; + } else { + temp = DIV_ROUND_CLOSEST((uint32_t)CTIA_fF - 400, 40U) + 0x40; + reg1DC = temp; + reg1DE = temp; + reg1DD = 0; + reg1DF = 0; + } + + ad9361_spi_write(phy->spi, REG_RX_TIA_CONFIG, reg1DB); + ad9361_spi_write(phy->spi, REG_TIA1_C_LSB, reg1DC); + ad9361_spi_write(phy->spi, REG_TIA1_C_MSB, reg1DD); + ad9361_spi_write(phy->spi, REG_TIA2_C_LSB, reg1DE); + ad9361_spi_write(phy->spi, REG_TIA2_C_MSB, reg1DF); + + return 0; +} + +/** + * Perform a baseband RX analog filter calibration. + * @param phy The AD9361 state structure. + * @param rx_bb_bw The baseband bandwidth [Hz]. + * @param bbpll_freq The BBPLL frequency [Hz]. + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t ad9361_rx_bb_analog_filter_calib(struct ad9361_rf_phy *phy, + uint32_t rx_bb_bw, + uint32_t bbpll_freq) +{ + uint32_t target; + uint8_t tmp; + int32_t ret; + + dev_dbg(&phy->spi->dev, "%s : rx_bb_bw %"PRIu32" bbpll_freq %"PRIu32, + __func__, rx_bb_bw, bbpll_freq); + + rx_bb_bw = clamp(rx_bb_bw, 200000UL, 28000000UL); + + /* 1.4 * BBBW * 2PI / ln(2) */ + target = 126906UL * (rx_bb_bw / 10000UL); + phy->rxbbf_div = min_t(uint32_t, 511UL, DIV_ROUND_UP(bbpll_freq, target)); + + /* Set RX baseband filter divide value */ + ad9361_spi_write(phy->spi, REG_RX_BBF_TUNE_DIVIDE, phy->rxbbf_div); + ad9361_spi_writef(phy->spi, REG_RX_BBF_TUNE_CONFIG, BIT(0), + phy->rxbbf_div >> 8); + + /* Write the BBBW into registers 0x1FB and 0x1FC */ + ad9361_spi_write(phy->spi, REG_RX_BBBW_MHZ, rx_bb_bw / 1000000UL); + + tmp = DIV_ROUND_CLOSEST((rx_bb_bw % 1000000UL) * 128, 1000000UL); + ad9361_spi_write(phy->spi, REG_RX_BBBW_KHZ, min_t(uint8_t, 127, tmp)); + + ad9361_spi_write(phy->spi, REG_RX_MIX_LO_CM, + RX_MIX_LO_CM(0x3F)); /* Set Rx Mix LO CM */ + ad9361_spi_write(phy->spi, REG_RX_MIX_GM_CONFIG, + RX_MIX_GM_PLOAD(3)); /* Set GM common mode */ + + /* Enable the RX BBF tune circuit by writing 0x1E2=0x02 and 0x1E3=0x02 */ + ad9361_spi_write(phy->spi, REG_RX1_TUNE_CTRL, RX1_TUNE_RESAMPLE); + ad9361_spi_write(phy->spi, REG_RX2_TUNE_CTRL, RX2_TUNE_RESAMPLE); + + /* Start the RX Baseband Filter calibration in register 0x016[7] */ + /* Calibration is complete when register 0x016[7] self clears */ + ret = ad9361_run_calibration(phy, RX_BB_TUNE_CAL); + + /* Disable the RX baseband filter tune circuit, write 0x1E2=3, 0x1E3=3 */ + ad9361_spi_write(phy->spi, REG_RX1_TUNE_CTRL, + RX1_TUNE_RESAMPLE | RX1_PD_TUNE); + ad9361_spi_write(phy->spi, REG_RX2_TUNE_CTRL, + RX2_TUNE_RESAMPLE | RX2_PD_TUNE); + + return ret; +} + +/** + * Perform a baseband TX analog filter calibration. + * @param phy The AD9361 state structure. + * @param tx_bb_bw The baseband bandwidth [Hz]. + * @param bbpll_freq The BBPLL frequency [Hz]. + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t ad9361_tx_bb_analog_filter_calib(struct ad9361_rf_phy *phy, + uint32_t tx_bb_bw, + uint32_t bbpll_freq) +{ + uint32_t target, txbbf_div; + int32_t ret; + + dev_dbg(&phy->spi->dev, "%s : tx_bb_bw %"PRIu32" bbpll_freq %"PRIu32, + __func__, tx_bb_bw, bbpll_freq); + + tx_bb_bw = clamp(tx_bb_bw, 625000UL, 20000000UL); + + /* 1.6 * BBBW * 2PI / ln(2) */ + target = 145036 * (tx_bb_bw / 10000UL); + txbbf_div = min_t(uint32_t, 511UL, DIV_ROUND_UP(bbpll_freq, target)); + + /* Set TX baseband filter divide value */ + ad9361_spi_write(phy->spi, REG_TX_BBF_TUNE_DIVIDER, txbbf_div); + ad9361_spi_writef(phy->spi, REG_TX_BBF_TUNE_MODE, + TX_BBF_TUNE_DIVIDER, txbbf_div >> 8); + + /* Enable the TX baseband filter tune circuit by setting 0x0CA=0x22. */ + ad9361_spi_write(phy->spi, REG_TX_TUNE_CTRL, TUNER_RESAMPLE | TUNE_CTRL(1)); + + /* Start the TX Baseband Filter calibration in register 0x016[6] */ + /* Calibration is complete when register 0x016[] self clears */ + ret = ad9361_run_calibration(phy, TX_BB_TUNE_CAL); + + /* Disable the TX baseband filter tune circuit by writing 0x0CA=0x26. */ + ad9361_spi_write(phy->spi, REG_TX_TUNE_CTRL, + TUNER_RESAMPLE | TUNE_CTRL(1) | PD_TUNE); + + return ret; +} + +/** + * Perform a baseband TX secondary filter calibration. + * @param phy The AD9361 state structure. + * @param tx_rf_bw The RF bandwidth [Hz]. + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t ad9361_tx_bb_second_filter_calib(struct ad9361_rf_phy *phy, + uint32_t tx_bb_bw) +{ + uint64_t cap; + uint32_t corner, res, div; + uint32_t reg_conf, reg_res; + int32_t ret, i; + + dev_dbg(&phy->spi->dev, "%s : tx_bb_bw %"PRIu32, + __func__, tx_bb_bw); + + tx_bb_bw = clamp(tx_bb_bw, 530000UL, 20000000UL); + + /* BBBW * 5PI */ + corner = 15708 * (tx_bb_bw / 10000UL); + + for (i = 0, res = 1; i < 4; i++) { + div = corner * res; + cap = (500000000ULL) + (div >> 1); + do_div(&cap, div); + cap -= 12ULL; + if (cap < 64ULL) + break; + + res <<= 1; + } + + if (cap > 63ULL) + cap = 63ULL; + + if (tx_bb_bw <= 4500000UL) + reg_conf = 0x59; + else if (tx_bb_bw <= 12000000UL) + reg_conf = 0x56; + else + reg_conf = 0x57; + + switch (res) { + case 1: + reg_res = 0x0C; + break; + case 2: + reg_res = 0x04; + break; + case 4: + reg_res = 0x03; + break; + case 8: + reg_res = 0x01; + break; + default: + reg_res = 0x01; + } + + ret = ad9361_spi_write(phy->spi, REG_CONFIG0, reg_conf); + ret |= ad9361_spi_write(phy->spi, REG_RESISTOR, reg_res); + ret |= ad9361_spi_write(phy->spi, REG_CAPACITOR, (uint8_t)cap); + + return ret; +} + +/** + * Perform a RF synthesizer charge pump calibration. + * @param phy The AD9361 state structure. + * @param ref_clk_hz The reference clock rate [Hz]. + * @param tx The Synthesizer TX = 1, RX = 0. + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t ad9361_txrx_synth_cp_calib(struct ad9361_rf_phy *phy, + uint32_t ref_clk_hz, bool tx) +{ + uint32_t offs = tx ? 0x40 : 0; + uint32_t vco_cal_cnt; + dev_dbg(&phy->spi->dev, "%s : ref_clk_hz %"PRIu32" : is_tx %d", + __func__, ref_clk_hz, tx); + + /* REVIST: */ + ad9361_spi_write(phy->spi, REG_RX_CP_LEVEL_DETECT + offs, 0x17); + + ad9361_spi_write(phy->spi, REG_RX_DSM_SETUP_1 + offs, 0x0); + + ad9361_spi_write(phy->spi, REG_RX_LO_GEN_POWER_MODE + offs, 0x00); + ad9361_spi_write(phy->spi, REG_RX_VCO_LDO + offs, 0x0B); + ad9361_spi_write(phy->spi, REG_RX_VCO_PD_OVERRIDES + offs, 0x02); + ad9361_spi_write(phy->spi, REG_RX_CP_CURRENT + offs, 0x80); + ad9361_spi_write(phy->spi, REG_RX_CP_CONFIG + offs, CP_OFFSET_OFF); + + /* see Table 70 Example Calibration Times for RF VCO Cal */ + if (phy->pdata->fdd) { + vco_cal_cnt = VCO_CAL_EN | VCO_CAL_COUNT(3) | FB_CLOCK_ADV(2); + } else { + if (ref_clk_hz > 40000000UL) + vco_cal_cnt = VCO_CAL_EN | VCO_CAL_COUNT(1) | + FB_CLOCK_ADV(2); + else + vco_cal_cnt = VCO_CAL_EN | VCO_CAL_COUNT(0) | + FB_CLOCK_ADV(2); + } + + ad9361_spi_write(phy->spi, REG_RX_VCO_CAL + offs, vco_cal_cnt); + + /* Enable FDD mode during calibrations */ + + if (!phy->pdata->fdd) { + ad9361_spi_writef(phy->spi, REG_PARALLEL_PORT_CONF_3, + HALF_DUPLEX_MODE, 0); + } + + ad9361_spi_write(phy->spi, REG_ENSM_CONFIG_2, DUAL_SYNTH_MODE); + ad9361_spi_write(phy->spi, REG_ENSM_CONFIG_1, + FORCE_ALERT_STATE | + TO_ALERT); + ad9361_spi_write(phy->spi, REG_ENSM_MODE, FDD_MODE); + + ad9361_spi_write(phy->spi, REG_RX_CP_CONFIG + offs, + CP_OFFSET_OFF | CP_CAL_ENABLE); + + return ad9361_check_cal_done(phy, REG_RX_CAL_STATUS + offs, + CP_CAL_VALID, 1); +} + +/** + * Perform a baseband DC offset calibration. + * @param phy The AD9361 state structure. + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t ad9361_bb_dc_offset_calib(struct ad9361_rf_phy *phy) +{ + dev_dbg(&phy->spi->dev, "%s", __func__); + + ad9361_spi_write(phy->spi, REG_BB_DC_OFFSET_COUNT, 0x3F); + ad9361_spi_write(phy->spi, REG_BB_DC_OFFSET_SHIFT, BB_DC_M_SHIFT(0xF)); + ad9361_spi_write(phy->spi, REG_BB_DC_OFFSET_ATTEN, BB_DC_OFFSET_ATTEN(1)); + + return ad9361_run_calibration(phy, BBDC_CAL); +} + +/** + * Perform a RF DC offset calibration. + * @param phy The AD9361 state structure. + * @param ref_clk_hz The RX LO frequency [Hz]. + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t ad9361_rf_dc_offset_calib(struct ad9361_rf_phy *phy, + uint64_t rx_freq) +{ + struct spi_desc *spi = phy->spi; + + dev_dbg(&phy->spi->dev, "%s : rx_freq %"PRIu64, + __func__, rx_freq); + + ad9361_spi_write(spi, REG_WAIT_COUNT, 0x20); + + if (rx_freq <= 4000000000ULL) { + ad9361_spi_write(spi, REG_RF_DC_OFFSET_COUNT, + phy->pdata->rf_dc_offset_count_low); + ad9361_spi_write(spi, REG_RF_DC_OFFSET_CONFIG_1, + RF_DC_CALIBRATION_COUNT(4) | DAC_FS(2)); + ad9361_spi_write(spi, REG_RF_DC_OFFSET_ATTEN, + RF_DC_OFFSET_ATTEN( + phy->pdata->dc_offset_attenuation_low)); + } else { + ad9361_spi_write(spi, REG_RF_DC_OFFSET_COUNT, + phy->pdata->rf_dc_offset_count_high); + ad9361_spi_write(spi, REG_RF_DC_OFFSET_CONFIG_1, + RF_DC_CALIBRATION_COUNT(4) | DAC_FS(3)); + ad9361_spi_write(spi, REG_RF_DC_OFFSET_ATTEN, + RF_DC_OFFSET_ATTEN( + phy->pdata->dc_offset_attenuation_high)); + } + + ad9361_spi_write(spi, REG_DC_OFFSET_CONFIG2, + USE_WAIT_COUNTER_FOR_RF_DC_INIT_CAL | + DC_OFFSET_UPDATE(3)); + + if (phy->pdata->rx1rx2_phase_inversion_en || + (phy->pdata->port_ctrl.pp_conf[1] & INVERT_RX2)) { + ad9361_spi_write(spi, REG_INVERT_BITS, + INVERT_RX1_RF_DC_CGOUT_WORD); + } else { + ad9361_spi_write(spi, REG_INVERT_BITS, + INVERT_RX1_RF_DC_CGOUT_WORD | + INVERT_RX2_RF_DC_CGOUT_WORD); + } + + return ad9361_run_calibration(phy, RFDC_CAL); +} + +/** + * Update RF bandwidth. + * @param phy The AD9361 state structure. + * @param rf_rx_bw RF RX bandwidth [Hz]. + * @param rf_tx_bw RF TX bandwidth [Hz]. + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t __ad9361_update_rf_bandwidth(struct ad9361_rf_phy *phy, + uint32_t rf_rx_bw, uint32_t rf_tx_bw) +{ + uint32_t real_rx_bandwidth = rf_rx_bw / 2; + uint32_t real_tx_bandwidth = rf_tx_bw / 2; + uint32_t bbpll_freq; + int32_t ret; + + dev_dbg(&phy->spi->dev, "%s: %"PRIu32" %"PRIu32, + __func__, rf_rx_bw, rf_tx_bw); + + bbpll_freq = clk_get_rate(phy, phy->ref_clk_scale[BBPLL_CLK]); + + ret = ad9361_rx_bb_analog_filter_calib(phy, + real_rx_bandwidth, + bbpll_freq); + if (ret < 0) + return ret; + + ret = ad9361_tx_bb_analog_filter_calib(phy, + real_tx_bandwidth, + bbpll_freq); + if (ret < 0) + return ret; + + ret = ad9361_rx_tia_calib(phy, real_rx_bandwidth); + if (ret < 0) + return ret; + + ret = ad9361_tx_bb_second_filter_calib(phy, real_tx_bandwidth); + if (ret < 0) + return ret; + + ret = ad9361_rx_adc_setup(phy, + bbpll_freq, + clk_get_rate(phy, phy->ref_clk_scale[ADC_CLK])); + if (ret < 0) + return ret; + + return 0; +} + +/** + * TX Quad Calib. + * @param phy The AD9361 state structure. + * @param phase phase + * @param rxnco_word Rx NCO word. + * @param decim decim + * @param res res + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t __ad9361_tx_quad_calib(struct ad9361_rf_phy *phy, uint32_t phase, + uint32_t rxnco_word, uint32_t decim, uint8_t *res) +{ + int32_t ret; + + ad9361_spi_write(phy->spi, REG_QUAD_CAL_NCO_FREQ_PHASE_OFFSET, + RX_NCO_FREQ(rxnco_word) | RX_NCO_PHASE_OFFSET(phase)); + ad9361_spi_write(phy->spi, REG_QUAD_CAL_CTRL, + SETTLE_MAIN_ENABLE | DC_OFFSET_ENABLE | QUAD_CAL_SOFT_RESET | + GAIN_ENABLE | PHASE_ENABLE | M_DECIM(decim)); + ad9361_spi_write(phy->spi, REG_QUAD_CAL_CTRL, + SETTLE_MAIN_ENABLE | DC_OFFSET_ENABLE | + GAIN_ENABLE | PHASE_ENABLE | M_DECIM(decim)); + + ret = ad9361_run_calibration(phy, TX_QUAD_CAL); + if (ret < 0) + return ret; + + if (res) { + *res = ad9361_spi_read(phy->spi, + (phy->pdata->rx1tx1_mode_use_tx_num == 2) ? + REG_QUAD_CAL_STATUS_TX2 : REG_QUAD_CAL_STATUS_TX1) & + (TX1_LO_CONV | TX1_SSB_CONV); + if (phy->pdata->rx2tx2) + *res &= ad9361_spi_read(phy->spi, REG_QUAD_CAL_STATUS_TX2) & + (TX2_LO_CONV | TX2_SSB_CONV); + } + + return 0; +} + +/** + * Loop through all possible phase offsets in case the QUAD CAL doesn't converge. + * @param phy The AD9361 state structure. + * @param rxnco_word Rx NCO word. + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t ad9361_tx_quad_phase_search(struct ad9361_rf_phy *phy, + uint32_t rxnco_word, uint8_t decim) +{ + int32_t i, ret; + uint8_t field[64], val; + uint32_t start; + + dev_dbg(&phy->spi->dev, "%s", __func__); + + for (i = 0; i < (int64_t)(ARRAY_SIZE(field) / 2); i++) { + ret = __ad9361_tx_quad_calib(phy, i, rxnco_word, decim, &val); + if (ret < 0) + return ret; + + /* Handle 360/0 wrap around */ + field[i] = field[i + 32] = !((val & TX1_LO_CONV) && (val & TX1_SSB_CONV)); + } + + ret = ad9361_find_opt(field, ARRAY_SIZE(field), &start); + + phy->last_tx_quad_cal_phase = (start + ret / 2) & 0x1F; + +#ifdef _DEBUG + for (i = 0; i < 64; i++) { + printk("%c", (field[i] ? '#' : 'o')); + } +#ifdef WIN32 + printk(" RX_NCO_PHASE_OFFSET(%d, 0x%X) \n", phy->last_tx_quad_cal_phase, + phy->last_tx_quad_cal_phase); +#else + printk(" RX_NCO_PHASE_OFFSET(%"PRIu32", 0x%"PRIX32") \n", + phy->last_tx_quad_cal_phase, + phy->last_tx_quad_cal_phase); +#endif +#endif + + ret = __ad9361_tx_quad_calib(phy, phy->last_tx_quad_cal_phase, rxnco_word, + decim, NULL); + if (ret < 0) + return ret; + + return 0; +} + +/** + * Perform a TX quadrature calibration. + * @param phy The AD9361 state structure. + * @param bw The bandwidth [Hz]. + * @param rx_phase The optional RX phase value overwrite (set to zero). + * @return 0 in case of success, negative error code otherwise. + */ + +static int ad9361_tx_quad_calib(struct ad9361_rf_phy *phy, + uint32_t bw_rx, uint32_t bw_tx, + int32_t rx_phase) +{ + struct spi_desc *spi = phy->spi; + uint32_t clktf, clkrf; + int32_t txnco_word, rxnco_word, txnco_freq, ret; + uint8_t __rx_phase = 0, reg_inv_bits = 0, val, decim; + bool phase_inversion_en; + + ret = 0; + if (phy->cached_synth_pd[0] & TX_LO_POWER_DOWN) { + if (phy->pdata->lo_powerdown_managed_en) { + ad9361_spi_writef(spi, REG_TX_SYNTH_POWER_DOWN_OVERRIDE, + TX_LO_POWER_DOWN, 0); + } else { + dev_err(dev, + "%s : Tx QUAD Cal abort due to TX LO in powerdown\n", + __func__); + return -EFAULT; + } + } + /* + * Find NCO frequency that matches this equation: + * BW / 4 = Rx NCO freq = Tx NCO freq: + * Rx NCO = ClkRF * (rxNCO <1:0> + 1) / 32 + * Tx NCO = ClkTF * (txNCO <1:0> + 1) / 32 + */ + + clkrf = clk_get_rate(phy, phy->ref_clk_scale[CLKRF_CLK]); + clktf = clk_get_rate(phy, phy->ref_clk_scale[CLKTF_CLK]); + + dev_dbg(&phy->spi->dev, "%s : bw_tx %"PRIu32" clkrf %"PRIu32" clktf %"PRIu32, + __func__, bw_tx, clkrf, clktf); + + txnco_word = DIV_ROUND_CLOSEST(bw_tx * 8, clktf) - 1; + txnco_word = clamp_t(int, txnco_word, 0, 3); + rxnco_word = txnco_word; + + dev_dbg(dev, "Tx NCO frequency: %"PRIu32" (BW/4: %"PRIu32") txnco_word %"PRId32, + clktf * (txnco_word + 1) / 32, bw_tx / 4, txnco_word); + + if (clktf <= 4000000UL) + decim = 2; + else + decim = 3; + + if (clkrf == (2 * clktf)) { + __rx_phase = 0x0E; + switch (txnco_word) { + case 0: + txnco_word++; + break; + case 1: + rxnco_word--; + break; + case 2: + rxnco_word -= 2; + txnco_word--; + break; + case 3: + rxnco_word -= 2; /* REVISIT */ + __rx_phase = 0x08; + break; + } + } else if (clkrf == clktf) { + switch (txnco_word) { + case 0: + case 3: + __rx_phase = 0x15; + break; + case 2: + __rx_phase = 0x1F; + break; + case 1: + if (ad9361_spi_readf(spi, + REG_TX_ENABLE_FILTER_CTRL, 0x3F) == 0x22) + __rx_phase = 0x15; /* REVISIT */ + else + __rx_phase = 0x1A; + break; + } + } else + dev_err(dev, "Unhandled case in %s line %d clkrf %"PRIu32" clktf %"PRIu32, + __func__, __LINE__, clkrf, clktf); + + if (rx_phase >= 0) + __rx_phase = rx_phase; + + txnco_freq = clktf * (txnco_word + 1) / 32; + + if (txnco_freq > (int64_t)(bw_rx / 4) || txnco_freq > (int64_t)(bw_tx / 4)) { + /* Make sure the BW during calibration is wide enough */ + ret = __ad9361_update_rf_bandwidth(phy, txnco_freq * 8, txnco_freq * 8); + if (ret < 0) + goto out_restore; + } + + phase_inversion_en = phy->pdata->rx1rx2_phase_inversion_en || + (phy->pdata->port_ctrl.pp_conf[1] & INVERT_RX2); + + if (phase_inversion_en) { + ad9361_spi_writef(spi, REG_PARALLEL_PORT_CONF_2, INVERT_RX2, 0); + + reg_inv_bits = ad9361_spi_read(spi, REG_INVERT_BITS); + + ad9361_spi_write(spi, REG_INVERT_BITS, + INVERT_RX1_RF_DC_CGOUT_WORD | + INVERT_RX2_RF_DC_CGOUT_WORD); + } + + ad9361_spi_writef(spi, REG_KEXP_2, TX_NCO_FREQ(~0), txnco_word); + ad9361_spi_write(spi, REG_QUAD_CAL_COUNT, 0xFF); + ad9361_spi_write(spi, REG_KEXP_1, KEXP_TX(1) | KEXP_TX_COMP(3) | + KEXP_DC_I(3) | KEXP_DC_Q(3)); + ad9361_spi_write(spi, REG_MAG_FTEST_THRESH, 0x03); + ad9361_spi_write(spi, REG_MAG_FTEST_THRESH_2, 0x03); + + if (phy->tx_quad_lpf_tia_match < 0) /* set in ad9361_load_gt() */ + dev_err(dev, "failed to find suitable LPF TIA value in gain table\n"); + else + ad9361_spi_write(spi, REG_TX_QUAD_FULL_LMT_GAIN, + phy->tx_quad_lpf_tia_match); + + ad9361_spi_write(spi, REG_QUAD_SETTLE_COUNT, 0xF0); + ad9361_spi_write(spi, REG_TX_QUAD_LPF_GAIN, 0x00); + + if (rx_phase != -2) { + ret = __ad9361_tx_quad_calib(phy, __rx_phase, rxnco_word, decim, &val); + + dev_dbg(dev, "LO leakage: %d Quadrature Calibration: %d : rx_phase %d\n", + !!(val & TX1_LO_CONV), !!(val & TX1_SSB_CONV), __rx_phase); + + /* Calibration failed -> try last phase offset */ + if (val != (TX1_LO_CONV | TX1_SSB_CONV)) { + if (phy->last_tx_quad_cal_phase < 31) + ret = __ad9361_tx_quad_calib(phy, phy->last_tx_quad_cal_phase, + rxnco_word, decim, &val); + } else { + phy->last_tx_quad_cal_phase = __rx_phase; + } + } else { + /* force phase search */ + val = 0; + } + /* Calibration failed -> loop through all 32 phase offsets */ + if (val != (TX1_LO_CONV | TX1_SSB_CONV)) + ret = ad9361_tx_quad_phase_search(phy, rxnco_word, decim); + + if (phase_inversion_en) { + ad9361_spi_writef(spi, REG_PARALLEL_PORT_CONF_2, INVERT_RX2, 1); + ad9361_spi_write(spi, REG_INVERT_BITS, reg_inv_bits); + } + + if (txnco_freq > (int64_t)(bw_rx / 4) || txnco_freq > (int64_t)(bw_tx / 4)) { + __ad9361_update_rf_bandwidth(phy, + phy->current_rx_bw_Hz, + phy->current_tx_bw_Hz); + } + +out_restore: + /* Restore synthesizer powerdown configuration */ + if (phy->pdata->lo_powerdown_managed_en && + (phy->cached_synth_pd[0] & TX_LO_POWER_DOWN)) + ad9361_synth_lo_powerdown(phy, LO_DONTCARE, LO_DONTCARE); + + return ret; +} + +/** + * Setup RX tracking calibrations. + * @param phy The AD9361 state structure. + * @param bbdc_track Set true, will enable the BBDC tracking. + * @param rfdc_track Set true, will enable the RFDC tracking. + * @param rxquad_track Set true, will enable the RXQUAD tracking. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_tracking_control(struct ad9361_rf_phy *phy, bool bbdc_track, + bool rfdc_track, bool rxquad_track) +{ + struct spi_desc *spi = phy->spi; + uint32_t qtrack = 0; + + dev_dbg(&spi->dev, "%s : bbdc_track=%d, rfdc_track=%d, rxquad_track=%d", + __func__, bbdc_track, rfdc_track, rxquad_track); + + ad9361_spi_write(spi, REG_CALIBRATION_CONFIG_2, + CALIBRATION_CONFIG2_DFLT | K_EXP_PHASE(0x15)); + ad9361_spi_write(spi, REG_CALIBRATION_CONFIG_3, + PREVENT_POS_LOOP_GAIN | K_EXP_AMPLITUDE(0x15)); + + ad9361_spi_write(spi, REG_DC_OFFSET_CONFIG2, + USE_WAIT_COUNTER_FOR_RF_DC_INIT_CAL | + DC_OFFSET_UPDATE(phy->pdata->dc_offset_update_events) | + (bbdc_track ? ENABLE_BB_DC_OFFSET_TRACKING : 0) | + (rfdc_track ? ENABLE_RF_OFFSET_TRACKING : 0)); + + ad9361_spi_writef(spi, REG_RX_QUAD_GAIN2, + CORRECTION_WORD_DECIMATION_M(~0), + phy->pdata->qec_tracking_slow_mode_en ? 4 : 0); + + if (rxquad_track) { + if (phy->pdata->rx2tx2) + qtrack = ENABLE_TRACKING_MODE_CH1 | ENABLE_TRACKING_MODE_CH2; + else + qtrack = (phy->pdata->rx1tx1_mode_use_rx_num == 1) ? + ENABLE_TRACKING_MODE_CH1 : ENABLE_TRACKING_MODE_CH2; + } + + ad9361_spi_write(spi, REG_CALIBRATION_CONFIG_1, + ENABLE_PHASE_CORR | ENABLE_GAIN_CORR | + FREE_RUN_MODE | ENABLE_CORR_WORD_DECIMATION | + qtrack); + + return 0; +} + +/** + * Enable/disable the VCO cal. + * @param phy The AD9361 state structure. + * @param rx Set true for rx. + * @param enable Set true to enable. + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t ad9361_trx_vco_cal_control(struct ad9361_rf_phy *phy, + bool tx, bool enable) +{ + dev_dbg(&phy->spi->dev, "%s : state %d", + __func__, enable); + + return ad9361_spi_writef(phy->spi, + tx ? REG_TX_PFD_CONFIG : REG_RX_PFD_CONFIG, + BYPASS_LD_SYNTH, !enable); +} + +/** + * Enable/disable the ext. LO. + * @param phy The AD9361 state structure. + * @param rx Set true for rx. + * @param enable Set true to enable. + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t ad9361_trx_ext_lo_control(struct ad9361_rf_phy *phy, + bool tx, bool enable) +{ + uint32_t val = enable ? ~0 : 0; + int32_t ret; + + /* REVIST: + * POWER_DOWN_TRX_SYNTH and MCS_RF_ENABLE somehow conflict + */ + + bool mcs_rf_enable = ad9361_spi_readf(phy->spi, + REG_MULTICHIP_SYNC_AND_TX_MON_CTRL, + MCS_RF_ENABLE); + + dev_dbg(&phy->spi->dev, "%s : %s state %d", __func__, + tx ? "TX" : "RX", enable); + + if (tx) { + ret = ad9361_spi_writef(phy->spi, REG_ENSM_CONFIG_2, + POWER_DOWN_TX_SYNTH, mcs_rf_enable ? 0 : enable); + + ret = ad9361_spi_writef(phy->spi, REG_ENSM_CONFIG_2, + TX_SYNTH_READY_MASK, enable); + + ret |= ad9361_spi_writef(phy->spi, REG_RFPLL_DIVIDERS, + TX_VCO_DIVIDER(~0), enable ? 7 : + phy->cached_tx_rfpll_div); + + if (enable) + phy->cached_synth_pd[0] |= TX_SYNTH_VCO_ALC_POWER_DOWN | + TX_SYNTH_PTAT_POWER_DOWN | + TX_SYNTH_VCO_POWER_DOWN; + else + phy->cached_synth_pd[0] &= ~(TX_SYNTH_VCO_ALC_POWER_DOWN | + TX_SYNTH_PTAT_POWER_DOWN | + TX_SYNTH_VCO_POWER_DOWN); + + + ret |= ad9361_spi_write(phy->spi, REG_TX_SYNTH_POWER_DOWN_OVERRIDE, + phy->cached_synth_pd[0]); + + ret |= ad9361_spi_writef(phy->spi, REG_ANALOG_POWER_DOWN_OVERRIDE, + TX_EXT_VCO_BUFFER_POWER_DOWN, !enable); + + ret |= ad9361_spi_write(phy->spi, REG_TX_LO_GEN_POWER_MODE, + TX_LO_GEN_POWER_MODE(val)); + } else { + ret = ad9361_spi_writef(phy->spi, REG_ENSM_CONFIG_2, + POWER_DOWN_RX_SYNTH, mcs_rf_enable ? 0 : enable); + + ret = ad9361_spi_writef(phy->spi, REG_ENSM_CONFIG_2, + RX_SYNTH_READY_MASK, enable); + + ret |= ad9361_spi_writef(phy->spi, REG_RFPLL_DIVIDERS, + RX_VCO_DIVIDER(~0), enable ? 7 : + phy->cached_rx_rfpll_div); + + if (enable) + phy->cached_synth_pd[1] |= RX_SYNTH_VCO_ALC_POWER_DOWN | + RX_SYNTH_PTAT_POWER_DOWN | + RX_SYNTH_VCO_POWER_DOWN; + else + phy->cached_synth_pd[1] &= ~(TX_SYNTH_VCO_ALC_POWER_DOWN | + RX_SYNTH_PTAT_POWER_DOWN | + RX_SYNTH_VCO_POWER_DOWN); + + ret |= ad9361_spi_write(phy->spi, REG_RX_SYNTH_POWER_DOWN_OVERRIDE, + phy->cached_synth_pd[1]); + + ret |= ad9361_spi_writef(phy->spi, REG_ANALOG_POWER_DOWN_OVERRIDE, + RX_EXT_VCO_BUFFER_POWER_DOWN, !enable); + + ret |= ad9361_spi_write(phy->spi, REG_RX_LO_GEN_POWER_MODE, + RX_LO_GEN_POWER_MODE(val)); + } + + return ret; +} + +/** + * Power down the TX and/or RX Local Oscillators. + * @param phy The AD9361 state structure. + * @param rx The RX LO setting. + * @param tx The TX LO setting. + * @return 0 in case of success, negative error code otherwise. + */ +int ad9361_synth_lo_powerdown(struct ad9361_rf_phy *phy, + enum synth_pd_ctrl rx, + enum synth_pd_ctrl tx) +{ + dev_dbg(&phy->spi->dev, "%s : RX(%d) TX(%d)", __func__, rx, tx); + + switch (rx) { + case LO_OFF: + phy->cached_synth_pd[1] |= RX_LO_POWER_DOWN; + break; + case LO_ON: + phy->cached_synth_pd[1] &= ~RX_LO_POWER_DOWN; + break; + case LO_DONTCARE: + break; + } + + switch (tx) { + case LO_OFF: + phy->cached_synth_pd[0] |= TX_LO_POWER_DOWN; + break; + case LO_ON: + phy->cached_synth_pd[0] &= ~TX_LO_POWER_DOWN; + break; + case LO_DONTCARE: + break; + } + + return ad9361_spi_writem(phy->spi, REG_TX_SYNTH_POWER_DOWN_OVERRIDE, + phy->cached_synth_pd, 2); +} + +/** + * Setup the reference clock delay unit counter register. + * @param phy The AD9361 state structure. + * @param ref_clk_hz The reference clock frequency [Hz]. + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t ad9361_set_ref_clk_cycles(struct ad9361_rf_phy *phy, + uint32_t ref_clk_hz) +{ + dev_dbg(&phy->spi->dev, "%s : ref_clk_hz %"PRIu32, + __func__, ref_clk_hz); + + return ad9361_spi_write(phy->spi, REG_REFERENCE_CLOCK_CYCLES, + REFERENCE_CLOCK_CYCLES_PER_US((ref_clk_hz / 1000000UL) - 1)); +} + +/** + * Setup the DCXO tune. + * @param phy The AD9361 state structure. + * @param coarse The DCXO tune coarse. + * @param fine The DCXO tune fine. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_set_dcxo_tune(struct ad9361_rf_phy *phy, + uint32_t coarse, uint32_t fine) +{ + dev_dbg(&phy->spi->dev, "%s : coarse %"PRIu32" fine %"PRIu32, + __func__, coarse, fine); + + if (phy->pdata->use_extclk) + return -ENODEV; + + ad9361_spi_write(phy->spi, REG_DCXO_COARSE_TUNE, + DCXO_TUNE_COARSE(coarse)); + ad9361_spi_write(phy->spi, REG_DCXO_FINE_TUNE_LOW, + DCXO_TUNE_FINE_LOW(fine)); + return ad9361_spi_write(phy->spi, REG_DCXO_FINE_TUNE_HIGH, + DCXO_TUNE_FINE_HIGH(fine)); +} + +/** + * Setup TXMON. + * @param phy The AD9361 state structure. + * @param ctrl The TXMON settings. + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t ad9361_txmon_setup(struct ad9361_rf_phy *phy, + struct tx_monitor_control *ctrl) +{ + struct spi_desc *spi = phy->spi; + + dev_dbg(&phy->spi->dev, "%s", __func__); + + ad9361_spi_write(spi, REG_TPM_MODE_ENABLE, + (ctrl->one_shot_mode_en ? ONE_SHOT_MODE : 0) | + TX_MON_DURATION(ilog2(ctrl->tx_mon_duration / 16))); + + ad9361_spi_write(spi, REG_TX_MON_DELAY, ctrl->tx_mon_delay & 0xFF); + ad9361_spi_writef(spi, REG_TX_LEVEL_THRESH, + TX_MON_DELAY_COUNTER(~0), ctrl->tx_mon_delay >> 8); + + ad9361_spi_write(spi, REG_TX_MON_1_CONFIG, + TX_MON_1_LO_CM(ctrl->tx1_mon_lo_cm) | + TX_MON_1_GAIN(ctrl->tx1_mon_front_end_gain)); + ad9361_spi_write(spi, REG_TX_MON_2_CONFIG, + TX_MON_2_LO_CM(ctrl->tx2_mon_lo_cm) | + TX_MON_2_GAIN(ctrl->tx2_mon_front_end_gain)); + + ad9361_spi_write(spi, REG_TX_ATTEN_THRESH, + ctrl->low_high_gain_threshold_mdB / 250); + + ad9361_spi_write(spi, REG_TX_MON_HIGH_GAIN, + TX_MON_HIGH_GAIN(ctrl->high_gain_dB)); + + ad9361_spi_write(spi, REG_TX_MON_LOW_GAIN, + (ctrl->tx_mon_track_en ? TX_MON_TRACK : 0) | + TX_MON_LOW_GAIN(ctrl->low_gain_dB)); + + return 0; +} + +/** + * Enable TXMON. + * @param phy The AD9361 state structure. + * @param en_mask The enable mask. + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t ad9361_txmon_control(struct ad9361_rf_phy *phy, + int32_t en_mask) +{ + dev_dbg(&phy->spi->dev, "%s: mask 0x%"PRIx32, __func__, en_mask); + +#if 0 + if (!phy->pdata->fdd && en_mask) { + ad9361_spi_writef(phy->spi, REG_ENSM_CONFIG_1, + ENABLE_RX_DATA_PORT_FOR_CAL, 1); + phy->txmon_tdd_en = true; + } else { + ad9361_spi_writef(phy->spi, REG_ENSM_CONFIG_1, + ENABLE_RX_DATA_PORT_FOR_CAL, 0); + phy->txmon_tdd_en = false; + } +#endif + + ad9361_spi_writef(phy->spi, REG_ANALOG_POWER_DOWN_OVERRIDE, + TX_MONITOR_POWER_DOWN(~0), ~en_mask); + + ad9361_spi_writef(phy->spi, REG_TPM_MODE_ENABLE, + TX1_MON_ENABLE, !!(en_mask & TX_1)); + + return ad9361_spi_writef(phy->spi, REG_TPM_MODE_ENABLE, + TX2_MON_ENABLE, !!(en_mask & TX_2)); +} + +/** +* Setup the RF port. +* Note: +* val +* 0 (RX1A_N & RX1A_P) and (RX2A_N & RX2A_P) enabled; balanced +* 1 (RX1B_N & RX1B_P) and (RX2B_N & RX2B_P) enabled; balanced +* 2 (RX1C_N & RX1C_P) and (RX2C_N & RX2C_P) enabled; balanced +* +* 3 RX1A_N and RX2A_N enabled; unbalanced +* 4 RX1A_P and RX2A_P enabled; unbalanced +* 5 RX1B_N and RX2B_N enabled; unbalanced +* 6 RX1B_P and RX2B_P enabled; unbalanced +* 7 RX1C_N and RX2C_N enabled; unbalanced +* 8 RX1C_P and RX2C_P enabled; unbalanced +* 9 TX_MON1 +* 10 TX_MON2 +* 11 TX_MON1 & TX_MON2 +* @param phy The AD9361 state structure. +* @param is_out TX RF output port enabled. +* @param rx_inputs RX input option identifier +* @param txb TX output option identifier +* @return 0 in case of success, negative error code otherwise. +*/ +int32_t ad9361_rf_port_setup(struct ad9361_rf_phy *phy, bool is_out, + uint32_t rx_inputs, uint32_t txb) +{ + uint32_t val; + + if (rx_inputs > 11) + return -EINVAL; + + if (!is_out) { + if (rx_inputs > 8) + return ad9361_txmon_control(phy, rx_inputs & (TX_1 | TX_2)); + else + ad9361_txmon_control(phy, 0); + } + + if (rx_inputs < 3) + val = 3 << (rx_inputs * 2); + else + val = 1 << (rx_inputs - 3); + + if (txb) + val |= TX_OUTPUT; /* Select TX1B, TX2B */ + + dev_dbg(&phy->spi->dev, "%s : INPUT_SELECT 0x%"PRIx32, + __func__, val); + + return ad9361_spi_write(phy->spi, REG_INPUT_SELECT, val); +} + +/** + * Setup the Parallel Port (Digital Data Interface). + * @param phy The AD9361 state structure. + * @param restore_c3 Set true, will restore the Parallel Port Configuration 3 + * register. + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t ad9361_pp_port_setup(struct ad9361_rf_phy *phy, bool restore_c3) +{ + struct spi_desc *spi = phy->spi; + struct ad9361_phy_platform_data *pd = phy->pdata; + + dev_dbg(&phy->spi->dev, "%s", __func__); + + if (restore_c3) { + return ad9361_spi_write(spi, REG_PARALLEL_PORT_CONF_3, + pd->port_ctrl.pp_conf[2]); + } + + /* Sanity check */ + if (pd->port_ctrl.pp_conf[2] & LVDS_MODE) + pd->port_ctrl.pp_conf[2] &= + ~(HALF_DUPLEX_MODE | SINGLE_DATA_RATE | SINGLE_PORT_MODE); + + if (pd->port_ctrl.pp_conf[2] & FULL_PORT) + pd->port_ctrl.pp_conf[2] &= ~(HALF_DUPLEX_MODE | SINGLE_PORT_MODE); + + ad9361_spi_write(spi, REG_PARALLEL_PORT_CONF_1, pd->port_ctrl.pp_conf[0]); + ad9361_spi_write(spi, REG_PARALLEL_PORT_CONF_2, pd->port_ctrl.pp_conf[1]); + ad9361_spi_write(spi, REG_PARALLEL_PORT_CONF_3, pd->port_ctrl.pp_conf[2]); + ad9361_spi_write(spi, REG_RX_CLOCK_DATA_DELAY, pd->port_ctrl.rx_clk_data_delay); + ad9361_spi_write(spi, REG_TX_CLOCK_DATA_DELAY, pd->port_ctrl.tx_clk_data_delay); + + ad9361_spi_write(spi, REG_LVDS_BIAS_CTRL, pd->port_ctrl.lvds_bias_ctrl); + // ad9361_spi_write(spi, REG_DIGITAL_IO_CTRL, pd->port_ctrl.digital_io_ctrl); + ad9361_spi_write(spi, REG_LVDS_INVERT_CTRL1, pd->port_ctrl.lvds_invert[0]); + ad9361_spi_write(spi, REG_LVDS_INVERT_CTRL2, pd->port_ctrl.lvds_invert[1]); + + if (pd->rx1rx2_phase_inversion_en || + (pd->port_ctrl.pp_conf[1] & INVERT_RX2)) { + + ad9361_spi_writef(spi, REG_PARALLEL_PORT_CONF_2, INVERT_RX2, 1); + ad9361_spi_writef(spi, REG_INVERT_BITS, + INVERT_RX2_RF_DC_CGOUT_WORD, 0); + } + + return 0; +} + +/** + * Setup the Gain Control Blocks (common function for MGC, AGC modes) + * @param phy The AD9361 state structure. + * @param ctrl The gain control settings. + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t ad9361_gc_setup(struct ad9361_rf_phy *phy, + struct gain_control *ctrl) +{ + struct spi_desc *spi = phy->spi; + uint32_t reg, tmp1, tmp2; + + dev_dbg(&phy->spi->dev, "%s", __func__); + + reg = DEC_PWR_FOR_GAIN_LOCK_EXIT | DEC_PWR_FOR_LOCK_LEVEL | + DEC_PWR_FOR_LOW_PWR; + + if (ctrl->rx1_mode == RF_GAIN_HYBRID_AGC || + ctrl->rx2_mode == RF_GAIN_HYBRID_AGC) + reg |= SLOW_ATTACK_HYBRID_MODE; + + reg |= RX1_GAIN_CTRL_SETUP(ctrl->rx1_mode) | + RX2_GAIN_CTRL_SETUP(ctrl->rx2_mode); + + phy->agc_mode[0] = ctrl->rx1_mode; + phy->agc_mode[1] = ctrl->rx2_mode; + + ad9361_spi_write(spi, REG_AGC_CONFIG_1, reg); // Gain Control Mode Select + + /* AGC_USE_FULL_GAIN_TABLE handled in ad9361_load_gt() */ + ad9361_spi_writef(spi, REG_AGC_CONFIG_2, MAN_GAIN_CTRL_RX1, + ctrl->mgc_rx1_ctrl_inp_en); + ad9361_spi_writef(spi, REG_AGC_CONFIG_2, MAN_GAIN_CTRL_RX2, + ctrl->mgc_rx2_ctrl_inp_en); + ad9361_spi_writef(spi, REG_AGC_CONFIG_2, DIG_GAIN_EN, + ctrl->dig_gain_en); + + ctrl->adc_ovr_sample_size = clamp_t(uint8_t, ctrl->adc_ovr_sample_size, 1U, 8U); + reg = ADC_OVERRANGE_SAMPLE_SIZE(ctrl->adc_ovr_sample_size - 1); + + if (has_split_gt && phy->pdata->split_gt && + (ctrl->mgc_rx1_ctrl_inp_en || ctrl->mgc_rx2_ctrl_inp_en)) { + switch (ctrl->mgc_split_table_ctrl_inp_gain_mode) { + case 1: + reg &= ~INCDEC_LMT_GAIN; + break; + case 2: + reg |= INCDEC_LMT_GAIN; + break; + default: + case 0: + reg |= USE_AGC_FOR_LMTLPF_GAIN; + break; + } + } + + ctrl->mgc_inc_gain_step = clamp_t(uint8_t, ctrl->mgc_inc_gain_step, 1U, 8U); + reg |= MANUAL_INCR_STEP_SIZE(ctrl->mgc_inc_gain_step - 1); + ad9361_spi_write(spi, REG_AGC_CONFIG_3, + reg); // Incr Step Size, ADC Overrange Size + + ctrl->mgc_dec_gain_step = clamp_t(uint8_t, ctrl->mgc_dec_gain_step, 1U, 8U); + reg = MANUAL_CTRL_IN_DECR_GAIN_STP_SIZE(ctrl->mgc_dec_gain_step - 1); + ad9361_spi_write(spi, REG_PEAK_WAIT_TIME, + reg); // Decr Step Size, Peak Overload Time + + if (ctrl->dig_gain_en) + ad9361_spi_write(spi, REG_DIGITAL_GAIN, + MAXIMUM_DIGITAL_GAIN(ctrl->max_dig_gain) | + DIG_GAIN_STP_SIZE(ctrl->dig_gain_step_size)); + + if (ctrl->adc_large_overload_thresh >= ctrl->adc_small_overload_thresh) { + ad9361_spi_write(spi, REG_ADC_SMALL_OVERLOAD_THRESH, + ctrl->adc_small_overload_thresh); // ADC Small Overload Threshold + ad9361_spi_write(spi, REG_ADC_LARGE_OVERLOAD_THRESH, + ctrl->adc_large_overload_thresh); // ADC Large Overload Threshold + } else { + ad9361_spi_write(spi, REG_ADC_SMALL_OVERLOAD_THRESH, + ctrl->adc_large_overload_thresh); // ADC Small Overload Threshold + ad9361_spi_write(spi, REG_ADC_LARGE_OVERLOAD_THRESH, + ctrl->adc_small_overload_thresh); // ADC Large Overload Threshold + } + + reg = (ctrl->lmt_overload_high_thresh / 16) - 1; + reg = clamp(reg, 0U, 63U); + ad9361_spi_write(spi, REG_LARGE_LMT_OVERLOAD_THRESH, reg); + reg = (ctrl->lmt_overload_low_thresh / 16) - 1; + reg = clamp(reg, 0U, 63U); + ad9361_spi_writef(spi, REG_SMALL_LMT_OVERLOAD_THRESH, + SMALL_LMT_OVERLOAD_THRESH(~0), reg); + + if (has_split_gt && phy->pdata->split_gt) { + /* REVIST */ + ad9361_spi_write(spi, REG_RX1_MANUAL_LPF_GAIN, 0x58); // Rx1 LPF Gain Index + ad9361_spi_write(spi, REG_RX2_MANUAL_LPF_GAIN, 0x18); // Rx2 LPF Gain Index + ad9361_spi_write(spi, REG_FAST_INITIAL_LMT_GAIN_LIMIT, + 0x27); // Initial LMT Gain Limit + } + + ad9361_spi_write(spi, REG_RX1_MANUAL_DIGITALFORCED_GAIN, + 0x00); // Rx1 Digital Gain Index + ad9361_spi_write(spi, REG_RX2_MANUAL_DIGITALFORCED_GAIN, + 0x00); // Rx2 Digital Gain Index + + reg = clamp_t(uint8_t, ctrl->low_power_thresh, 0U, 64U) * 2; + ad9361_spi_write(spi, REG_FAST_LOW_POWER_THRESH, reg); // Low Power Threshold + ad9361_spi_write(spi, REG_TX_SYMBOL_ATTEN_CONFIG, + 0x00); // Tx Symbol Gain Control + + ad9361_spi_writef(spi, REG_DEC_POWER_MEASURE_DURATION_0, + USE_HB1_OUT_FOR_DEC_PWR_MEAS, + !ctrl->use_rx_fir_out_for_dec_pwr_meas); // USE HB1 or FIR output for power measurements + + ad9361_spi_writef(spi, REG_DEC_POWER_MEASURE_DURATION_0, + ENABLE_DEC_PWR_MEAS, 1); // Power Measurement Duration + + if (ctrl->rx1_mode == RF_GAIN_FASTATTACK_AGC || + ctrl->rx2_mode == RF_GAIN_FASTATTACK_AGC) + reg = ilog2(ctrl->f_agc_dec_pow_measuremnt_duration / 16); + else + reg = ilog2(ctrl->dec_pow_measuremnt_duration / 16); + + ad9361_spi_writef(spi, REG_DEC_POWER_MEASURE_DURATION_0, + DEC_POWER_MEASUREMENT_DURATION(~0), reg); // Power Measurement Duration + + /* AGC */ + + tmp1 = reg = clamp_t(uint8_t, ctrl->agc_inner_thresh_high, 0U, 127U); + ad9361_spi_writef(spi, REG_AGC_LOCK_LEVEL, + AGC_LOCK_LEVEL_FAST_AGC_INNER_HIGH_THRESH_SLOW(~0), + reg); + + tmp2 = reg = clamp_t(uint8_t, ctrl->agc_inner_thresh_low, 0U, 127U); + reg |= (ctrl->adc_lmt_small_overload_prevent_gain_inc ? + PREVENT_GAIN_INC : 0); + ad9361_spi_write(spi, REG_AGC_INNER_LOW_THRESH, reg); + + reg = AGC_OUTER_HIGH_THRESH(tmp1 - ctrl->agc_outer_thresh_high) | + AGC_OUTER_LOW_THRESH(ctrl->agc_outer_thresh_low - tmp2); + ad9361_spi_write(spi, REG_OUTER_POWER_THRESHS, reg); + + reg = AGC_OUTER_HIGH_THRESH_EXED_STP_SIZE(ctrl->agc_outer_thresh_high_dec_steps) + | + AGC_OUTER_LOW_THRESH_EXED_STP_SIZE(ctrl->agc_outer_thresh_low_inc_steps); + ad9361_spi_write(spi, REG_GAIN_STP_2, reg); + + reg = ((ctrl->immed_gain_change_if_large_adc_overload) ? + IMMED_GAIN_CHANGE_IF_LG_ADC_OVERLOAD : 0) | + ((ctrl->immed_gain_change_if_large_lmt_overload) ? + IMMED_GAIN_CHANGE_IF_LG_LMT_OVERLOAD : 0) | + AGC_INNER_HIGH_THRESH_EXED_STP_SIZE(ctrl->agc_inner_thresh_high_dec_steps) | + AGC_INNER_LOW_THRESH_EXED_STP_SIZE(ctrl->agc_inner_thresh_low_inc_steps); + ad9361_spi_write(spi, REG_GAIN_STP1, reg); + + reg = LARGE_ADC_OVERLOAD_EXED_COUNTER(ctrl->adc_large_overload_exceed_counter) | + SMALL_ADC_OVERLOAD_EXED_COUNTER(ctrl->adc_small_overload_exceed_counter); + ad9361_spi_write(spi, REG_ADC_OVERLOAD_COUNTERS, reg); + + reg = DECREMENT_STP_SIZE_FOR_SMALL_LPF_GAIN_CHANGE( + ctrl->f_agc_large_overload_inc_steps) | + LARGE_LPF_GAIN_STEP(ctrl->adc_large_overload_inc_steps); + ad9361_spi_write(spi, REG_GAIN_STP_CONFIG_2, reg); + + reg = LARGE_LMT_OVERLOAD_EXED_COUNTER(ctrl->lmt_overload_large_exceed_counter) | + SMALL_LMT_OVERLOAD_EXED_COUNTER(ctrl->lmt_overload_small_exceed_counter); + ad9361_spi_write(spi, REG_LMT_OVERLOAD_COUNTERS, reg); + + ad9361_spi_writef(spi, REG_GAIN_STP_CONFIG1, + DEC_STP_SIZE_FOR_LARGE_LMT_OVERLOAD(~0), + ctrl->lmt_overload_large_inc_steps); + + reg = DIG_SATURATION_EXED_COUNTER(ctrl->dig_saturation_exceed_counter) | + (ctrl->sync_for_gain_counter_en ? + ENABLE_SYNC_FOR_GAIN_COUNTER : 0); + ad9361_spi_write(spi, REG_DIGITAL_SAT_COUNTER, reg); + + /* + * Fast AGC + */ + + /* Fast AGC - Low Power */ + ad9361_spi_writef(spi, REG_FAST_CONFIG_1, + ENABLE_INCR_GAIN, + ctrl->f_agc_allow_agc_gain_increase); + + ad9361_spi_write(spi, REG_FAST_INCREMENT_TIME, + ctrl->f_agc_lp_thresh_increment_time); + + reg = ctrl->f_agc_lp_thresh_increment_steps - 1; + reg = clamp_t(uint32_t, reg, 0U, 7U); + ad9361_spi_writef(spi, REG_FAST_ENERGY_DETECT_COUNT, + INCREMENT_GAIN_STP_LPFLMT(~0), reg); + + /* Fast AGC - Lock Level */ + /* Dual use see also agc_inner_thresh_high */ + ad9361_spi_writef(spi, REG_FAST_CONFIG_2_SETTLING_DELAY, + ENABLE_LMT_GAIN_INC_FOR_LOCK_LEVEL, + ctrl->f_agc_lock_level_lmt_gain_increase_en); + + reg = ctrl->f_agc_lock_level_gain_increase_upper_limit; + reg = clamp_t(uint32_t, reg, 0U, 63U); + ad9361_spi_writef(spi, REG_FAST_AGCLL_UPPER_LIMIT, + AGCLL_MAX_INCREASE(~0), reg); + + /* Fast AGC - Peak Detectors and Final Settling */ + reg = ctrl->f_agc_lpf_final_settling_steps; + reg = clamp_t(uint32_t, reg, 0U, 3U); + ad9361_spi_writef(spi, REG_FAST_ENERGY_LOST_THRESH, + POST_LOCK_LEVEL_STP_SIZE_FOR_LPF_TABLE_FULL_TABLE(~0), + reg); + + reg = ctrl->f_agc_lmt_final_settling_steps; + reg = clamp_t(uint32_t, reg, 0U, 3U); + ad9361_spi_writef(spi, REG_FAST_STRONGER_SIGNAL_THRESH, + POST_LOCK_LEVEL_STP_FOR_LMT_TABLE(~0), reg); + + reg = ctrl->f_agc_final_overrange_count; + reg = clamp_t(uint32_t, reg, 0U, 7U); + ad9361_spi_writef(spi, REG_FAST_FINAL_OVER_RANGE_AND_OPT_GAIN, + FINAL_OVER_RANGE_COUNT(~0), reg); + + /* Fast AGC - Final Power Test */ + ad9361_spi_writef(spi, REG_FAST_CONFIG_1, + ENABLE_GAIN_INC_AFTER_GAIN_LOCK, + ctrl->f_agc_gain_increase_after_gain_lock_en); + + /* Fast AGC - Unlocking the Gain */ + /* 0 = MAX Gain, 1 = Optimized Gain, 2 = Set Gain */ + + reg = ctrl->f_agc_gain_index_type_after_exit_rx_mode; + ad9361_spi_writef(spi, REG_FAST_CONFIG_1, + GOTO_SET_GAIN_IF_EXIT_RX_STATE, reg == SET_GAIN); + ad9361_spi_writef(spi, REG_FAST_CONFIG_1, + GOTO_OPTIMIZED_GAIN_IF_EXIT_RX_STATE, + reg == OPTIMIZED_GAIN); + + ad9361_spi_writef(spi, REG_FAST_CONFIG_2_SETTLING_DELAY, + USE_LAST_LOCK_LEVEL_FOR_SET_GAIN, + ctrl->f_agc_use_last_lock_level_for_set_gain_en); + + reg = ctrl->f_agc_optimized_gain_offset; + reg = clamp_t(uint32_t, reg, 0U, 15U); + ad9361_spi_writef(spi, REG_FAST_FINAL_OVER_RANGE_AND_OPT_GAIN, + OPTIMIZE_GAIN_OFFSET(~0), reg); + + tmp1 = !ctrl->f_agc_rst_gla_stronger_sig_thresh_exceeded_en || + !ctrl->f_agc_rst_gla_engergy_lost_sig_thresh_exceeded_en || + !ctrl->f_agc_rst_gla_large_adc_overload_en || + !ctrl->f_agc_rst_gla_large_lmt_overload_en || + ctrl->f_agc_rst_gla_en_agc_pulled_high_en; + + ad9361_spi_writef(spi, REG_AGC_CONFIG_2, + AGC_GAIN_UNLOCK_CTRL, tmp1); + + reg = !ctrl->f_agc_rst_gla_stronger_sig_thresh_exceeded_en; + ad9361_spi_writef(spi, REG_FAST_STRONG_SIGNAL_FREEZE, + DONT_UNLOCK_GAIN_IF_STRONGER_SIGNAL, reg); + + reg = ctrl->f_agc_rst_gla_stronger_sig_thresh_above_ll; + reg = clamp_t(uint32_t, reg, 0U, 63U); + ad9361_spi_writef(spi, REG_FAST_STRONGER_SIGNAL_THRESH, + STRONGER_SIGNAL_THRESH(~0), reg); + + reg = ctrl->f_agc_rst_gla_engergy_lost_sig_thresh_below_ll; + reg = clamp_t(uint32_t, reg, 0U, 63U); + ad9361_spi_writef(spi, REG_FAST_ENERGY_LOST_THRESH, + ENERGY_LOST_THRESH(~0), reg); + + reg = ctrl->f_agc_rst_gla_engergy_lost_goto_optim_gain_en; + ad9361_spi_writef(spi, REG_FAST_CONFIG_1, + GOTO_OPT_GAIN_IF_ENERGY_LOST_OR_EN_AGC_HIGH, reg); + + reg = !ctrl->f_agc_rst_gla_engergy_lost_sig_thresh_exceeded_en; + ad9361_spi_writef(spi, REG_FAST_CONFIG_1, + DONT_UNLOCK_GAIN_IF_ENERGY_LOST, reg); + + reg = ctrl->f_agc_energy_lost_stronger_sig_gain_lock_exit_cnt; + reg = clamp_t(uint32_t, reg, 0U, 63U); + ad9361_spi_writef(spi, REG_FAST_GAIN_LOCK_EXIT_COUNT, + GAIN_LOCK_EXIT_COUNT(~0), reg); + + reg = !ctrl->f_agc_rst_gla_large_adc_overload_en || + !ctrl->f_agc_rst_gla_large_lmt_overload_en; + ad9361_spi_writef(spi, REG_FAST_CONFIG_1, + DONT_UNLOCK_GAIN_IF_LG_ADC_OR_LMT_OVRG, reg); + + reg = !ctrl->f_agc_rst_gla_large_adc_overload_en; + ad9361_spi_writef(spi, REG_FAST_LOW_POWER_THRESH, + DONT_UNLOCK_GAIN_IF_ADC_OVRG, reg); + + /* 0 = Max Gain, 1 = Set Gain, 2 = Optimized Gain, 3 = No Gain Change */ + + if (ctrl->f_agc_rst_gla_en_agc_pulled_high_en) { + switch (ctrl->f_agc_rst_gla_if_en_agc_pulled_high_mode) { + case MAX_GAIN: + ad9361_spi_writef(spi, REG_FAST_CONFIG_2_SETTLING_DELAY, + GOTO_MAX_GAIN_OR_OPT_GAIN_IF_EN_AGC_HIGH, 1); + + ad9361_spi_writef(spi, REG_FAST_CONFIG_1, + GOTO_SET_GAIN_IF_EN_AGC_HIGH, 0); + + ad9361_spi_writef(spi, REG_FAST_CONFIG_1, + GOTO_OPT_GAIN_IF_ENERGY_LOST_OR_EN_AGC_HIGH, 0); + break; + case SET_GAIN: + ad9361_spi_writef(spi, REG_FAST_CONFIG_2_SETTLING_DELAY, + GOTO_MAX_GAIN_OR_OPT_GAIN_IF_EN_AGC_HIGH, 0); + + ad9361_spi_writef(spi, REG_FAST_CONFIG_1, + GOTO_SET_GAIN_IF_EN_AGC_HIGH, 1); + break; + case OPTIMIZED_GAIN: + ad9361_spi_writef(spi, REG_FAST_CONFIG_2_SETTLING_DELAY, + GOTO_MAX_GAIN_OR_OPT_GAIN_IF_EN_AGC_HIGH, 1); + + ad9361_spi_writef(spi, REG_FAST_CONFIG_1, + GOTO_SET_GAIN_IF_EN_AGC_HIGH, 0); + + ad9361_spi_writef(spi, REG_FAST_CONFIG_1, + GOTO_OPT_GAIN_IF_ENERGY_LOST_OR_EN_AGC_HIGH, 1); + break; + case NO_GAIN_CHANGE: + ad9361_spi_writef(spi, REG_FAST_CONFIG_1, + GOTO_SET_GAIN_IF_EN_AGC_HIGH, 0); + ad9361_spi_writef(spi, REG_FAST_CONFIG_2_SETTLING_DELAY, + GOTO_MAX_GAIN_OR_OPT_GAIN_IF_EN_AGC_HIGH, 0); + break; + } + } else { + ad9361_spi_writef(spi, REG_FAST_CONFIG_1, + GOTO_SET_GAIN_IF_EN_AGC_HIGH, 0); + ad9361_spi_writef(spi, REG_FAST_CONFIG_2_SETTLING_DELAY, + GOTO_MAX_GAIN_OR_OPT_GAIN_IF_EN_AGC_HIGH, 0); + } + + reg = ilog2(ctrl->f_agc_power_measurement_duration_in_state5 / 16); + reg = clamp_t(uint32_t, reg, 0U, 15U); + ad9361_spi_writef(spi, REG_RX1_MANUAL_LPF_GAIN, + POWER_MEAS_IN_STATE_5(~0), reg); + ad9361_spi_writef(spi, REG_RX1_MANUAL_LMT_FULL_GAIN, + POWER_MEAS_IN_STATE_5_MSB, reg >> 3); + + return ad9361_gc_update(phy); +} + +/** + * Set the Aux DAC. + * @param phy The AD9361 state structure. + * @param dac The DAC. + * @param val_mV The value. + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t ad9361_auxdac_set(struct ad9361_rf_phy *phy, int32_t dac, + int32_t val_mV) +{ + struct spi_desc *spi = phy->spi; + uint32_t val, tmp; + + dev_dbg(&phy->spi->dev, "%s DAC%"PRId32" = %"PRId32" mV", __func__, dac, + val_mV); + + /* Disable DAC if val == 0, Ignored in ENSM Auto Mode */ + ad9361_spi_writef(spi, REG_AUXDAC_ENABLE_CTRL, + AUXDAC_MANUAL_BAR(dac), val_mV ? 0 : 1); + + if (val_mV < 306) + val_mV = 306; + + if (val_mV < 1888) { + val = ((val_mV - 306) * 1000) / 1469; /* Vref = 1V, Step = 2 */ + tmp = AUXDAC_1_VREF(0); + } else { + val = ((val_mV - 1761) * 1000) / 1512; /* Vref = 2.5V, Step = 2 */ + tmp = AUXDAC_1_VREF(3); + } + + val = clamp_t(uint32_t, val, 0, 1023); + + switch (dac) { + case 1: + ad9361_spi_write(spi, REG_AUXDAC_1_WORD, val >> 2); + ad9361_spi_write(spi, REG_AUXDAC_1_CONFIG, AUXDAC_1_WORD_LSB(val) | tmp); + phy->auxdac1_value = val_mV; + break; + case 2: + ad9361_spi_write(spi, REG_AUXDAC_2_WORD, val >> 2); + ad9361_spi_write(spi, REG_AUXDAC_2_CONFIG, AUXDAC_2_WORD_LSB(val) | tmp); + phy->auxdac2_value = val_mV; + break; + default: + return -EINVAL; + } + + return 0; +} + +/** + * Get the Aux DAC value. + * @param phy The AD9361 state structure. + * @param dac The DAC. + * @return The value in case of success, negative error code otherwise. + */ +int32_t ad9361_auxdac_get(struct ad9361_rf_phy *phy, int32_t dac) +{ + + switch (dac) { + case 1: + return phy->auxdac1_value; + case 2: + return phy->auxdac2_value; + default: + return -EINVAL; + } + + return 0; +} + +/** + * Setup the AuxDAC. + * @param phy The AD9361 state structure. + * @param ctrl Pointer to auxdac_control structure. + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t ad9361_auxdac_setup(struct ad9361_rf_phy *phy, + struct auxdac_control *ctrl) +{ + struct spi_desc *spi = phy->spi; + uint8_t tmp; + + dev_dbg(&phy->spi->dev, "%s", __func__); + + ad9361_auxdac_set(phy, 1, ctrl->dac1_default_value); + ad9361_auxdac_set(phy, 2, ctrl->dac2_default_value); + + tmp = ~(AUXDAC_AUTO_TX_BAR(ctrl->dac2_in_tx_en << 1 | ctrl->dac1_in_tx_en) | + AUXDAC_AUTO_RX_BAR(ctrl->dac2_in_rx_en << 1 | ctrl->dac1_in_rx_en) | + AUXDAC_INIT_BAR(ctrl->dac2_in_alert_en << 1 | ctrl->dac1_in_alert_en)); + + ad9361_spi_writef(spi, REG_AUXDAC_ENABLE_CTRL, + AUXDAC_AUTO_TX_BAR(~0) | + AUXDAC_AUTO_RX_BAR(~0) | + AUXDAC_INIT_BAR(~0), + tmp); /* Auto Control */ + + ad9361_spi_writef(spi, REG_EXTERNAL_LNA_CTRL, + AUXDAC_MANUAL_SELECT, ctrl->auxdac_manual_mode_en); + ad9361_spi_write(spi, REG_AUXDAC1_RX_DELAY, ctrl->dac1_rx_delay_us); + ad9361_spi_write(spi, REG_AUXDAC1_TX_DELAY, ctrl->dac1_tx_delay_us); + ad9361_spi_write(spi, REG_AUXDAC2_RX_DELAY, ctrl->dac2_rx_delay_us); + ad9361_spi_write(spi, REG_AUXDAC2_TX_DELAY, ctrl->dac2_tx_delay_us); + + return 0; +} + +/** + * Setup the AuxADC. + * @param phy The AD9361 state structure. + * @param ctrl The AuxADC settings. + * @param bbpll_freq The BBPLL frequency [Hz]. + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t ad9361_auxadc_setup(struct ad9361_rf_phy *phy, + struct auxadc_control *ctrl, + uint32_t bbpll_freq) +{ + struct spi_desc *spi = phy->spi; + uint32_t val; + + dev_dbg(&phy->spi->dev, "%s", __func__); + + val = DIV_ROUND_CLOSEST(ctrl->temp_time_inteval_ms * + (bbpll_freq / 1000UL), (1 << 29)); + + ad9361_spi_write(spi, REG_TEMP_OFFSET, ctrl->offset); + ad9361_spi_write(spi, REG_START_TEMP_READING, 0x00); + ad9361_spi_write(spi, REG_TEMP_SENSE2, + MEASUREMENT_TIME_INTERVAL(val) | + (ctrl->periodic_temp_measuremnt ? + TEMP_SENSE_PERIODIC_ENABLE : 0)); + ad9361_spi_write(spi, REG_TEMP_SENSOR_CONFIG, + TEMP_SENSOR_DECIMATION( + ilog2(ctrl->temp_sensor_decimation) - 8)); + ad9361_spi_write(spi, REG_AUXADC_CLOCK_DIVIDER, + bbpll_freq / ctrl->auxadc_clock_rate); + ad9361_spi_write(spi, REG_AUXADC_CONFIG, + AUX_ADC_DECIMATION( + ilog2(ctrl->auxadc_decimation) - 8)); + + return 0; +} + +/** + * Get the measured temperature of the device. + * @param phy The AD9361 state structure. + * @return The measured temperature of the device. + */ +int32_t ad9361_get_temp(struct ad9361_rf_phy *phy) +{ + uint32_t val; + + ad9361_spi_writef(phy->spi, REG_AUXADC_CONFIG, AUXADC_POWER_DOWN, 1); + val = ad9361_spi_read(phy->spi, REG_TEMPERATURE); + ad9361_spi_writef(phy->spi, REG_AUXADC_CONFIG, AUXADC_POWER_DOWN, 0); + + return DIV_ROUND_CLOSEST(val * 1000000, 1140); +} + +/** + * Get the Aux ADC value. + * @param phy The AD9361 state structure. + * @return The value in case of success, negative error code otherwise. + */ +int32_t ad9361_get_auxadc(struct ad9361_rf_phy *phy) +{ + uint8_t buf[2]; + + ad9361_spi_writef(phy->spi, REG_AUXADC_CONFIG, AUXADC_POWER_DOWN, 1); + ad9361_spi_readm(phy->spi, REG_AUXADC_LSB, buf, 2); + ad9361_spi_writef(phy->spi, REG_AUXADC_CONFIG, AUXADC_POWER_DOWN, 0); + + return (buf[1] << 4) | AUXADC_WORD_LSB(buf[0]); +} + +/** + * Setup the Control Output pins. + * @param phy The AD9361 state structure. + * @param ctrl The Control Output pins settings. + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t ad9361_ctrl_outs_setup(struct ad9361_rf_phy *phy, + struct ctrl_outs_control *ctrl) +{ + struct spi_desc *spi = phy->spi; + + dev_dbg(&phy->spi->dev, "%s", __func__); + + ad9361_spi_write(spi, REG_CTRL_OUTPUT_POINTER, ctrl->index); // Ctrl Out index + return ad9361_spi_write(spi, REG_CTRL_OUTPUT_ENABLE, + ctrl->en_mask); // Ctrl Out [7:0] output enable +} + +/** + * Setup the GPO pins. + * @param phy The AD9361 state structure. + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t ad9361_gpo_setup(struct ad9361_rf_phy *phy, + struct gpo_control *ctrl) +{ + struct spi_desc *spi = phy->spi; + + dev_dbg(&phy->spi->dev, "%s", __func__); + + ad9361_spi_write(spi, REG_AUTO_GPO, + GPO_ENABLE_AUTO_RX(ctrl->gpo0_slave_rx_en | + (ctrl->gpo1_slave_rx_en << 1) | + (ctrl->gpo2_slave_rx_en << 2) | + (ctrl->gpo3_slave_rx_en << 3)) | + GPO_ENABLE_AUTO_TX(ctrl->gpo0_slave_tx_en | + (ctrl->gpo1_slave_tx_en << 1) | + (ctrl->gpo2_slave_tx_en << 2) | + (ctrl->gpo3_slave_tx_en << 3))); + + ad9361_spi_write(spi, REG_GPO_FORCE_AND_INIT, + GPO_MANUAL_CTRL(ctrl->gpo_manual_mode_enable_mask) | + GPO_INIT_STATE(ctrl->gpo0_inactive_state_high_en | + (ctrl->gpo1_inactive_state_high_en << 1) | + (ctrl->gpo2_inactive_state_high_en << 2) | + (ctrl->gpo3_inactive_state_high_en << 3))); + + ad9361_spi_write(spi, REG_GPO0_RX_DELAY, ctrl->gpo0_rx_delay_us); + ad9361_spi_write(spi, REG_GPO0_TX_DELAY, ctrl->gpo0_tx_delay_us); + ad9361_spi_write(spi, REG_GPO1_RX_DELAY, ctrl->gpo1_rx_delay_us); + ad9361_spi_write(spi, REG_GPO1_TX_DELAY, ctrl->gpo1_tx_delay_us); + ad9361_spi_write(spi, REG_GPO2_RX_DELAY, ctrl->gpo2_rx_delay_us); + ad9361_spi_write(spi, REG_GPO2_TX_DELAY, ctrl->gpo2_tx_delay_us); + ad9361_spi_write(spi, REG_GPO3_RX_DELAY, ctrl->gpo3_rx_delay_us); + ad9361_spi_write(spi, REG_GPO3_TX_DELAY, ctrl->gpo3_tx_delay_us); + + /* + * GPO manual mode conflicts with automatic ENSM slave and eLNA mode + */ + ad9361_spi_writef(phy->spi, REG_EXTERNAL_LNA_CTRL, GPO_MANUAL_SELECT, + ctrl->gpo_manual_mode_en); + + return 0; +} + +/** + * Setup the RSSI. + * @param phy The AD9361 state structure. + * @param ctrl The RSSI settings. + * @param is_update True if update + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t ad9361_rssi_setup(struct ad9361_rf_phy *phy, + struct rssi_control *ctrl, + bool is_update) +{ + struct spi_desc *spi = phy->spi; + uint32_t total_weight, weight[4], total_dur = 0, temp; + uint8_t dur_buf[4] = { 0 }; + int32_t val, ret, i, j = 0; + uint32_t rssi_delay; + uint32_t rssi_wait; + int32_t rssi_duration; + uint32_t rate; + + dev_dbg(&phy->spi->dev, "%s", __func__); + + if (ctrl->rssi_unit_is_rx_samples) { + if (is_update) + return 0; /* no update required */ + + rssi_delay = ctrl->rssi_delay; + rssi_wait = ctrl->rssi_wait; + rssi_duration = ctrl->rssi_duration; + } else { + /* update sample based on RX rate */ + rate = DIV_ROUND_CLOSEST( + clk_get_rate(phy, phy->ref_clk_scale[RX_SAMPL_CLK]), 1000); + /* units are in us */ + rssi_delay = DIV_ROUND_CLOSEST(ctrl->rssi_delay * rate, 1000); + rssi_wait = DIV_ROUND_CLOSEST(ctrl->rssi_wait * rate, 1000); + rssi_duration = DIV_ROUND_CLOSEST( + ctrl->rssi_duration * rate, 1000); + } + + if (ctrl->restart_mode == EN_AGC_PIN_IS_PULLED_HIGH) + rssi_delay = 0; + + rssi_delay = clamp(rssi_delay / 8, 0U, 255U); + rssi_wait = clamp(rssi_wait / 4, 0U, 255U); + + do { + for (i = 14; rssi_duration > 0 && i >= 0; i--) { + val = 1 << i; + if ((int64_t)rssi_duration >= val) { + dur_buf[j++] = i; + total_dur += val; + rssi_duration -= val; + break; + } + } + + } while (j < 4 && rssi_duration > 0); + + for (i = 0, total_weight = 0; i < 4; i++) { + if (i < j) + total_weight += weight[i] = + DIV_ROUND_CLOSEST(RSSI_MAX_WEIGHT * + (1 << dur_buf[i]), total_dur); + else + total_weight += weight[i] = 0; + } + + /* total of all weights must be 0xFF */ + val = total_weight - 0xFF; + weight[j - 1] -= val; + + ad9361_spi_write(spi, REG_MEASURE_DURATION_01, + (dur_buf[1] << 4) | dur_buf[0]); // RSSI Measurement Duration 0, 1 + ad9361_spi_write(spi, REG_MEASURE_DURATION_23, + (dur_buf[3] << 4) | dur_buf[2]); // RSSI Measurement Duration 2, 3 + ad9361_spi_write(spi, REG_RSSI_WEIGHT_0, + weight[0]); // RSSI Weighted Multiplier 0 + ad9361_spi_write(spi, REG_RSSI_WEIGHT_1, + weight[1]); // RSSI Weighted Multiplier 1 + ad9361_spi_write(spi, REG_RSSI_WEIGHT_2, + weight[2]); // RSSI Weighted Multiplier 2 + ad9361_spi_write(spi, REG_RSSI_WEIGHT_3, + weight[3]); // RSSI Weighted Multiplier 3 + ad9361_spi_write(spi, REG_RSSI_DELAY, rssi_delay); // RSSI Delay + ad9361_spi_write(spi, REG_RSSI_WAIT_TIME, rssi_wait); // RSSI Wait + + temp = RSSI_MODE_SELECT(ctrl->restart_mode); + if (ctrl->restart_mode == SPI_WRITE_TO_REGISTER) + temp |= START_RSSI_MEAS; + + if (rssi_duration == 0 && j == 1) /* Power of two */ + temp |= DEFAULT_RSSI_MEAS_MODE; + + ret = ad9361_spi_write(spi, REG_RSSI_CONFIG, temp); // RSSI Mode Select + + if (ret < 0) + dev_err(&phy->spi->dev, "Unable to write rssi config"); + + return 0; +} + +/** + * This function needs to be called whenever BBPLL changes. + * @param phy The AD9361 state structure. + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t ad9361_bb_clk_change_handler(struct ad9361_rf_phy *phy) +{ + int32_t ret; + + ret = ad9361_gc_update(phy); + ret |= ad9361_rssi_setup(phy, &phy->pdata->rssi_ctrl, true); + ret |= ad9361_auxadc_setup(phy, &phy->pdata->auxadc_ctrl, + clk_get_rate(phy, phy->ref_clk_scale[BBPLL_CLK])); + + return ret; +} + +/** + * Set the desired Enable State Machine (ENSM) state. + * @param phy The AD9361 state structure. + * @param ensm_state The ENSM state [ENSM_STATE_SLEEP_WAIT, ENSM_STATE_ALERT, + * ENSM_STATE_TX, ENSM_STATE_TX_FLUSH, ENSM_STATE_RX, + * ENSM_STATE_RX_FLUSH, ENSM_STATE_FDD, ENSM_STATE_FDD_FLUSH]. + * @param pinctrl Set true, will enable the ENSM pin control. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_ensm_set_state(struct ad9361_rf_phy *phy, uint8_t ensm_state, + bool pinctrl) +{ + struct spi_desc *spi = phy->spi; + int32_t rc = 0; + uint32_t val; + uint32_t tmp; + + dev_dbg(dev, "Device is in %x state, moving to %x", phy->curr_ensm_state, + ensm_state); + + + if (phy->curr_ensm_state == ENSM_STATE_SLEEP) { + ad9361_spi_write(spi, REG_CLOCK_ENABLE, + DIGITAL_POWER_UP | CLOCK_ENABLE_DFLT | BBPLL_ENABLE | + (phy->pdata->use_extclk ? XO_BYPASS : 0)); /* Enable Clocks */ + udelay(20); + ad9361_spi_write(spi, REG_ENSM_CONFIG_1, TO_ALERT | FORCE_ALERT_STATE); + ad9361_trx_vco_cal_control(phy, false, true); /* Enable VCO Cal */ + ad9361_trx_vco_cal_control(phy, true, true); + } + + val = (phy->pdata->ensm_pin_pulse_mode ? 0 : LEVEL_MODE) | + (pinctrl ? ENABLE_ENSM_PIN_CTRL : 0) | + (phy->txmon_tdd_en ? ENABLE_RX_DATA_PORT_FOR_CAL : 0) | + TO_ALERT; + + switch (ensm_state) { + case ENSM_STATE_TX: + val |= FORCE_TX_ON; + if (phy->pdata->fdd) + rc = -EINVAL; + else if (phy->curr_ensm_state != ENSM_STATE_ALERT) + rc = -EINVAL; + break; + case ENSM_STATE_RX: + val |= FORCE_RX_ON; + if (phy->pdata->fdd) + rc = -EINVAL; + else if (phy->curr_ensm_state != ENSM_STATE_ALERT) + rc = -EINVAL; + break; + case ENSM_STATE_FDD: + val |= FORCE_TX_ON; + if (!phy->pdata->fdd) + rc = -EINVAL; + break; + case ENSM_STATE_ALERT: + val &= ~(FORCE_TX_ON | FORCE_RX_ON); + val |= TO_ALERT | FORCE_ALERT_STATE; + break; + case ENSM_STATE_SLEEP_WAIT: + break; + case ENSM_STATE_SLEEP: + ad9361_trx_vco_cal_control(phy, false, false); /* Disable VCO Cal */ + ad9361_trx_vco_cal_control(phy, true, false); + ad9361_spi_write(spi, REG_ENSM_CONFIG_1, 0); /* Clear To Alert */ + ad9361_spi_write(spi, REG_ENSM_CONFIG_1, + phy->pdata->fdd ? FORCE_TX_ON : FORCE_RX_ON); + /* Delay Flush Time 384 ADC clock cycles */ + udelay(384000000UL / clk_get_rate(phy, phy->ref_clk_scale[ADC_CLK])); + ad9361_spi_write(spi, REG_ENSM_CONFIG_1, 0); /* Move to Wait*/ + udelay(1); /* Wait for ENSM settle */ + ad9361_spi_write(spi, REG_CLOCK_ENABLE, + (phy->pdata->use_extclk ? XO_BYPASS : 0)); /* Turn off all clocks */ + phy->curr_ensm_state = ensm_state; + return 0; + + default: + dev_err(dev, "No handling for forcing %d ensm state", + ensm_state); + goto out; + } + + if (rc) { + if ((phy->curr_ensm_state != ENSM_STATE_ALERT) + && (val & (FORCE_RX_ON | FORCE_TX_ON))) { + uint32_t val2 = val; + + val2 &= ~(FORCE_TX_ON | FORCE_RX_ON); + val2 |= TO_ALERT | FORCE_ALERT_STATE; + ad9361_spi_write(spi, REG_ENSM_CONFIG_1, val2); + + ad9361_check_cal_done(phy, REG_STATE, ENSM_STATE(~0), ENSM_STATE_ALERT); + } else { + dev_err(dev, "Invalid ENSM state transition in %s mode", + phy->pdata->fdd ? "FDD" : "TDD"); + goto out; + } + } + + if (!phy->pdata->fdd && !pinctrl && !phy->pdata->tdd_use_dual_synth && + (ensm_state == ENSM_STATE_TX || ensm_state == ENSM_STATE_RX)) { + uint32_t reg, check; + + if (ensm_state == ENSM_STATE_TX) { + reg = REG_TX_CP_OVERRANGE_VCO_LOCK; + check = !(phy->cached_synth_pd[0] & + TX_SYNTH_VCO_POWER_DOWN); + } else { + reg = REG_RX_CP_OVERRANGE_VCO_LOCK; + check = !(phy->cached_synth_pd[1] & + RX_SYNTH_VCO_POWER_DOWN); + } + + ad9361_spi_writef(phy->spi, REG_ENSM_CONFIG_2, + TXNRX_SPI_CTRL, ensm_state == ENSM_STATE_TX); + + if (check) + ad9361_check_cal_done(phy, reg, VCO_LOCK, 1); + } + + rc = ad9361_spi_write(spi, REG_ENSM_CONFIG_1, val); + if (rc) + dev_err(dev, "Failed to restore state"); + + if ((val & FORCE_RX_ON) && + (phy->agc_mode[0] == RF_GAIN_MGC || + phy->agc_mode[1] == RF_GAIN_MGC)) { + tmp = ad9361_spi_read(spi, REG_SMALL_LMT_OVERLOAD_THRESH); + ad9361_spi_write(spi, REG_SMALL_LMT_OVERLOAD_THRESH, + (tmp & SMALL_LMT_OVERLOAD_THRESH(~0)) | + (phy->agc_mode[0] == RF_GAIN_MGC ? FORCE_PD_RESET_RX1 : 0) | + (phy->agc_mode[1] == RF_GAIN_MGC ? FORCE_PD_RESET_RX2 : 0)); + ad9361_spi_write(spi, REG_SMALL_LMT_OVERLOAD_THRESH, + tmp & SMALL_LMT_OVERLOAD_THRESH(~0)); + } + + phy->curr_ensm_state = ensm_state; + +out: + return rc; + +} + +/** + * Check if at least one of the clock rates is equal to the DATA_CLK (lvds) rate. + * @param phy The AD9361 state structure. + * @param rx_path_clks RX path rates buffer. + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t ad9361_validate_trx_clock_chain(struct ad9361_rf_phy *phy, + uint32_t *rx_path_clks, uint32_t *tx_path_clks) +{ + static const uint32_t max_rx_rates[] = {MAX_BBPLL_FREQ, MAX_ADC_CLK, + MAX_RX_HB3, MAX_RX_HB2, MAX_RX_HB1, MAX_BASEBAND_RATE + }; + static const uint32_t max_tx_rates[] = {MAX_BBPLL_FREQ, MAX_DAC_CLK, + MAX_TX_HB3, MAX_TX_HB2, MAX_TX_HB1, MAX_BASEBAND_RATE + }; + uint32_t i; + uint32_t data_clk; + + data_clk = (phy->pdata->rx2tx2 ? 4 : 2) / + ((phy->pdata->port_ctrl.pp_conf[2] & LVDS_MODE) ? 1 : 2) * + rx_path_clks[RX_SAMPL_FREQ]; + + /* CMOS Mode */ + if (!(phy->pdata->port_ctrl.pp_conf[2] & LVDS_MODE) && + (data_clk > MAX_BASEBAND_RATE)) { + dev_err(&phy->spi->dev, + "%s: Failed CMOS MODE DATA_CLK > 61.44MSPS", __func__); + return -EINVAL; + } + + /* Validate MAX PLL, ADC, DAC and HB filter rates */ + for (i = 0; i < ARRAY_SIZE(max_rx_rates); i++) { + if (rx_path_clks[i] > max_rx_rates[i]) { + dev_err(&phy->spi->dev, + "%s: Failed RX max rate check (%"PRIu32" > %"PRIu32")", + __func__, rx_path_clks[i], max_rx_rates[i]); + return -EINVAL; + } + + if (tx_path_clks[i] > max_tx_rates[i]) { + dev_err(&phy->spi->dev, + "%s: Failed TX max rate check (%"PRIu32" > %"PRIu32")", + __func__, tx_path_clks[i], max_tx_rates[i]); + return -EINVAL; + } + } + + /* Validate that DATA_CLK exist within the clock chain */ + for (i = 1; i <= 3; i++) { + if (diff_abs(rx_path_clks[ADC_FREQ] / i, data_clk) < 4) + return 0; + } + + for (i = 1; i <= 4; i++) { + if (diff_abs((rx_path_clks[R2_FREQ] >> i), data_clk) < 4) + return 0; + } + + dev_err(&phy->spi->dev, "%s: Failed - at least one of the clock rates" + " must be equal to the DATA_CLK (lvds) rate", __func__); + + return -EINVAL; +} + +/** + * Set the RX and TX path rates. + * @param phy The AD9361 state structure. + * @param rx_path_clks RX path rates buffer. + * @param tx_path_clks TX path rates buffer. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_set_trx_clock_chain(struct ad9361_rf_phy *phy, + uint32_t *rx_path_clks, + uint32_t *tx_path_clks) +{ + int32_t ret, i, j, n; + + dev_dbg(&phy->spi->dev, "%s", __func__); + + if (!rx_path_clks || !tx_path_clks) + return -EINVAL; + + dev_dbg(&phy->spi->dev, + "%s: %"PRIu32" %"PRIu32" %"PRIu32" %"PRIu32" %"PRIu32" %"PRIu32, + __func__, rx_path_clks[BBPLL_FREQ], rx_path_clks[ADC_FREQ], + rx_path_clks[R2_FREQ], rx_path_clks[R1_FREQ], + rx_path_clks[CLKRF_FREQ], rx_path_clks[RX_SAMPL_FREQ]); + + dev_dbg(&phy->spi->dev, + "%s: %"PRIu32" %"PRIu32" %"PRIu32" %"PRIu32" %"PRIu32" %"PRIu32, + __func__, tx_path_clks[BBPLL_FREQ], tx_path_clks[ADC_FREQ], + tx_path_clks[R2_FREQ], tx_path_clks[R1_FREQ], + tx_path_clks[CLKRF_FREQ], tx_path_clks[RX_SAMPL_FREQ]); + + ret = ad9361_validate_trx_clock_chain(phy, rx_path_clks, tx_path_clks); + if (ret < 0) + return ret; + + ret = clk_set_rate(phy, phy->ref_clk_scale[BBPLL_CLK], + rx_path_clks[BBPLL_FREQ]); + if (ret < 0) + return ret; + + phy->current_rx_path_clks[BBPLL_FREQ] = rx_path_clks[BBPLL_FREQ]; + + for (i = ADC_CLK, j = DAC_CLK, n = ADC_FREQ; + i <= RX_SAMPL_CLK; i++, j++, n++) { + ret = clk_set_rate(phy, phy->ref_clk_scale[i], rx_path_clks[n]); + if (ret < 0) { + dev_err(dev, "Failed to set BB ref clock rate (%"PRId32")", + ret); + return ret; + } + phy->current_rx_path_clks[n] = rx_path_clks[n]; + ret = clk_set_rate(phy, phy->ref_clk_scale[j], tx_path_clks[n]); + if (ret < 0) { + dev_err(dev, "Failed to set BB ref clock rate (%"PRId32")", + ret); + return ret; + } + phy->current_tx_path_clks[n] = tx_path_clks[n]; + } + + /* + * Workaround for clock framework since clocks don't change we + * manually need to enable the filter + */ + + if (phy->rx_fir_dec == 1 || phy->bypass_rx_fir) { + ad9361_spi_writef(phy->spi, REG_RX_ENABLE_FILTER_CTRL, + RX_FIR_ENABLE_DECIMATION(~0), !phy->bypass_rx_fir); + } + + if (phy->tx_fir_int == 1 || phy->bypass_tx_fir) { + ad9361_spi_writef(phy->spi, REG_TX_ENABLE_FILTER_CTRL, + TX_FIR_ENABLE_INTERPOLATION(~0), !phy->bypass_tx_fir); + } + + /* The FIR filter once enabled causes the interface timing to change. + * It's typically not a problem if the timing margin is big enough. + * However at 61.44 MSPS it causes problems on some systems. + * So we always run the digital tune in case the filter is enabled. + * If it is disabled we restore the values from the initial calibration. + */ + + if (!phy->pdata->dig_interface_tune_fir_disable && + !(phy->bypass_tx_fir && phy->bypass_rx_fir)) + ret = ad9361_dig_tune(phy, 0, SKIP_STORE_RESULT); + + return ad9361_bb_clk_change_handler(phy); +} + +/** + * Get the RX and TX path rates. + * @param phy The AD9361 state structure. + * @param rx_path_clks RX path rates buffer. + * @param tx_path_clks TX path rates buffer. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_get_trx_clock_chain(struct ad9361_rf_phy *phy, + uint32_t *rx_path_clks, + uint32_t *tx_path_clks) +{ + int32_t i, j, n; + uint32_t bbpll_freq; + + if (!rx_path_clks && !tx_path_clks) + return -EINVAL; + + bbpll_freq = clk_get_rate(phy, phy->ref_clk_scale[BBPLL_CLK]); + + if (rx_path_clks) + rx_path_clks[BBPLL_FREQ] = bbpll_freq; + + if (tx_path_clks) + tx_path_clks[BBPLL_FREQ] = bbpll_freq; + + for (i = ADC_CLK, j = DAC_CLK, n = ADC_FREQ; + i <= RX_SAMPL_CLK; i++, j++, n++) { + if (rx_path_clks) + rx_path_clks[n] = clk_get_rate(phy, phy->ref_clk_scale[i]); + if (tx_path_clks) + tx_path_clks[n] = clk_get_rate(phy, phy->ref_clk_scale[j]); + } + + return 0; +} + +/** + * Calculate the RX and TX path rates to obtain the desired sample rate. + * @param phy The AD9361 state structure. + * @param tx_sample_rate The desired sample rate. + * @param rate_gov The rate governor option. + * @param rx_path_clks RX path rates buffer. + * @param tx_path_clks TX path rates buffer. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_calculate_rf_clock_chain(struct ad9361_rf_phy *phy, + uint32_t tx_sample_rate, + uint32_t rate_gov, + uint32_t *rx_path_clks, + uint32_t *tx_path_clks) +{ + uint32_t clktf, clkrf, adc_rate = 0, dac_rate = 0; + uint64_t bbpll_rate; + int32_t i, index_rx = -1, index_tx = -1, tmp; + uint32_t div, tx_intdec, rx_intdec, recursion = 1; + const int8_t clk_dividers[][4] = { + { 12, 3, 2, 2 }, + { 8, 2, 2, 2 }, + { 6, 3, 1, 2 }, + { 4, 2, 2, 1 }, + { 3, 3, 1, 1 }, + { 2, 2, 1, 1 }, + { 1, 1, 1, 1 }, + }; + + if (phy->bypass_rx_fir) + rx_intdec = 1; + else + rx_intdec = phy->rx_fir_dec; + + if (phy->bypass_tx_fir) + tx_intdec = 1; + else + tx_intdec = phy->tx_fir_int; + + if ((rate_gov == 1) && ((rx_intdec * tx_sample_rate * 8) < MIN_ADC_CLK)) { + recursion = 0; + rate_gov = 0; + } + + dev_dbg(&phy->spi->dev, + "%s: requested rate %"PRIu32" TXFIR int %"PRIu32" RXFIR dec %"PRIu32" mode %s", + __func__, tx_sample_rate, tx_intdec, rx_intdec, + rate_gov ? "Nominal" : "Highest OSR"); + + if (tx_sample_rate > MAX_BASEBAND_RATE) + return -EINVAL; + + clktf = tx_sample_rate * tx_intdec; + clkrf = tx_sample_rate * rx_intdec * (phy->rx_eq_2tx ? 2 : 1); + + for (i = rate_gov; i < 7; i++) { + adc_rate = clkrf * clk_dividers[i][0]; + dac_rate = clktf * clk_dividers[i][0]; + + if ((adc_rate <= MAX_ADC_CLK) && (adc_rate >= MIN_ADC_CLK)) { + + + if (dac_rate > adc_rate) + tmp = (dac_rate / adc_rate) * -1; + else + tmp = adc_rate / dac_rate; + + if (adc_rate <= MAX_DAC_CLK) { + index_rx = i; + index_tx = i - ((tmp == 1) ? 0 : tmp); + dac_rate = adc_rate; /* ADC_CLK */ + break; + } else { + dac_rate = adc_rate / 2; /* ADC_CLK/2 */ + index_rx = i; + + if (i == 4 && tmp >= 0) + index_tx = 7; /* STOP: 3/2 != 1 */ + else + index_tx = i + ((i == 5 && tmp >= 0) ? 1 : 2) - + ((tmp == 1) ? 0 : tmp); + + break; + } + } + } + + if ((index_tx < 0 || index_tx > 6 || index_rx < 0 || index_rx > 6) + && rate_gov < 7 && recursion) { + return ad9361_calculate_rf_clock_chain(phy, tx_sample_rate, + ++rate_gov, rx_path_clks, tx_path_clks); + } else if ((index_tx < 0 || index_tx > 6 || index_rx < 0 || index_rx > 6)) { + dev_err(&phy->spi->dev, "%s: Failed to find suitable dividers: %s", + __func__, (adc_rate < MIN_ADC_CLK) ? "ADC clock below limit" : + "BBPLL rate above limit"); + + return -EINVAL; + } + + /* Calculate target BBPLL rate */ + div = MAX_BBPLL_DIV; + + do { + bbpll_rate = (uint64_t)adc_rate * div; + div >>= 1; + + } while ((bbpll_rate > MAX_BBPLL_FREQ) && (div >= MIN_BBPLL_DIV)); + + rx_path_clks[BBPLL_FREQ] = bbpll_rate; + rx_path_clks[ADC_FREQ] = adc_rate; + rx_path_clks[R2_FREQ] = rx_path_clks[ADC_FREQ] / clk_dividers[index_rx][1]; + rx_path_clks[R1_FREQ] = rx_path_clks[R2_FREQ] / clk_dividers[index_rx][2]; + rx_path_clks[CLKRF_FREQ] = rx_path_clks[R1_FREQ] / clk_dividers[index_rx][3]; + rx_path_clks[RX_SAMPL_FREQ] = rx_path_clks[CLKRF_FREQ] / rx_intdec; + + tx_path_clks[BBPLL_FREQ] = bbpll_rate; + tx_path_clks[DAC_FREQ] = dac_rate; + tx_path_clks[T2_FREQ] = tx_path_clks[DAC_FREQ] / clk_dividers[index_tx][1]; + tx_path_clks[T1_FREQ] = tx_path_clks[T2_FREQ] / clk_dividers[index_tx][2]; + tx_path_clks[CLKTF_FREQ] = tx_path_clks[T1_FREQ] / clk_dividers[index_tx][3]; + tx_path_clks[TX_SAMPL_FREQ] = tx_path_clks[CLKTF_FREQ] / tx_intdec; + + return 0; +} + +/** + * Set the desired sample rate. + * @param phy The AD9361 state structure. + * @param freq The desired sample rate. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_set_trx_clock_chain_freq(struct ad9361_rf_phy *phy, + uint32_t freq) +{ + uint32_t rx[6], tx[6]; + int32_t ret; + + ret = ad9361_calculate_rf_clock_chain(phy, freq, + phy->rate_governor, rx, tx); + if (ret < 0) + return ret; + return ad9361_set_trx_clock_chain(phy, rx, tx); +} + +/** + * Internal ENSM mode options helper function. + * @param phy The AD9361 state structure. + * @param fdd + * @param pinctrl + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_set_ensm_mode(struct ad9361_rf_phy *phy, bool fdd, bool pinctrl) +{ + struct ad9361_phy_platform_data *pd = phy->pdata; + int32_t ret; + uint32_t val = 0; + + ad9361_spi_write(phy->spi, REG_ENSM_MODE, fdd ? FDD_MODE : 0); + + val = ad9361_spi_read(phy->spi, REG_ENSM_CONFIG_2); + val &= POWER_DOWN_RX_SYNTH | POWER_DOWN_TX_SYNTH | + RX_SYNTH_READY_MASK | TX_SYNTH_READY_MASK; + + if (fdd) + ret = ad9361_spi_write(phy->spi, REG_ENSM_CONFIG_2, + val | DUAL_SYNTH_MODE | + (pd->fdd_independent_mode ? FDD_EXTERNAL_CTRL_ENABLE : 0)); + else + ret = ad9361_spi_write(phy->spi, REG_ENSM_CONFIG_2, val | + (pd->tdd_use_dual_synth ? DUAL_SYNTH_MODE : 0) | + (pd->tdd_use_dual_synth ? 0 : + (pinctrl ? SYNTH_ENABLE_PIN_CTRL_MODE : 0))); + + return ret; +} + +/** + * Fastlock read value. + * @param spi + * @param tx + * @param profile + * @param word + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t ad9361_fastlock_readval(struct spi_desc *spi, bool tx, + uint32_t profile, uint32_t word) +{ + uint32_t offs = 0; + + if (tx) + offs = REG_TX_FAST_LOCK_SETUP - REG_RX_FAST_LOCK_SETUP; + + ad9361_spi_write(spi, REG_RX_FAST_LOCK_PROGRAM_ADDR + offs, + RX_FAST_LOCK_PROFILE_ADDR(profile) | + RX_FAST_LOCK_PROFILE_WORD(word)); + + return ad9361_spi_read(spi, REG_RX_FAST_LOCK_PROGRAM_READ + offs); +} + +/** + * Fastlock write value. + * @param spi + * @param tx + * @param profile + * @param word + * @param val + * @param last + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t ad9361_fastlock_writeval(struct spi_desc *spi, bool tx, + uint32_t profile, uint32_t word, uint8_t val, bool last) +{ + uint32_t offs = 0; + int32_t ret; + + if (tx) + offs = REG_TX_FAST_LOCK_SETUP - REG_RX_FAST_LOCK_SETUP; + + ret = ad9361_spi_write(spi, REG_RX_FAST_LOCK_PROGRAM_ADDR + offs, + RX_FAST_LOCK_PROFILE_ADDR(profile) | + RX_FAST_LOCK_PROFILE_WORD(word)); + ret |= ad9361_spi_write(spi, REG_RX_FAST_LOCK_PROGRAM_DATA + offs, val); + ret |= ad9361_spi_write(spi, REG_RX_FAST_LOCK_PROGRAM_CTRL + offs, + RX_FAST_LOCK_PROGRAM_WRITE | + RX_FAST_LOCK_PROGRAM_CLOCK_ENABLE); + + if (last) /* Stop Clocks */ + ret |= ad9361_spi_write(spi, + REG_RX_FAST_LOCK_PROGRAM_CTRL + offs, 0); + + return ret; +} + +/** + * Fastlock load values. + * @param phy The AD9361 state structure. + * @param tx + * @param profile + * @param values + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_fastlock_load(struct ad9361_rf_phy *phy, bool tx, + uint32_t profile, uint8_t *values) +{ + uint32_t offs = 0; + int32_t i, ret = 0; + uint8_t buf[4]; + + dev_dbg(&phy->spi->dev, "%s: %s Profile %"PRIu32":", + __func__, tx ? "TX" : "RX", profile); + + if (tx) + offs = REG_TX_FAST_LOCK_SETUP - REG_RX_FAST_LOCK_SETUP; + + buf[0] = values[0]; + buf[1] = RX_FAST_LOCK_PROFILE_ADDR(profile) | RX_FAST_LOCK_PROFILE_WORD(0); + ad9361_spi_writem(phy->spi, REG_RX_FAST_LOCK_PROGRAM_DATA + offs, buf, 2); + + for (i = 1; i < RX_FAST_LOCK_CONFIG_WORD_NUM; i++) { + buf[0] = RX_FAST_LOCK_PROGRAM_WRITE | RX_FAST_LOCK_PROGRAM_CLOCK_ENABLE; + buf[1] = 0; + buf[2] = values[i]; + buf[3] = RX_FAST_LOCK_PROFILE_ADDR(profile) | RX_FAST_LOCK_PROFILE_WORD(i); + ad9361_spi_writem(phy->spi, REG_RX_FAST_LOCK_PROGRAM_CTRL + offs, buf, 4); + } + + ad9361_spi_write(phy->spi, REG_RX_FAST_LOCK_PROGRAM_CTRL + offs, + RX_FAST_LOCK_PROGRAM_WRITE | RX_FAST_LOCK_PROGRAM_CLOCK_ENABLE); + ad9361_spi_write(phy->spi, REG_RX_FAST_LOCK_PROGRAM_CTRL + offs, 0); + + phy->fastlock.entry[tx][profile].flags = FASTLOOK_INIT; + phy->fastlock.entry[tx][profile].alc_orig = values[15]; + phy->fastlock.entry[tx][profile].alc_written = values[15]; + + return ret; +} + +/** + * Fastlock store. + * @param phy The AD9361 state structure. + * @param tx + * @param profile + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_fastlock_store(struct ad9361_rf_phy *phy, bool tx, + uint32_t profile) +{ + struct spi_desc *spi = phy->spi; + uint8_t val[16]; + uint32_t offs = 0, x, y; + + dev_dbg(&phy->spi->dev, "%s: %s Profile %"PRIu32":", + __func__, tx ? "TX" : "RX", profile); + + if (tx) + offs = REG_TX_FAST_LOCK_SETUP - REG_RX_FAST_LOCK_SETUP; + + val[0] = ad9361_spi_read(spi, REG_RX_INTEGER_BYTE_0 + offs); + val[1] = ad9361_spi_read(spi, REG_RX_INTEGER_BYTE_1 + offs); + val[2] = ad9361_spi_read(spi, REG_RX_FRACT_BYTE_0 + offs); + val[3] = ad9361_spi_read(spi, REG_RX_FRACT_BYTE_1 + offs); + val[4] = ad9361_spi_read(spi, REG_RX_FRACT_BYTE_2 + offs); + + x = ad9361_spi_readf(spi, REG_RX_VCO_BIAS_1 + offs, VCO_BIAS_REF(~0)); + y = ad9361_spi_readf(spi, REG_RX_ALC_VARACTOR + offs, VCO_VARACTOR(~0)); + val[5] = (x << 4) | y; + + x = ad9361_spi_readf(spi, REG_RX_VCO_BIAS_1 + offs, VCO_BIAS_TCF(~0)); + y = ad9361_spi_readf(spi, REG_RX_CP_CURRENT + offs, CHARGE_PUMP_CURRENT(~0)); + /* Wide BW option: N = 1 + * Set init and steady state values to the same - let user space handle it + */ + val[6] = (x << 3) | y; + val[7] = y; + + x = ad9361_spi_readf(spi, REG_RX_LOOP_FILTER_3 + offs, LOOP_FILTER_R3(~0)); + val[8] = (x << 4) | x; + + x = ad9361_spi_readf(spi, REG_RX_LOOP_FILTER_2 + offs, LOOP_FILTER_C3(~0)); + val[9] = (x << 4) | x; + + x = ad9361_spi_readf(spi, REG_RX_LOOP_FILTER_1 + offs, LOOP_FILTER_C1(~0)); + y = ad9361_spi_readf(spi, REG_RX_LOOP_FILTER_1 + offs, LOOP_FILTER_C2(~0)); + val[10] = (x << 4) | y; + + x = ad9361_spi_readf(spi, REG_RX_LOOP_FILTER_2 + offs, LOOP_FILTER_R1(~0)); + val[11] = (x << 4) | x; + + x = ad9361_spi_readf(spi, REG_RX_VCO_VARACTOR_CTRL_0 + offs, + VCO_VARACTOR_REFERENCE_TCF(~0)); + y = ad9361_spi_readf(spi, REG_RFPLL_DIVIDERS, + tx ? TX_VCO_DIVIDER(~0) : RX_VCO_DIVIDER(~0)); + val[12] = (x << 4) | y; + + x = ad9361_spi_readf(spi, REG_RX_FORCE_VCO_TUNE_1 + offs, VCO_CAL_OFFSET(~0)); + y = ad9361_spi_readf(spi, REG_RX_VCO_VARACTOR_CTRL_1 + offs, + VCO_VARACTOR_REFERENCE(~0)); + val[13] = (x << 4) | y; + + val[14] = ad9361_spi_read(spi, REG_RX_FORCE_VCO_TUNE_0 + offs); + + x = ad9361_spi_readf(spi, REG_RX_FORCE_ALC + offs, FORCE_ALC_WORD(~0)); + y = ad9361_spi_readf(spi, REG_RX_FORCE_VCO_TUNE_1 + offs, FORCE_VCO_TUNE); + val[15] = (x << 1) | y; + + return ad9361_fastlock_load(phy, tx, profile, val); +} + +/** + * Fastlock prepare. + * @param phy The AD9361 state structure. + * @param tx + * @param profile + * @param prepare + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t ad9361_fastlock_prepare(struct ad9361_rf_phy *phy, bool tx, + uint32_t profile, bool prepare) +{ + uint32_t offs, ready_mask; + bool is_prepared; + + dev_dbg(&phy->spi->dev, "%s: %s Profile %"PRIu32": %s", + __func__, tx ? "TX" : "RX", profile, + prepare ? "Prepare" : "Un-Prepare"); + + if (tx) { + offs = REG_TX_FAST_LOCK_SETUP - REG_RX_FAST_LOCK_SETUP; + ready_mask = TX_SYNTH_READY_MASK; + } else { + offs = 0; + ready_mask = RX_SYNTH_READY_MASK; + } + + is_prepared = !!phy->fastlock.current_profile[tx]; + + if (prepare && !is_prepared) { + ad9361_spi_write(phy->spi, + REG_RX_FAST_LOCK_SETUP_INIT_DELAY + offs, + (tx ? phy->pdata->tx_fastlock_delay_ns : + phy->pdata->rx_fastlock_delay_ns) / 250); + ad9361_spi_write(phy->spi, REG_RX_FAST_LOCK_SETUP + offs, + RX_FAST_LOCK_PROFILE(profile) | + RX_FAST_LOCK_MODE_ENABLE); + ad9361_spi_write(phy->spi, REG_RX_FAST_LOCK_PROGRAM_CTRL + offs, + 0); + + ad9361_spi_writef(phy->spi, REG_ENSM_CONFIG_2, ready_mask, 1); + ad9361_trx_vco_cal_control(phy, tx, false); + } else if (!prepare && is_prepared) { + ad9361_spi_write(phy->spi, REG_RX_FAST_LOCK_SETUP + offs, 0); + + /* Workaround: Exiting Fastlock Mode */ + ad9361_spi_writef(phy->spi, REG_RX_FORCE_ALC + offs, FORCE_ALC_ENABLE, 1); + ad9361_spi_writef(phy->spi, REG_RX_FORCE_VCO_TUNE_1 + offs, FORCE_VCO_TUNE, 1); + ad9361_spi_writef(phy->spi, REG_RX_FORCE_ALC + offs, FORCE_ALC_ENABLE, 0); + ad9361_spi_writef(phy->spi, REG_RX_FORCE_VCO_TUNE_1 + offs, FORCE_VCO_TUNE, 0); + + ad9361_trx_vco_cal_control(phy, tx, true); + ad9361_spi_writef(phy->spi, REG_ENSM_CONFIG_2, ready_mask, 0); + + phy->fastlock.current_profile[tx] = 0; + } + + return 0; +} + +/** + * Fastlock recall. + * @param phy The AD9361 state structure. + * @param tx + * @param profile + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_fastlock_recall(struct ad9361_rf_phy *phy, bool tx, + uint32_t profile) +{ + uint32_t offs = 0; + uint8_t curr, _new, orig, current_profile; + + dev_dbg(&phy->spi->dev, "%s: %s Profile %"PRIu32":", + __func__, tx ? "TX" : "RX", profile); + + if (tx) + offs = REG_TX_FAST_LOCK_SETUP - REG_RX_FAST_LOCK_SETUP; + + if (phy->fastlock.entry[tx][profile].flags != FASTLOOK_INIT) + return -EINVAL; + + /* Workaround: Lock problem with same ALC word */ + + current_profile = phy->fastlock.current_profile[tx]; + _new = phy->fastlock.entry[tx][profile].alc_written; + + if (current_profile == 0) + curr = ad9361_spi_readf(phy->spi, REG_RX_FORCE_ALC + offs, + FORCE_ALC_WORD(~0)) << 1; + else + curr = phy->fastlock.entry[tx][current_profile - 1].alc_written; + + if ((curr >> 1) == (_new >> 1)) { + orig = phy->fastlock.entry[tx][profile].alc_orig; + + if ((orig >> 1) == (_new >> 1)) + phy->fastlock.entry[tx][profile].alc_written += 2; + else + phy->fastlock.entry[tx][profile].alc_written = orig; + + ad9361_fastlock_writeval(phy->spi, tx, profile, 0xF, + phy->fastlock.entry[tx][profile].alc_written, true); + } + + ad9361_fastlock_prepare(phy, tx, profile, true); + phy->fastlock.current_profile[tx] = profile + 1; + + return ad9361_spi_write(phy->spi, REG_RX_FAST_LOCK_SETUP + offs, + RX_FAST_LOCK_PROFILE(profile) | + (phy->pdata->trx_fastlock_pinctrl_en[tx] ? + RX_FAST_LOCK_PROFILE_PIN_SELECT : 0) | + RX_FAST_LOCK_MODE_ENABLE); +} + +/** + * Fastlock save. + * @param phy The AD9361 state structure. + * @param tx + * @param profile + * @param values + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_fastlock_save(struct ad9361_rf_phy *phy, bool tx, + uint32_t profile, uint8_t *values) +{ + int32_t i; + + dev_dbg(&phy->spi->dev, "%s: %s Profile %"PRIu32":", + __func__, tx ? "TX" : "RX", profile); + + for (i = 0; i < RX_FAST_LOCK_CONFIG_WORD_NUM; i++) + values[i] = ad9361_fastlock_readval(phy->spi, tx, profile, i); + + return 0; +} + +/** + * Multi Chip Sync (MCS) config. + * @param phy The AD9361 state structure. + * @param step MCS step. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_mcs(struct ad9361_rf_phy *phy, int32_t step) +{ + int32_t mcs_mask = MCS_RF_ENABLE | MCS_BBPLL_ENABLE | + MCS_DIGITAL_CLK_ENABLE | MCS_BB_ENABLE; + + dev_dbg(&phy->spi->dev, "%s: MCS step %"PRId32, __func__, step); + + switch (step) { + case 1: + /* REVIST: + * POWER_DOWN_TRX_SYNTH and MCS_RF_ENABLE somehow conflict + */ + ad9361_spi_writef(phy->spi, REG_ENSM_CONFIG_2, + POWER_DOWN_TX_SYNTH | POWER_DOWN_RX_SYNTH, 0); + + ad9361_spi_writef(phy->spi, REG_MULTICHIP_SYNC_AND_TX_MON_CTRL, + mcs_mask, MCS_BB_ENABLE | MCS_BBPLL_ENABLE | MCS_RF_ENABLE); + ad9361_spi_writef(phy->spi, REG_CP_BLEED_CURRENT, + MCS_REFCLK_SCALE_EN, 1); + break; + case 2: + if(!phy->gpio_desc_sync) + break; + /* + * NOTE: This is not a regular GPIO - + * HDL ensures Multi-chip Synchronization SYNC_IN Pulse Timing + * relative to rising and falling edge of REF_CLK + */ + gpio_set_value(phy->gpio_desc_sync, 1); + gpio_set_value(phy->gpio_desc_sync, 0); + break; + case 3: + ad9361_spi_writef(phy->spi, REG_MULTICHIP_SYNC_AND_TX_MON_CTRL, + mcs_mask, MCS_BB_ENABLE | MCS_DIGITAL_CLK_ENABLE | MCS_RF_ENABLE); + break; + case 4: + if(!phy->gpio_desc_sync) + break; + gpio_set_value(phy->gpio_desc_sync, 1); + gpio_set_value(phy->gpio_desc_sync, 0); + break; + case 5: + ad9361_spi_writef(phy->spi, REG_MULTICHIP_SYNC_AND_TX_MON_CTRL, + mcs_mask, MCS_RF_ENABLE); + break; + } + + return 0; +} + +/** + * Clear state. + * @param phy The AD9361 state structure. + * @return None. + */ +void ad9361_clear_state(struct ad9361_rf_phy *phy) +{ + phy->current_table = NO_GAIN_TABLE; + phy->bypass_tx_fir = true; + phy->bypass_rx_fir = true; + phy->rate_governor = 1; + phy->rfdc_track_en = true; + phy->bbdc_track_en = true; + phy->quad_track_en = true; + phy->prev_ensm_state = 0; + phy->curr_ensm_state = 0; + phy->auto_cal_en = false; + phy->manual_tx_quad_cal_en = false; + phy->last_tx_quad_cal_freq = 0; + phy->flags = 0; + phy->current_rx_bw_Hz = 0; + phy->current_tx_bw_Hz = 0; + phy->rxbbf_div = 0; + phy->tx_fir_int = 0; + phy->tx_fir_ntaps = 0; + phy->rx_fir_dec = 0; + phy->rx_fir_ntaps = 0; + phy->ensm_pin_ctl_en = false; + phy->txmon_tdd_en = 0; + phy->current_tx_lo_freq = 0; + phy->current_rx_lo_freq = 0; + phy->current_tx_use_tdd_table = false; + phy->current_rx_use_tdd_table = false; + phy->cached_synth_pd[0] = 0; + phy->cached_synth_pd[1] = 0; + + memset(&phy->fastlock, 0, sizeof(phy->fastlock)); +} + +/** + * Determine the reference frequency value. + * @param refin_Hz Maximum allowed frequency. + * @param max Reference in frequency value. + * @return Reference frequency value. + */ +static uint32_t ad9361_ref_div_sel(uint32_t refin_Hz, uint32_t max) +{ + if (refin_Hz <= (max / 2)) + return 2 * refin_Hz; + else if (refin_Hz <= max) + return refin_Hz; + else if (refin_Hz <= (max * 2)) + return refin_Hz / 2; + else if (refin_Hz <= (max * 4)) + return refin_Hz / 4; + else + return 0; +} + +/** + * Setup the AD9361 device. + * @param phy The AD9361 state structure. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_setup(struct ad9361_rf_phy *phy) +{ + uint32_t refin_Hz, ref_freq, bbpll_freq; + struct spi_desc *spi = phy->spi; + struct ad9361_phy_platform_data *pd = phy->pdata; + int32_t ret; + uint32_t real_rx_bandwidth, real_tx_bandwidth; + bool tmp_use_ext_rx_lo = pd->use_ext_rx_lo; + bool tmp_use_ext_tx_lo = pd->use_ext_tx_lo; + + dev_dbg(dev, "%s", __func__); + + pd->rf_rx_bandwidth_Hz = ad9361_validate_rf_bw(phy, pd->rf_rx_bandwidth_Hz); + pd->rf_tx_bandwidth_Hz = ad9361_validate_rf_bw(phy, pd->rf_tx_bandwidth_Hz); + + real_rx_bandwidth = pd->rf_rx_bandwidth_Hz / 2; + real_tx_bandwidth = pd->rf_tx_bandwidth_Hz / 2; + + if (pd->fdd) { + pd->tdd_skip_vco_cal = false; + if (pd->ensm_pin_ctrl && pd->fdd_independent_mode) { + dev_warn(dev, + "%s: Either set ENSM PINCTRL or FDD Independent Mode", + __func__); + pd->ensm_pin_ctrl = false; + } + } + + ret = ad9361_auxdac_setup(phy, &pd->auxdac_ctrl); + if (ret < 0) + return ret; + + ret = ad9361_gpo_setup(phy, &pd->gpo_ctrl); + if (ret < 0) + return ret; + + if (pd->port_ctrl.pp_conf[2] & FDD_RX_RATE_2TX_RATE) + phy->rx_eq_2tx = true; + + ad9361_spi_write(spi, REG_CTRL, CTRL_ENABLE); + ad9361_spi_write(spi, REG_BANDGAP_CONFIG0, + MASTER_BIAS_TRIM(0x0E)); /* Enable Master Bias */ + ad9361_spi_write(spi, REG_BANDGAP_CONFIG1, + BANDGAP_TEMP_TRIM(0x0E)); /* Set Bandgap Trim */ + + ad9361_set_dcxo_tune(phy, pd->dcxo_coarse, pd->dcxo_fine); + + refin_Hz = phy->clk_refin->rate; + + ref_freq = ad9361_ref_div_sel(refin_Hz, MAX_BBPLL_FREF); + if (!ref_freq) + return -EINVAL; + + ad9361_spi_writef(spi, REG_REF_DIVIDE_CONFIG_1, RX_REF_RESET_BAR, 1); + ad9361_spi_writef(spi, REG_REF_DIVIDE_CONFIG_2, TX_REF_RESET_BAR, 1); + ad9361_spi_writef(spi, REG_REF_DIVIDE_CONFIG_2, + TX_REF_DOUBLER_FB_DELAY(~0), 3); /* FB DELAY */ + ad9361_spi_writef(spi, REG_REF_DIVIDE_CONFIG_2, + RX_REF_DOUBLER_FB_DELAY(~0), 3); /* FB DELAY */ + + ad9361_spi_write(spi, REG_CLOCK_ENABLE, + DIGITAL_POWER_UP | CLOCK_ENABLE_DFLT | BBPLL_ENABLE | + (pd->use_extclk ? XO_BYPASS : 0)); /* Enable Clocks */ + + ret = clk_set_rate(phy, phy->ref_clk_scale[BB_REFCLK], ref_freq); + if (ret < 0) { + dev_err(dev, "Failed to set BB ref clock rate (%"PRId32")", + ret); + return ret; + } + + ret = clk_prepare_enable(phy->clks[BB_REFCLK]); + if (ret < 0) { + dev_err(dev, "Failed to enable BB ref clock rate (%"PRId32")", + ret); + return ret; + } + + ad9361_spi_write(spi, REG_FRACT_BB_FREQ_WORD_2, 0x12); + ad9361_spi_write(spi, REG_FRACT_BB_FREQ_WORD_3, 0x34); + + ret = ad9361_set_trx_clock_chain(phy, pd->rx_path_clks, + pd->tx_path_clks); + if (ret < 0) + return ret; + + if (!pd->rx2tx2) { + pd->rx1tx1_mode_use_tx_num = + clamp_t(uint32_t, pd->rx1tx1_mode_use_tx_num, TX_1, TX_2); + pd->rx1tx1_mode_use_rx_num = + clamp_t(uint32_t, pd->rx1tx1_mode_use_rx_num, RX_1, RX_2); + + ad9361_en_dis_tx(phy, TX_1 | TX_2, pd->rx1tx1_mode_use_tx_num); + ad9361_en_dis_rx(phy, TX_1 | TX_2, pd->rx1tx1_mode_use_rx_num); + } else { + ad9361_en_dis_tx(phy, TX_1 | TX_2, TX_1 | TX_2); + ad9361_en_dis_rx(phy, RX_1 | RX_2, RX_1 | RX_2); + } + + ret = ad9361_rf_port_setup(phy, true, pd->rf_rx_input_sel, + pd->rf_tx_output_sel); + if (ret < 0) + return ret; + + ret = ad9361_pp_port_setup(phy, false); + if (ret < 0) + return ret; + + bbpll_freq = clk_get_rate(phy, phy->ref_clk_scale[BBPLL_CLK]); + ret = ad9361_auxadc_setup(phy, &pd->auxadc_ctrl, bbpll_freq); + if (ret < 0) + return ret; + + ret = ad9361_ctrl_outs_setup(phy, &pd->ctrl_outs_ctrl); + if (ret < 0) + return ret; + + ret = ad9361_set_ref_clk_cycles(phy, refin_Hz); + if (ret < 0) + return ret; + + ret = ad9361_setup_ext_lna(phy, &pd->elna_ctrl); + if (ret < 0) + return ret; + + /* + * This allows forcing a lower F_REF window + * (worse phase noise, better fractional spurs) + */ + pd->trx_synth_max_fref = clamp_t(uint32_t, pd->trx_synth_max_fref, + MIN_SYNTH_FREF, MAX_SYNTH_FREF); + + ref_freq = ad9361_ref_div_sel(refin_Hz, pd->trx_synth_max_fref); + if (!ref_freq) + return -EINVAL; + + ret = clk_set_rate(phy, phy->ref_clk_scale[RX_REFCLK], ref_freq); + if (ret < 0) { + dev_err(dev, "Failed to set RX Synth ref clock rate (%"PRId32")", ret); + return ret; + } + + ret = clk_set_rate(phy, phy->ref_clk_scale[TX_REFCLK], ref_freq); + if (ret < 0) { + dev_err(dev, "Failed to set TX Synth ref clock rate (%"PRId32")", ret); + return ret; + } + + ret = ad9361_txrx_synth_cp_calib(phy, ref_freq, false); /* RXCP */ + if (ret < 0) + return ret; + + ret = ad9361_txrx_synth_cp_calib(phy, ref_freq, true); /* TXCP */ + if (ret < 0) + return ret; + + phy->pdata->use_ext_rx_lo = 0; + phy->pdata->use_ext_tx_lo = 0; + + ret = clk_set_rate(phy, phy->ref_clk_scale[RX_RFPLL], + ad9361_to_clk(pd->rx_synth_freq)); + if (ret < 0) { + dev_err(dev, "Failed to set RX Synth rate (%"PRId32")", + ret); + return ret; + } + + ret = clk_prepare_enable(phy->clks[RX_REFCLK]); + if (ret < 0) { + dev_err(dev, "Failed to enable RX Synth ref clock (%"PRId32")", ret); + return ret; + } + + ret = clk_prepare_enable(phy->clks[RX_RFPLL]); + if (ret < 0) + return ret; + + /* Skip quad cal here we do it later again */ + phy->last_tx_quad_cal_freq = pd->tx_synth_freq; + ret = clk_set_rate(phy, phy->ref_clk_scale[TX_RFPLL], + ad9361_to_clk(pd->tx_synth_freq)); + if (ret < 0) { + dev_err(dev, "Failed to set TX Synth rate (%"PRId32")", + ret); + return ret; + } + + ret = clk_prepare_enable(phy->clks[TX_REFCLK]); + if (ret < 0) { + dev_err(dev, "Failed to enable TX Synth ref clock (%"PRId32")", ret); + return ret; + } + + ret = clk_prepare_enable(phy->clks[TX_RFPLL]); + if (ret < 0) + return ret; + + phy->pdata->use_ext_rx_lo = tmp_use_ext_rx_lo; + phy->pdata->use_ext_tx_lo = tmp_use_ext_tx_lo; + + ad9361_clk_mux_set_parent(phy->ref_clk_scale[RX_RFPLL], + pd->use_ext_rx_lo); + + ad9361_clk_mux_set_parent(phy->ref_clk_scale[TX_RFPLL], + pd->use_ext_tx_lo); + + ret = ad9361_load_mixer_gm_subtable(phy); + if (ret < 0) + return ret; + + ret = ad9361_gc_setup(phy, &pd->gain_ctrl); + if (ret < 0) + return ret; + + ret = ad9361_rx_bb_analog_filter_calib(phy, + real_rx_bandwidth, + bbpll_freq); + if (ret < 0) + return ret; + + ret = ad9361_tx_bb_analog_filter_calib(phy, + real_tx_bandwidth, + bbpll_freq); + if (ret < 0) + return ret; + + ret = ad9361_rx_tia_calib(phy, real_rx_bandwidth); + if (ret < 0) + return ret; + + ret = ad9361_tx_bb_second_filter_calib(phy, real_tx_bandwidth); + if (ret < 0) + return ret; + + ret = ad9361_rx_adc_setup(phy, + bbpll_freq, + clk_get_rate(phy, phy->ref_clk_scale[ADC_CLK])); + if (ret < 0) + return ret; + + ret = ad9361_bb_dc_offset_calib(phy); + if (ret < 0) + return ret; + + ret = ad9361_rf_dc_offset_calib(phy, + ad9361_from_clk(clk_get_rate(phy, phy->ref_clk_scale[RX_RFPLL]))); + if (ret < 0) + return ret; + + phy->current_rx_bw_Hz = pd->rf_rx_bandwidth_Hz; + phy->current_tx_bw_Hz = pd->rf_tx_bandwidth_Hz; + phy->last_tx_quad_cal_phase = ~0; + ret = ad9361_tx_quad_calib(phy, real_rx_bandwidth, real_tx_bandwidth, -1); + if (ret < 0) + return ret; + + ret = ad9361_tracking_control(phy, phy->bbdc_track_en, + phy->rfdc_track_en, phy->quad_track_en); + if (ret < 0) + return ret; + + ad9361_pp_port_setup(phy, true); + + ret = ad9361_set_ensm_mode(phy, pd->fdd, pd->ensm_pin_ctrl); + if (ret < 0) + return ret; + + ad9361_spi_writef(phy->spi, REG_TX_ATTEN_OFFSET, + MASK_CLR_ATTEN_UPDATE, 0); + + ret = ad9361_set_tx_atten(phy, pd->tx_atten, + pd->rx2tx2 ? true : pd->rx1tx1_mode_use_tx_num == 1, + pd->rx2tx2 ? true : pd->rx1tx1_mode_use_tx_num == 2, true); + if (ret < 0) + return ret; + + if (!pd->rx2tx2) { + ret = ad9361_set_tx_atten(phy, 89750, + pd->rx1tx1_mode_use_tx_num == 2, + pd->rx1tx1_mode_use_tx_num == 1, true); + if (ret < 0) + return ret; + } + + ret = ad9361_rssi_setup(phy, &pd->rssi_ctrl, false); + if (ret < 0) + return ret; + + ret = ad9361_clkout_control(phy, pd->ad9361_clkout_mode); + if (ret < 0) + return ret; + + ret = ad9361_txmon_setup(phy, &pd->txmon_ctrl); + if (ret < 0) + return ret; + + phy->curr_ensm_state = ad9361_spi_readf(spi, REG_STATE, ENSM_STATE(~0)); + ad9361_ensm_set_state(phy, pd->fdd ? ENSM_STATE_FDD : ENSM_STATE_RX, + pd->ensm_pin_ctrl); + + phy->auto_cal_en = true; + phy->cal_threshold_freq = 100000000ULL; /* 100 MHz */ + + return 0; + +} + +/** + * Perform the selected calibration + * @param phy The AD9361 state structure. + * @param cal The selected calibration. + * @param arg The argument of the calibration. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_do_calib_run(struct ad9361_rf_phy *phy, uint32_t cal, + int32_t arg) +{ + int32_t ret; + + dev_dbg(&phy->spi->dev, "%s: CAL %"PRIu32" ARG %"PRId32, __func__, cal, arg); + + ret = ad9361_tracking_control(phy, false, false, false); + if (ret < 0) + return ret; + + ad9361_ensm_force_state(phy, ENSM_STATE_ALERT); + + switch (cal) { + case TX_QUAD_CAL: + ret = ad9361_tx_quad_calib(phy, phy->current_rx_bw_Hz / 2, + phy->current_tx_bw_Hz / 2, arg); + break; + case RFDC_CAL: + ret = ad9361_rf_dc_offset_calib(phy, + ad9361_from_clk(clk_get_rate(phy, phy->ref_clk_scale[RX_RFPLL]))); + break; + default: + ret = -EINVAL; + break; + } + + ret = ad9361_tracking_control(phy, phy->bbdc_track_en, + phy->rfdc_track_en, phy->quad_track_en); + ad9361_ensm_restore_prev_state(phy); + + return ret; +} + +/** + * Set the RF bandwidth. + * @param phy The AD9361 state structure. + * @param rf_rx_bw The desired RX bandwidth [Hz]. + * @param rf_tx_bw The desired TX bandwidth [Hz]. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_update_rf_bandwidth(struct ad9361_rf_phy *phy, + uint32_t rf_rx_bw, uint32_t rf_tx_bw) +{ + int32_t ret; + + ret = ad9361_tracking_control(phy, false, false, false); + if (ret < 0) + return ret; + + ad9361_ensm_force_state(phy, ENSM_STATE_ALERT); + + ret = __ad9361_update_rf_bandwidth(phy, rf_rx_bw, rf_tx_bw); + if (ret < 0) + return ret; + + phy->current_rx_bw_Hz = rf_rx_bw; + phy->current_tx_bw_Hz = rf_tx_bw; + + if (phy->manual_tx_quad_cal_en == false) { + ret = ad9361_tx_quad_calib(phy, rf_rx_bw / 2, rf_tx_bw / 2, -1); + if (ret < 0) + return ret; + } + + ret = ad9361_tracking_control(phy, phy->bbdc_track_en, + phy->rfdc_track_en, phy->quad_track_en); + if (ret < 0) + return ret; + + ad9361_ensm_restore_prev_state(phy); + + return 0; +} + +/** + * Verify the FIR filter coefficients. + * @param phy The AD9361 state structure. + * @param dest Destination identifier (RX1,2 / TX1,2). + * @param ntaps Number of filter Taps. + * @param coef Pointer to filter coefficients. + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t ad9361_verify_fir_filter_coef(struct ad9361_rf_phy *phy, + enum fir_dest dest, + uint32_t ntaps, short *coef) +{ + struct spi_desc *spi = phy->spi; + uint32_t val, offs = 0, gain = 0, conf, sel, cnt; + int32_t ret = 0; + +#ifndef DEBUG + return 0; +#endif + dev_dbg(&phy->spi->dev, "%s: TAPS %"PRIu32", dest %d", + __func__, ntaps, dest); + + if (dest & FIR_IS_RX) { + gain = ad9361_spi_read(spi, REG_RX_FILTER_GAIN); + offs = REG_RX_FILTER_COEF_ADDR - REG_TX_FILTER_COEF_ADDR; + ad9361_spi_write(spi, REG_RX_FILTER_GAIN, 0); + } + + conf = ad9361_spi_read(spi, REG_TX_FILTER_CONF + offs); + + if ((dest & 3) == 3) { + sel = 1; + cnt = 2; + } else { + sel = (dest & 3); + cnt = 1; + } + + for (; cnt > 0; cnt--, sel++) { + + ad9361_spi_write(spi, REG_TX_FILTER_CONF + offs, + FIR_NUM_TAPS(ntaps / 16 - 1) | + FIR_SELECT(sel) | FIR_START_CLK); + for (val = 0; val < ntaps; val++) { + short tmp; + ad9361_spi_write(spi, REG_TX_FILTER_COEF_ADDR + offs, val); + + tmp = (ad9361_spi_read(spi, REG_TX_FILTER_COEF_READ_DATA_1 + offs) & 0xFF) | + (ad9361_spi_read(spi, REG_TX_FILTER_COEF_READ_DATA_2 + offs) << 8); + + if (tmp != coef[val]) { + dev_err(&phy->spi->dev,"%s%"PRIu32" read verify failed TAP%"PRIu32" %d =! %d", + (dest & FIR_IS_RX) ? "RX" : "TX", sel, + val, tmp, coef[val]); + ret = -EIO; + } + } + } + + if (dest & FIR_IS_RX) { + ad9361_spi_write(spi, REG_RX_FILTER_GAIN, gain); + } + + ad9361_spi_write(spi, REG_TX_FILTER_CONF + offs, conf); + + return ret; +} + +/** + * Load the FIR filter coefficients. + * @param phy The AD9361 state structure. + * @param dest Destination identifier (RX1,2 / TX1,2). + * @param gain_dB Gain option. + * @param ntaps Number of filter Taps. + * @param coef Pointer to filter coefficients. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_load_fir_filter_coef(struct ad9361_rf_phy *phy, + enum fir_dest dest, int32_t gain_dB, + uint32_t ntaps, int16_t *coef) +{ + struct spi_desc *spi = phy->spi; + uint32_t val, offs = 0, fir_conf = 0, fir_enable = 0; + int32_t ret; + + dev_dbg(&phy->spi->dev, "%s: TAPS %"PRIu32", gain %"PRId32", dest %d", + __func__, ntaps, gain_dB, dest); + + if (coef == NULL || !ntaps || ntaps > 128 || ntaps % 16) { + dev_err(&phy->spi->dev, + "%s: Invalid parameters: TAPS %"PRIu32", gain %"PRId32", dest 0x%X", + __func__, ntaps, gain_dB, dest); + + return -EINVAL; + } + + ad9361_ensm_force_state(phy, ENSM_STATE_ALERT); + + if (dest & FIR_IS_RX) { + val = 3 - (gain_dB + 12) / 6; + ad9361_spi_write(spi, REG_RX_FILTER_GAIN, val & 0x3); + offs = REG_RX_FILTER_COEF_ADDR - REG_TX_FILTER_COEF_ADDR; + phy->rx_fir_ntaps = ntaps; + fir_enable = ad9361_spi_readf(phy->spi, + REG_RX_ENABLE_FILTER_CTRL, RX_FIR_ENABLE_DECIMATION(~0)); + ad9361_spi_writef(phy->spi, REG_RX_ENABLE_FILTER_CTRL, + RX_FIR_ENABLE_DECIMATION(~0), + (phy->rx_fir_dec == 4) ? 3 : phy->rx_fir_dec); + } else { + if (gain_dB == -6) + fir_conf = TX_FIR_GAIN_6DB; + phy->tx_fir_ntaps = ntaps; + fir_enable = ad9361_spi_readf(phy->spi, + REG_TX_ENABLE_FILTER_CTRL, TX_FIR_ENABLE_INTERPOLATION(~0)); + ad9361_spi_writef(phy->spi, REG_TX_ENABLE_FILTER_CTRL, + TX_FIR_ENABLE_INTERPOLATION(~0), + (phy->tx_fir_int == 4) ? 3 : phy->tx_fir_int); + } + + val = ntaps / 16 - 1; + + fir_conf |= FIR_NUM_TAPS(val) | FIR_SELECT(dest) | FIR_START_CLK; + + ad9361_spi_write(spi, REG_TX_FILTER_CONF + offs, fir_conf); + + for (val = 0; val < ntaps; val++) { + ad9361_spi_write(spi, REG_TX_FILTER_COEF_ADDR + offs, val); + ad9361_spi_write(spi, REG_TX_FILTER_COEF_WRITE_DATA_1 + offs, + coef[val] & 0xFF); + ad9361_spi_write(spi, REG_TX_FILTER_COEF_WRITE_DATA_2 + offs, + coef[val] >> 8); + ad9361_spi_write(spi, REG_TX_FILTER_CONF + offs, + fir_conf | FIR_WRITE); + ad9361_spi_write(spi, REG_TX_FILTER_COEF_READ_DATA_2 + offs, 0); + ad9361_spi_write(spi, REG_TX_FILTER_COEF_READ_DATA_2 + offs, 0); + } + + ad9361_spi_write(spi, REG_TX_FILTER_CONF + offs, fir_conf); + fir_conf &= ~FIR_START_CLK; + ad9361_spi_write(spi, REG_TX_FILTER_CONF + offs, fir_conf); + + ret = ad9361_verify_fir_filter_coef(phy, dest, ntaps, coef); + + if (dest & FIR_IS_RX) + ad9361_spi_writef(phy->spi, REG_RX_ENABLE_FILTER_CTRL, + RX_FIR_ENABLE_DECIMATION(~0), fir_enable); + else + ad9361_spi_writef(phy->spi, REG_TX_ENABLE_FILTER_CTRL, + TX_FIR_ENABLE_INTERPOLATION(~0), fir_enable); + + ad9361_ensm_restore_prev_state(phy); + + return ret; +} + +/** + * Parse the FIR filter file/buffer. + * @param phy The AD9361 state structure. + * @param data Pointer to buffer. + * @param size Buffer size. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_parse_fir(struct ad9361_rf_phy *phy, + char *data, uint32_t size) +{ + char *line; + int32_t i = 0, ret, txc, rxc; + int32_t tx = -1, tx_gain = 0, tx_int = 0; + int32_t rx = -1, rx_gain = 0, rx_dec = 0; + int32_t rtx = -1, rrx = -1; + int16_t coef_tx[128]; + int16_t coef_rx[128]; + char *ptr = data; + + phy->filt_rx_bw_Hz = 0; + phy->filt_tx_bw_Hz = 0; + phy->filt_valid = false; + + while ((line = strsep(&ptr, "\n"))) { + if (line >= data + size) { + break; + } + + if (line[0] == '#') + continue; + + if (tx < 0) { +#ifdef WIN32 + ret = sscanf_s(line, "TX %d GAIN %d INT %d", + &tx, &tx_gain, &tx_int); +#else + ret = sscanf(line, "TX %"PRId32" GAIN %"PRId32" INT %"PRId32, + &tx, &tx_gain, &tx_int); +#endif + if (ret == 3) + continue; + else + tx = -1; + } + if (rx < 0) { +#ifdef WIN32 + ret = sscanf_s(line, "RX %d GAIN %d DEC %d", + &rx, &rx_gain, &rx_dec); +#else + ret = sscanf(line, "RX %"PRId32" GAIN %"PRId32" DEC %"PRId32, + &rx, &rx_gain, &rx_dec); +#endif + if (ret == 3) + continue; + else + tx = -1; + } + + if (rtx < 0) { +#ifdef WIN32 + ret = sscanf(line, "RTX %lu %lu %lu %lu %lu %lu", +#else + ret = sscanf(line, + "RTX %"PRIu32" %"PRIu32" %"PRIu32" %"PRIu32" %"PRIu32" %"PRIu32, +#endif + &phy->filt_tx_path_clks[0], + &phy->filt_tx_path_clks[1], + &phy->filt_tx_path_clks[2], + &phy->filt_tx_path_clks[3], + &phy->filt_tx_path_clks[4], + &phy->filt_tx_path_clks[5]); + if (ret == 6) { + rtx = 0; + continue; + } else { + rtx = -1; + } + } + + if (rrx < 0) { +#ifdef WIN32 + ret = sscanf(line, "RRX %lu %lu %lu %lu %lu %lu", +#else + ret = sscanf(line, + "RRX %"PRIu32" %"PRIu32" %"PRIu32" %"PRIu32" %"PRIu32" %"PRIu32, +#endif + &phy->filt_rx_path_clks[0], + &phy->filt_rx_path_clks[1], + &phy->filt_rx_path_clks[2], + &phy->filt_rx_path_clks[3], + &phy->filt_rx_path_clks[4], + &phy->filt_rx_path_clks[5]); + if (ret == 6) { + rrx = 0; + continue; + } else { + rrx = -1; + } + } + + if (!phy->filt_rx_bw_Hz) { +#ifdef WIN32 + ret = sscanf(line, "BWRX %d", &phy->filt_rx_bw_Hz); +#else + ret = sscanf(line, "BWRX %"PRId32, &phy->filt_rx_bw_Hz); +#endif + if (ret == 1) + continue; + else + phy->filt_rx_bw_Hz = 0; + } + + if (!phy->filt_tx_bw_Hz) { +#ifdef WIN32 + ret = sscanf(line, "BWTX %d", &phy->filt_tx_bw_Hz); +#else + ret = sscanf(line, "BWTX %"PRId32, &phy->filt_tx_bw_Hz); +#endif + if (ret == 1) + continue; + else + phy->filt_tx_bw_Hz = 0; + } + +#ifdef WIN32 + ret = sscanf_s(line, "%d,%d", &txc, &rxc); +#else + ret = sscanf(line, "%"PRId32",%"PRId32, &txc, &rxc); +#endif + if (ret == 1) { + coef_tx[i] = coef_rx[i] = (int16_t)txc; + i++; + continue; + } else if (ret == 2) { + coef_tx[i] = (int16_t)txc; + coef_rx[i] = (int16_t)rxc; + i++; + continue; + } + } + + switch (tx) { + case FIR_TX1: + case FIR_TX2: + case FIR_TX1_TX2: + phy->tx_fir_int = tx_int; + ret = ad9361_load_fir_filter_coef(phy, (enum fir_dest)tx, tx_gain, i, coef_tx); + break; + default: + ret = -EINVAL; + } + + switch (rx | FIR_IS_RX) { + case FIR_RX1: + case FIR_RX2: + case FIR_RX1_RX2: + phy->rx_fir_dec = rx_dec; + ret = ad9361_load_fir_filter_coef(phy, (enum fir_dest)(rx | FIR_IS_RX), + rx_gain, i, coef_rx); + break; + default: + ret = -EINVAL; + } + + if (ret < 0) + return ret; + + if (!(rrx | rtx)) + phy->filt_valid = true; + + return size; +} + +/** + * Validate FIR filter configuration - on pass enable. + * @param phy The AD9361 state structure. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_validate_enable_fir(struct ad9361_rf_phy *phy) +{ + int32_t ret; + uint32_t rx[6], tx[6]; + uint32_t max, min, valid; + + dev_dbg(dev, "%s: TX FIR EN=%d/TAPS%d/INT%d, RX FIR EN=%d/TAPS%d/DEC%d", + __func__, !phy->bypass_tx_fir, phy->tx_fir_ntaps, phy->tx_fir_int, + !phy->bypass_rx_fir, phy->rx_fir_ntaps, phy->rx_fir_dec); + + if (!phy->bypass_tx_fir) { + if (!(phy->tx_fir_int == 1 || phy->tx_fir_int == 2 || + phy->tx_fir_int == 4)) { + dev_err(dev, + "%s: Invalid: Interpolation %d in filter config", + __func__, phy->tx_fir_int); + return -EINVAL; + } + + + if (phy->tx_fir_int == 1 && phy->tx_fir_ntaps > 64) { + dev_err(dev, + "%s: Invalid: TAPS > 64 and Interpolation = 1", + __func__); + return -EINVAL; + } + } + + if (!phy->bypass_rx_fir) { + if (!(phy->rx_fir_dec == 1 || phy->rx_fir_dec == 2 || + phy->rx_fir_dec == 4)) { + dev_err(dev, + "%s: Invalid: Decimation %d in filter config", + __func__, phy->rx_fir_dec); + + return -EINVAL; + } + } + + if (!phy->filt_valid || phy->bypass_rx_fir || phy->bypass_tx_fir) { + ret = ad9361_calculate_rf_clock_chain(phy, + clk_get_rate(phy, phy->ref_clk_scale[TX_SAMPL_CLK]), + phy->rate_governor, rx, tx); + if (ret < 0) { + min = phy->rate_governor ? 1500000U : 1000000U; + dev_err(dev, + "%s: Calculating filter rates failed %"PRId32 + " using min frequency",__func__, ret); + ret = ad9361_calculate_rf_clock_chain(phy, min, + phy->rate_governor, rx, tx); + if (ret < 0) { + return ret; + } + } + valid = false; + } else { +#ifndef ALTERA_PLATFORM + memcpy(rx, phy->filt_rx_path_clks, sizeof(rx)); + memcpy(tx, phy->filt_tx_path_clks, sizeof(tx)); +#else + int32_t i; + uint32_t num; + num = sizeof(rx) / sizeof(rx[0]); + for (i = 0; i < num; i++) + rx[i] = phy->filt_rx_path_clks[i]; + num = sizeof(tx) / sizeof(rx[0]); + for (i = 0; i < num; i++) + tx[i] = phy->filt_tx_path_clks[i]; +#endif + valid = true; + + } + +#ifdef _DEBUG + dev_dbg(&phy->spi->dev, + "%s:RX %"PRIu32" %"PRIu32" %"PRIu32" %"PRIu32" %"PRIu32" %"PRIu32, + __func__, rx[BBPLL_FREQ], rx[ADC_FREQ], + rx[R2_FREQ], rx[R1_FREQ], + rx[CLKRF_FREQ], rx[RX_SAMPL_FREQ]); + + dev_dbg(&phy->spi->dev, + "%s:TX %"PRIu32" %"PRIu32" %"PRIu32" %"PRIu32" %"PRIu32" %"PRIu32, + __func__, tx[BBPLL_FREQ], tx[ADC_FREQ], + tx[R2_FREQ], tx[R1_FREQ], + tx[CLKRF_FREQ], tx[RX_SAMPL_FREQ]); +#endif + + if (!phy->bypass_tx_fir) { + max = (tx[DAC_FREQ] / tx[TX_SAMPL_FREQ]) * 16; + if (phy->tx_fir_ntaps > max) { + dev_err(dev, + "%s: Invalid: ratio DAC / TX_SAMPL * 16 > TAPS" + "(max %"PRIu32", adc %"PRIu32", tx %"PRIu32")", + __func__, max, tx[DAC_FREQ], tx[TX_SAMPL_FREQ]); + return -EINVAL; + } + } + + if (!phy->bypass_rx_fir) { + max = ((rx[ADC_FREQ] / ((rx[ADC_FREQ] == rx[R2_FREQ]) ? 1 : 2)) / + rx[RX_SAMPL_FREQ]) * 16; + if (phy->rx_fir_ntaps > max) { + dev_err(dev, + "%s: Invalid: ratio ADC/2 / RX_SAMPL * 16 > TAPS (max %"PRIu32")", + __func__, max); + return -EINVAL; + } + } + + ret = ad9361_set_trx_clock_chain(phy, rx, tx); + if (ret < 0) + return ret; + + /* See also: ad9361_set_trx_clock_chain() */ + if (!phy->pdata->dig_interface_tune_fir_disable && + phy->bypass_tx_fir && phy->bypass_rx_fir) + ad9361_dig_tune(phy, 0, RESTORE_DEFAULT); + + return ad9361_update_rf_bandwidth(phy, + valid ? phy->filt_rx_bw_Hz : phy->current_rx_bw_Hz, + valid ? phy->filt_tx_bw_Hz : phy->current_tx_bw_Hz); +} + +/* +* AD9361 Clocks +*/ + +/** +* Set the multiplier and the divider for the selected refclk_scale structure. +* @param priv The selected refclk_scale structure. +* @param mul The multiplier value. +* @param div The divider value. +* @return 0 in case of success, negative error code otherwise. +*/ +static inline int32_t ad9361_set_muldiv(struct refclk_scale *priv, uint32_t mul, + uint32_t div) +{ + priv->mult = mul; + priv->div = div; + return 0; +} + +/** + * Get the clk scaler for the selected refclk_scale structure. + * @param priv The selected refclk_scale structure. + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t ad9361_get_clk_scaler(struct refclk_scale *clk_priv) +{ + struct spi_desc *spi = clk_priv->spi; + uint32_t tmp, tmp1; + + switch (clk_priv->source) { + case BB_REFCLK: + tmp = ad9361_spi_read(spi, REG_CLOCK_CTRL); + tmp &= 0x3; + break; + case RX_REFCLK: + tmp = ad9361_spi_readf(spi, REG_REF_DIVIDE_CONFIG_1, + RX_REF_DIVIDER_MSB); + tmp1 = ad9361_spi_readf(spi, REG_REF_DIVIDE_CONFIG_2, + RX_REF_DIVIDER_LSB); + tmp = (tmp << 1) | tmp1; + break; + case TX_REFCLK: + tmp = ad9361_spi_readf(spi, REG_REF_DIVIDE_CONFIG_2, + TX_REF_DIVIDER(~0)); + break; + case ADC_CLK: + tmp = ad9361_spi_read(spi, REG_BBPLL); + return ad9361_set_muldiv(clk_priv, 1, 1 << (tmp & 0x7)); + case R2_CLK: + tmp = ad9361_spi_readf(spi, REG_RX_ENABLE_FILTER_CTRL, + DEC3_ENABLE_DECIMATION(~0)); + return ad9361_set_muldiv(clk_priv, 1, tmp + 1); + case R1_CLK: + tmp = ad9361_spi_readf(spi, REG_RX_ENABLE_FILTER_CTRL, RHB2_EN); + return ad9361_set_muldiv(clk_priv, 1, tmp + 1); + case CLKRF_CLK: + tmp = ad9361_spi_readf(spi, REG_RX_ENABLE_FILTER_CTRL, RHB1_EN); + return ad9361_set_muldiv(clk_priv, 1, tmp + 1); + case RX_SAMPL_CLK: + tmp = ad9361_spi_readf(spi, REG_RX_ENABLE_FILTER_CTRL, + RX_FIR_ENABLE_DECIMATION(~0)); + + if (!tmp) + tmp = 1; /* bypass filter */ + else + tmp = (1 << (tmp - 1)); + + return ad9361_set_muldiv(clk_priv, 1, tmp); + case DAC_CLK: + tmp = ad9361_spi_readf(spi, REG_BBPLL, BIT(3)); + return ad9361_set_muldiv(clk_priv, 1, tmp + 1); + case T2_CLK: + tmp = ad9361_spi_readf(spi, REG_TX_ENABLE_FILTER_CTRL, + THB3_ENABLE_INTERP(~0)); + return ad9361_set_muldiv(clk_priv, 1, tmp + 1); + case T1_CLK: + tmp = ad9361_spi_readf(spi, REG_TX_ENABLE_FILTER_CTRL, THB2_EN); + return ad9361_set_muldiv(clk_priv, 1, tmp + 1); + case CLKTF_CLK: + tmp = ad9361_spi_readf(spi, REG_TX_ENABLE_FILTER_CTRL, THB1_EN); + return ad9361_set_muldiv(clk_priv, 1, tmp + 1); + case TX_SAMPL_CLK: + tmp = ad9361_spi_readf(spi, REG_TX_ENABLE_FILTER_CTRL, + TX_FIR_ENABLE_INTERPOLATION(~0)); + + if (!tmp) + tmp = 1; /* bypass filter */ + else + tmp = (1 << (tmp - 1)); + + return ad9361_set_muldiv(clk_priv, 1, tmp); + default: + return -EINVAL; + } + + /* REFCLK Scaler */ + switch (tmp) { + case 0: + ad9361_set_muldiv(clk_priv, 1, 1); + break; + case 1: + ad9361_set_muldiv(clk_priv, 1, 2); + break; + case 2: + ad9361_set_muldiv(clk_priv, 1, 4); + break; + case 3: + ad9361_set_muldiv(clk_priv, 2, 1); + break; + default: + return -EINVAL; + + } + + return 0; +} + +/** + * Calculate the REFCLK Scaler for the selected refclk_scale structure. + * Note: REFCLK Scaler values - 00: x1; 01: x½; 10: x¼; 11: x2. + * @param clk_priv The selected refclk_scale structure. + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t ad9361_to_refclk_scaler(struct refclk_scale *clk_priv) +{ + /* REFCLK Scaler */ + switch (((clk_priv->mult & 0xF) << 4) | (clk_priv->div & 0xF)) { + case 0x11: + return 0; + case 0x12: + return 1; + case 0x14: + return 2; + case 0x21: + return 3; + default: + return -EINVAL; + } +}; + +/** + * Set clk scaler for the selected refclk_scale structure. + * @param clk_priv The selected refclk_scale structure. + * @param set Set true, the reference clock frequency will be scaled before + * it enters the BBPLL. + * @return 0 in case of success, negative error code otherwise. + */ +static int32_t ad9361_set_clk_scaler(struct refclk_scale *clk_priv, bool set) +{ + struct spi_desc *spi = clk_priv->spi; + uint32_t tmp; + int32_t ret; + + switch (clk_priv->source) { + case BB_REFCLK: + ret = ad9361_to_refclk_scaler(clk_priv); + if (ret < 0) + return ret; + if (set) + return ad9361_spi_writef(spi, REG_CLOCK_CTRL, + REF_FREQ_SCALER(~0), ret); + break; + + case RX_REFCLK: + ret = ad9361_to_refclk_scaler(clk_priv); + if (ret < 0) + return ret; + if (set) { + tmp = ret; + ret = ad9361_spi_writef(spi, REG_REF_DIVIDE_CONFIG_1, + RX_REF_DIVIDER_MSB, tmp >> 1); + ret |= ad9361_spi_writef(spi, REG_REF_DIVIDE_CONFIG_2, + RX_REF_DIVIDER_LSB, tmp & 1); + return ret; + } + break; + case TX_REFCLK: + ret = ad9361_to_refclk_scaler(clk_priv); + if (ret < 0) + return ret; + if (set) + return ad9361_spi_writef(spi, REG_REF_DIVIDE_CONFIG_2, + TX_REF_DIVIDER(~0), ret); + break; + case ADC_CLK: + tmp = ilog2((uint8_t)clk_priv->div); + if (clk_priv->mult != 1 || tmp > 6 || tmp < 1) + return -EINVAL; + + if (set) + return ad9361_spi_writef(spi, REG_BBPLL, 0x7, tmp); + break; + case R2_CLK: + if (clk_priv->mult != 1 || clk_priv->div > 3 || clk_priv->div < 1) + return -EINVAL; + if (set) + return ad9361_spi_writef(spi, REG_RX_ENABLE_FILTER_CTRL, + DEC3_ENABLE_DECIMATION(~0), + clk_priv->div - 1); + break; + case R1_CLK: + if (clk_priv->mult != 1 || clk_priv->div > 2 || clk_priv->div < 1) + return -EINVAL; + if (set) + return ad9361_spi_writef(spi, REG_RX_ENABLE_FILTER_CTRL, + RHB2_EN, clk_priv->div - 1); + break; + case CLKRF_CLK: + if (clk_priv->mult != 1 || clk_priv->div > 2 || clk_priv->div < 1) + return -EINVAL; + if (set) + return ad9361_spi_writef(spi, REG_RX_ENABLE_FILTER_CTRL, + RHB1_EN, clk_priv->div - 1); + break; + case RX_SAMPL_CLK: + if (clk_priv->mult != 1 || clk_priv->div > 4 || + clk_priv->div < 1 || clk_priv->div == 3) + return -EINVAL; + + if (clk_priv->phy->bypass_rx_fir) + tmp = 0; + else + tmp = ilog2(clk_priv->div) + 1; + + if (set) + return ad9361_spi_writef(spi, REG_RX_ENABLE_FILTER_CTRL, + RX_FIR_ENABLE_DECIMATION(~0), tmp); + break; + case DAC_CLK: + if (clk_priv->mult != 1 || clk_priv->div > 2 || clk_priv->div < 1) + return -EINVAL; + if (set) + return ad9361_spi_writef(spi, REG_BBPLL, + BIT(3), clk_priv->div - 1); + break; + case T2_CLK: + if (clk_priv->mult != 1 || clk_priv->div > 3 || clk_priv->div < 1) + return -EINVAL; + if (set) + return ad9361_spi_writef(spi, REG_TX_ENABLE_FILTER_CTRL, + THB3_ENABLE_INTERP(~0), + clk_priv->div - 1); + break; + case T1_CLK: + if (clk_priv->mult != 1 || clk_priv->div > 2 || clk_priv->div < 1) + return -EINVAL; + if (set) + return ad9361_spi_writef(spi, REG_TX_ENABLE_FILTER_CTRL, + THB2_EN, clk_priv->div - 1); + break; + case CLKTF_CLK: + if (clk_priv->mult != 1 || clk_priv->div > 2 || clk_priv->div < 1) + return -EINVAL; + if (set) + return ad9361_spi_writef(spi, REG_TX_ENABLE_FILTER_CTRL, + THB1_EN, clk_priv->div - 1); + break; + case TX_SAMPL_CLK: + if (clk_priv->mult != 1 || clk_priv->div > 4 || + clk_priv->div < 1 || clk_priv->div == 3) + return -EINVAL; + + if (clk_priv->phy->bypass_tx_fir) + tmp = 0; + else + tmp = ilog2(clk_priv->div) + 1; + + if (set) + return ad9361_spi_writef(spi, REG_TX_ENABLE_FILTER_CTRL, + TX_FIR_ENABLE_INTERPOLATION(~0), tmp); + break; + default: + return -EINVAL; + } + + return 0; +} + +/** + * Recalculate the clock rate. + * @param clk_priv The refclk_scale structure. + * @param parent_rate The parent clock rate. + * @return The clock rate. + */ +uint32_t ad9361_clk_factor_recalc_rate(struct refclk_scale *clk_priv, + uint32_t parent_rate) +{ + uint64_t rate; + + ad9361_get_clk_scaler(clk_priv); + rate = (parent_rate * clk_priv->mult) / clk_priv->div; + + return (uint32_t)rate; +} + +/** + * Calculate the closest possible clock rate that can be set. + * @param clk_priv The refclk_scale structure. + * @param rate The clock rate. + * @param prate The parent clock rate. + * @return The closest possible clock rate that can be set. + */ +int32_t ad9361_clk_factor_round_rate(struct refclk_scale *clk_priv, + uint32_t rate, + uint32_t *prate) +{ + int32_t ret; + + if (rate >= *prate) { + clk_priv->mult = DIV_ROUND_CLOSEST(rate, *prate); + clk_priv->div = 1; + + } else { + clk_priv->div = DIV_ROUND_CLOSEST(*prate, rate); + clk_priv->mult = 1; + if (!clk_priv->div) { + dev_err(&clk_priv->spi->dev, "%s: divide by zero", + __func__); + clk_priv->div = 1; + } + } + + ret = ad9361_set_clk_scaler(clk_priv, false); + if (ret < 0) + return ret; + + return (*prate / clk_priv->div) * clk_priv->mult; +} + +/** + * Set the clock rate. + * @param clk_priv The refclk_scale structure. + * @param rate The clock rate. + * @param parent_rate The parent clock rate. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_clk_factor_set_rate(struct refclk_scale *clk_priv, uint32_t rate, + uint32_t parent_rate) +{ + dev_dbg(&clk_priv->spi->dev, "%s: Rate %"PRIu32" Hz Parent Rate %"PRIu32" Hz", + __func__, rate, parent_rate); + + if (rate >= parent_rate) { + clk_priv->mult = DIV_ROUND_CLOSEST(rate, parent_rate); + clk_priv->div = 1; + } else { + clk_priv->div = DIV_ROUND_CLOSEST(parent_rate, rate); + clk_priv->mult = 1; + if (!clk_priv->div) { + dev_err(&clk_priv->spi->dev, "%s: divide by zero", + __func__); + clk_priv->div = 1; + } + } + + return ad9361_set_clk_scaler(clk_priv, true); +} + +/* + * BBPLL + */ +/** + * Recalculate the clock rate. + * @param clk_priv The refclk_scale structure. + * @param parent_rate The parent clock rate. + * @return The clock rate. + */ +uint32_t ad9361_bbpll_recalc_rate(struct refclk_scale *clk_priv, + uint32_t parent_rate) +{ + uint64_t rate; + uint32_t fract, integer; + uint8_t buf[4]; + + ad9361_spi_readm(clk_priv->spi, REG_INTEGER_BB_FREQ_WORD, &buf[0], + REG_INTEGER_BB_FREQ_WORD - REG_FRACT_BB_FREQ_WORD_1 + 1); + + fract = (buf[3] << 16) | (buf[2] << 8) | buf[1]; + integer = buf[0]; + + rate = ((uint64_t)parent_rate * fract); + do_div(&rate, BBPLL_MODULUS); + rate += (uint64_t)parent_rate * integer; + + return (uint32_t)rate; +} + +/** + * Calculate the closest possible clock rate that can be set. + * @param clk_priv The refclk_scale structure. + * @param rate The clock rate. + * @param prate The parent clock rate. + * @return The closest possible clock rate that can be set. + */ +int32_t ad9361_bbpll_round_rate(struct refclk_scale *clk_priv, uint32_t rate, + uint32_t *prate) +{ + uint64_t tmp; + uint32_t fract, integer; + uint64_t temp; + + if (clk_priv) { + // Unused variable - fix compiler warning + } + + if (rate > MAX_BBPLL_FREQ) + return MAX_BBPLL_FREQ; + + if (rate < MIN_BBPLL_FREQ) + return MIN_BBPLL_FREQ; + + temp = rate; + tmp = do_div(&temp, *prate); + rate = temp; + tmp = tmp * BBPLL_MODULUS + (*prate >> 1); + do_div(&tmp, *prate); + + integer = rate; + fract = tmp; + + tmp = *prate * (uint64_t)fract; + do_div(&tmp, BBPLL_MODULUS); + tmp += *prate * integer; + + return tmp; +} + +/** + * Set the clock rate. + * @param clk_priv The refclk_scale structure. + * @param rate The clock rate. + * @param parent_rate The parent clock rate. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_bbpll_set_rate(struct refclk_scale *clk_priv, uint32_t rate, + uint32_t parent_rate) +{ + struct spi_desc *spi = clk_priv->spi; + uint64_t tmp; + uint32_t fract, integer; + int32_t icp_val; + uint8_t lf_defaults[3] = { 0x35, 0x5B, 0xE8 }; + uint64_t temp; + + dev_dbg(&spi->dev, "%s: Rate %"PRIu32" Hz Parent Rate %"PRIu32" Hz", + __func__, rate, parent_rate); + + /* + * Setup Loop Filter and CP Current + * Scale is 150uA @ (1280MHz BBPLL, 40MHz REFCLK) + */ + tmp = (rate >> 7) * 150ULL; + do_div(&tmp, (parent_rate >> 7) * 32UL); + + /* 25uA/LSB, Offset 25uA */ + icp_val = DIV_ROUND_CLOSEST((uint32_t)tmp, 25U) - 1; + + icp_val = clamp(icp_val, 1, 64); + + ad9361_spi_write(spi, REG_CP_CURRENT, icp_val); + ad9361_spi_writem(spi, REG_LOOP_FILTER_3, lf_defaults, + ARRAY_SIZE(lf_defaults)); + + /* Allow calibration to occur and set cal count to 1024 for max accuracy */ + ad9361_spi_write(spi, REG_VCO_CTRL, + FREQ_CAL_ENABLE | FREQ_CAL_COUNT_LENGTH(3)); + /* Set calibration clock to REFCLK/4 for more accuracy */ + ad9361_spi_write(spi, REG_SDM_CTRL, 0x10); + + /* Calculate and set BBPLL frequency word */ + temp = rate; + tmp = do_div(&temp, parent_rate); + rate = temp; + tmp = tmp *(uint64_t)BBPLL_MODULUS + (parent_rate >> 1); + do_div(&tmp, parent_rate); + + integer = rate; + fract = tmp; + + ad9361_spi_write(spi, REG_INTEGER_BB_FREQ_WORD, integer); + ad9361_spi_write(spi, REG_FRACT_BB_FREQ_WORD_3, fract); + ad9361_spi_write(spi, REG_FRACT_BB_FREQ_WORD_2, fract >> 8); + ad9361_spi_write(spi, REG_FRACT_BB_FREQ_WORD_1, fract >> 16); + + ad9361_spi_write(spi, REG_SDM_CTRL_1, + INIT_BB_FO_CAL | BBPLL_RESET_BAR); /* Start BBPLL Calibration */ + ad9361_spi_write(spi, REG_SDM_CTRL_1, + BBPLL_RESET_BAR); /* Clear BBPLL start calibration bit */ + + ad9361_spi_write(spi, REG_VCO_PROGRAM_1, + 0x86); /* Increase BBPLL KV and phase margin */ + ad9361_spi_write(spi, REG_VCO_PROGRAM_2, + 0x01); /* Increase BBPLL KV and phase margin */ + ad9361_spi_write(spi, REG_VCO_PROGRAM_2, + 0x05); /* Increase BBPLL KV and phase margin */ + + return ad9361_check_cal_done(clk_priv->phy, REG_CH_1_OVERFLOW, + BBPLL_LOCK, 1); +} + +/* + * RFPLL + */ + +/** + * Calculate the RFPLL frequency. + * @param parent_rate The parent clock rate. + * @param integer The integer value. + * @param fract The fractional value. + * @param vco_div The VCO divider. + * @return The RFPLL frequency. + */ +static uint64_t ad9361_calc_rfpll_int_freq(uint64_t parent_rate, + uint64_t integer, + uint64_t fract, uint32_t vco_div) +{ + uint64_t rate; + + rate = parent_rate * fract; + do_div(&rate, RFPLL_MODULUS); + rate += parent_rate * integer; + + return rate >> (vco_div + 1); +} + +/** + * Calculate the RFPLL dividers. + * @param phy The AD9361 state structure. + * @param clk_priv The refclk_scale structure. + * @param freq The RFPLL frequency. + * @param parent_rate The parent clock rate. + * @param integer The integer value. + * @param fract The fractional value. + * @param vco_div The VCO divider. + * @param vco_freq The VCO frequency. + * @return The RFPLL frequency. + */ +static int32_t ad9361_calc_rfpll_int_divder(struct ad9361_rf_phy *phy, + struct refclk_scale *clk_priv, uint64_t freq, + uint64_t parent_rate, uint32_t *integer, + uint32_t *fract, int32_t *vco_div, uint64_t *vco_freq) +{ + uint64_t tmp; + int32_t div, ret; + + ret = ad9361_validate_rfpll(phy, clk_priv->source == TX_RFPLL_INT, freq); + if (ret) + return ret; + + div = -1; + + while (freq <= MIN_VCO_FREQ_HZ) { + freq <<= 1; + div++; + } + + *vco_div = div; + *vco_freq = freq; + tmp = do_div(&freq, parent_rate); + tmp = tmp * RFPLL_MODULUS + (parent_rate >> 1); + do_div(&tmp, parent_rate); + *integer = freq; + *fract = tmp; + + return 0; +} + +/** + * Recalculate the clock rate. + * @param clk_priv The refclk_scale structure. + * @param parent_rate The parent clock rate. + * @return The clock rate. + */ +uint32_t ad9361_rfpll_int_recalc_rate(struct refclk_scale *clk_priv, + uint32_t parent_rate) +{ + struct ad9361_rf_phy *phy = clk_priv->phy; + uint32_t fract, integer; + uint8_t buf[5]; + uint32_t reg, div_mask, vco_div, profile; + + dev_dbg(&clk_priv->spi->dev, "%s: Parent Rate %"PRIu32" Hz", + __func__, parent_rate); + + switch (clk_priv->source) { + case RX_RFPLL_INT: + reg = REG_RX_FRACT_BYTE_2; + div_mask = RX_VCO_DIVIDER(~0); + profile = phy->fastlock.current_profile[0]; + break; + case TX_RFPLL_INT: + reg = REG_TX_FRACT_BYTE_2; + div_mask = TX_VCO_DIVIDER(~0); + profile = phy->fastlock.current_profile[1]; + break; + default: + return -EINVAL; + } + + if (profile) { + bool tx = clk_priv->source == TX_RFPLL_INT; + profile = profile - 1; + + buf[0] = ad9361_fastlock_readval(phy->spi, tx, profile, 4); + buf[1] = ad9361_fastlock_readval(phy->spi, tx, profile, 3); + buf[2] = ad9361_fastlock_readval(phy->spi, tx, profile, 2); + buf[3] = ad9361_fastlock_readval(phy->spi, tx, profile, 1); + buf[4] = ad9361_fastlock_readval(phy->spi, tx, profile, 0); + vco_div = ad9361_fastlock_readval(phy->spi, tx, profile, 12) & 0xF; + + } else { + ad9361_spi_readm(clk_priv->spi, reg, &buf[0], ARRAY_SIZE(buf)); + vco_div = ad9361_spi_readf(clk_priv->spi, REG_RFPLL_DIVIDERS, div_mask); + } + + fract = (SYNTH_FRACT_WORD(buf[0]) << 16) | (buf[1] << 8) | buf[2]; + integer = (SYNTH_INTEGER_WORD(buf[3]) << 8) | buf[4]; + + return ad9361_to_clk(ad9361_calc_rfpll_int_freq(parent_rate, integer, + fract, vco_div)); +} + +/** + * Calculate the closest possible clock rate that can be set. + * @param clk_priv The refclk_scale structure. + * @param rate The clock rate. + * @param prate The parent clock rate. + * @return The closest possible clock rate that can be set. + */ +int32_t ad9361_rfpll_int_round_rate(struct refclk_scale *clk_priv, + uint32_t rate, + uint32_t *prate) +{ + dev_dbg(&clk_priv->spi->dev, "%s: Rate %"PRIu32" Hz", __func__, rate); + + if (prate) { + // Unused variable - fix compiler warning + } + + if (clk_priv) { + // Unused variable - fix compiler warning + } + + if (ad9361_from_clk(rate) > MAX_CARRIER_FREQ_HZ || + ad9361_from_clk(rate) < ((clk_priv->source == TX_RFPLL_INT) ? + MIN_TX_CARRIER_FREQ_HZ : MIN_RX_CARRIER_FREQ_HZ)) + return -EINVAL; + + return rate; +} + +/** + * Set the clock rate. + * @param clk_priv The refclk_scale structure. + * @param rate The clock rate. + * @param parent_rate The parent clock rate. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_rfpll_int_set_rate(struct refclk_scale *clk_priv, uint32_t rate, + uint32_t parent_rate) +{ + struct ad9361_rf_phy *phy = clk_priv->phy; + uint64_t vco = 0; + uint8_t buf[5]; + uint32_t reg, div_mask, lock_reg, fract = 0, integer = 0; + int32_t vco_div, ret, fixup_other; + + dev_dbg(&clk_priv->spi->dev, + "%s: %s Rate %"PRIu32" Hz Parent Rate %"PRIu32" Hz", + __func__, clk_priv->source == TX_RFPLL_INT ? "TX" : "RX", + rate, parent_rate); + + ad9361_fastlock_prepare(phy, clk_priv->source == TX_RFPLL_INT, 0, false); + + ret = ad9361_calc_rfpll_int_divder(phy, clk_priv, ad9361_from_clk(rate), + parent_rate, + &integer, &fract, &vco_div, &vco); + if (ret < 0) + return ret; + + switch (clk_priv->source) { + case RX_RFPLL_INT: + reg = REG_RX_FRACT_BYTE_2; + lock_reg = REG_RX_CP_OVERRANGE_VCO_LOCK; + div_mask = RX_VCO_DIVIDER(~0); + phy->cached_rx_rfpll_div = vco_div; + phy->current_rx_lo_freq = rate; + break; + case TX_RFPLL_INT: + reg = REG_TX_FRACT_BYTE_2; + lock_reg = REG_TX_CP_OVERRANGE_VCO_LOCK; + div_mask = TX_VCO_DIVIDER(~0); + phy->cached_tx_rfpll_div = vco_div; + phy->current_tx_lo_freq = rate; + break; + default: + return -EINVAL; + + } + + /* Option to skip VCO cal in TDD mode when moving from TX/RX to Alert */ + if (phy->pdata->tdd_skip_vco_cal) + ad9361_trx_vco_cal_control(phy, clk_priv->source == TX_RFPLL_INT, + true); + + do { + fixup_other = 0; + ad9361_rfpll_vco_init(phy, div_mask == TX_VCO_DIVIDER(~0), + vco, parent_rate); + + buf[0] = SYNTH_FRACT_WORD(fract >> 16); + buf[1] = fract >> 8; + buf[2] = fract & 0xFF; + buf[3] = SYNTH_INTEGER_WORD(integer >> 8) | + (~SYNTH_INTEGER_WORD(~0) & + ad9361_spi_read(clk_priv->spi, reg - 3)); + buf[4] = integer & 0xFF; + + ad9361_spi_writem(clk_priv->spi, reg, buf, 5); + ad9361_spi_writef(clk_priv->spi, REG_RFPLL_DIVIDERS, div_mask, vco_div); + + ret = ad9361_check_cal_done(phy, lock_reg, VCO_LOCK, 1); + + /* In FDD mode with RX LO == TX LO frequency we use TDD tables to + * reduce VCO pulling + */ + + if (((phy->pdata->fdd && !phy->pdata->fdd_independent_mode) && + (phy->current_tx_lo_freq == phy->current_rx_lo_freq) && + (phy->current_tx_use_tdd_table != phy->current_rx_use_tdd_table)) || + ((phy->pdata->fdd && !phy->pdata->fdd_independent_mode) && + (phy->current_tx_lo_freq != phy->current_rx_lo_freq) && + (phy->current_tx_use_tdd_table || phy->current_rx_use_tdd_table))) { + unsigned long _rate; + + switch (clk_priv->source) { + case RX_RFPLL_INT: + reg = REG_TX_FRACT_BYTE_2; + lock_reg = REG_TX_CP_OVERRANGE_VCO_LOCK; + div_mask = TX_VCO_DIVIDER(~0); + _rate = phy->current_tx_lo_freq; + break; + case TX_RFPLL_INT: + reg = REG_RX_FRACT_BYTE_2; + lock_reg = REG_RX_CP_OVERRANGE_VCO_LOCK; + div_mask = RX_VCO_DIVIDER(~0); + _rate = phy->current_rx_lo_freq; + break; + default: + return -EINVAL; + + } + + if (phy->current_tx_lo_freq != phy->current_rx_lo_freq) { + ad9361_calc_rfpll_int_divder(phy, clk_priv, ad9361_from_clk(_rate), + parent_rate, &integer, &fract, &vco_div, &vco); + + ad9361_fastlock_prepare(phy, clk_priv->source == RX_RFPLL_INT, 0, false); + } + + fixup_other = 1; + } + + } while (fixup_other); + + if (phy->pdata->tdd_skip_vco_cal) + ad9361_trx_vco_cal_control(phy, clk_priv->source == TX_RFPLL_INT, + false); + + return ret; +} + +/** + * Recalculate the clock rate. + * @param clk_priv The refclk_scale structure. + * @return The clock rate. + */ +uint32_t ad9361_rfpll_dummy_recalc_rate(struct refclk_scale *clk_priv) +{ + struct ad9361_rf_phy *phy = clk_priv->phy; + + return phy->clks[clk_priv->source]->rate; +} + +/** + * Set the clock rate. + * @param clk_priv The refclk_scale structure. + * @param rate The clock rate. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_rfpll_dummy_set_rate(struct refclk_scale *clk_priv, + uint32_t rate) +{ + struct ad9361_rf_phy *phy = clk_priv->phy; + + phy->clks[clk_priv->source]->rate = rate; + + return 0; +} + +/** + * Recalculate the clock rate. + * @param clk_priv The refclk_scale structure. + * @return The clock rate. + */ +uint32_t ad9361_rfpll_recalc_rate(struct refclk_scale *clk_priv) +{ + struct ad9361_rf_phy *phy = clk_priv->phy; + uint32_t rate; + + switch (clk_priv->source) { + case RX_RFPLL: + if (phy->pdata->use_ext_rx_lo) { + if (phy->ad9361_rfpll_ext_recalc_rate) + rate = phy->ad9361_rfpll_ext_recalc_rate(clk_priv); + else + rate = ad9361_rfpll_dummy_recalc_rate(phy->ref_clk_scale[RX_RFPLL_DUMMY]); + } else { + rate = ad9361_rfpll_int_recalc_rate(phy->ref_clk_scale[RX_RFPLL_INT], + phy->clks[RX_REFCLK]->rate); + } + break; + case TX_RFPLL: + if (phy->pdata->use_ext_tx_lo) { + if (phy->ad9361_rfpll_ext_recalc_rate) + rate = phy->ad9361_rfpll_ext_recalc_rate(clk_priv); + else + rate = ad9361_rfpll_dummy_recalc_rate(phy->ref_clk_scale[TX_RFPLL_DUMMY]); + } else { + rate = ad9361_rfpll_int_recalc_rate(phy->ref_clk_scale[TX_RFPLL_INT], + phy->clks[TX_REFCLK]->rate); + } + break; + default: + rate = 0; + break; + } + + return rate; +} + +/** + * Calculate the closest possible clock rate that can be set. + * @param clk_priv The refclk_scale structure. + * @param rate The clock rate. + * @return The closest possible clock rate that can be set. + */ +int32_t ad9361_rfpll_round_rate(struct refclk_scale *clk_priv, uint32_t rate) +{ + struct ad9361_rf_phy *phy = clk_priv->phy; + int32_t round_rate; + + switch (clk_priv->source) { + case RX_RFPLL: + if (phy->pdata->use_ext_rx_lo) { + if (phy->ad9361_rfpll_ext_round_rate) + round_rate = phy->ad9361_rfpll_ext_round_rate(clk_priv, rate); + else + round_rate = rate; + } else { + round_rate = ad9361_rfpll_int_round_rate(phy->ref_clk_scale[RX_RFPLL_INT], rate, + &phy->clks[phy->ref_clk_scale[RX_RFPLL_INT]->parent_source]->rate); + } + break; + case TX_RFPLL: + if (phy->pdata->use_ext_tx_lo) { + if (phy->ad9361_rfpll_ext_round_rate) + round_rate = phy->ad9361_rfpll_ext_round_rate(clk_priv, rate); + else + round_rate = rate; + } else { + round_rate = ad9361_rfpll_int_round_rate(phy->ref_clk_scale[TX_RFPLL_INT], rate, + &phy->clks[phy->ref_clk_scale[TX_RFPLL_INT]->parent_source]->rate); + } + break; + default: + round_rate = 0; + break; + } + + return round_rate; +} + +/** + * Set the clock rate. + * @param clk_priv The refclk_scale structure. + * @param rate The clock rate. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_rfpll_set_rate(struct refclk_scale *clk_priv, uint32_t rate) +{ + struct ad9361_rf_phy *phy = clk_priv->phy; + int32_t ret; + + switch (clk_priv->source) { + case RX_RFPLL: + if (phy->pdata->use_ext_rx_lo) { + if (phy->ad9361_rfpll_ext_set_rate) + phy->ad9361_rfpll_ext_set_rate(clk_priv, rate); + else + ad9361_rfpll_dummy_set_rate(phy->ref_clk_scale[RX_RFPLL_DUMMY], rate); + } else { + ad9361_rfpll_int_set_rate(phy->ref_clk_scale[RX_RFPLL_INT], rate, + phy->clks[phy->ref_clk_scale[RX_RFPLL_INT]->parent_source]->rate); + } + /* Load Gain Table */ + ret = ad9361_load_gt(phy, ad9361_from_clk(rate), GT_RX1 + GT_RX2); + if (ret < 0) + return ret; + break; + case TX_RFPLL: + if (phy->pdata->use_ext_tx_lo) { + if (phy->ad9361_rfpll_ext_set_rate) + phy->ad9361_rfpll_ext_set_rate(clk_priv, rate); + else + ad9361_rfpll_dummy_set_rate(phy->ref_clk_scale[TX_RFPLL_DUMMY], rate); + } else { + ad9361_rfpll_int_set_rate(phy->ref_clk_scale[TX_RFPLL_INT], rate, + phy->clks[phy->ref_clk_scale[TX_RFPLL_INT]->parent_source]->rate); + } + /* For RX LO we typically have the tracking option enabled + * so for now do nothing here. + */ + if (phy->auto_cal_en && !phy->pdata->use_ext_tx_lo) + if ((diff_abs(phy->last_tx_quad_cal_freq, ad9361_from_clk(rate))) > + phy->cal_threshold_freq) { + ret = ad9361_do_calib_run(phy, TX_QUAD_CAL, -1); + if (ret < 0) + dev_err(&phy->spi->dev, + "%s: TX QUAD cal failed", __func__); + phy->last_tx_quad_cal_freq = ad9361_from_clk(rate); + } + break; + default: + break; + } + + return 0; +} + +/** + * Set clock mux parent. + * @param clk_priv The refclk_scale structure. + * @param index Index - Enable (1), disable (0) ext lo. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_clk_mux_set_parent(struct refclk_scale *clk_priv, uint8_t index) +{ + struct ad9361_rf_phy *phy = clk_priv->phy; + int32_t ret; + + dev_dbg(&clk_priv->spi->dev, "%s: index %d", __func__, index); + + ad9361_ensm_force_state(phy, ENSM_STATE_ALERT); + + ret = ad9361_trx_ext_lo_control(phy, clk_priv->source == TX_RFPLL, index == 1); + if (ret >= 0) + clk_priv->mult = index; + + ad9361_ensm_restore_prev_state(phy); + + return ret; +} + +/** + * Register and initialize a new clock. + * @param phy The AD9361 state structure. + * @param name The name of the new clock. + * @param parent_name The name of the parent clock. + * @param flags The flags. + * @param source The source of the new clock. + * @param parent_source The source of the parent clock. + * @return A struct clk for the new clock or a negative error code. + */ +static struct clk *ad9361_clk_register(struct ad9361_rf_phy *phy, + const char *name, + const char *parent_name, uint32_t flags, + uint32_t source, uint32_t parent_source) +{ + struct refclk_scale *clk_priv; + struct clk *clk; + + if (name) { + // Unused variable - fix compiler warning + } + if (parent_name) { + // Unused variable - fix compiler warning + } + if (flags) { + // Unused variable - fix compiler warning + } + + clk_priv = (struct refclk_scale *)malloc(sizeof(*clk_priv)); + if (!clk_priv) { + dev_err(&phy->spi->dev, + "ad9361_clk_register: could not allocate fixed factor clk"); + return (struct clk *)ERR_PTR(-ENOMEM); + } + + /* struct refclk_scale assignments */ + clk_priv->source = (enum ad9361_clocks)source; + clk_priv->parent_source = (enum ad9361_clocks)parent_source; + clk_priv->spi = phy->spi; + clk_priv->phy = phy; + + phy->ref_clk_scale[source] = clk_priv; + + clk = (struct clk *)malloc(sizeof(*clk)); + if (!clk) { + free(clk_priv); + return (struct clk *)ERR_PTR(-ENOMEM); + } + + switch (source) { + case TX_REFCLK: + clk->rate = ad9361_clk_factor_recalc_rate(clk_priv, phy->clk_refin->rate); + break; + case RX_REFCLK: + clk->rate = ad9361_clk_factor_recalc_rate(clk_priv, phy->clk_refin->rate); + break; + case BB_REFCLK: + clk->rate = ad9361_clk_factor_recalc_rate(clk_priv, phy->clk_refin->rate); + break; + case BBPLL_CLK: + clk->rate = ad9361_bbpll_recalc_rate(clk_priv, phy->clks[BB_REFCLK]->rate); + break; + case ADC_CLK: + clk->rate = ad9361_clk_factor_recalc_rate(clk_priv, phy->clks[BBPLL_CLK]->rate); + break; + case R2_CLK: + clk->rate = ad9361_clk_factor_recalc_rate(clk_priv, phy->clks[ADC_CLK]->rate); + break; + case R1_CLK: + clk->rate = ad9361_clk_factor_recalc_rate(clk_priv, phy->clks[R2_CLK]->rate); + break; + case CLKRF_CLK: + clk->rate = ad9361_clk_factor_recalc_rate(clk_priv, phy->clks[R1_CLK]->rate); + break; + case RX_SAMPL_CLK: + clk->rate = ad9361_clk_factor_recalc_rate(clk_priv, phy->clks[CLKRF_CLK]->rate); + break; + case DAC_CLK: + clk->rate = ad9361_clk_factor_recalc_rate(clk_priv, phy->clks[ADC_CLK]->rate); + break; + case T2_CLK: + clk->rate = ad9361_clk_factor_recalc_rate(clk_priv, phy->clks[DAC_CLK]->rate); + break; + case T1_CLK: + clk->rate = ad9361_clk_factor_recalc_rate(clk_priv, phy->clks[T2_CLK]->rate); + break; + case CLKTF_CLK: + clk->rate = ad9361_clk_factor_recalc_rate(clk_priv, phy->clks[T1_CLK]->rate); + break; + case TX_SAMPL_CLK: + clk->rate = ad9361_clk_factor_recalc_rate(clk_priv, phy->clks[CLKTF_CLK]->rate); + break; + case RX_RFPLL_INT: + clk->rate = ad9361_rfpll_int_recalc_rate(clk_priv, phy->clks[RX_REFCLK]->rate); + break; + case TX_RFPLL_INT: + clk->rate = ad9361_rfpll_int_recalc_rate(clk_priv, phy->clks[TX_REFCLK]->rate); + break; + case RX_RFPLL_DUMMY: + clk->rate = phy->pdata->rx_synth_freq; + break; + case TX_RFPLL_DUMMY: + clk->rate = phy->pdata->tx_synth_freq; + break; + case RX_RFPLL: + clk->rate = ad9361_rfpll_recalc_rate(clk_priv); + break; + case TX_RFPLL: + clk->rate = ad9361_rfpll_recalc_rate(clk_priv); + } + + return clk; +} + +/** + * Register and initialize all the system clocks. + * @param phy The AD9361 state structure. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_register_clocks(struct ad9361_rf_phy *phy) +{ + uint32_t flags = CLK_GET_RATE_NOCACHE; + + /* Scaled Reference Clocks */ + phy->clks[TX_REFCLK] = ad9361_clk_register(phy, + "tx_refclk", "ad9361_ext_refclk", + flags | CLK_IGNORE_UNUSED, + TX_REFCLK, EXT_REF_CLK); + + phy->clks[RX_REFCLK] = ad9361_clk_register(phy, + "rx_refclk", "ad9361_ext_refclk", + flags | CLK_IGNORE_UNUSED, + RX_REFCLK, EXT_REF_CLK); + + phy->clks[BB_REFCLK] = ad9361_clk_register(phy, + "bb_refclk", "ad9361_ext_refclk", + flags | CLK_IGNORE_UNUSED, + BB_REFCLK, EXT_REF_CLK); + + /* Base Band PLL Clock */ + phy->clks[BBPLL_CLK] = ad9361_clk_register(phy, + "bbpll_clk", "bb_refclk", + flags | CLK_IGNORE_UNUSED, + BBPLL_CLK, BB_REFCLK); + + phy->clks[ADC_CLK] = ad9361_clk_register(phy, + "adc_clk", "bbpll_clk", + flags | CLK_IGNORE_UNUSED, + ADC_CLK, BBPLL_CLK); + + phy->clks[R2_CLK] = ad9361_clk_register(phy, + "r2_clk", "adc_clk", + flags | CLK_IGNORE_UNUSED, + R2_CLK, ADC_CLK); + + phy->clks[R1_CLK] = ad9361_clk_register(phy, + "r1_clk", "r2_clk", + flags | CLK_IGNORE_UNUSED, + R1_CLK, R2_CLK); + + phy->clks[CLKRF_CLK] = ad9361_clk_register(phy, + "clkrf_clk", "r1_clk", + flags | CLK_IGNORE_UNUSED, + CLKRF_CLK, R1_CLK); + + phy->clks[RX_SAMPL_CLK] = ad9361_clk_register(phy, + "rx_sampl_clk", "clkrf_clk", + flags | CLK_IGNORE_UNUSED, + RX_SAMPL_CLK, CLKRF_CLK); + + + phy->clks[DAC_CLK] = ad9361_clk_register(phy, + "dac_clk", "adc_clk", + flags | CLK_IGNORE_UNUSED, + DAC_CLK, ADC_CLK); + + phy->clks[T2_CLK] = ad9361_clk_register(phy, + "t2_clk", "dac_clk", + flags | CLK_IGNORE_UNUSED, + T2_CLK, DAC_CLK); + + phy->clks[T1_CLK] = ad9361_clk_register(phy, + "t1_clk", "t2_clk", + flags | CLK_IGNORE_UNUSED, + T1_CLK, T2_CLK); + + phy->clks[CLKTF_CLK] = ad9361_clk_register(phy, + "clktf_clk", "t1_clk", + flags | CLK_IGNORE_UNUSED, + CLKTF_CLK, T1_CLK); + + phy->clks[TX_SAMPL_CLK] = ad9361_clk_register(phy, + "tx_sampl_clk", "clktf_clk", + flags | CLK_IGNORE_UNUSED, + TX_SAMPL_CLK, CLKTF_CLK); + + phy->clks[RX_RFPLL_INT] = ad9361_clk_register(phy, + "rx_rfpll", "rx_refclk", + flags | CLK_IGNORE_UNUSED, + RX_RFPLL_INT, RX_REFCLK); + + phy->clks[TX_RFPLL_INT] = ad9361_clk_register(phy, + "tx_rfpll", "tx_refclk", + flags | CLK_IGNORE_UNUSED, + TX_RFPLL_INT, TX_REFCLK); + + phy->clks[RX_RFPLL_DUMMY] = ad9361_clk_register(phy, + "rx_rfpll_dummy", NULL, + flags | CLK_IGNORE_UNUSED, + RX_RFPLL_DUMMY, 0); + + phy->clks[TX_RFPLL_DUMMY] = ad9361_clk_register(phy, + "tx_rfpll_dummy", NULL, + flags | CLK_IGNORE_UNUSED, + TX_RFPLL_DUMMY, 0); + + phy->clks[RX_RFPLL] = ad9361_clk_register(phy, + "rx_rfpll", NULL, + flags | CLK_IGNORE_UNUSED, + RX_RFPLL, 0); + + phy->clks[TX_RFPLL] = ad9361_clk_register(phy, + "tx_rfpll", NULL, + flags | CLK_IGNORE_UNUSED, + TX_RFPLL, 0); + + return 0; +} + +/** + * Unregister all the system clocks. + * @param phy The AD9361 state structure. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_unregister_clocks(struct ad9361_rf_phy *phy) +{ + int32_t i; + + for (i = 0; i < NUM_AD9361_CLKS; i++) { + free(phy->clks[i]); + free(phy->ref_clk_scale[i]); + } + + return 0; +} + +/** + * Perform an RSSI gain step calibration. + * Note: Before running the function, provide a single tone within the channel + * bandwidth and monitor the received data. Adjust the tone amplitude until + * the received data is within a few dB of full scale but not overloading. + * @param phy The AD9361 state structure. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_rssi_gain_step_calib(struct ad9361_rf_phy *phy) +{ + uint32_t lna_error[4]; + uint32_t mixer_error[15]; + uint64_t lo_freq_hz; + uint8_t lo_index; + uint8_t i; + + lo_freq_hz = ad9361_from_clk(clk_get_rate(phy, + phy->ref_clk_scale[RX_RFPLL])); + if (lo_freq_hz < 1300000000ULL) + lo_index = 0; + else if (lo_freq_hz < 3300000000ULL) + lo_index = 1; + else if (lo_freq_hz < 4100000000ULL) + lo_index = 2; + else + lo_index = 3; + + /* Put the AD9361 into the Alert state. */ + ad9361_ensm_force_state(phy, ENSM_STATE_ALERT); + + /* Program the directly-addressable register values. */ + ad9361_spi_write(phy->spi, REG_MAX_MIXER_CALIBRATION_GAIN_INDEX, + MAX_MIXER_CALIBRATION_GAIN_INDEX(0x0F)); + ad9361_spi_write(phy->spi, REG_MEASURE_DURATION, + GAIN_CAL_MEAS_DURATION(0x0E)); + ad9361_spi_write(phy->spi, REG_SETTLE_TIME, + SETTLE_TIME(0x3F)); + ad9361_spi_write(phy->spi, REG_RSSI_CONFIG, + RSSI_MODE_SELECT(0x3) | DEFAULT_RSSI_MEAS_MODE); + ad9361_spi_write(phy->spi, REG_MEASURE_DURATION_01, + MEASUREMENT_DURATION_0(0x0E)); + ad9361_spi_write(phy->spi, REG_LNA_GAIN, + gain_step_calib_reg_val[lo_index][0]); + + /* Program the LNA gain step words into the internal table. */ + ad9361_spi_write(phy->spi, REG_CONFIG, + CALIB_TABLE_SELECT(0x3) | START_CALIB_TABLE_CLOCK); + for(i = 0; i < 4; i++) { + ad9361_spi_write(phy->spi, REG_WORD_ADDRESS, i); + ad9361_spi_write(phy->spi, REG_GAIN_DIFF_WORDERROR_WRITE, + gain_step_calib_reg_val[lo_index][i+1]); + ad9361_spi_write(phy->spi, REG_CONFIG, + CALIB_TABLE_SELECT(0x3) | WRITE_LNA_GAIN_DIFF | START_CALIB_TABLE_CLOCK); + udelay(3); //Wait for data to fully write to internal table + } + + ad9361_spi_write(phy->spi, REG_CONFIG, START_CALIB_TABLE_CLOCK); + ad9361_spi_write(phy->spi, REG_CONFIG, 0x00); + + /* Run and wait until the calibration completes. */ + ad9361_run_calibration(phy, RX_GAIN_STEP_CAL); + + /* Read the LNA and Mixer error terms into nonvolatile memory. */ + ad9361_spi_write(phy->spi, REG_CONFIG, CALIB_TABLE_SELECT(0x1) | READ_SELECT); + for(i = 0; i < 4; i++) { + ad9361_spi_write(phy->spi, REG_WORD_ADDRESS, i); + lna_error[i] = ad9361_spi_read(phy->spi, REG_GAIN_ERROR_READ); + } + ad9361_spi_write(phy->spi, REG_CONFIG, CALIB_TABLE_SELECT(0x1)); + for(i = 0; i < 15; i++) { + ad9361_spi_write(phy->spi, REG_WORD_ADDRESS, i); + mixer_error[i] = ad9361_spi_read(phy->spi, REG_GAIN_ERROR_READ); + } + ad9361_spi_write(phy->spi, REG_CONFIG, 0x00); + + /* Programming gain step errors into the AD9361 in the field */ + ad9361_spi_write(phy->spi, + REG_CONFIG, CALIB_TABLE_SELECT(0x3) | START_CALIB_TABLE_CLOCK); + for(i = 0; i < 4; i++) { + ad9361_spi_write(phy->spi, REG_WORD_ADDRESS, i); + ad9361_spi_write(phy->spi, REG_GAIN_DIFF_WORDERROR_WRITE, lna_error[i]); + ad9361_spi_write(phy->spi, REG_CONFIG, + CALIB_TABLE_SELECT(0x3) | WRITE_LNA_ERROR_TABLE | START_CALIB_TABLE_CLOCK); + } + ad9361_spi_write(phy->spi, REG_CONFIG, + CALIB_TABLE_SELECT(0x3) | START_CALIB_TABLE_CLOCK); + for(i = 0; i < 15; i++) { + ad9361_spi_write(phy->spi, REG_WORD_ADDRESS, i); + ad9361_spi_write(phy->spi, REG_GAIN_DIFF_WORDERROR_WRITE, mixer_error[i]); + ad9361_spi_write(phy->spi, REG_CONFIG, + CALIB_TABLE_SELECT(0x3) | WRITE_MIXER_ERROR_TABLE | START_CALIB_TABLE_CLOCK); + } + ad9361_spi_write(phy->spi, REG_CONFIG, 0x00); + + ad9361_ensm_restore_prev_state(phy); + + return 0; +} diff --git a/df_datalink_sp/src/drivers/rf-transceiver/ad9361/ad9361.h b/df_datalink_sp/src/drivers/rf-transceiver/ad9361/ad9361.h new file mode 100644 index 0000000..638acdc --- /dev/null +++ b/df_datalink_sp/src/drivers/rf-transceiver/ad9361/ad9361.h @@ -0,0 +1,3568 @@ +/***************************************************************************//** + * @file ad9361.h + * @brief Header file of AD9361 Driver. +******************************************************************************** + * Copyright 2014(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ +#ifndef IIO_FREQUENCY_AD9361_H_ +#define IIO_FREQUENCY_AD9361_H_ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ +#include +#include "common.h" +#include "../../../include/gpio.h" + +/******************************************************************************/ +/********************** Macros and Constants Definitions **********************/ +/******************************************************************************/ +#define REG_SPI_CONF 0x000 /* SPI Configuration */ +#define REG_MULTICHIP_SYNC_AND_TX_MON_CTRL 0x001 /* Multi-Chip Sync and Tx Mon Control */ +#define REG_TX_ENABLE_FILTER_CTRL 0x002 /* Tx Enable & Filter Control */ +#define REG_RX_ENABLE_FILTER_CTRL 0x003 /* Rx Enable & Filter Control */ +#define REG_INPUT_SELECT 0x004 /* Input Select */ +#define REG_RFPLL_DIVIDERS 0x005 /* RFPLL Dividers */ +#define REG_RX_CLOCK_DATA_DELAY 0x006 /* Rx Clock & Data Delay */ +#define REG_TX_CLOCK_DATA_DELAY 0x007 /* Tx Clock & Data Delay */ +#define REG_CLOCK_ENABLE 0x009 /* Clock Enable */ +#define REG_BBPLL 0x00A /* BBPLL */ +#define REG_TEMP_OFFSET 0x00B /* Offset */ +#define REG_START_TEMP_READING 0x00C /* Start Temp Reading */ +#define REG_TEMP_SENSE2 0x00D /* Temp Sense2 */ +#define REG_TEMPERATURE 0x00E /* Temperature */ +#define REG_TEMP_SENSOR_CONFIG 0x00F /* Temp Sensor Config */ +#define REG_PARALLEL_PORT_CONF_1 0x010 /* Parallel Port Configuration 1 */ +#define REG_PARALLEL_PORT_CONF_2 0x011 /* Parallel Port Configuration 2 */ +#define REG_PARALLEL_PORT_CONF_3 0x012 /* Parallel Port Configuration 3 */ +#define REG_ENSM_MODE 0x013 /* ENSM Mode */ +#define REG_ENSM_CONFIG_1 0x014 /* ENSM Config 1 */ +#define REG_ENSM_CONFIG_2 0x015 /* ENSM Config 2 */ +#define REG_CALIBRATION_CTRL 0x016 /* Calibration Control */ +#define REG_STATE 0x017 /* State */ +#define REG_AUXDAC_1_WORD 0x018 /* AuxDAC 1 Word */ +#define REG_AUXDAC_2_WORD 0x019 /* AuxDAC 2 Word */ +#define REG_AUXDAC_1_CONFIG 0x01A /* AuxDAC 1 Config */ +#define REG_AUXDAC_2_CONFIG 0x01B /* AuxDAC 2 Config */ +#define REG_AUXADC_CLOCK_DIVIDER 0x01C /* AuxADC Clock Divider */ +#define REG_AUXADC_CONFIG 0x01D /* Aux ADC Config */ +#define REG_AUXADC_WORD_MSB 0x01E /* AuxADC Word MSB */ +#define REG_AUXADC_LSB 0x01F /* AuxADC LSB */ +#define REG_AUTO_GPO 0x020 /* Auto GPO */ +#define REG_AGC_GAIN_LOCK_DELAY 0x021 /* AGC Gain Lock Delay */ +#define REG_AGC_ATTACK_DELAY 0x022 /* AGC Attack Delay */ +#define REG_AUXDAC_ENABLE_CTRL 0x023 /* AuxDAC Enable Control */ +#define REG_RX_LOAD_SYNTH_DELAY 0x024 /* RX Load Synth Delay */ +#define REG_TX_LOAD_SYNTH_DELAY 0x025 /* TX Load Synth Delay */ +#define REG_EXTERNAL_LNA_CTRL 0x026 /* External LNA control */ +#define REG_GPO_FORCE_AND_INIT 0x027 /* GPO Force and Init */ +#define REG_GPO0_RX_DELAY 0x028 /* GPO0 Rx delay */ +#define REG_GPO1_RX_DELAY 0x029 /* GPO1 Rx delay */ +#define REG_GPO2_RX_DELAY 0x02A /* GPO2 Rx delay */ +#define REG_GPO3_RX_DELAY 0x02B /* GPO3 Rx delay */ +#define REG_GPO0_TX_DELAY 0x02C /* GPO0 Tx Delay */ +#define REG_GPO1_TX_DELAY 0x02D /* GPO1 Tx Delay */ +#define REG_GPO2_TX_DELAY 0x02E /* GPO2 Tx Delay */ +#define REG_GPO3_TX_DELAY 0x02F /* GPO3 Tx Delay */ +#define REG_AUXDAC1_RX_DELAY 0x030 /* AuxDAC1 Rx Delay */ +#define REG_AUXDAC1_TX_DELAY 0x031 /* AuxDAC1 Tx Delay */ +#define REG_AUXDAC2_RX_DELAY 0x032 /* AuxDAC2 Rx Delay */ +#define REG_AUXDAC2_TX_DELAY 0x033 /* AuxDAC2 Tx Delay */ +#define REG_CTRL_OUTPUT_POINTER 0x035 /* Control Output Pointer */ +#define REG_CTRL_OUTPUT_ENABLE 0x036 /* Control Output Enable */ +#define REG_PRODUCT_ID 0x037 /* Product ID */ +#define REG_REFERENCE_CLOCK_CYCLES 0x03A /* Reference Clock Cycles */ +#define REG_DIGITAL_IO_CTRL 0x03B /* Digital I/O Control */ +#define REG_LVDS_BIAS_CTRL 0x03C /* LVDS Bias control */ +#define REG_LVDS_INVERT_CTRL1 0x03D /* LVDS Invert control1 */ +#define REG_LVDS_INVERT_CTRL2 0x03E /* LVDS Invert control2 */ +#define REG_SDM_CTRL_1 0x03F /* SDM Control 1 */ +#define REG_FRACT_BB_FREQ_WORD_1 0x041 /* Fractional BB Freq Word 1 */ +#define REG_FRACT_BB_FREQ_WORD_2 0x042 /* Fractional BB Freq Word 2 */ +#define REG_FRACT_BB_FREQ_WORD_3 0x043 /* Fractional BB Freq Word 3 */ +#define REG_INTEGER_BB_FREQ_WORD 0x044 /* Integer BB Freq Word */ +#define REG_CLOCK_CTRL 0x045 /* Clock Control */ +#define REG_CP_CURRENT 0x046 /* CP Current */ +#define REG_CP_BLEED_CURRENT 0x047 /* CP Bleed Current */ +#define REG_LOOP_FILTER_1 0x048 /* Loop Filter 1 */ +#define REG_LOOP_FILTER_2 0x049 /* Loop Filter 2 */ +#define REG_LOOP_FILTER_3 0x04A /* Loop Filter 3 */ +#define REG_VCO_CTRL 0x04B /* VCO Control */ +#define REG_VCO_PROGRAM_1 0x04C +#define REG_VCO_PROGRAM_2 0x04D +#define REG_SDM_CTRL 0x04E /* SDM Control */ +#define REG_RX_SYNTH_POWER_DOWN_OVERRIDE 0x050 /* Rx Synth Power Down Override */ +#define REG_TX_SYNTH_POWER_DOWN_OVERRIDE 0x051 /* TX Synth Power Down Override */ +#define REG_RX_ANALOG_POWER_DOWN_OVERRIDE_1 0x052 /* Rx Analog Power Down Override 1 */ +#define REG_RX_ANALOG_POWER_DOWN_OVERRIDE_2 0x053 /* Rx Analog Power Down Override 2 */ +#define REG_RX1_ADC_POWER_DOWN_OVERRIDE 0x054 /* Rx1 ADC Power Down Override */ +#define REG_RX2_ADC_POWER_DOWN_OVERRIDE 0x055 /* Rx2 ADC Power Down Override */ +#define REG_TX_ANALOG_POWER_DOWN_OVERRIDE_1 0x056 /* Tx Analog Power Down Override 1 */ +#define REG_ANALOG_POWER_DOWN_OVERRIDE 0x057 /* Analog Power Down Override */ +#define REG_MISC_POWER_DOWN_OVERRIDE 0x058 /* Misc Power Down Override */ +#define REG_CH_1_OVERFLOW 0x05E /* CH 1 Overflow */ +#define REG_CH_2_OVERFLOW 0x05F /* CH 2 Overflow */ +#define REG_TX_FILTER_COEF_ADDR 0x060 /* TX Filter Coefficient Address */ +#define REG_TX_FILTER_COEF_WRITE_DATA_1 0x061 /* TX Filter Coefficient Write Data 1 */ +#define REG_TX_FILTER_COEF_WRITE_DATA_2 0x062 /* TX Filter Coefficient Write Data 2 */ +#define REG_TX_FILTER_COEF_READ_DATA_1 0x063 /* TX Filter Coefficient Read Data 1 */ +#define REG_TX_FILTER_COEF_READ_DATA_2 0x064 /* TX Filter Coefficient Read Data 2 */ +#define REG_TX_FILTER_CONF 0x065 /* TX Filter Configuration */ +#define REG_TX_MON_LOW_GAIN 0x067 /* Tx Mon Low Gain */ +#define REG_TX_MON_HIGH_GAIN 0x068 /* Tx Mon High Gain */ +#define REG_TX_MON_DELAY 0x069 /* Tx Mon Delay */ +#define REG_TX_LEVEL_THRESH 0x06A /* Tx Level Threshold */ +#define REG_TX_RSSI1 0x06B /* TX RSSI1 */ +#define REG_TX_RSSI2 0x06C /* TX RSSI2 */ +#define REG_TX_RSSI_LSB 0x06D /* TX RSSI LSB */ +#define REG_TPM_MODE_ENABLE 0x06E /* TPM Mode Enable */ +#define REG_TX_MON_TEMP_GAIN_COEF 0x06F /* Temp Gain Coefficient */ +#define REG_TX_MON_1_CONFIG 0x070 /* Tx Mon 1 Config */ +#define REG_TX_MON_2_CONFIG 0x071 /* Tx Mon 2 Config */ +#define REG_TX1_ATTEN_0 0x073 /* Tx1 Atten 0 */ +#define REG_TX1_ATTEN_1 0x074 /* Tx1 Atten 1 */ +#define REG_TX2_ATTEN_0 0x075 /* Tx2 Atten 0 */ +#define REG_TX2_ATTEN_1 0x076 /* Tx2 Atten 1 */ +#define REG_TX_ATTEN_OFFSET 0x077 /* Tx Atten Offset */ +#define REG_TX_ATTEN_THRESH 0x078 /* Tx Atten Threshold */ +#define REG_TX1_DIG_ATTEN 0x079 /* Tx1 Dig Attenuation */ +#define REG_TX2_DIG_ATTEN 0x07C /* Tx2 Dig Attenuation */ +#define REG_TX1_SYMBOL_ATTEN 0x07F /* TX1 Symbol Attenuation */ +#define REG_TX2_SYMBOL_ATTEN 0x080 /* TX2 Symbol Attenuation */ +#define REG_TX_SYMBOL_ATTEN_CONFIG 0x081 /* TX Symbol Atten Config */ +#define REG_TX1_OUT_1_PHASE_CORR 0x08E /* Tx1 Out 1 Phase Corr */ +#define REG_TX1_OUT_1_GAIN_CORR 0x08F /* Tx1 Out 1 Gain Corr */ +#define REG_TX2_OUT_1_PHASE_CORR 0x090 /* Tx2 Out 1 Phase Corr */ +#define REG_TX2_OUT_1_GAIN_CORR 0x091 /* Tx2 Out 1 Gain Corr */ +#define REG_TX1_OUT_1_OFFSET_I 0x092 /* Tx1 Out 1 Offset I */ +#define REG_TX1_OUT_1_OFFSET_Q 0x093 /* Tx1 Out 1 Offset Q */ +#define REG_TX2_OUT_1_OFFSET_I 0x094 /* Tx2 Out 1 Offset I */ +#define REG_TX2_OUT_1_OFFSET_Q 0x095 /* Tx2 Out 1 Offset Q */ +#define REG_TX1_OUT_2_PHASE_CORR 0x096 /* Tx1 Out 2 Phase Corr */ +#define REG_TX1_OUT_2_GAIN_CORR 0x097 /* Tx1 Out 2 Gain Corr */ +#define REG_TX2_OUT_2_PHASE_CORR 0x098 /* Tx2 Out 2 Phase Corr */ +#define REG_TX2_OUT_2_GAIN_CORR 0x099 /* Tx2 Out 2 Gain Corr */ +#define REG_TX1_OUT_2_OFFSET_I 0x09A /* Tx1 Out 2 Offset I */ +#define REG_TX1_OUT_2_OFFSET_Q 0x09B /* Tx1 Out 2 Offset Q */ +#define REG_TX2_OUT_2_OFFSET_I 0x09C /* Tx2 Out 2 Offset I */ +#define REG_TX2_OUT_2_OFFSET_Q 0x09D /* Tx2 Out 2 Offset Q */ +#define REG_TX_FORCE_BITS 0x09F /* Force Bits */ +#define REG_QUAD_CAL_NCO_FREQ_PHASE_OFFSET 0x0A0 /* Quad Cal NCO Freq & Phase Offset */ +#define REG_QUAD_CAL_CTRL 0x0A1 /* Quad Cal Control */ +#define REG_KEXP_1 0x0A2 /* Kexp 1 */ +#define REG_KEXP_2 0x0A3 /* Kexp 2 */ +#define REG_QUAD_SETTLE_COUNT 0x0A4 /* QUAD Settle count */ +#define REG_MAG_FTEST_THRESH 0x0A5 /* Mag. Ftest Thresh */ +#define REG_MAG_FTEST_THRESH_2 0x0A6 /* Mag. Ftest Thresh 2 */ +#define REG_QUAD_CAL_STATUS_TX1 0x0A7 /* Quad cal status Tx1 */ +#define REG_QUAD_CAL_STATUS_TX2 0x0A8 /* Quad cal status Tx2 */ +#define REG_QUAD_CAL_COUNT 0x0A9 /* Quad cal Count */ +#define REG_TX_QUAD_FULL_LMT_GAIN 0x0AA /* Tx Quad Full/LMT Gain */ +#define REG_SQUARER_CONFIG 0x0AB /* Squarer Config */ +#define REG_TX_QUAD_CAL_ATTEN 0x0AC /* TX Quad Cal Atten */ +#define REG_THRESH_ACCUM 0x0AD /* Thresh Accum */ +#define REG_TX_QUAD_LPF_GAIN 0x0AE /* Tx Quad LPF Gain */ +#define REG_TXDAC_VDS_I 0x0B0 /* TxDAC Vds I */ +#define REG_TXDAC_VDS_Q 0x0B1 /* TxDAC Vds Q */ +#define REG_TXDAC_GN_I 0x0B2 /* TxDAC gn I */ +#define REG_TXDAC_GN_Q 0x0B3 /* TxDAC gn Q */ +#define REG_TXBBF_OPAMP_A 0x0C0 /* TxBBF OpAmp A */ +#define REG_TXBBF_OPAMP_B 0x0C1 /* TxBBF OpAmp B */ +#define REG_TX_BBF_R1 0x0C2 /* Tx BBF R1 */ +#define REG_TX_BBF_R2 0x0C3 /* Tx BBF R2 */ +#define REG_TX_BBF_R3 0x0C4 /* Tx BBF R3 */ +#define REG_TX_BBF_R4 0x0C5 /* Tx BBF R4 */ +#define REG_TX_BBF_RP 0x0C6 /* Tx BBF RP */ +#define REG_TX_BBF_C1 0x0C7 /* Tx BBF C1 */ +#define REG_TX_BBF_C2 0x0C8 /* Tx BBF C2 */ +#define REG_TX_BBF_CP 0x0C9 /* Tx BBF Cp */ +#define REG_TX_TUNE_CTRL 0x0CA /* Tx Tune Control */ +#define REG_TX_BBF_R2B 0x0CB /* Tx BBF R2b */ +#define REG_TX_BBF_TUNE 0x0CC /* Tx BBF Tune */ +#define REG_CONFIG0 0x0D0 /* Config0 */ +#define REG_RESISTOR 0x0D1 /* Resistor */ +#define REG_CAPACITOR 0x0D2 /* Capacitor */ +#define REG_LO_CM 0x0D3 /* LO CM */ +#define REG_TX_BBF_TUNE_DIVIDER 0x0D6 /* TX BBF Tune Divider */ +#define REG_TX_BBF_TUNE_MODE 0x0D7 /* TX BBF Tune Mode */ +#define REG_RX_FILTER_COEF_ADDR 0x0F0 /* Rx Filter Coeff Addr */ +#define REG_RX_FILTER_COEF_DATA_1 0x0F1 /* Rx Filter Coeff Data 1 */ +#define REG_RX_FILTER_COEF_DATA_2 0x0F2 /* Rx Filter Coeff Data 2 */ +#define REG_RX_FILTER_COEF_READ_DATA_1 0x0F3 /* Rx Filter Coeff Read Data 1 */ +#define REG_RX_FILTER_COEF_READ_DATA_2 0x0F4 /* Rx Filter Coeff Read Data 2 */ +#define REG_RX_FILTER_CONFIG 0x0F5 /* Rx Filter Config */ +#define REG_RX_FILTER_GAIN 0x0F6 /* Rx Filter Gain */ +#define REG_AGC_CONFIG_1 0x0FA /* AGC Config1 */ +#define REG_AGC_CONFIG_2 0x0FB /* AGC config2 */ +#define REG_AGC_CONFIG_3 0x0FC /* AGC Config3 */ +#define REG_MAX_LMT_FULL_GAIN 0x0FD /* Max LMT/Full Gain */ +#define REG_PEAK_WAIT_TIME 0x0FE /* Peak Wait Time */ +#define REG_DIGITAL_GAIN 0x100 /* Digital Gain */ +#define REG_AGC_LOCK_LEVEL 0x101 /* AGC Lock Level */ +#define REG_ADC_NOISE_CORRECTION_FACTOR 0x102 /* ADC noise Correction Factor */ +#define REG_GAIN_STP_CONFIG1 0x103 /* Gain Step Config1 */ +#define REG_ADC_SMALL_OVERLOAD_THRESH 0x104 /* ADC Small Overload Threshold */ +#define REG_ADC_LARGE_OVERLOAD_THRESH 0x105 /* ADC Large Overload Threshold */ +#define REG_GAIN_STP_CONFIG_2 0x106 /* Gain Step Config 2 */ +#define REG_SMALL_LMT_OVERLOAD_THRESH 0x107 /* Small LMT Overload Threshold */ +#define REG_LARGE_LMT_OVERLOAD_THRESH 0x108 /* Large LMT Overload Threshold */ +#define REG_RX1_MANUAL_LMT_FULL_GAIN 0x109 /* Rx1 Manual LMT/Full Gain */ +#define REG_RX1_MANUAL_LPF_GAIN 0x10A /* Rx1 Manual LPF gain */ +#define REG_RX1_MANUAL_DIGITALFORCED_GAIN 0x10B /* Rx1 Manual Digital/Forced Gain */ +#define REG_RX2_MANUAL_LMT_FULL_GAIN 0x10C /* Rx2 Manual LMT/Full Gain */ +#define REG_RX2_MANUAL_LPF_GAIN 0x10D /* Rx2 Manual LPF Gain */ +#define REG_RX2_MANUAL_DIGITALFORCED_GAIN 0x10E /* Rx2 Manual Digital/Forced Gain */ +#define REG_FAST_CONFIG_1 0x110 /* Config 1 */ +#define REG_FAST_CONFIG_2_SETTLING_DELAY 0x111 /* Config 2 & Settling Delay */ +#define REG_FAST_ENERGY_LOST_THRESH 0x112 /* Energy Lost Threshold */ +#define REG_FAST_STRONGER_SIGNAL_THRESH 0x113 /* Stronger Signal Threshold */ +#define REG_FAST_LOW_POWER_THRESH 0x114 /* Low Power Threshold */ +#define REG_FAST_STRONG_SIGNAL_FREEZE 0x115 /* Strong Signal Freeze */ +#define REG_FAST_FINAL_OVER_RANGE_AND_OPT_GAIN 0x116 /* Final Over Range and Opt Gain */ +#define REG_FAST_ENERGY_DETECT_COUNT 0x117 /* Energy Detect Count */ +#define REG_FAST_AGCLL_UPPER_LIMIT 0x118 /* AGCLL Upper Limit */ +#define REG_FAST_GAIN_LOCK_EXIT_COUNT 0x119 /* Gain Lock Exit Count */ +#define REG_FAST_INITIAL_LMT_GAIN_LIMIT 0x11A /* Initial LMT Gain Limit */ +#define REG_FAST_INCREMENT_TIME 0x11B /* Increment Time */ +#define REG_AGC_INNER_LOW_THRESH 0x120 /* AGC Inner Low Threshold */ +#define REG_LMT_OVERLOAD_COUNTERS 0x121 /* LMT Overload Counters */ +#define REG_ADC_OVERLOAD_COUNTERS 0x122 /* ADC Overload Counters */ +#define REG_GAIN_STP1 0x123 /* Gain Step1 */ +#define REG_GAIN_UPDATE_COUNTER1 0x124 /* Gain Update Counter1 */ +#define REG_GAIN_UPDATE_COUNTER2 0x125 /* Gain Update Counter2 */ +#define REG_DIGITAL_SAT_COUNTER 0x128 /* Digital Sat Counter */ +#define REG_OUTER_POWER_THRESHS 0x129 /* Outer Power Thresholds */ +#define REG_GAIN_STP_2 0x12A /* Gain Step 2 */ +#define REG_EXT_LNA_HIGH_GAIN 0x12C /* Ext LNA High Gain */ +#define REG_EXT_LNA_LOW_GAIN 0x12D /* Ext LNA Low Gain */ +#define REG_GAIN_TABLE_ADDRESS 0x130 /* Gain Table Address */ +#define REG_GAIN_TABLE_WRITE_DATA1 0x131 /* Gain Table Write Data1 */ +#define REG_GAIN_TABLE_WRITE_DATA2 0x132 /* Gain Table Write Data2 */ +#define REG_GAIN_TABLE_WRITE_DATA3 0x133 /* Gain Table Write Data 3 */ +#define REG_GAIN_TABLE_READ_DATA1 0x134 /* Gain Table Read Data 1 */ +#define REG_GAIN_TABLE_READ_DATA2 0x135 /* Gain Table Read Data 2 */ +#define REG_GAIN_TABLE_READ_DATA3 0x136 /* Gain Table Read Data 3 */ +#define REG_GAIN_TABLE_CONFIG 0x137 /* Gain Table Config */ +#define REG_GM_SUB_TABLE_ADDRESS 0x138 /* Gm Sub Table Address */ +#define REG_GM_SUB_TABLE_GAIN_WRITE 0x139 /* Gm Sub Table Gain Word Write */ +#define REG_GM_SUB_TABLE_BIAS_WRITE 0x13A /* Gm Sub Table Bias Word Write */ +#define REG_GM_SUB_TABLE_CTRL_WRITE 0x13B /* Gm Sub Table Control Word Write */ +#define REG_GM_SUB_TABLE_GAIN_READ 0x13C /* Gm Sub Table Gain Word Read */ +#define REG_GM_SUB_TABLE_BIAS_READ 0x13D /* Gm Sub Table Bias Word Read */ +#define REG_GM_SUB_TABLE_CTRL_READ 0x13E /* Gm Sub Table Control Word Read */ +#define REG_GM_SUB_TABLE_CONFIG 0x13F /* Gm Sub Table Config */ +#define REG_WORD_ADDRESS 0x140 /* Word Address */ +#define REG_GAIN_DIFF_WORDERROR_WRITE 0x141 /* Gain Diff Word/Error Write */ +#define REG_GAIN_ERROR_READ 0x142 /* Gain Error Read */ +#define REG_CONFIG 0x143 /* Config */ +#define REG_LNA_GAIN_DIFF_READ_BACK 0x144 /* LNA Gain Diff Read Back */ +#define REG_MAX_MIXER_CALIBRATION_GAIN_INDEX 0x145 /* Max Mixer Calibration Gain Index */ +#define REG_TEMP_GAIN_COEF 0x146 /* Temp Gain Coefficient */ +#define REG_SETTLE_TIME 0x147 /* Settle Time */ +#define REG_MEASURE_DURATION 0x148 /* Measure Duration */ +#define REG_CAL_TEMP_SENSOR_WORD 0x149 /* Cal Temp sensor word */ +#define REG_MEASURE_DURATION_01 0x150 /* Measure Duration 0&1 */ +#define REG_MEASURE_DURATION_23 0x151 /* Measure Duration 2&3 */ +#define REG_RSSI_WEIGHT_0 0x152 /* RSSI Weight 0 */ +#define REG_RSSI_WEIGHT_1 0x153 /* RSSI Weight 1 */ +#define REG_RSSI_WEIGHT_2 0x154 /* RSSI Weight 2 */ +#define REG_RSSI_WEIGHT_3 0x155 /* RSSI Weight 3 */ +#define REG_RSSI_DELAY 0x156 /* RSSI delay */ +#define REG_RSSI_WAIT_TIME 0x157 /* RSSI wait time */ +#define REG_RSSI_CONFIG 0x158 /* RSSI Config */ +#define REG_ADC_MEASURE_DURATION_01 0x159 /* ADC Measure Duration 0&1 */ +#define REG_ADC_WEIGHT_0 0x15A /* ADC Weight 0 */ +#define REG_ADC_WEIGHT_1 0x15B /* ADC Weight 1 */ +#define REG_DEC_POWER_MEASURE_DURATION_0 0x15C /* Dec Power Measure Duration 0 */ +#define REG_LNA_GAIN 0x15D /* LNA Gain */ +#define REG_CH1_ADC_POWER 0x160 /* CH1 ADC Power */ +#define REG_CH1_RX_FILTER_POWER 0x161 /* CH1 Rx filter Power */ +#define REG_CH2_ADC_POWER 0x162 /* CH2 ADC Power */ +#define REG_CH2_RX_FILTER_POWER 0x163 /* CH2 Rx filter Power */ +#define REG_RX_QUAD_CAL_LEVEL 0x168 /* Rx Quad Cal Level */ +#define REG_CALIBRATION_CONFIG_1 0x169 /* Calibration Config 1 */ +#define REG_CALIBRATION_CONFIG_2 0x16A /* Calibration config2 */ +#define REG_CALIBRATION_CONFIG_3 0x16B /* Calibration config3 */ +#define REG_CALIB_COUNT 0x16C /* Calib count */ +#define REG_SETTLE_COUNT 0x16D /* Settle count */ +#define REG_RX_QUAD_GAIN1 0x16E /* Rx Quad gain1 */ +#define REG_RX_QUAD_GAIN2 0x16F /* Rx Quad gain2 */ +#define REG_RX1_INPUT_A_PHASE_CORR 0x170 /* Rx1 Input A Phase Corr */ +#define REG_RX1_INPUT_A_GAIN_CORR 0x171 /* Rx1 Input A Gain Corr */ +#define REG_RX2_INPUT_A_PHASE_CORR 0x172 /* Rx2 Input A Phase Corr */ +#define REG_RX2_INPUT_A_GAIN_CORR 0x173 /* Rx2 Input A Gain Corr */ +#define REG_RX1_INPUT_A_Q_OFFSET 0x174 /* Rx1 Input A Q" Offset */ +#define REG_RX1_INPUT_A_OFFSETS 0x175 /* Rx1 Input A Offsets */ +#define REG_INPUT_A_OFFSETS_1 0x176 /* Input A Offsets 1 */ +#define REG_RX2_INPUT_A_OFFSETS 0x177 /* Rx2 Input A Offsets */ +#define REG_RX2_INPUT_A_I_OFFSET 0x178 /* Rx2 Input A "I" Offset */ +#define REG_RX1_INPUT_BC_PHASE_CORR 0x179 /* Rx1 Input B&C Phase Corr */ +#define REG_RX1_INPUT_BC_GAIN_CORR 0x17A /* Rx1 Input B&C Gain Corr */ +#define REG_RX2_INPUT_BC_PHASE_CORR 0x17B /* Rx2 Input B&C Phase Corr */ +#define REG_RX2_INPUT_BC_GAIN_CORR 0x17C /* Rx2 Input B&C Gain Corr */ +#define REG_RX1_INPUT_BC_Q_OFFSET 0x17D /* Rx1 Input B&C "Q" Offset */ +#define REG_RX1_INPUT_BC_OFFSETS 0x17E /* Rx1 Input B&C Offsets */ +#define REG_INPUT_BC_OFFSETS_1 0x17F /* Input B&C Offsets 1 */ +#define REG_RX2_INPUT_BC_OFFSETS 0x180 /* Rx2 Input B&C Offsets */ +#define REG_RX2_INPUT_BC_I_OFFSET 0x181 /* Rx2 Input B&C "I" Offset */ +#define REG_FORCE_BITS 0x182 /* Force Bits */ +#define REG_WAIT_COUNT 0x185 /* Wait Count */ +#define REG_RF_DC_OFFSET_COUNT 0x186 /* RF DC Offset Count */ +#define REG_RF_DC_OFFSET_CONFIG_1 0x187 /* RF DC Offset Config1 */ +#define REG_RF_DC_OFFSET_ATTEN 0x188 /* RF DC Offset Attenuation */ +#define REG_INVERT_BITS 0x189 /* Invert Bits */ +#define REG_DC_OFFSET_CONFIG2 0x18B /* DC Offset Config2 */ +#define REG_RF_CAL_GAIN_INDEX 0x18C /* RF Cal Gain Index */ +#define REG_SOI_THRESH 0x18D /* SOI Threshold */ +#define REG_BB_DC_OFFSET_SHIFT 0x190 /* BB DC Offset Shift */ +#define REG_BB_DC_OFFSET_FAST_SETTLE_SHIFT 0x191 /* BB DC Offset Fast Settle Shift */ +#define REG_BB_FAST_SETTLE_DUR 0x192 /* BB Fast Settle Dur */ +#define REG_BB_DC_OFFSET_COUNT 0x193 /* BB DC Offset Count */ +#define REG_BB_DC_OFFSET_ATTEN 0x194 /* BB DC Offset Attenuation */ +#define REG_RX1_BB_DC_WORD_I_MSB 0x19A /* RX1 BB DC word I MSB */ +#define REG_RX1_BB_DC_WORD_I_LSB 0x19B /* RX1 BB DC word I LSB */ +#define REG_RX1_BB_DC_WORD_Q_MSB 0x19C /* RX1 BB DC word Q MSB */ +#define REG_RX1_BB_DC_WORD_Q_LSB 0x19D /* RX1 BB DC word Q LSB */ +#define REG_RX2_BB_DC_WORD_I_MSB 0x19E /* RX2 BB DC word I MSB */ +#define REG_RX2_BB_DC_WORD_I_LSB 0x19F /* RX2 BB DC word I LSB */ +#define REG_RX2_BB_DC_WORD_Q_MSB 0x1A0 /* RX2 BB DC word Q MSB */ +#define REG_RX2_BB_DC_WORD_Q_LSB 0x1A1 /* RX2 BB DC word Q LSB */ +#define REG_BB_TRACK_CORR_WORD_I_MSB 0x1A2 /* BB Track corr word I MSB */ +#define REG_BB_TRACK_CORR_WORD_I_LSB 0x1A3 /* BB Track corr word I LSB */ +#define REG_BB_TRACK_CORR_WORD_Q_MSB 0x1A4 /* BB Track corr word Q MSB */ +#define REG_BB_TRACK_CORR_WORD_Q_LSB 0x1A5 /* BB Track corr word Q LSB */ +#define REG_RX1_RSSI_SYMBOL 0x1A7 /* Rx1 RSSI Symbol */ +#define REG_RX1_RSSI_PREAMBLE 0x1A8 /* Rx1 RSSI preamble */ +#define REG_RX2_RSSI_SYMBOL 0x1A9 /* Rx2 RSSI symbol */ +#define REG_RX2_RSSI_PREAMBLE 0x1AA /* Rx2 RSSI preamble */ +#define REG_SYMBOL_LSB 0x1AB /* Symbol LSB */ +#define REG_PREAMBLE_LSB 0x1AC /* Preamble LSB */ +#define REG_RX_PATH_GAIN_MSB 0x1AD /* Rx Path Gain */ +#define REG_RX_PATH_GAIN_LSB 0x1AE /* Rx Path Gain */ +#define REG_RX_DIFF_LNA_FORCE 0x1B0 /* Rx Diff LNA Force */ +#define REG_RX_LNA_BIAS_COARSE 0x1B1 /* Rx LNA Bias Coarse */ +#define REG_RX_LNA_BIAS_FINE_0 0x1B2 /* Rx LNA Bias Fine 0 */ +#define REG_RX_LNA_BIAS_FINE_1 0x1B3 /* Rx LNA Bias Fine 1 */ +#define REG_RX_MIX_GM_CONFIG 0x1C0 /* Rx Mix Gm Config */ +#define REG_RX1_MIX_GM_FORCE 0x1C1 /* Rx1 Mix Gm Force */ +#define REG_RX1_MIX_GM_BIAS_FORCE 0x1C2 /* Rx1 Mix Gm Bias (Force) */ +#define REG_RX2_MIX_GM_FORCE 0x1C3 /* Rx2 Mix Gm Force */ +#define REG_RX2_MIX_GM_BIAS_FORCE 0x1C4 /* Rx2 Mix Gm Bias (Force) */ +#define REG_INPUT_A_MSBS 0x1C8 /* Input A MSBs */ +#define REG_INPUT_A_RX1_I 0x1C9 /* Input A RX1 I */ +#define REG_INPUT_A_RX1_Q 0x1CA /* Input A RX1 Q */ +#define REG_INPUT_A_RX2_I 0x1CB /* Input A RX2 I */ +#define REG_INPUT_A_RX2_Q 0x1CC /* Input A RX2 Q */ +#define REG_INPUTS_BC_RX1_I 0x1CD /* Inputs B&C RX1 I */ +#define REG_BAND1_RX1_Q 0x1CE /* Band1 RX1 Q */ +#define REG_INPUTS_BC_RX2_I 0x1CF /* Inputs B&C RX2 I */ +#define REG_INPUTS_BC_RX2_Q 0x1D0 /* Inputs B&C RX2 Q */ +#define REG_INPUTS_BC_MSBS 0x1D1 /* Inputs B&C MSBs */ +#define REG_FORCE_OS_DAC 0x1D2 /* Force OS DAC */ +#define REG_RX_MIX_LO_CM 0x1D5 /* Rx Mix LO CM */ +#define REG_RX_CGB_SEG_ENABLE 0x1D6 /* Rx CGB Seg Enable */ +#define REG_RX_MIX_INPUTBIAS 0x1D7 /* Rx Mix Input/Bias */ +#define REG_RX_TIA_CONFIG 0x1DB /* Rx TIA Config */ +#define REG_TIA1_C_LSB 0x1DC /* TIA1 C LSB */ +#define REG_TIA1_C_MSB 0x1DD /* TIA1 C MSB */ +#define REG_TIA2_C_LSB 0x1DE /* TIA2 C LSB */ +#define REG_TIA2_C_MSB 0x1DF /* TIA2 C MSB */ +#define REG_RX1_BBF_R1A 0x1E0 /* Rx1 BBF R1A */ +#define REG_RX2_BBF_R1A 0x1E1 /* Rx2 BBF R1A */ +#define REG_RX1_TUNE_CTRL 0x1E2 /* Rx1 Tune Control */ +#define REG_RX2_TUNE_CTRL 0x1E3 /* Rx2 Tune Control */ +#define REG_RX1_BBF_R5 0x1E4 /* Rx1 BBF R5 */ +#define REG_RX2_BBF_R5 0x1E5 /* Rx2 BBF R5 */ +#define REG_RX_BBF_R2346 0x1E6 /* Rx BBF R2346 */ +#define REG_RX_BBF_C1_MSB 0x1E7 /* Rx BBF C1 MSB */ +#define REG_RX_BBF_C1_LSB 0x1E8 /* Rx BBF C1 LSB */ +#define REG_RX_BBF_C2_MSB 0x1E9 /* Rx BBF C2 MSB */ +#define REG_RX_BBF_C2_LSB 0x1EA /* Rx BBF C2 LSB */ +#define REG_RX_BBF_C3_MSB 0x1EB /* Rx BBF C3 MSB */ +#define REG_RX_BBF_C3_LSB 0x1EC /* Rx BBF C3 LSB */ +#define REG_RX_BBF_CC1_CTR 0x1ED /* Rx BBF CC1 Ctr */ +#define REG_RX_BBF_POW_RZ_BYTE0 0x1EE /* Rx BBF Pow Rz Byte0 */ +#define REG_RX_BBF_CC2_CTR 0x1EF /* Rx BBF CC2 Ctr */ +#define REG_RX_BBF_POW_RZ_BYTE1 0x1F0 /* Rx BBF Pow Rz Byte1 */ +#define REG_RX_BBF_CC3_CTR 0x1F1 /* Rx BBF CC3 Ctr */ +#define REG_RX_BBF_R5_TUNE 0x1F2 /* Rx BBF R5 Tune */ +#define REG_RX_BBF_TUNE 0x1F3 /* Rx BBF Tune */ +#define REG_RX1_BBF_MAN_GAIN 0x1F4 /* Rx1 BBF Man Gain */ +#define REG_RX2_BBF_MAN_GAIN 0x1F5 /* Rx2 BBF Man Gain */ +#define REG_RX_BBF_TUNE_DIVIDE 0x1F8 /* RX BBF Tune Divide */ +#define REG_RX_BBF_TUNE_CONFIG 0x1F9 /* RX BBF Tune Config */ +#define REG_POLE_GAIN 0x1FA /* Pole gain */ +#define REG_RX_BBBW_MHZ 0x1FB /* Rx BBBW MHz */ +#define REG_RX_BBBW_KHZ 0x1FC /* Rx BBBW kHz */ +#define REG_FB_DAC_CLK_DELAY1 0x201 /* FB DAC Clk Delay1 */ +#define REG_FB_DAC_CLK_DELAY2 0x202 /* FB DAC Clk Delay2 */ +#define REG_FLASH_SAMPLE_CLK_DELAY_3P 0x203 /* Flash Sample Clk Delay 3p */ +#define REG_FLASH_SAMPLE_CLK_DELAY_3N 0x204 /* Flash Sample Clk Delay 3n */ +#define REG_TEST_MUX_2I 0x205 /* Test MUX 2i */ +#define REG_TEST_MUX_2Q 0x206 /* Test MUX 2q */ +#define REG_INTEGRATOR_1_RESISTANCE 0x207 /* Integrator 1 Resistance */ +#define REG_INTEGRATOR_1_CAPACITANCE 0x208 /* Integrator 1 Capacitance */ +#define REG_INTEGRATOR_23_RESISTANCE 0x209 /* Integrator 23 Resistance */ +#define REG_INTEGRATOR_2_RESISTANCE 0x20A /* Integrator 2 Resistance */ +#define REG_INTEGRATOR_2_CAPACITANCE 0x20B /* Integrator 2 Capacitance */ +#define REG_INTEGRATOR_3_RESISTANCE 0x20C /* Integrator 3 Resistance */ +#define REG_INTEGRATOR_3_CAPACITANCE 0x20D /* Integrator 3 Capacitance */ +#define REG_INTEGRATOR_AMP_CC 0x20E /* Integrator Amp Cc */ +#define REG_INT_1_FB_DAC_NMOS_CURRENT_SOURCE 0x20F /* Int 1 FB DAC NMOS Current Source */ +#define REG_INT_1_FB_DAC_NMOS_CASOADE_BIAS_CURRENT 0x210 /* Int 1 FB DAC NMOS Casoade Bias Current */ +#define REG_INT_1_FB_DAC_PMOS_CURRENT_SOURCE 0x211 /* Int 1 FB DAC PMOS Current Source */ +#define REG_INT_2_FB_DAC_NMOS_CURRENT_SOURCE 0x212 /* Int 2 FB DAC NMOS Current Source */ +#define REG_INT_2_FB_DAC_NMOS_CASCODE_BIAS_CURRENT 0x213 /* Int 2 FB DAC NMOS Cascode Bias Current */ +#define REG_INT_2_FB_DAC_PMOS_CURRENT_SOURCE 0x214 /* Int 2 FB DAC PMOS Current Source */ +#define REG_INT_3_FB_DAC_NMOS_CURRENT_SOURCE 0x215 /* Int 3 FB DAC NMOS Current Source */ +#define REG_INT_3_FB_DAC_NMOS_CASCODE_BIAS_CURRENT 0x216 /* Int 3 FB DAC NMOS Cascode Bias Current */ +#define REG_INT_3_FB_DAC_PMOS_CURRENT_SOURCE 0x217 /* Int 3 FB DAC PMOS Current Source */ +#define REG_FB_DAC_BIAS_CURRENT 0x218 /* FB DAC Bias Current */ +#define REG_INT_1_1ST_STAGE_CURRENT 0x219 /* Int 1 1st Stage Current */ +#define REG_INT_1_1ST_STAGE_CASCODE_CURRENT 0x21A /* Int 1 1st Stage Cascode Current */ +#define REG_INT_1_2ND_STAGE_CURRENT 0x21B /* Int 1 2nd Stage Current */ +#define REG_INTEGRATOR_2_1ST_STAGE_CURRENT 0x21C /* Integrator 2 1st Stage Current */ +#define REG_INT_2_1ST_STAGE_CASCODE_CURRENT 0x21D /* Int 2 1st Stage Cascode Current */ +#define REG_INT_2_2ND_STAGE_CURRENT 0x21E /* Int 2 2nd Stage Current */ +#define REG_INT_3_1ST_STAGE_CURRENT 0x21F /* Int 3 1st Stage Current */ +#define REG_INT_3_1ST_STAGE_CASCODE_CURRENT 0x220 /* Int 3 1st Stage Cascode Current */ +#define REG_INT_3_2ND_STAGE_CURRENT 0x221 /* Int 3 2nd Stage Current */ +#define REG_FLASH_BIAS_CURRENT 0x222 /* Flash Bias Current */ +#define REG_FLASH_LADDER_BIAS 0x223 /* Flash Ladder Bias */ +#define REG_FLASH_LADDER_CASCODE_CURRENT 0x224 /* Flash Ladder Cascode Current */ +#define REG_FLASH_LADDER_BIAS2 0x225 /* Flash Ladder Bias2 */ +#define REG_RESET 0x226 /* Reset */ +#define REG_RX_PFD_CONFIG 0x230 /* RX PFD Config */ +#define REG_RX_INTEGER_BYTE_0 0x231 /* RX Integer Byte 0 */ +#define REG_RX_INTEGER_BYTE_1 0x232 /* RX Integer Byte 1 */ +#define REG_RX_FRACT_BYTE_0 0x233 /* RX Fractional Byte 0 */ +#define REG_RX_FRACT_BYTE_1 0x234 /* RX Fractional Byte 1 */ +#define REG_RX_FRACT_BYTE_2 0x235 /* RX Fractional Byte 2 */ +#define REG_RX_FORCE_ALC 0x236 /* RX Force ALC */ +#define REG_RX_FORCE_VCO_TUNE_0 0x237 /* RX Force VCO Tune 0 */ +#define REG_RX_FORCE_VCO_TUNE_1 0x238 /* RX Force VCO Tune 1 */ +#define REG_RX_ALC_VARACTOR 0x239 /* RX ALC/Varactor */ +#define REG_RX_VCO_OUTPUT 0x23A /* RX VCO Output */ +#define REG_RX_CP_CURRENT 0x23B /* RX CP Current */ +#define REG_RX_CP_OFFSET 0x23C /* RX CP Offset */ +#define REG_RX_CP_CONFIG 0x23D /* RX CP Config */ +#define REG_RX_LOOP_FILTER_1 0x23E /* RX Loop Filter 1 */ +#define REG_RX_LOOP_FILTER_2 0x23F /* RX Loop Filter 2 */ +#define REG_RX_LOOP_FILTER_3 0x240 /* RX Loop Filter 3 */ +#define REG_RX_DITHERCP_CAL 0x241 /* RX Dither/CP Cal */ +#define REG_RX_VCO_BIAS_1 0x242 /* RX VCO Bias 1 */ +#define REG_RX_CAL_STATUS 0x244 /* RX Cal Status */ +#define REG_RX_VCO_CAL_REF 0x245 /* RX VCO Cal Ref */ +#define REG_RX_VCO_PD_OVERRIDES 0x246 /* RX VCO Pd Overrides */ +#define REG_RX_CP_OVERRANGE_VCO_LOCK 0x247 /* RX CP Over Range/VCO Lock */ +#define REG_RX_VCO_LDO 0x248 /* RX VCO LDO */ +#define REG_RX_VCO_CAL 0x249 /* RX VCO Cal */ +#define REG_RX_LOCK_DETECT_CONFIG 0x24A /* RX Lock Detect Config */ +#define REG_RX_CP_LEVEL_DETECT 0x24B /* RX CP Level Detect */ +#define REG_RX_DSM_SETUP_0 0x24C /* RX DSM Setup 0 */ +#define REG_RX_DSM_SETUP_1 0x24D /* RX DSM Setup 1 */ +#define REG_RX_CORRECTION_WORD0 0x24E /* RX Correction Word0 */ +#define REG_RX_CORRECTION_WORD1 0x24F /* RX Correction Word1 */ +#define REG_RX_VCO_VARACTOR_CTRL_0 0x250 /* RX VCO Varactor Control 0 */ +#define REG_RX_VCO_VARACTOR_CTRL_1 0x251 /* RX VCO Varactor Control 1 */ +#define REG_RX_FAST_LOCK_SETUP 0x25A /* Rx Fast Lock Setup */ +#define REG_RX_FAST_LOCK_SETUP_INIT_DELAY 0x25B /* Rx Fast Lock Setup Init Delay */ +#define REG_RX_FAST_LOCK_PROGRAM_ADDR 0x25C /* Rx Fast Lock Program Addr */ +#define REG_RX_FAST_LOCK_PROGRAM_DATA 0x25D /* Rx Fast Lock Program Data */ +#define REG_RX_FAST_LOCK_PROGRAM_READ 0x25E /* Rx Fast Lock Program Read */ +#define REG_RX_FAST_LOCK_PROGRAM_CTRL 0x25F /* Rx Fast Lock Program Control */ +#define REG_RX_LO_GEN_POWER_MODE 0x261 /* Rx LO Gen Power Mode */ +#define REG_TX_PFD_CONFIG 0x270 /* TX PFD Config */ +#define REG_TX_INTEGER_BYTE_0 0x271 /* TX Integer Byte 0 */ +#define REG_TX_INTEGER_BYTE_1 0x272 /* TX Integer Byte 1 */ +#define REG_TX_FRACT_BYTE_0 0x273 /* TX Fractional Byte 0 */ +#define REG_TX_FRACT_BYTE_1 0x274 /* TX Fractional Byte 1 */ +#define REG_TX_FRACT_BYTE_2 0x275 /* TX Fractional Byte 2 */ +#define REG_TX_FORCE_ALC 0x276 /* TX Force ALC */ +#define REG_TX_FORCE_VCO_TUNE_0 0x277 /* TX Force VCO Tune 0 */ +#define REG_TX_FORCE_VCO_TUNE_1 0x278 /* TX Force VCO Tune 1 */ +#define REG_TX_ALCVARACT_OR 0x279 /* TX ALC/Varact or */ +#define REG_TX_VCO_OUTPUT 0x27A /* TX VCO Output */ +#define REG_TX_CP_CURRENT 0x27B /* TX CP Current */ +#define REG_TX_CP_OFFSET 0x27C /* TX CP Offset */ +#define REG_TX_CP_CONFIG 0x27D /* TX CP Config */ +#define REG_TX_LOOP_FILTER_1 0x27E /* TX Loop Filter 1 */ +#define REG_TX_LOOP_FILTER_2 0x27F /* TX Loop Filter 2 */ +#define REG_TX_LOOP_FILTER_3 0x280 /* TX Loop Filter 3 */ +#define REG_TX_DITHERCP_CAL 0x281 /* TX Dither/CP Cal */ +#define REG_TX_VCO_BIAS_1 0x282 /* TX VCO Bias 1 */ +#define REG_TX_VCO_BIAS_2 0x283 /* TX VCO Bias 2 */ +#define REG_TX_CAL_STATUS 0x284 /* TX Cal Status */ +#define REG_TX_VCO_CAL_REF 0x285 /* TX VCO Cal Ref */ +#define REG_TX_VCO_PD_OVERRIDES 0x286 /* TX VCO Pd Overrides */ +#define REG_TX_CP_OVERRANGE_VCO_LOCK 0x287 /* TX CP Over Range/VCO Lock */ +#define REG_TX_VCO_LDO 0x288 /* TX VCO LDO */ +#define REG_TX_VCO_CAL 0x289 /* TX VCO Cal */ +#define REG_TX_LOCK_DETECT_CONFIG 0x28A /* TX Lock Detect Config */ +#define REG_TX_CP_LEVEL_DETECT 0x28B /* TX CP Level Detect */ +#define REG_TX_DSM_SETUP_0 0x28C /* TX DSM Setup 0 */ +#define REG_TX_DSM_SETUP_1 0x28D /* TX DSM Setup 1 */ +#define REG_TX_CORRECTION_WORD0 0x28E /* TX Correction Word0 */ +#define REG_TX_CORRECTION_WORD1 0x28F /* TX Correction Word1 */ +#define REG_TX_VCO_VARACTOR_CTRL_0 0x290 /* TX VCO Varactor Control 0 */ +#define REG_TX_VCO_VARACTOR_CTRL_1 0x291 /* TX VCO Varactor Control 1 */ +#define REG_DCXO_COARSE_TUNE 0x292 /* DCXO Coarse Tune */ +#define REG_DCXO_FINE_TUNE_HIGH 0x293 /* DCXO Fine Tune2 */ +#define REG_DCXO_FINE_TUNE_LOW 0x294 /* DCXO Fine Tune1 */ +#define REG_DCXO_CONFIG 0x295 /* DCXO Config */ +#define REG_DCXO_TEMPCO_WRITE 0x296 /* DCXO Tempco Write */ +#define REG_DCXO_TEMPCO_READ 0x297 /* DCXO Tempco Read */ +#define REG_DCXO_TEMPCO_ADDR 0x298 /* DCXO Tempco Addr */ +#define REG_DELTA_T_READ 0x299 /* Delta T Read */ +#define REG_TX_FAST_LOCK_SETUP 0x29A /* Tx Fast Lock Setup */ +#define REG_TX_FAST_LOCK_SETUP_INIT_DELAY 0x29B /* Tx Fast Lock Setup Init Delay */ +#define REG_TX_FAST_LOCK_PROGRAM_ADDR 0x29C /* Tx Fast Lock Program Addr */ +#define REG_TX_FAST_LOCK_PROGRAM_DATA 0x29D /* Tx Fast Lock Program Data */ +#define REG_TX_FAST_LOCK_PROGRAM_READ 0x29E /* Tx Fast Lock Program Read */ +#define REG_TX_FAST_LOCK_PROGRAM_CTRL 0x29F /* Tx Fast Lock Program Ctrl */ +#define REG_TX_LO_GEN_POWER_MODE 0x2A1 /* Tx LO Gen Power Mode */ +#define REG_BANDGAP_CONFIG0 0x2A6 /* Bandgap Config0 */ +#define REG_BANDGAP_CONFIG1 0x2A8 /* Bandgap Config1 */ +#define REG_REF_DIVIDE_CONFIG_1 0x2AB /* Ref Divide Config 1 */ +#define REG_REF_DIVIDE_CONFIG_2 0x2AC /* Ref Divide Config 2 */ +#define REG_GAIN_RX1 0x2B0 /* Gain Rx1 */ +#define REG_LPF_GAIN_RX1 0x2B1 /* LPF Gain Rx1 */ +#define REG_DIG_GAIN_RX1 0x2B2 /* Dig gain Rx1 */ +#define REG_FAST_ATTACK_STATE 0x2B3 /* Fast Attack State */ +#define REG_SLOW_LOOP_STATE 0x2B4 /* Slow Loop State */ +#define REG_GAIN_RX2 0x2B5 /* Gain Rx2 */ +#define REG_LPF_GAIN_RX2 0x2B6 /* LPF Gain Rx2 */ +#define REG_DIG_GAIN_RX2 0x2B7 /* Dig Gain Rx2 */ +#define REG_OVRG_SIGS_RX1 0x2B8 /* Ovrg Sigs Rx1 */ +#define REG_OVRG_SIGS_RX2 0x2B9 /* Ovrg Sigs Rx2 */ +#define REG_CTRL 0x3DF /* Control */ +#define REG_BIST_CONFIG 0x3F4 /* BIST Config */ +#define REG_OBSERVE_CONFIG 0x3F5 /* Observe Config */ +#define REG_BIST_AND_DATA_PORT_TEST_CONFIG 0x3F6 /* BIST and Data Port Test Config */ +#define REG_DAC_TEST_0 0x3FC /* DAC Test 0 */ +#define REG_DAC_TEST_1 0x3FD /* DAC Test 1 */ +#define REG_DAC_TEST_2 0x3FE /* DAC Test 2 */ + +/* +* REG_SPI_CONF +*/ +#define SOFT_RESET (1 << 7) /* Soft Reset */ +#define WIRE3_SPI (1 << 6) /* 3-Wire SPI */ +#define LSB_FIRST (1 << 5) /* LSB First */ +#define _LSB_FIRST (1 << 2) /* LSB First */ +#define _WIRE3_SPI (1 << 1) /* 3-Wire SPI */ +#define _SOFT_RESET (1 << 0) /* Soft reset */ + +/* +* REG_MULTICHIP_SYNC_AND_TX_MON_CTRL +*/ +#define TX2_MONITOR_ENABLE (1 << 6) /* Tx2 Monitor Enable */ +#define TX1_MONITOR_ENABLE (1 << 5) /* Tx1 Monitor Enable */ +#define MCS_RF_ENABLE (1 << 3) /* MCS RF Enable */ +#define MCS_BBPLL_ENABLE (1 << 2) /* MCS BBPLL enable */ +#define MCS_DIGITAL_CLK_ENABLE (1 << 1) /* MCS Digital CLK Enable */ +#define MCS_BB_ENABLE (1 << 0) /* MCS BB Enable */ + +/* +* REG_TX_ENABLE_FILTER_CTRL +*/ +#define THB2_EN (1 << 3) /* THB2 Enable */ +#define THB1_EN (1 << 2) /* THB1 Enable */ +#define TX_CHANNEL_ENABLE(x) (((x) & 0x3) << 6) /* Tx channel Enable<1:0> */ +#define THB3_ENABLE_INTERP(x) (((x) & 0x3) << 4) /* THB3 Enable & Interp<1:0> */ +#define TX_FIR_ENABLE_INTERPOLATION(x) (((x) & 0x3) << 0) /* Tx FIR Enable & Interpolation<1:0> */ +#define TX_1 1 +#define TX_2 2 +#define TX_ENABLE 1 +#define TX_DISABLE 0 + +/* +* REG_RX_ENABLE_FILTER_CTRL +*/ +#define RHB2_EN (1 << 3) /* RHB2 Enable */ +#define RHB1_EN (1 << 2) /* RHB1 Enable */ +#define RX_CHANNEL_ENABLE(x) (((x) & 0x3) << 6) /* Rx channel Enable<1:0> */ +#define DEC3_ENABLE_DECIMATION(x) (((x) & 0x3) << 4) /* DEC3 Enable & Decimation<1:0> */ +#define RX_FIR_ENABLE_DECIMATION(x) (((x) & 0x3) << 0) /* Rx FIR Enable & Decimation<1:0> */ +#define RX_1 1 +#define RX_2 2 +#define RX_ENABLE 1 +#define RX_DISABLE 0 + +/* +* REG_INPUT_SELECT +*/ +#define TX_OUTPUT (1 << 6) /* TX Output */ +#define RX_INPUT(x) (((x) & 0x3F) << 0) /* RX Input <5:0> */ + +/* +* REG_RFPLL_DIVIDERS +*/ +#define TX_VCO_DIVIDER(x) (((x) & 0xF) << 4) /* TX VCO Divider<3:0> */ +#define RX_VCO_DIVIDER(x) (((x) & 0xF) << 0) /* RX VCO Divider<3:0> */ + +/* +* REG_RX_CLOCK_DATA_DELAY +*/ +#define DATA_CLK_DELAY(x) (((x) & 0xF) << 4) /* DATA_CLK Delay<3:0> */ +#define RX_DATA_DELAY(x) (((x) & 0xF) << 0) /* Rx Data Delay <3:0> */ + +/* +* REG_TX_CLOCK_DATA_DELAY +*/ +#define FB_CLK_DELAY(x) (((x) & 0xF) << 4) /* FB_CLK Delay<3:0> */ +#define TX_DATA_DELAY(x) (((x) & 0xF) << 0) /* Tx Data Delay <3:0> */ + +/* +* REG_CLOCK_ENABLE +*/ +#define XO_BYPASS (1 << 4) /* XO Bypass */ +#define DIGITAL_POWER_UP (1 << 2) /* Digital Power Up */ +#define CLOCK_ENABLE_DFLT (1 << 1) /* Set to 1 */ +#define BBPLL_ENABLE (1 << 0) /* BBPLL Enable */ + +/* +* REG_BBPLL +*/ +#define CLKOUT_ENABLE (1 << 4) /* CLKOUT Enable */ +#define DAC_CLK_DIV2 (1 << 3) /* DAC Clk div2 */ +#define CLKOUT_SELECT(x) (((x) & 0x7) << 5) /* CLKOUT Select<2:0> */ +#define BBPLL_DIVIDER(x) (((x) & 0x7) << 0) /* BBPLL Divider <2:0> */ + +/* +* REG_START_TEMP_READING +*/ +#define START_TEMP_READING (1 << 0) /* Start Temp Reading */ + +/* +* REG_TEMP_SENSE2 +*/ +#define TEMP_SENSE_PERIODIC_ENABLE (1 << 0) /* Temp Sense Periodic Enable */ +#define MEASUREMENT_TIME_INTERVAL(x) (((x) & 0x7F) << 1) /* Measurement Time Interval<6:0> */ + +/* +* REG_TEMP_SENSOR_CONFIG +*/ +#define TEMP_SENSOR_DECIMATION(x) (((x) & 0x7) << 0) /* Temp Sensor Decimation<2:0> */ + +/* +* REG_PARALLEL_PORT_CONF_1 +*/ +#define PP_TX_SWAP_IQ (1 << 7) /* PP Tx Swap IQ */ +#define PP_RX_SWAP_IQ (1 << 6) /* PP Rx Swap IQ */ +#define TX_CHANNEL_SWAP (1 << 5) /* Tx Channel swap */ +#define RX_CHANNEL_SWAP (1 << 4) /* Rx Channel swap */ +#define RX_FRAME_PULSE_MODE (1 << 3) /* Rx Frame Pulse Mode */ +#define R2T2_TIMING (1 << 2) /* 2R2T Timing */ +#define INVERT_DATA_BUS (1 << 1) /* Invert data bus */ +#define INVERT_DATA_CLK (1 << 0) /* Invert DATA CLK */ + +/* +* REG_PARALLEL_PORT_CONF_2 +*/ +#define FDD_ALT_WORD_ORDER (1 << 7) /* FDD Alt Word Order */ +#define INVERT_RX1 (1 << 6) /* Invert Rx1 */ +#define INVERT_RX2 (1 << 5) /* Invert Rx2 */ +#define INVERT_TX1 (1 << 4) /* Invert Tx1 */ +#define INVERT_TX2 (1 << 3) /* Invert Tx2 */ +#define INVERT_RX_FRAME (1 << 2) /* Invert Rx Frame */ +#define DELAY_RX_DATA(x) (((x) & 0x3) << 0) /* Delay Rx Data<1:0> */ + +/* +* REG_PARALLEL_PORT_CONF_3 +*/ +#define FDD_RX_RATE_2TX_RATE (1 << 7) /* FDD Rx Rate = 2*Tx Rate */ +#define SWAP_PORTS (1 << 6) /* Swap Ports */ +#define SINGLE_DATA_RATE (1 << 5) /* Single Data Rate */ +#define LVDS_MODE (1 << 4) /* LVDS Mode */ +#define HALF_DUPLEX_MODE (1 << 3) /* Half Duplex Mode */ +#define SINGLE_PORT_MODE (1 << 2) /* Single Port Mode */ +#define FULL_PORT (1 << 1) /* Full Port */ +#define FULL_DUPLEX_SWAP_BITS (1 << 0) /* Full Duplex Swap Bits */ + +/* +* REG_ENSM_MODE +*/ +#define FDD_MODE (1 << 0) /* FDD Mode */ + +/* +* REG_ENSM_CONFIG_1 +*/ +#define ENABLE_RX_DATA_PORT_FOR_CAL (1 << 7) /* Enable Rx Data Port for Cal */ +#define FORCE_RX_ON (1 << 6) /* Force Rx On */ +#define FORCE_TX_ON (1 << 5) /* Force Tx On */ +#define ENABLE_ENSM_PIN_CTRL (1 << 4) /* Enable ENSM Pin Control */ +#define LEVEL_MODE (1 << 3) /* Level Mode */ +#define FORCE_ALERT_STATE (1 << 2) /* Force Alert State */ +#define AUTO_GAIN_LOCK (1 << 1) /* Auto Gain Lock */ +#define TO_ALERT (1 << 0) /* To Alert */ + +/* +* REG_ENSM_CONFIG_2 +*/ +#define FDD_EXTERNAL_CTRL_ENABLE (1 << 7) /* FDD External Control Enable */ +#define POWER_DOWN_RX_SYNTH (1 << 6) /* Power Down Rx Synth */ +#define POWER_DOWN_TX_SYNTH (1 << 5) /* Power Down Tx Synth */ +#define TXNRX_SPI_CTRL (1 << 4) /* TXNRX SPI Control */ +#define SYNTH_ENABLE_PIN_CTRL_MODE (1 << 3) /* Synth Enable Pin Control Mode */ +#define DUAL_SYNTH_MODE (1 << 2) /* Dual Synth Mode */ +#define RX_SYNTH_READY_MASK (1 << 1) /* Rx Synth Ready Mask */ +#define TX_SYNTH_READY_MASK (1 << 0) /* Tx Synth Ready Mask */ + +/* +* REG_CALIBRATION_CTRL +*/ +#define RX_BB_TUNE_CAL (1 << 7) /* Rx BB Tune */ +#define TX_BB_TUNE_CAL (1 << 6) /* Tx BB Tune */ +#define RX_QUAD_CAL (1 << 5) /* Rx Quad Cal */ +#define TX_QUAD_CAL (1 << 4) /* Tx Quad Cal */ +#define RX_GAIN_STEP_CAL (1 << 3) /* Rx Gain Step Cal */ +#define TXMON_CAL (1 << 2) +#define RFDC_CAL (1 << 1) /* DC Cal RF Start */ +#define BBDC_CAL (1 << 0) /* DC cal BB Start */ + + +/* +* REG_STATE +*/ +#define CALIBRATION_SEQUENCE_STATE(x) (((x) & 0xF) << 4) /* Calibration Sequence State<3:0> */ +#define ENSM_STATE(x) (((x) & 0xF) << 0) /* ENSM State<3:0> */ +#define ENSM_STATE_SLEEP_WAIT 0x0 +#define ENSM_STATE_ALERT 0x5 +#define ENSM_STATE_TX 0x6 +#define ENSM_STATE_TX_FLUSH 0x7 +#define ENSM_STATE_RX 0x8 +#define ENSM_STATE_RX_FLUSH 0x9 +#define ENSM_STATE_FDD 0xA +#define ENSM_STATE_FDD_FLUSH 0xB +#define ENSM_STATE_INVALID 0xFF +#define ENSM_STATE_SLEEP 0x80 + +/* +* REG_AUXDAC_2_WORD +*/ +#define AUXDAC_2_WORD_MSB(x) (((x) & 0x3F) << 2) /* AuxDAC 2 Word<9:2> */ +#define AUXDAC_1_WORD(x) (((x) & 0x3) << 0) /* AuxDAC 1 Word <1:0> */ + +/* +* REG_AUXDAC_1_CONFIG +*/ +#define COMP_CTRL_1 (1 << 5) /* Comp Ctrl 1 */ +#define AUXDAC1_STP_FACTOR (1 << 4) /* AuxDAC1 Step Factor */ +#define AUXDAC_1_VREF(x) (((x) & 0x3) << 2) /* AuxDAC 1 Vref<1:0> */ +#define AUXDAC_1_WORD_LSB(x) (((x) & 0x3) << 0) /* AuxDAC 2 Word <1:0> */ + +/* +* REG_AUXDAC_2_CONFIG +*/ +#define COMP_CTRL_2 (1 << 5) /* Comp Ctrl 2 */ +#define AUXDAC2_STP_FACTOR (1 << 4) /* AuxDAC2 Step Factor */ +#define AUXDAC_2_VREF(x) (((x) & 0xF) << 2) /* AuxDAC 2 Vref<1:0> */ +#define AUXDAC_2_WORD_LSB(x) (((x) & 0x3) << 0) /* AuxDAC 2 Word <1:0> */ + +/* +* REG_AUXADC_CLOCK_DIVIDER +*/ +#define AUXADC_CLOCK_DIVIDER(x) (((x) & 0x3F) << 0) /* AuxADC Clock Divider<5:0> */ + +/* +* REG_AUXADC_CONFIG +*/ +#define AUXADC_POWER_DOWN (1 << 0) /* AuxADC Power Down */ +#define AUX_ADC_DECIMATION(x) (((x) & 0x7) << 1) /* Aux ADC Decimation<2:0> */ + +/* +* REG_AUXADC_LSB +*/ +#define AUXADC_WORD_LSB(x) (((x) & 0xF) << 0) /* AuxADC Word LSB<3:0> */ + +/* +* REG_AUTO_GPO +*/ +#define GPO_ENABLE_AUTO_RX(x) (((x) & 0xF) << 4) /* GPO Enable Auto Rx<3:0> */ +#define GPO_ENABLE_AUTO_TX(x) (((x) & 0xF) << 0) /* GPO Enable Auto Tx<3:0> */ + +/* +* REG_AGC_ATTACK_DELAY +*/ +#define INVERT_BYPASSED_LNA_POLARITY (1 << 6) /* Invert Bypassed LNA Polarity */ +#define AGC_ATTACK_DELAY(x) (((x) & 0x3F) << 0) /* AGC Attack Delay<5:0> */ + +/* +* REG_AUXDAC_ENABLE_CTRL +*/ +#define AUXDAC_MANUAL_BAR(x) (((x) & 0x3) << 6) /* AuxDac Manual Bar<1:0> */ +#define AUXDAC_AUTO_TX_BAR(x) (((x) & 0x3) << 4) /* AuxDAC Auto Tx Bar<1:0> */ +#define AUXDAC_AUTO_RX_BAR(x) (((x) & 0x3) << 2) /* AuxDAC Auto Rx Bar<1:0> */ +#define AUXDAC_INIT_BAR(x) (((x) & 0x3) << 0) /* AuxDAC Init Bar<1:0> */ + +/* +* REG_EXTERNAL_LNA_CTRL +*/ +#define AUXDAC_MANUAL_SELECT (1 << 7) /* AuxDAC Manual Select */ +#define EXTERNAL_LNA2_CTRL (1 << 6) /* External LNA2 control */ +#define EXTERNAL_LNA1_CTRL (1 << 5) /* External LNA1 control */ +#define GPO_MANUAL_SELECT (1 << 4) /* GPO manual select */ +#define OPEN(x) (((x) & 0xF) << 0) /* Open<3:0> */ + +/* +* REG_GPO_FORCE_AND_INIT +*/ +#define GPO_MANUAL_CTRL(x) (((x) & 0xF) << 4) /* GPO Manual Control<3:0> */ +#define GPO_INIT_STATE(x) (((x) & 0xF) << 0) /* GPO Init State<3:0> */ + +/* +* REG_CTRL_OUTPUT_ENABLE +*/ +#define EN_CTRL7 (1 << 7) /* En ctrl7 */ +#define EN_CTRL6 (1 << 6) /* En ctrl6 */ +#define EN_CTRL5 (1 << 5) /* En ctrl5 */ +#define EN_CTRL4 (1 << 4) /* En ctrl4 */ +#define EN_CTRL3 (1 << 3) /* En ctrl3 */ +#define EN_CTRL2 (1 << 2) /* En ctrl2 */ +#define EN_CTRL1 (1 << 1) /* En ctrl1 */ +#define EN_CTRL0 (1 << 0) /* En ctrl0 */ + +/* +* REG_PRODUCT_ID +*/ +#define PRODUCT_ID_MASK 0xF8 +#define PRODUCT_ID_9361 0x08 +#define REV_MASK 0x07 + +/* +* REG_REFERENCE_CLOCK_CYCLES +*/ +#define REFERENCE_CLOCK_CYCLES_PER_US(x) (((x) & 0x7F) << 0) /* Reference Clock Cycles per us<6:0> */ + +/* +* REG_DIGITAL_IO_CTRL +*/ +#define CLK_OUT_DRIVE (1 << 7) /* CLK Out Drive */ +#define DATACLK_DRIVE (1 << 6) /* DATACLK drive */ +#define DATA_PORT_DRIVE (1 << 2) /* Data Port Drive */ +#define DATACLK_SLEW(x) (((x) & 0x3) << 4) /* DATACLK slew <1:0> */ +#define DATA_PORT_SLEW(x) (((x) & 0x3) << 0) /* Data Port Slew<1:0> */ + +/* +* REG_LVDS_BIAS_CTRL +*/ +#define RX_ON_CHIP_TERM (1 << 5) /* Rx On Chip Term */ +#define LVDS_BYPASS_BIAS_R (1 << 4) /* Bypass Bias R */ +#define LVDS_TX_LO_VCM (1 << 3) /* LVDS Tx LO VCM */ +#define CLK_OUT_SLEW(x) (((x) & 0x3) << 6) /* CLK Out Slew<1:0> */ +#define LVDS_BIAS(x) (((x) & 0x7) << 0) /* LVDS Bias <2:0> */ + +/* +* REG_SDM_CTRL_1 +*/ +#define INIT_BB_FO_CAL (1 << 2) /* Init BB FO CAL */ +#define BBPLL_RESET_BAR (1 << 0) /* BBPLL Reset Bar */ + +/* +* REG_CLOCK_CTRL +*/ +#define REF_FREQ_SCALER(x) (((x) & 0x3) << 0) /* Ref Frequency Scaler */ + +/* +* REG_CP_CURRENT +*/ +#define CHARGE_PUMP_CURRENT(x) (((x) & 0x3F) << 0) /* Charge Pump Current<5:0> */ + +/* +* REG_CP_BLEED_CURRENT +*/ +#define MCS_REFCLK_SCALE_EN (1 << 7) /* MCS refclk Scale En */ + +/* +* REG_LOOP_FILTER_1 +*/ +#define C1_WORD(x) (((x) & 0x7) << 5) /* C1 Word<2:0> */ +#define R1_WORD(x) (((x) & 0x1F) << 0) /* R1 Word<4:0> */ + +/* +* REG_LOOP_FILTER_2 +*/ +#define R2_WORD (1 << 7) /* R2 Word<0> */ +#define C2_WORD(x) (((x) & 0x1F) << 2) /* C2 Word<4:0> */ +#define C1_WORD_LSB(x) (((x) & 0x3) << 0) /* C1 Word<4:3> */ + +/* +* REG_LOOP_FILTER_3 +*/ +#define BYPASS_C3 (1 << 7) /* Bypass C3 */ +#define BYPASS_R2 (1 << 6) /* Bypass R2 */ +#define C3_WORD(x) (((x) & 0xF) << 2) /* C3 Word<3:0> */ +#define R2_WORD_LSB(x) (((x) & 0x3) << 0) /* R2 Word<2:1> */ + +/* +* REG_VCO_CTRL +*/ +#define FREQ_CAL_ENABLE (1 << 7) /* Freq Cal Enable */ +#define FREQ_CAL_RESET (1 << 4) /* Freq Cal Reset */ +#define FREQ_CAL_COUNT_LENGTH(x) (((x) & 0x3) << 5) /* Freq Cal Count Length<1:0> */ + +/* +* REG_SDM_CTRL +*/ +#define CAL_CLOCK_DIV_4 (1 << 4) /* Cal Clock div 4 */ + +/* +* REG_RX_SYNTH_POWER_DOWN_OVERRIDE +*/ +#define RX_LO_POWER_DOWN (1 << 4) /* Rx LO Power Down */ +#define RX_SYNTH_VCO_ALC_POWER_DOWN (1 << 3) /* Rx Synth VCO ALC Power Down */ +#define RX_SYNTH_PTAT_POWER_DOWN (1 << 2) /* Rx Synth PTAT Power Down */ +#define RX_SYNTH_VCO_POWER_DOWN (1 << 1) /* Rx Synth VCO Power Down */ +#define RX_SYNTH_VCO_LDO_POWER_DOWN (1 << 0) /* Rx Synth VCO LDO Power Down */ + +/* +* REG_TX_SYNTH_POWER_DOWN_OVERRIDE +*/ +#define TX_LO_POWER_DOWN (1 << 4) /* Tx LO Power Down */ +#define TX_SYNTH_VCO_ALC_POWER_DOWN (1 << 3) /* Tx Synth VCO ALC Power Down */ +#define TX_SYNTH_PTAT_POWER_DOWN (1 << 2) /* Tx Synth PTAT Power Down */ +#define TX_SYNTH_VCO_POWER_DOWN (1 << 1) /* Tx Synth VCO Power Down */ +#define TX_SYNTH_VCO_LDO_POWER_DOWN (1 << 0) /* Tx Synth VCO LDO Power Down */ + +/* +* REG_RX_ANALOG_POWER_DOWN_OVERRIDE_1 +*/ +#define RX_OFFSET_DAC_CGIN_POWER_DOWN(x) (((x) & 0x3) << 6) /* Rx Offset DAC CGin Power Down<1:0> */ +#define RX_LMT_OVERLOAD_POWER_DOWN(x) (((x) & 0x3) << 4) /* Rx LMT Overload Power Down<1:0> */ +#define RX_MIXER_GM_POWER_DOWN(x) (((x) & 0x3) << 2) /* Rx Mixer Gm Power Down<1:0> */ +#define RX_CGB_POWER_DOWN(x) (((x) & 0x3) << 0) /* Rx CGB Power Down<1:0> */ + +/* +* REG_RX_ANALOG_POWER_DOWN_OVERRIDE_2 +*/ +#define RX_BBF_POWER_DOWN(x) (((x) & 0x3) << 6) /* Rx BBF Power Down<1:0> */ +#define RX_TIA_POWER_DOWN(x) (((x) & 0x3) << 4) /* Rx TIA Power Down<1:0> */ +#define RX_MIXER_POWER_DOWN(x) (((x) & 0x3) << 2) /* Rx Mixer Power Down<1:0> */ +#define RX_OFFSET_DAC_CGOUT_POWER_DOWN(x) (((x) & 0x3) << 0) /* Rx Offset DAC CGOut Power Down<1:0> */ + +/* +* REG_TX_ANALOG_POWER_DOWN_OVERRIDE_1 +*/ +#define TX_SECONDARY_FILTER_POWER_DOWN(x) (((x) & 0x3) << 6) /* Tx Secondary Filter Power Down<1:0> */ +#define TX_BBF_POWER_DOWN(x) (((x) & 0x3) << 4) /* Tx BBF Power Down<1:0> */ +#define TX_DAC_POWER_DOWN(x) (((x) & 0x3) << 2) /* Tx DAC Power Down<1:0> */ +#define TX_DAC_BIAS_POWER_DOWN(x) (((x) & 0x3) << 0) /* Tx DAC Bias Power Down<1:0> */ + +/* +* REG_ANALOG_POWER_DOWN_OVERRIDE +*/ +#define RX_EXT_VCO_BUFFER_POWER_DOWN (1 << 5) /* Rx Ext VCO Buffer Power Down */ +#define TX_EXT_VCO_BUFFER_POWER_DOWN (1 << 4) /* Tx Ext VCO Buffer Power Down */ +#define TX_MONITOR_POWER_DOWN(x) (((x) & 0x3) << 2) /* Tx Monitor Power Down<1:0> */ +#define TX_UPCONVERTER_POWER_DOWN(x) (((x) & 0x3) << 0) /* Tx Upconverter Power Down<1:0> */ + +/* +* REG_MISC_POWER_DOWN_OVERRIDE +*/ +#define RX_LNA_POWER_DOWN (1 << 6) /* Rx LNA Power Down */ +#define DCXO_POWER_DOWN (1 << 1) /* DCXO Power Down */ +#define MASTER_BIAS_POWER_DOWN (1 << 0) /* Master Bias Power Down */ +#define RX_CALIBRATION_POWER_DOWN(x) (((x) & 0x3) << 2) /* Rx Calibration Power Down<1:0> */ + +/* +* REG_CH_1_OVERFLOW +*/ +#define BBPLL_LOCK (1 << 7) /* BBPLL Lock */ +#define CH_1_INT3 (1 << 6) /* CH 1 INT3 */ +#define CH1_HB3 (1 << 5) /* CH1 HB3 */ +#define CH1_HB2 (1 << 4) /* CH1 HB2 */ +#define CH1_QEC (1 << 3) /* CH1 QEC */ +#define CH1_HB1 (1 << 2) /* CH1 HB1 */ +#define CH1_TFIR (1 << 1) /* CH1 TFIR */ +#define CH1_RFIR (1 << 0) /* CH1 RFIR */ + +/* +* REG_CH_2_OVERFLOW +*/ +#define CH2_INT3 (1 << 6) /* CH2 INT3 */ +#define CH2_HB3 (1 << 5) /* CH2 HB3 */ +#define CH2_HB2 (1 << 4) /* CH2 HB2 */ +#define CH2_QEC (1 << 3) /* CH2 QEC */ +#define CH2_HB1 (1 << 2) /* CH2 HB1 */ +#define CH2_TFIR (1 << 1) /* CH2 TFIR */ +#define CH2_RFIR (1 << 0) /* CH2 RFIR */ + +/* +* REG_TX_FILTER_CONF +*/ +#define TX_FIR_GAIN_6DB (1 << 0) /* Filter Gain */ +#define FIR_START_CLK (1 << 1) /* Start Tx/Rx Clock */ +#define FIR_WRITE (1 << 2) /* Write Tx/Rx */ +#define FIR_SELECT(x) (((x) & 0x3) << 3) /* Select Tx/Rx CH<1:0> */ +#define FIR_NUM_TAPS(x) (((x) & 0x7) << 5) /* Number of Taps<2:0> */ + +/* +* REG_TX_MON_LOW_GAIN +*/ +#define TX_MON_TRACK (1 << 5) /* Tx Mon Track */ +#define TX_MON_LOW_GAIN(x) (((x) & 0x1F) << 0) /* Tx Mon Low Gain<4:0> */ + +/* +* REG_TX_MON_HIGH_GAIN +*/ +#define TX_MON_HIGH_GAIN(x) (((x) & 0x1F) << 0) /* Tx Mon High Gain<4:0> */ + +/* +* REG_TX_LEVEL_THRESH +*/ +#define TX_LEVEL_THRESH(x) (((x) & 0x3F) << 2) /* Tx Level Threshold<5:0> */ +#define TX_MON_DELAY_COUNTER(x) (((x) & 0x3) << 0) /* Tx Mon Delay Counter<9:8> */ + +/* +* REG_TX_RSSI_LSB +*/ +#define TX_RSSI_2 (1 << 1) /* Tx RSSI 2<0> */ +#define TX_RSSI_1 (1 << 0) /* TX RSSI 1<0> */ + +/* +* REG_TPM_MODE_ENABLE +*/ +#define TX2_MON_ENABLE (1 << 7) /* Tx2 Monitor Enable */ +#define TX1_MON_ENABLE (1 << 5) /* Tx1 Monitor Enable */ +#define ONE_SHOT_MODE (1 << 6) /* One Shot Mode */ +#define TX_MON_DURATION(x) (((x) & 0xF) << 0) /* Tx Mon Duration<3:0> */ + +/* +* REG_TX_MON_1_CONFIG +*/ +#define TX_MON_1_LO_CM(x) (((x) & 0x3F) << 2) /* Tx Mon 1 LO CM<5:0> */ +#define TX_MON_1_GAIN(x) (((x) & 0x3) << 0) /* Tx Mon 1 Gain<1:0> */ + +/* +* REG_TX_MON_2_CONFIG +*/ +#define TX_MON_2_LO_CM(x) (((x) & 0x3F) << 2) /* Tx Mon 2 LO CM<5:0> */ +#define TX_MON_2_GAIN(x) (((x) & 0x3) << 0) /* Tx Mon 2 Gain<1:0> */ + +/* +* REG_TX1_ATTEN_1 +*/ +#define TX_1_ATTEN (1 << 0) /* Tx 1 Atten <8> */ + +/* +* REG_TX2_ATTEN_1 +*/ +#define TX_2_ATTEN (1 << 0) /* Tx 2 Atten <8> */ + +/* +* REG_TX_ATTEN_OFFSET +*/ +#define MASK_CLR_ATTEN_UPDATE (1 << 6) /* Mask Clr Atten Update */ +#define TX_ATTEN_OFFSET(x) (((x) & 0x3F) << 0) /* Tx Atten Offset<5:0> */ + +/* +* REG_TX1_DIG_ATTEN +*/ +#define SEL_TX1_TX2 (1 << 6) /* Sel Tx1 & Ttx2 */ + +/* +* REG_TX2_DIG_ATTEN +*/ +#define IMMEDIATELY_UPDATE_TPC_ATTEN (1 << 6) /* Immediately Update TPC Atten */ + +/* +* REG_TX1_SYMBOL_ATTEN +*/ +#define TX_1_SYMBOL_ATTEN(x) (((x) & 0x7F) << 0) /* Tx 1 Symbol Attenuation<6:0> */ + +/* +* REG_TX2_SYMBOL_ATTEN +*/ +#define TX_2_SYMBOL_ATTEN(x) (((x) & 0x7F) << 0) /* Tx 2 Symbol Attenuation<6:0> */ + +/* +* REG_TX_SYMBOL_ATTEN_CONFIG +*/ +#define USE_TX1_PIN_SYMBOL_ATTEN (1 << 3) /* Use Tx1 Pin & Symbol Atten */ +#define USE_CTRL_IN_FOR_SYMBOL_ATTEN (1 << 1) /* Use CTRL IN for symbol Atten */ +#define ENABLE_SYMBOL_ATTEN (1 << 0) /* Enable Symbol Atten */ + +/* +* REG_TX_FORCE_BITS +*/ +#define FORCE_OUT_2_TX2_OFFSET (1 << 7) /* Force Out 2 Tx2 Offset */ +#define FORCE_OUT_2_TX1_OFFSET (1 << 6) /* Force Out 2 Tx1 Offset */ +#define FORCE_OUT_2_TX2_PHASE_GAIN (1 << 5) /* Force Out 2 Tx2 Phase & Gain */ +#define FORCE_OUT_2_TX1_PHASE_GAIN (1 << 4) /* Force Out 2 Tx1 Phase & Gain */ +#define FORCE_OUT_1_TX2_OFFSET (1 << 3) /* Force Out 1 Tx2 Offset */ +#define FORCE_OUT_1_TX1_OFFSET (1 << 2) /* Force Out 1 Tx1 Offset */ +#define FORCE_OUT_1_TX2_PHASE_GAIN (1 << 1) /* Force Out 1 Tx2 Phase & Gain */ +#define FORCE_OUT_1_TX1_PHASE_GAIN (1 << 0) /* Force Out 1 Tx1 Phase & Gain */ + +/* +* REG_QUAD_CAL_NCO_FREQ_PHASE_OFFSET +*/ +#define RX_NCO_FREQ(x) (((x) & 0x3) << 5) /* Rx NCO Frequency<1:0> */ +#define RX_NCO_PHASE_OFFSET(x) (((x) & 0x1F) << 0) /* Rx NCO Phase Offset<4:0> */ + +/* +* REG_QUAD_CAL_CTRL +*/ +#define FREE_RUN_ENABLE (1 << 7) /* Free Run Enable */ +#define SETTLE_MAIN_ENABLE (1 << 6) /* Settle Main Enable */ +#define DC_OFFSET_ENABLE (1 << 5) /* DC Offset Enable */ +#define GAIN_ENABLE (1 << 4) /* Gain Enable */ +#define PHASE_ENABLE (1 << 3) /* Phase Enable */ +#define QUAD_CAL_SOFT_RESET (1 << 2) /* Quad Cal Soft Reset */ +#define M_DECIM(x) (((x) & 0x3) << 0) /* M<1:0> */ + +/* +* REG_KEXP_1 +*/ +#define KEXP_TX(x) (((x) & 0x3) << 6) /* Kexp Tx<1:0> */ +#define KEXP_TX_COMP(x) (((x) & 0x3) << 4) /* Kexp Tx_comp <1:0> */ +#define KEXP_DC_I(x) (((x) & 0x3) << 2) /* Kexp DC I <1:0> */ +#define KEXP_DC_Q(x) (((x) & 0x3) << 0) /* Kexp DC Q <1:0> */ + +/* +* REG_KEXP_2 +*/ +#define INVERT_I_DATA (1 << 5) /* Invert I data */ +#define INVERT_Q_DATA (1 << 4) /* Invert Q data */ +#define TX_NCO_FREQ(x) (((x) & 0x3) << 6) /* Tx NCO frequency<1:0> */ +#define KEXP_PHASE(x) (((x) & 0x3) << 2) /* Kexp Phase <1:0> */ +#define KEXP_AMP(x) (((x) & 0x3) << 0) /* Kexp Amp <1:0> */ + +/* +* REG_QUAD_CAL_STATUS_TX1 +*/ +#define TX1_LO_CONV (1 << 1) /* Tx1 LO Conv */ +#define TX1_SSB_CONV (1 << 0) /* Tx1 SSB Conv */ +#define TX1_CONVERGENCE_COUNT(x) (((x) & 0x3F) << 2) /* Tx1 Convergence Count<5:0> */ + +/* +* REG_QUAD_CAL_STATUS_TX2 +*/ +#define TX2_LO_CONV (1 << 1) /* Tx2 LO Conv */ +#define TX2_SSB_CONV (1 << 0) /* Tx2 SSB Conv */ +#define TX2_CONVERGENCE_COUNT(x) (((x) & 0x3F) << 2) /* Tx2 Convergence Count<5:0> */ + +/* +* REG_TX_QUAD_FULL_LMT_GAIN +*/ +#define RX_FULL_TABLELMT_TABLE_GAIN(x) (((x) & 0x7F) << 0) /* RX Full table/LMT table gain<6:0> */ + +/* +* REG_SQUARER_CONFIG +*/ +#define GM_STAGE_TIME_CON_OVERRIDE (1 << 5) /* Gm Stage Time Con Override */ +#define GM_STAGE_MV_HP_POLE (1 << 4) /* Gm Stage MV HP Pole */ +#define GM_STAGE_LOWER_CM (1 << 3) /* Gm Stage Lower CM */ +#define BYPASS_BIAS_R (1 << 0) /* Bypass Bias R */ +#define VBIAS_CTRL(x) (((x) & 0x3) << 1) /* Vbias Control<1:0> */ + +/* +* REG_THRESH_ACCUM +*/ +#define THRESH_ACCUMULATOR(x) (((x) & 0xF) << 0) /* Threshold Accumulator<3:0> */ + +/* +* REG_TX_QUAD_LPF_GAIN +*/ +#define RX_LPF_GAIN(x) (((x) & 0x1F) << 0) /* RX LPF gain<4:0> */ + +/* +* REG_TXDAC_VDS_I +*/ +#define TXDAC_VDS_I(x) (((x) & 0x3F) << 0) /* TxDAC Vds I<5:0> */ + +/* +* REG_TXDAC_VDS_Q +*/ +#define TXDAC_VDS_Q(x) (((x) & 0x3F) << 0) /* TxDAC Vds Q<5:0> */ + +/* +* REG_TXDAC_GN_I +*/ +#define TXDAC_GN_I(x) (((x) & 0x3F) << 0) /* txDAC_gn_I<5:0> */ + +/* +* REG_TXDAC_GN_Q +*/ +#define TXDAC_GN_Q(x) (((x) & 0x3F) << 0) /* txDAC_gn_Q<5:0> */ + +/* +* REG_TXBBF_OPAMP_A +*/ +#define OPAMPA_OUTPUT_BIAS(x) (((x) & 0x3) << 5) /* OpAmpA Output Bias<1:0> */ +#define OPAMPA_RZ(x) (((x) & 0x3) << 3) /* OpAmpA RZ<1:0> */ +#define OPAMP_A_CC(x) (((x) & 0x7) << 0) /* OpAmp A CC<2:0> */ + +/* +* REG_TXBBF_OPAMP_B +*/ +#define OPAMPB_OUTPUT_BIAS(x) (((x) & 0x3) << 5) /* OpAmpB Output Bias<1:0> */ +#define OPAMPB_RZ(x) (((x) & 0x3) << 3) /* OpAmpB RZ<1:0> */ +#define OPAMP_B_CC(x) (((x) & 0x7) << 0) /* OpAmp B CC<2:0> */ + +/* +* REG_TX_BBF_R1 +*/ +#define OVERRIDE_ENABLE (1 << 7) /* Override enable */ +#define R1(x) (((x) & 0x1F) << 0) /* R1<4:0> */ + +/* +* REG_TX_BBF_R2 +*/ +#define R2(x) (((x) & 0x1F) << 0) /* R2<4:0> */ + +/* +* REG_TX_BBF_R3 +*/ +#define R3(x) (((x) & 0x1F) << 0) /* R3<4:0> */ + +/* +* REG_TX_BBF_R4 +*/ +#define R4(x) (((x) & 0x1F) << 0) /* R4<4:0> */ + +/* +* REG_TX_BBF_RP +*/ +#define RP(x) (((x) & 0x1F) << 0) /* Rp<4:0> */ + +/* +* REG_TX_BBF_C1 +*/ +#define C1(x) (((x) & 0x3F) << 0) /* C1<5:0> */ + +/* +* REG_TX_BBF_C2 +*/ +#define C2(x) (((x) & 0x3F) << 0) /* C2<5:0> */ + +/* +* REG_TX_BBF_CP +*/ +#define CP(x) (((x) & 0x3F) << 0) /* Cp<5:0> */ + +/* +* REG_TX_TUNE_CTRL +*/ +#define PD_TUNE (1 << 2) /* PD Tune */ +#define TUNER_RESAMPLE (1 << 1) /* Tuner Resample */ +#define TUNER_RESAMPLE_PHASE (1 << 0) /* Tuner Resample Phase */ +#define TUNE_CTRL(x) (((x) & 0x3) << 5) /* Tune Control<1:0> */ + +/* +* REG_TX_BBF_R2B +*/ +#define TX_BBF_BYPASS_BIAS_R (1 << 7) /* Bypass Bias R */ +#define R2B_OVR (1 << 5) /* R2b Ovr */ +#define R2B(x) (((x) & 0x1F) << 0) /* R2b<4:0> */ + +/* +* REG_TX_BBF_TUNE +*/ +#define BBF1_COMP_I (1 << 3) /* BBF1 Comp I */ +#define BBF1_COMP_Q (1 << 2) /* BBF1 Comp Q */ +#define BBF2_COMP_I (1 << 1) /* BBF2 Comp I */ +#define BBF2_COMP_Q (1 << 0) /* BBF2 Comp Q */ + +/* +* REG_CONFIG0 +*/ +#define BIAS(x) (((x) & 0x3) << 6) /* Bias<1:0> */ +#define RGM(x) (((x) & 0x3) << 4) /* Rgm<1:0> */ +#define CC(x) (((x) & 0x3) << 2) /* Cc<1:0> */ +#define AMPBIAS(x) (((x) & 0x3) << 0) /* AmpBias<1:0> */ + +/* +* REG_RESISTOR +*/ +#define RESISTOR(x) (((x) & 0xF) << 0) /* Resistor<3:0> */ + +/* +* REG_CAPACITOR +*/ +#define CAPACITOR(x) (((x) & 0x3F) << 0) /* Capacitor<5:0> */ + +/* +* REG_LO_CM +*/ +#define LO_COMMON_MODE(x) (((x) & 0x3) << 5) /* LO Common Mode<1:0> */ + +/* +* REG_TX_BBF_TUNE_MODE +*/ +#define EVALTIME (1 << 4) /* EvalTime */ +#define TX_BBF_TUNE_DIVIDER (1 << 0) /* TX BBF Tune Divider<8> */ +#define TUNE_COMP_MASK(x) (((x) & 0x3) << 5) /* Tune Comp Mask<1:0> */ +#define TUNER_MODE(x) (((x) & 0x7) << 1) /* Tuner Mode<2:0> */ + +/* +* REG_RX_FILTER_CONFIG +*/ +#define WRITE_RX (1 << 2) /* Write Rx */ +#define START_RX_CLOCK (1 << 1) /* Start Rx Clock */ +#define NUMBER_OF_TAPS(x) (((x) & 0x7) << 5) /* Number of Taps */ +#define SELECT_RX_CH(x) (((x) & 0x3) << 3) /* Select Rx Ch<1:0> */ + +/* +* REG_RX_FILTER_GAIN +*/ +#define FILTER_GAIN(x) (((x) & 0x3) << 0) /* Filter gain<1:0> */ + +/* +* REG_AGC_CONFIG_1 +*/ +#define DEC_PWR_FOR_LOW_PWR (1 << 7) /* Dec Pwr for Low Pwr */ +#define DEC_PWR_FOR_LOCK_LEVEL (1 << 6) /* Dec Pwr for Lock Level */ +#define DEC_PWR_FOR_GAIN_LOCK_EXIT (1 << 5) /* Dec Pwr for Gain Lock Exit */ +#define SLOW_ATTACK_HYBRID_MODE (1 << 4) /* Slow Attack Hybrid Mode */ +#define RX2_GAIN_CTRL_SETUP(x) (((x) & 0x3) << 2) /* Rx 2 Gain Control Setup<1:0> */ +#define RX1_GAIN_CTRL_SETUP(x) (((x) & 0x3) << 0) /* Rx 1 Gain Control Setup<1:0> */ +#define RX_GAIN_CTL_MASK 0x03 +#define RX2_GAIN_CTRL_SHIFT 2 +#define RX1_GAIN_CTRL_SHIFT 0 +#define RX_GAIN_CTL_MGC 0x00 +#define RX_GAIN_CTL_AGC_FAST_ATK 0x01 +#define RX_GAIN_CTL_AGC_SLOW_ATK 0x02 +#define RX_GAIN_CTL_AGC_SLOW_ATK_HYBD 0x03 + +/* +* REG_AGC_CONFIG_2 +*/ +#define AGC_SOFT_RESET (1 << 7) /* Soft Reset */ +#define AGC_GAIN_UNLOCK_CTRL (1 << 6) /* Gain Unlock Control */ +#define AGC_USE_FULL_GAIN_TABLE (1 << 3) /* Use Full Gain Table */ +#define DIG_GAIN_EN (1 << 2) /* Enable Digital Gain */ +#define MAN_GAIN_CTRL_RX2 (1 << 1) /* Manual Gain Control Rx 2 */ +#define MAN_GAIN_CTRL_RX1 (1 << 0) /* Manual Gain Control Rx 1 */ + +/* +* REG_AGC_CONFIG_3 +*/ +#define INCDEC_LMT_GAIN (1 << 4) /* Inc/Dec LMT Gain */ +#define USE_AGC_FOR_LMTLPF_GAIN (1 << 3) /* Use AGC for LMT/LPF Gain */ +#define MANUAL_INCR_STEP_SIZE(x) (((x) & 0x7) << 5) /* Manual (CTRL_IN) Incr Gain Step Size<2:0> */ +#define ADC_OVERRANGE_SAMPLE_SIZE(x) (((x) & 0x7) << 0) /* ADC Overrange Sample Size<2:0> */ + +/* +* REG_MAX_LMT_FULL_GAIN +*/ +#define MAXIMUM_FULL_TABLELMT_TABLE_INDEX(x) (((x) & 0x7F) << 0) /* Maximum Full Table/LMT Table Index<6:0> */ + +/* +* REG_PEAK_WAIT_TIME +*/ +#define MANUAL_CTRL_IN_DECR_GAIN_STP_SIZE(x) (((x) & 0x7) << 5) /* Manual (CTRL_IN) Decr Gain Step Size<2:0> */ +#define PEAK_OVERLOAD_WAIT_TIME(x) (((x) & 0x1F) << 0) /* Peak Overload Wait Time<4:0> */ + +/* +* REG_DIGITAL_GAIN +*/ +#define DIG_GAIN_STP_SIZE(x) (((x) & 0x7) << 5) /* Dig Gain Step Size<2:0> */ +#define MAXIMUM_DIGITAL_GAIN(x) (((x) & 0x1F) << 0) /* Maximum Digital Gain<4:0> */ + +/* +* REG_AGC_LOCK_LEVEL +*/ +#define ENABLE_DIG_SAT_OVRG (1 << 7) /* Enable Dig Sat Ovrg */ +#define AGC_LOCK_LEVEL_FAST_AGC_INNER_HIGH_THRESH_SLOW(x) (((x) & 0x7F) << 0) /* AGC Lock Level (Fast)/ AGC Inner High Threshold (Slow) <6:0> */ + +/* +* REG_GAIN_STP_CONFIG1 +*/ +#define LMT_DETECTOR_SETTLING_TIME(x) (((x) & 0x7) << 5) /* LMT Detector Settling Time<2:0> */ +#define DEC_STP_SIZE_FOR_LARGE_LMT_OVERLOAD(x) (((x) & 0x7) << 2) /* Dec Step Size for: Large LMT Overload/ Full Table Case #3 <2:0> */ +#define ADC_NOISE_CORRECTION_FACTOR(x) (((x) & 0x3) << 0) /* ADC Noise Correction Factor<1:0> */ + +/* +* REG_GAIN_STP_CONFIG_2 +*/ +#define DECREMENT_STP_SIZE_FOR_SMALL_LPF_GAIN_CHANGE(x) (((x) & 0x7) << 4) /* Fast Attack Only. Decrement Step Size for: Small LPF Gain Change / Full Table Case #2 <2:0> */ +#define LARGE_LPF_GAIN_STEP(x) (((x) & 0xF) << 0) /* Decrement Step Size for: Large LPF Gain Change / Full Table Case #1<3:0> */ + +/* +* REG_SMALL_LMT_OVERLOAD_THRESH +*/ +#define FORCE_PD_RESET_RX2 (1 << 7) /* Force PD Reset Rx2 */ +#define FORCE_PD_RESET_RX1 (1 << 6) /* Force PD Reset Rx1 */ +#define SMALL_LMT_OVERLOAD_THRESH(x) (((x) & 0x3F) << 0) /* Small LMT Overload Threshold<5:0> */ + +/* +* REG_LARGE_LMT_OVERLOAD_THRESH +*/ +#define LARGE_LMT_OVERLOAD_THRESH(x) (((x) & 0x3F) << 0) /* Large LMT Overload Threshold<5:0> */ + +/* +* REG_RX1_MANUAL_LMT_FULL_GAIN +*/ +#define POWER_MEAS_IN_STATE_5_MSB (1 << 7) /* Power Meas in State 5 <3> */ +#define RX1_MANUAL_FULL_TABLE_LMT_TABLE_GAIN_INDEX(x) (((x) & 0x7F) << 0) /* Rx1 Manual Full table/LMT table Gain Index<6:0> */ +#define RX_FULL_TBL_IDX_MASK RX1_MANUAL_FULL_TABLE_LMT_TABLE_GAIN_INDEX(~0) + +/* +* REG_RX1_MANUAL_LPF_GAIN +*/ +#define POWER_MEAS_IN_STATE_5(x) (((x) & 0x7) << 5) /* Power Meas in State 5<2:0> */ +#define RX1_MANUAL_LPF_GAIN(x) (((x) & 0x1F) << 0) /* Rx1 Manual LPF Gain <4:0> */ +#define RX_LPF_IDX_MASK RX1_MANUAL_LPF_GAIN(~0) + +/* +* REG_RX1_MANUAL_DIGITALFORCED_GAIN +*/ +#define FORCE_RX1_DIGITAL_GAIN (1 << 5) /* Force Rx1 Digital Gain */ +#define RX1_MANUALFORCED_DIGITAL_GAIN(x) (((x) & 0x1F) << 0) /* Rx1 Manual/Forced Digital Gain<4:0> */ +#define RX_DIGITAL_IDX_MASK RX1_MANUALFORCED_DIGITAL_GAIN(~0) +/* +* REG_RX2_MANUAL_LMT_FULL_GAIN +*/ +#define RX2_MANUAL_FULL_TABLE_LMT_TABLE_GAIN_INDEX(x) (((x) & 0x7F) << 0) /* Rx2 Manual Full table/ LMT table Gain Index<6:0> */ + +/* +* REG_RX2_MANUAL_LPF_GAIN +*/ +#define RX2_MANUAL_LPF_GAIN(x) (((x) & 0x1F) << 0) /* Rx2 Manual LPF Gain<4:0> */ + +/* +* REG_RX2_MANUAL_DIGITALFORCED_GAIN +*/ +#define FORCE_RX2_DIGITAL_GAIN (1 << 5) /* Force Rx2 Digital Gain */ +#define RX2_MANUALFORCED_DIGITAL_GAIN(x) (((x) & 0x1F) << 0) /* Rx2 Manual/Forced Digital Gain<4:0> */ + +/* +* REG_FAST_CONFIG_1 +*/ +#define ENABLE_GAIN_INC_AFTER_GAIN_LOCK (1 << 7) /* Enable Gain Inc after Gain Lock */ +#define GOTO_OPT_GAIN_IF_ENERGY_LOST_OR_EN_AGC_HIGH (1 << 6) /* Goto Opt Gain if Energy Lost or EN_AGC High */ +#define GOTO_SET_GAIN_IF_EN_AGC_HIGH (1 << 5) /* Goto Set Gain if EN_AGC High */ +#define GOTO_SET_GAIN_IF_EXIT_RX_STATE (1 << 4) /* Goto Set Gain if Exit Rx State */ +#define DONT_UNLOCK_GAIN_IF_ENERGY_LOST (1 << 3) /* Don't Unlock Gain if Energy Lost */ +#define GOTO_OPTIMIZED_GAIN_IF_EXIT_RX_STATE (1 << 2) /* Goto Optimized Gain if Exit Rx State */ +#define DONT_UNLOCK_GAIN_IF_LG_ADC_OR_LMT_OVRG (1 << 1) /* Don't Unlock Gain If Lg ADC or LMT Ovrg */ +#define ENABLE_INCR_GAIN (1 << 0) /* Enable Incr Gain */ + +/* +* REG_FAST_CONFIG_2_SETTLING_DELAY +*/ +#define USE_LAST_LOCK_LEVEL_FOR_SET_GAIN (1 << 7) /* Use Last Lock Level for Set Gain */ +#define ENABLE_LMT_GAIN_INC_FOR_LOCK_LEVEL (1 << 6) /* Enable LMT Gain Inc for Lock Level */ +#define GOTO_MAX_GAIN_OR_OPT_GAIN_IF_EN_AGC_HIGH (1 << 5) /* Goto Max Gain or Opt Gain if EN_AGC High */ +#define SETTLING_DELAY(x) (((x) & 0x1F) << 0) /* Settling Delay<4:0> */ + +/* +* REG_FAST_ENERGY_LOST_THRESH +*/ +#define POST_LOCK_LEVEL_STP_SIZE_FOR_LPF_TABLE_FULL_TABLE(x) (((x) & 0x3) << 6) /* Post Lock Level Step Size for: LPF Table/ Full Table <1:0> */ +#define ENERGY_LOST_THRESH(x) (((x) & 0x3F) << 0) /* Energy lost threshold<5:0> */ + +/* +* REG_FAST_STRONGER_SIGNAL_THRESH +*/ +#define POST_LOCK_LEVEL_STP_FOR_LMT_TABLE(x) (((x) & 0x3) << 6) /* Post Lock Level Step for LMT Table <1:0> */ +#define STRONGER_SIGNAL_THRESH(x) (((x) & 0x3F) << 0) /* Stronger Signal Threshold<5:0> */ + +/* +* REG_FAST_LOW_POWER_THRESH +*/ +#define DONT_UNLOCK_GAIN_IF_ADC_OVRG (1 << 7) /* Don't unlock gain if ADC Ovrg */ +#define LOW_POWER_THRESH(x) (((x) & 0x7F) << 0) /* Low Power Threshold<6:0> */ + +/* +* REG_FAST_STRONG_SIGNAL_FREEZE +*/ +#define DONT_UNLOCK_GAIN_IF_STRONGER_SIGNAL (1 << 7) /* Don't unlock gain if Stronger Signal */ + +/* +* REG_FAST_FINAL_OVER_RANGE_AND_OPT_GAIN +*/ +#define FINAL_OVER_RANGE_COUNT(x) (((x) & 0x7) << 5) /* Final Over Range Count<2:0> */ +#define OPTIMIZE_GAIN_OFFSET(x) (((x) & 0xF) << 0) /* Optimize Gain Offset<3:0> */ + +/* +* REG_FAST_ENERGY_DETECT_COUNT +*/ +#define INCREMENT_GAIN_STP_LPFLMT(x) (((x) & 0x7) << 5) /* Increment Gain Step (LPF/LMT)<2:0> */ +#define ENERGY_DETECT_COUNT(x) (((x) & 0x1F) << 0) /* Energy Detect count<4:0> */ + +/* +* REG_FAST_AGCLL_UPPER_LIMIT +*/ +#define AGCLL_MAX_INCREASE(x) (((x) & 0x3F) << 0) /* AGCLL Max Increase<5:0> */ + +/* +* REG_FAST_GAIN_LOCK_EXIT_COUNT +*/ +#define GAIN_LOCK_EXIT_COUNT(x) (((x) & 0x3F) << 0) /* Gain Lock Exit Count<5:0> */ + +/* +* REG_FAST_INITIAL_LMT_GAIN_LIMIT +*/ +#define INITIAL_LMT_GAIN_LIMIT(x) (((x) & 0x7F) << 0) /* Initial LMT Gain Limit<6:0> */ + +/* +* REG_AGC_INNER_LOW_THRESH +*/ +#define PREVENT_GAIN_INC (1 << 7) /* Prevent Gain Inc */ +#define AGC_INNER_LOW_THRESH(x) (((x) & 0x7F) << 0) /* AGC Inner Low Threshold<6:0> */ + +/* +* REG_LMT_OVERLOAD_COUNTERS +*/ +#define LARGE_LMT_OVERLOAD_EXED_COUNTER(x) (((x) & 0xF) << 4) /* Large LMT Overload Exceeded Counter<3:0> */ +#define SMALL_LMT_OVERLOAD_EXED_COUNTER(x) (((x) & 0xF) << 0) /* Small LMT Overload Exceeded Counter<3:0> */ + +/* +* REG_ADC_OVERLOAD_COUNTERS +*/ +#define LARGE_ADC_OVERLOAD_EXED_COUNTER(x) (((x) & 0xF) << 4) /* Large ADC Overload Exceeded Counter<3:0> */ +#define SMALL_ADC_OVERLOAD_EXED_COUNTER(x) (((x) & 0xF) << 0) /* Small ADC Overload Exceeded Counter<3:0> */ + +/* +* REG_GAIN_STP1 +*/ +#define IMMED_GAIN_CHANGE_IF_LG_LMT_OVERLOAD (1 << 7) /* Immed. Gain Change if Lg LMT Overload */ +#define IMMED_GAIN_CHANGE_IF_LG_ADC_OVERLOAD (1 << 3) /* Immed. Gain Change if Lg ADC Overload */ +#define AGC_INNER_HIGH_THRESH_EXED_STP_SIZE(x) (((x) & 0x7) << 4) /* AGC Inner High Threshold Exceeded Step Size<2:0> */ +#define AGC_INNER_LOW_THRESH_EXED_STP_SIZE(x) (((x) & 0x7) << 0) /* AGC Inner Low Threshold Exceeded Step Size<2:0> */ + +/* +* REG_DIGITAL_SAT_COUNTER +*/ +#define DOUBLE_GAIN_COUNTER (1 << 5) /* Double Gain Counter */ +#define ENABLE_SYNC_FOR_GAIN_COUNTER (1 << 4) /* Enable Sync for Gain Counter */ +#define DIG_SATURATION_EXED_COUNTER(x) (((x) & 0xF) << 0) /* Dig Saturation Exceeded Counter<3:0> */ + +/* +* REG_OUTER_POWER_THRESHS +*/ +#define AGC_OUTER_HIGH_THRESH(x) (((x) & 0xF) << 4) /* AGC Outer High Threshold<3:0> */ +#define AGC_OUTER_LOW_THRESH(x) (((x) & 0xF) << 0) /* AGC Outer Low Threshold<3:0> */ + +/* +* REG_GAIN_STP_2 +*/ +#define AGC_OUTER_HIGH_THRESH_EXED_STP_SIZE(x) (((x) & 0xF) << 4) /* AGC outer High Threshold Exceeded Step Size<3:0> */ +#define AGC_OUTER_LOW_THRESH_EXED_STP_SIZE(x) (((x) & 0xF) << 0) /* AGC Outer Low Threshold Exceeded Step Size<3:0> */ + +/* +* REG_EXT_LNA_HIGH_GAIN +*/ +#define EXT_LNA_HIGH_GAIN(x) (((x) & 0x3F) << 0) /* Ext LNA High Gain<5:0> */ + +/* +* REG_EXT_LNA_LOW_GAIN +*/ +#define EXT_LNA_LOW_GAIN(x) (((x) & 0x3F) << 0) /* Ext LNA Low Gain<5:0> */ + +/* +* REG_GAIN_TABLE_ADDRESS +*/ +#define GAIN_TABLE_ADDRESS(x) (((x) & 0x7F) << 0) /* Gain Table Address<6:0> */ + +/* +* REG_GAIN_TABLE_WRITE_DATA1 +*/ +#define EXT_LNA_CTRL (1 << 7) /* Ext LNA Ctrl */ +#define LNA_GAIN(x) (((x) & 0x3) << 5) /* LNA Gain <1:0> */ +#define MIXER_GM_GAIN(x) (((x) & 0x1F) << 0) /* Mixer Gm Gain <4:0> */ + +/* +* REG_GAIN_TABLE_WRITE_DATA2 +*/ +#define TIA_GAIN (1 << 5) /* TIA Gain */ +#define LPF_GAIN(x) (((x) & 0x1F) << 0) /* LPF Gain <4:0> */ + +/* +* REG_GAIN_TABLE_WRITE_DATA_3 +*/ +#define RF_DC_CAL (1 << 5) /* RF DC Cal */ +#define DIGITAL_GAIN(x) (((x) & 0x1F) << 0) /* Digital Gain <4:0> */ + +/* +* REG_GAIN_TABLE_READ_DATA_1 +*/ +#define TO_LNA_GAIN(x) (((x) >> 5) & 0x3) /* LNA Gain <1:0> */ +#define TO_MIXER_GM_GAIN(x) (((x) >> 0) & 0x1F) /* Mixer Gm Gain <4:0> */ + +/* +* REG_GAIN_TABLE_READ_DATA_2 +*/ +#define TO_LPF_GAIN(x) (((x) >> 0) & 0x1F) /* LPF Gain <4:0> */ + +/* +* REG_GAIN_TABLE_READ_DATA_3 +*/ +#define TO_DIGITAL_GAIN(x) (((x) >> 0) & 0x1F) /* Digital Gain <4:0> */ + +/* +* REG_GAIN_TABLE_CONFIG +*/ +#define WRITE_GAIN_TABLE (1 << 2) /* Write Gain Table */ +#define START_GAIN_TABLE_CLOCK (1 << 1) /* Start Gain Table Clock */ +#define RECEIVER_SELECT(x) (((x) & 0x3) << 3) /* Receiver Select<1:0> */ +#define GT_RX1 1 +#define GT_RX2 2 + + +/* +* REG_GM_SUB_TABLE_GAIN_WRITE +*/ +#define GM_SUB_TABLE_GAIN_WRITE(x) (((x) & 0x7F) << 0) /* Gm Sub Table Gain Word Write<6:0> */ + +/* +* REG_GM_SUB_TABLE_BIAS_WRITE +*/ +#define GM_SUB_TABLE_BIAS_WRITE(x) (((x) & 0x1F) << 0) /* Gm Sub Table Bias Word Write<4:0> */ + +/* +* REG_GM_SUB_TABLE_CTRL_WRITE +*/ +#define GM_SUB_TABLE_CTRL_WRITE(x) (((x) & 0x3F) << 0) /* Gm Sub Table Control Word Write<5:0> */ + +/* +* REG_GM_SUB_TABLE_GAIN_READ +*/ +#define GM_SUB_TABLE_GAIN_READ(x) (((x) & 0x7F) << 0) /* Gm Sub Table Gain Word Read<6:0> */ + +/* +* REG_GM_SUB_TABLE_BIAS_READ +*/ +#define GM_SUB_TABLE_BIAS_READ(x) (((x) & 0x1F) << 0) /* Gm Sub Table Bias Word Read<4:0> */ + +/* +* REG_GM_SUB_TABLE_CTRL_READ +*/ +#define GM_SUB_TABLE_CTRL_READ(x) (((x) & 0x3F) << 0) /* Gm Sub Table Control Word Read<5:0> */ + +/* +* REG_GM_SUB_TABLE_CONFIG +*/ +#define WRITE_GM_SUB_TABLE (1 << 2) /* Write Gm Sub Table */ +#define START_GM_SUB_TABLE_CLOCK (1 << 1) /* Start Gm Sub Table Clock */ + +/* +* REG_GAIN_DIFF_WORDERROR_WRITE +*/ +#define CALIB_TABLE_GAIN_DIFFERROR_WORD(x) (((x) & 0x3F) << 0) /* Calib Table Gain Diff/Error Word<5:0> */ + +/* +* REG_GAIN_ERROR_READ +*/ +#define CALIB_TABLE_GAIN_ERROR(x) (((x) & 0x1F) << 0) /* Calib Table Gain Error<4:0> */ + +/* +* REG_CONFIG +*/ +#define READ_SELECT (1 << 4) /* Read Select */ +#define WRITE_MIXER_ERROR_TABLE (1 << 3) /* Write Mixer Error Table */ +#define WRITE_LNA_ERROR_TABLE (1 << 2) /* Write LNA Error Table */ +#define WRITE_LNA_GAIN_DIFF (1 << 1) /* Write LNA Gain Diff */ +#define START_CALIB_TABLE_CLOCK (1 << 0) /* Start Calib Table Clock */ +#define CALIB_TABLE_SELECT(x) (((x) & 0x3) << 5) /* Calib Table Select<1:0> */ + +/* +* REG_LNA_GAIN_DIFF_READ_BACK +*/ +#define LNA_CALIB_TABLE_GAIN_DIFFERENCE_WORD(x) (((x) & 0x3F) << 0) /* LNA Calib Table Gain Difference Word<5:0> */ + +/* +* REG_MAX_MIXER_CALIBRATION_GAIN_INDEX +*/ +#define MAX_MIXER_CALIBRATION_GAIN_INDEX(x) (((x) & 0x1F) << 0) /* Max Mixer Calibration Gain Index<4:0> */ + +/* +* REG_SETTLE_TIME +*/ +#define ENABLE_DIG_GAIN_CORR (1 << 7) /* Enable Dig Gain Corr */ +#define FORCE_TEMP_SENSOR_FOR_CAL (1 << 6) /* Force Temp Sensor for Cal */ +#define SETTLE_TIME(x) (((x) & 0x3F) << 0) /* Settle Time<5:0> */ + +/* +* REG_MEASURE_DURATION +*/ +#define GAIN_CAL_MEAS_DURATION(x) (((x) & 0xF) << 0) /* Gain Cal Meas Duration<3:0> */ + +/* +* REG_MEASURE_DURATION_01 +*/ +#define MEASUREMENT_DURATION_1(x) (((x) & 0xF) << 4) /* Measurement duration 1 <3:0> */ +#define MEASUREMENT_DURATION_0(x) (((x) & 0xF) << 0) /* Measurement duration 0 <3:0> */ + +/* +* REG_MEASURE_DURATION_23 +*/ +#define MEASUREMENT_DURATION_3(x) (((x) & 0xF) << 4) /* Measurement duration 3 <3:0> */ +#define MEASUREMENT_DURATION_2(x) (((x) & 0xF) << 0) /* Measurement duration 2 <3:0> */ + +/* +* REG_RSSI_CONFIG +*/ +#define START_RSSI_MEAS (1 << 5) /* Start RSSI Meas (Mode 4) */ +#define ENABLE_ADC_POWER_MEAS (1 << 1) /* Enable ADC Power Meas. */ +#define DEFAULT_RSSI_MEAS_MODE (1 << 0) /* Default RSSI Meas Mode */ +#define RFIR_FOR_RSSI_MEASUREMENT(x) (((x) & 0x3) << 6) /* RFIR for RSSI measurement<1:0> */ +#define RSSI_MODE_SELECT(x) (((x) & 0x7) << 2) /* RSSI Mode Select<2:0> */ + +/* +* REG_ADC_MEASURE_DURATION_01 +*/ +#define ADC_POWER_MEASUREMENT_DURATION_1(x) (((x) & 0xF) << 4) /* ADC Power Measurement Duration 1<3:0> */ +#define ADC_POWER_MEASUREMENT_DURATION_0(x) (((x) & 0xF) << 0) /* ADC Power Measurement Duration 0 <3:0> */ + +/* +* REG_DEC_POWER_MEASURE_DURATION_0 +*/ +#define USE_HB3_OUT_FOR_ADC_PWR_MEAS (1 << 7) /* Use HB3 Out for ADC Pwr Meas */ +#define USE_HB1_OUT_FOR_DEC_PWR_MEAS (1 << 6) /* Use HB1 Out for Dec pwr Meas */ +#define ENABLE_DEC_PWR_MEAS (1 << 5) /* Enable Dec Pwr Meas */ +#define DEFAULT_MODE_ADC_POWER (1 << 4) /* Default Mode ADC Power */ +#define DEC_POWER_MEASUREMENT_DURATION(x) (((x) & 0xF) << 0) /* Dec Power Measurement Duration <3:0> */ + +/* +* REG_LNA_GAIN +*/ +#define DB_GAIN_READBACK_CHANNEL (1 << 0) /* dB Gain Read-back Channel */ +#define MAX_LNA_GAIN(x) (((x) & 0x7F) << 1) /* Max LNA Gain<6:0> */ + +/* +* REG_RX_QUAD_CAL_LEVEL +*/ +#define RX_QUAD_CAL_LEVEL(x) (((x) & 0xF) << 0) /* Rx Quad Cal Level <3 :0> */ + +/* +* REG_CALIBRATION_CONFIG_1 +*/ +#define ENABLE_PHASE_CORR (1 << 7) /* Enable Phase Corr */ +#define ENABLE_GAIN_CORR (1 << 6) /* Enable Gain Corr */ +#define USE_SETTLE_COUNT_FOR_DC_CAL_WAIT (1 << 5) /* Use Settle Count for DC Cal Wait */ +#define FIXED_DC_CAL_WAIT_TIME (1 << 4) /* Fixed DC Cal Wait Time */ +#define FREE_RUN_MODE (1 << 3) /* Free Run Mode */ +#define ENABLE_CORR_WORD_DECIMATION (1 << 2) /* Enable Corr Word Decimation */ +#define ENABLE_TRACKING_MODE_CH2 (1 << 1) /* Enable Tracking Mode CH2 */ +#define ENABLE_TRACKING_MODE_CH1 (1 << 0) /* Enable Tracking Mode CH1 */ + +/* +* REG_CALIBRATION_CONFIG_2 +*/ +#define SOFT_RESET (1 << 7) /* Soft Reset */ +#define CALIBRATION_CONFIG2_DFLT (0x3 << 5) /* Must be 2'b11 */ +#define K_EXP_PHASE(x) (((x) & 0x1F) << 0) /* K exp Phase<4:0> */ + +/* +* REG_CALIBRATION_CONFIG_3 +*/ +#define PREVENT_POS_LOOP_GAIN (1 << 7) /* Prevent Pos Loop Gain */ +#define K_EXP_AMPLITUDE(x) (((x) & 0x1F) << 0) /* K exp Amplitude<4:0> */ + +/* +* REG_RX_QUAD_GAIN1 +*/ +#define RX_FULL_TABLELMT_TABLE_GAIN(x) (((x) & 0x7F) << 0) /* Rx Full table/LMT table gain<6:0> */ + +/* +* REG_RX_QUAD_GAIN2 +*/ +#define CORRECTION_WORD_DECIMATION_M(x) (((x) & 0x7) << 5) /* Correction Word Decimation M<2:0> */ +#define RX_LPF_GAIN(x) (((x) & 0x1F) << 0) /* Rx LPF gain<4:0> */ + +/* +* REG_RX1_INPUT_A_OFFSETS +*/ +#define RX1_INPUT_A_I_DC_OFFSET_LSB(x) (((x) & 0x3F) << 2) /* Rx1 Input A "I" DC Offset<5:0> */ +#define RX1_INPUT_A_Q_DC_OFFSET(x) (((x) & 0x3) << 0) /* Rx1 Input A "Q" DC Offset<9:8> */ + +/* +* REG_INPUT_A_OFFSETS_1 +*/ +#define RX2_INPUT_A_Q_DC_OFFSET_LSB(x) (((x) & 0xF) << 4) /* Rx2 Input A "Q" DC Offset<3:0> */ +#define RX1_INPUT_A_I_DC_OFFSET_MSB(x) (((x) & 0xF) << 0) /* Rx1 Input A "I" DC Offset<9:6> */ + +/* +* REG_RX2_INPUT_A_OFFSETS +*/ +#define RX2_INPUT_A_I_DC_OFFSET(x) (((x) & 0x3) << 6) /* Rx2 Input A "I" DC Offset<1:0> */ +#define RX2_INPUT_A_Q_DC_OFFSET_MSB(x) (((x) & 0x3F) << 0) /* Rx2 Input A "Q" DC Offset<9:4> */ + +/* +* REG_RX1_INPUT_BC_OFFSETS +*/ +#define RX1_INPUT_BC_I_DC_OFFSET_LSB(x) (((x) & 0x3F) << 2) /* Rx1 Input B&C "I" DC Offset<5:0> */ +#define RX1_INPUT_BC_Q_DC_OFFSET(x) (((x) & 0x3) << 0) /* Rx1 Input B&C "Q" DC Offset<9:8> */ + +/* +* REG_INPUT_BC_OFFSETS_1 +*/ +#define RX2_INPUT_BC_Q_DC_OFFSET_LSB(x) (((x) & 0xF) << 4) /* Rx2 Input B&C "Q" DC Offset<3:0> */ +#define RX1_INPUT_BC_I_DC_OFFSET_MSB(x) (((x) & 0xF) << 0) /* Rx1 Input B&C "I" DC Offset<9:6> */ + +/* +* REG_RX2_INPUT_BC_OFFSETS +*/ +#define RX2_INPUT_BC_I_DC_OFFSET(x) (((x) & 0x3) << 6) /* Rx2 Input B&C "I" DC Offset<1:0> */ +#define RX2_INPUT_BC_Q_DC_OFFSET_MSB(x) (((x) & 0x3F) << 0) /* Rx2 Input B&C "Q" DC Offset<9:4> */ + +/* +* REG_FORCE_BITS +*/ +#define RX2_INPUT_BC_FORCE_OFFSET (1 << 7) /* Rx2 Input B&C Force offset */ +#define RX1_INPUT_BC_FORCE_OFFSET (1 << 6) /* Rx1 Input B&C Force offset */ +#define RX2_INPUT_BC_FORCE_PHGAIN (1 << 5) /* Rx2 Input B&C Force Ph/Gain */ +#define RX1_INPUT_BC_FORCE_PHGAIN (1 << 4) /* Rx1 Input B&C Force Ph/Gain */ +#define RX2_INPUT_A_FORCE_OFFSET (1 << 3) /* Rx2 Input A Force offset */ +#define RX1_INPUT_A_FORCE_OFFSET (1 << 2) /* Rx1 Input A Force offset */ +#define RX2_INPUT_A_FORCE_PHGAIN (1 << 1) /* Rx2 Input A Force Ph/Gain */ +#define RX1_INPUT_A_FORCE_PHGAIN (1 << 0) /* Rx1 Input A Force Ph/Gain */ + +/* +* REG_RF_DC_OFFSET_CONFIG_1 +*/ +#define DAC_FS(x) (((x) & 0x3) << 4) /* DAC FS<1:0> */ +#define RF_DC_CALIBRATION_COUNT(x) (((x) & 0xF) << 0) /* RF DC Calibration Count<3:0> */ + +/* +* REG_RF_DC_OFFSET_ATTEN +*/ +#define RF_DC_OFFSET_TABLE_UPDATE_COUNT(x) (((x) & 0x7) << 5) /* RF DC Offset Table Update Count<2:0> */ +#define RF_DC_OFFSET_ATTEN(x) (((x) & 0x1F) << 0) /* RF DC Offset Attenuation<4:0> */ + +/* +* REG_INVERT_BITS +*/ +#define INVERT_RX2_RF_DC_CGIN_WORD (1 << 7) /* Invert Rx2 RF DC CGin Word */ +#define INVERT_RX1_RF_DC_CGIN_WORD (1 << 6) /* Invert Rx1 RF DC CGin Word */ +#define INVERT_RX2_RF_DC_CGOUT_WORD (1 << 5) /* Invert Rx2 RF DC CGout Word */ +#define INVERT_RX1_RF_DC_CGOUT_WORD (1 << 4) /* Invert Rx1 RF DC CGout Word */ + +/* +* REG_DC_OFFSET_CONFIG2 +*/ +#define USE_WAIT_COUNTER_FOR_RF_DC_INIT_CAL (1 << 7) /* Use Wait Counter for RF DC Init Cal */ +#define ENABLE_FAST_SETTLE_MODE (1 << 6) /* Enable Fast Settle Mode */ +#define ENABLE_BB_DC_OFFSET_TRACKING (1 << 5) /* Enable BB DC Offset Tracking */ +#define RESET_ACC_ON_GAIN_CHANGE (1 << 4) /* Reset Acc on Gain Change */ +#define ENABLE_RF_OFFSET_TRACKING (1 << 3) /* Enable RF Offset Tracking */ +#define DC_OFFSET_UPDATE(x) (((x) & 0x7) << 0) /* DC Offset Update<2:0> */ + +/* +* REG_RF_CAL_GAIN_INDEX +*/ +#define RF_MINIMUM_CALIBRATION_GAIN_INDEX(x) (((x) & 0x7F) << 0) /* RF Minimum Calibration Gain Index<6:0> */ + +/* +* REG_SOI_THRESH +*/ +#define RF_SOI_THRESH(x) (((x) & 0x7F) << 0) /* RF SOI Threshold<6:0> */ + +/* +* REG_BB_DC_OFFSET_SHIFT +*/ +#define INCREASE_COUNT_DURATION (1 << 7) /* Increase Count Duration */ +#define BB_TRACKING_DECIMATE(x) (((x) & 0x3) << 5) /* BB Tracking Decimate<1:0> */ +#define BB_DC_M_SHIFT(x) (((x) & 0x1F) << 0) /* BB DC M Shift<4:0> */ + +/* +* REG_BB_DC_OFFSET_FAST_SETTLE_SHIFT +*/ +#define READ_BACK_CH_SEL (1 << 7) /* Read Back CH Sel */ +#define UPDATE_TRACKING_WORD (1 << 6) /* Update Tracking Word */ +#define FORCE_RX_NULL (1 << 5) /* Force Rx Null */ +#define BB_DC_TRACKING_FAST_SETTLE_M_SHIFT(x) (((x) & 0x1F) << 0) /* BB DC Tracking Fast Settle M Shift<4:0> */ + +/* +* REG_BB_DC_OFFSET_ATTEN +*/ +#define BB_DC_OFFSET_ATTEN(x) (((x) & 0xF) << 0) /* BB DC Offset Atten<3:0> */ + +/* +* REG_RX1_BB_DC_WORD_I_MSB +*/ +#define RX1_BB_DC_OFFSET_CORRECTION_WORD_I(x) (((x) & 0x7F) << 0) /* RX1 BB DC Offset Correction word I<14:8> */ + +/* +* REG_RX1_BB_DC_WORD_Q_MSB +*/ +#define RX1_BB_DC_OFFSET_CORRECTION_WORD_Q(x) (((x) & 0x7F) << 0) /* RX1 BB DC Offset Correction word Q<14:8> */ + +/* +* REG_RX2_BB_DC_WORD_I_MSB +*/ +#define RX2_BB_DC_OFFSET_CORRECTION_WORD_I(x) (((x) & 0x7F) << 0) /* RX2 BB DC Offset Correction word I<14:8> */ + +/* +* REG_RX2_BB_DC_WORD_Q_MSB +*/ +#define RX2_BB_DC_OFFSET_CORRECTION_WORD_Q(x) (((x) & 0x7F) << 0) /* RX2 BB DC Offset Correction word Q<14:8> */ + +/* +* REG_BB_TRACK_CORR_WORD_I_MSB +*/ +#define RX1RX2_BB_DC_OFFSET_TRACKING_CORRECTION_WORD_I(x) (((x) & 0x7F) << 0) /* RX1/RX2 BB DC Offset Tracking correction word I<14:8> */ + +/* +* REG_BB_TRACK_CORR_WORD_Q_MSB +*/ +#define RX1RX2_BB_DC_OFFSET_TRACKING_CORRECTION_WORD_Q(x) (((x) & 0x7F) << 0) /* RX1/RX2 BB DC Offset Tracking correction word Q<14:8> */ + +/* +* REG_SYMBOL_LSB +*/ +#define RX2_RSSI_SYMBOL (1 << 1) /* Rx2 RSSI symbol <0> */ +#define RX1_RSSI_SYMBOL (1 << 0) /* Rx1 RSSI symbol <0> */ + +/* +* REG_PREAMBLE_LSB +*/ +#define RX2_RSSI_PREAMBLE (1 << 1) /* Rx2 RSSI preamble <0> */ +#define RX1_RSSI_PREAMBLE (1 << 0) /* Rx1 RSSI preamble <0> */ + +/* +* REG_RX1_RSSI_SYMBOL, REG_RX1_RSSI_PREAMBLE, +* REG_RX2_RSSI_SYMBOL, REG_RX2_RSSI_PREAMBLE +*/ +#define RSSI_LSB_SHIFT 1 +#define RSSI_LSB_MASK1 0x01 +#define RSSI_LSB_MASK2 0x02 + +/* +* REG_RX_PATH_GAIN_LSB +*/ +#define RX_PATH_GAIN (1 << 0) /* Rx Path Gain<0> */ + +/* +* REG_RX_DIFF_LNA_FORCE +*/ +#define FORCE_RX2_LNA_GAIN (1 << 7) /* Force Rx2 LNA Gain */ +#define RX2_LNA_BYPASS (1 << 6) /* Rx2 LNA Bypass */ +#define FORCE_RX1_LNA_GAIN (1 << 3) /* Force Rx1 LNA Gain */ +#define RX1_LNA_BYPASS (1 << 2) /* Rx1 LNA Bypass */ +#define RX2_LNA_GAIN(x) (((x) & 0x3) << 4) /* Rx2 LNA Gain<1:0> */ +#define RX1_LNA_GAIN(x) (((x) & 0x3) << 0) /* Rx1 LNA Gain<1:0> */ + +/* +* REG_RX_LNA_BIAS_COARSE +*/ +#define RX_LNA_BIAS_COARSE(x) (((x) & 0xF) << 0) /* Rx LNA Bias Coarse<3:0> */ + +/* +* REG_RX_LNA_BIAS_FINE_0 +*/ +#define RX_LNA_PCASCODE_BIAS(x) (((x) & 0x7) << 5) /* Rx LNA p-Cascode Bias<2:0> */ +#define RX_LNA_BIAS(x) (((x) & 0x1F) << 0) /* Rx LNA Bias<4:0> */ + +/* +* REG_RX_LNA_BIAS_FINE_1 +*/ +#define RX_LNA_P_CASCODE_BIAS_FINE(x) (((x) & 0x3) << 0) /* Rx LNA p- Cascode Bias Fine<4:3> */ + +/* +* REG_RX_MIX_GM_CONFIG +*/ +#define RX_MIX_GM_CM_OUT(x) (((x) & 0x7) << 5) /* Rx Mix Gm CM Out<2:0> */ +#define RX_MIX_GM_PLOAD(x) (((x) & 0x3) << 0) /* Rx Mix Gm pload <1:0> */ + +/* +* REG_RX1_MIX_GM_FORCE +*/ +#define FORCE_RX1_MIX_GM (1 << 6) /* Force Rx1 Mix Gm */ +#define RX1_MIX_GM_GAIN(x) (((x) & 0x3F) << 0) /* Rx1 Mix Gm Gain<5:0> */ + +/* +* REG_RX1_MIX_GM_BIAS_FORCE +*/ +#define RX1_MIX_GM_BIAS(x) (((x) & 0x1F) << 0) /* Rx1 Mix Gm Bias<4:0> */ + +/* +* REG_RX2_MIX_GM_FORCE +*/ +#define FORCE_RX2_MIX_GM (1 << 6) /* Force Rx2 Mix Gm */ +#define RX2_MIX_GM_GAIN(x) (((x) & 0x3F) << 0) /* Rx2 Mix Gm Gain<5:0> */ + +/* +* REG_RX2_MIX_GM_BIAS_FORCE +*/ +#define RX2_MIX_GM_BIAS(x) (((x) & 0x1F) << 0) /* Rx2 Mix Gm Bias<4:0> */ + +/* +* REG_INPUT_A_MSBS +*/ +#define INPUT_A_RX1_Q(x) (((x) & 0x3) << 6) /* Input A RX1 Q<9:8> */ +#define INPUT_A_RX1_I(x) (((x) & 0x3) << 4) /* Input A RX1 I<9:8> */ +#define INPUT_A_RX2_I(x) (((x) & 0x3) << 2) /* Input A RX2 I<9:8> */ +#define INPUT_A_RX2_Q(x) (((x) & 0x3) << 0) /* Input A RX2 Q<9:8> */ + +/* +* REG_INPUTS_BC_MSBS +*/ +#define INPUTS_BC_RX1_Q(x) (((x) & 0x3) << 6) /* Inputs B&C RX1 Q<9:8> */ +#define INPUTS_BC_RX1_I(x) (((x) & 0x3) << 4) /* Inputs B&C RX1 I<9:8> */ +#define INPUTS_BC_RX2_I(x) (((x) & 0x3) << 2) /* Inputs B&C RX2 I<9:8> */ +#define INPUTS_BC_RX2_Q(x) (((x) & 0x3) << 0) /* Inputs B&C RX2 Q<9:8> */ + +/* +* REG_FORCE_OS_DAC +*/ +#define FORCE_CGIN_DAC (1 << 2) /* Force CGin DAC */ + +/* +* REG_RX_MIX_LO_CM +*/ +#define RX_MIX_LO_CM(x) (((x) & 0x3F) << 0) /* Rx Mix LO CM<5:0> */ + +/* +* REG_RX_CGB_SEG_ENABLE +*/ +#define RX_CGB_SEG_ENABLE(x) (((x) & 0x3F) << 0) /* Rx CGB Seg Enable<5:0> */ + +/* +* REG_RX_MIX_INPUTBIAS +*/ +#define RX_CGB_INPUT_CM_SEL(x) (((x) & 0x3) << 4) /* Rx CGB Input CM Sel<1:0> */ +#define RX_CGB_BIAS(x) (((x) & 0xF) << 0) /* Rx CGB Bias<3:0> */ + +/* +* REG_RX_TIA_CONFIG +*/ +#define TIA2_OVERRIDE_C (1 << 3) /* TIA2 Override C */ +#define TIA2_OVERRIDE_R (1 << 2) /* TIA2 Override R */ +#define TIA1_OVERRIDE_C (1 << 1) /* TIA1 Override C */ +#define TIA1_OVERRIDE_R (1 << 0) /* TIA1 Override R */ +#define TIA_SEL_CC(x) (((x) & 0x7) << 5) /* TIA Sel CC<2:0> */ + +/* +* REG_TIA1_C_LSB +*/ +#define TIA1_RF(x) (((x) & 0x3) << 6) /* TIA1 RF<1:0> */ +#define TIA1_C_LSB(x) (((x) & 0x3F) << 0) /* TIA1 C LSB<5:0> */ + +/* +* REG_TIA1_C_MSB +*/ +#define TIA1_C_MSB(x) (((x) & 0x7F) << 0) /* TIA1 C MSB<6:0> */ + +/* +* REG_TIA2_C_LSB +*/ +#define TIA2_RF(x) (((x) & 0x3) << 6) /* TIA2 RF<1:0> */ +#define TIA2_C_LSB(x) (((x) & 0x3F) << 0) /* TIA2 C LSB<5:0> */ + +/* +* REG_TIA2_C_MSB +*/ +#define TIA2_C_MSB(x) (((x) & 0x7F) << 0) /* TIA2 C MSB<6:0> */ + +/* +* REG_RX1_BBF_R1A +*/ +#define FORCE_RX1_RESISTORS (1 << 7) /* Force Rx1 Resistors */ +#define RX1_BBF_R1A(x) (((x) & 0x3F) << 0) /* Rx1 BBF R1A<5:0> */ + +/* +* REG_RX2_BBF_R1A +*/ +#define FORCE_RX2_RESISTORS (1 << 7) /* Force Rx2 Resistors */ +#define RX2_BBF_R1A(x) (((x) & 0x3F) << 0) /* Rx2 BBF R1A<5:0> */ + +/* +* REG_RX1_TUNE_CTRL +*/ +#define RX1_TUNE_RESAMPLE_PHASE (1 << 2) /* Rx1 Tune Resample Phase */ +#define RX1_TUNE_RESAMPLE (1 << 1) /* Rx1 Tune Resample */ +#define RX1_PD_TUNE (1 << 0) /* Rx1 PD Tune */ + +/* +* REG_RX2_TUNE_CTRL +*/ +#define RX2_TUNE_RESAMPLE_PHASE (1 << 2) /* Rx2 Tune Resam ple Phase */ +#define RX2_TUNE_RESAMPLE (1 << 1) /* Rx2 Tune Resample */ +#define RX2_PD_TUNE (1 << 0) /* Rx2 PD Tune */ + +/* +* REG_RX_BBF_R2346 +*/ +#define TUNE_OVERRIDE (1 << 7) /* Tune Override */ +#define RX_BBF_R2346(x) (((x) & 0x7) << 0) /* Rx BBF R2346<2:0> */ + +/* +* REG_RX_BBF_C1_MSB +*/ +#define RX_BBF_C1_MSB(x) (((x) & 0x3F) << 0) /* Rx BBF C1 MSB<5:0> */ + +/* +* REG_RX_BBF_C1_LSB +*/ +#define RX_BBF_C1_LSB(x) (((x) & 0x7F) << 0) /* Rx BBF C1 LSB<6:0> */ + +/* +* REG_RX_BBF_C2_MSB +*/ +#define RX_BBF_C2_MSB(x) (((x) & 0x3F) << 0) /* Rx BBF C2 MSB<5:0> */ + +/* +* REG_RX_BBF_C2_LSB +*/ +#define RX_BBF_C2_LSB(x) (((x) & 0x7F) << 0) /* Rx BBF C2 LSB<6:0> */ + +/* +* REG_RX_BBF_C3_MSB +*/ +#define RX_BBF_C3_MSB(x) (((x) & 0x3F) << 0) /* Rx BBF C3 MSB<5:0> */ + +/* +* REG_RX_BBF_C3_LSB +*/ +#define RX_BBF_C3_LSB(x) (((x) & 0x7F) << 0) /* Rx BBF C3 LSB<6:0> */ + +/* +* REG_RX_BBF_CC1_CTR +*/ +#define RX_BBF_CC1_CTR(x) (((x) & 0x7F) << 0) /* Rx BBF CC1 Ctr<6:0> */ + +/* +* REG_RX_BBF_POW_RZ_BYTE0 +*/ +#define MUST_BE_ZERO (1 << 7) /* Must be zero */ +#define RX1_BBF_POW_CTR(x) (((x) & 0x3) << 5) /* Rx1 BBF Pow Ctr<1:0> */ +#define RX_BBF_RZ1_CTR(x) (((x) & 0x3) << 3) /* Rx BBF Rz1 Ctr<1:0> */ + +/* +* REG_RX_BBF_CC2_CTR +*/ +#define RX_BBF_CC2_CTR(x) (((x) & 0x7F) << 0) /* Rx BBF CC2 Ctr<6:0> */ + +/* +* REG_RX_BBF_POW_RZ_BYTE1 +*/ +#define RX_BBF_POW3_CTR(x) (((x) & 0x3) << 6) /* Rx BBF Pow3 Ctr<1:0> */ +#define RX_BBF_RZ3_CTR(x) (((x) & 0x3) << 4) /* Rx BBF RZ3 Ctr<1:0> */ +#define RX_BBF_POW2_CTR(x) (((x) & 0x3) << 2) /* Rx BBF Pow2 Ctr<1:0> */ +#define RX_BBF_RZ2_CTR(x) (((x) & 0x3) << 0) /* Rx BBF Rz2 Ctr<1:0> */ + +/* +* REG_RX_BBF_CC3_CTR +*/ +#define RX_BBF_CC3_CTR(x) (((x) & 0x7F) << 0) /* Rx BBF CC3 Ctr<6:0> */ + +/* +* REG_RX_BBF_TUNE +*/ +#define RXBBF_BYPASS_BIAS_R (1 << 7) /* RxBBF Bypass Bias R */ +#define RX_BBF_R5_TUNE (1 << 4) /* Rx BBF R5 Tune */ +#define RX1_BBF_TUNE_COMP_I (1 << 3) /* Rx1 BBF Tune Comp I */ +#define RX1_BBF_TUNE_COMP_Q (1 << 2) /* Rx1 BBF Tune Comp Q */ +#define RX2_BBF_TUNE_COMP_I (1 << 1) /* Rx2 BBF Tune Comp I */ +#define RX2_BBF_TUNE_COMP_Q (1 << 0) /* Rx2 BBF Tune Comp Q */ +#define RX_BBF_TUNE_CTR(x) (((x) & 0x3) << 5) /* Rx BBF Tune Ctr<1:0> */ + +/* +* REG_RX1_BBF_MAN_GAIN +*/ +#define RX1_BBF_FORCE_GAIN (1 << 5) /* Rx1 BBF Force Gain */ +#define RX1_BBF_BQ_GAIN(x) (((x) & 0x3) << 3) /* Rx1 BBF BQ Gain<1:0> */ +#define RX1_BBF_POLE_GAIN(x) (((x) & 0x7) << 0) /* Rx1 BBF Pole Gain<2:0> */ + +/* +* REG_RX2_BBF_MAN_GAIN +*/ +#define RX2_BBF_FORCE_GAIN (1 << 5) /* Rx2 BBF Force Gain */ +#define RX2_BBF_BQ_GAIN(x) (((x) & 0x3) << 3) /* Rx2 BBF BQ Gain<1:0> */ +#define RX2_BBF_POLE_GAIN(x) (((x) & 0x7) << 0) /* Rx2 BBF Pole Gain<2:0> */ + +/* +* REG_RX_BBF_TUNE_CONFIG +*/ +#define RX_TUNE_EVALTIME (1 << 4) /* Rx Tune Evaltime */ +#define RX_BBF_TUNE_DIVIDE (1 << 0) /* RX BBF Tune Divide<8> */ +#define TUNE_COMP_MASK(x) (((x) & 0x3) << 5) /* Tune Comp Mask <1:0> */ +#define RX_TUNE_MODE(x) (((x) & 0x7) << 1) /* Rx Tune Mode<2:0> */ + +/* +* REG_POLE_GAIN +*/ +#define POLE_GAIN_TUNE(x) (((x) & 0x3) << 0) /* Pole Gain Tune<1:0> */ + +/* +* REG_RX_BBBW_MHZ +*/ +#define RX_TUNE_BBBW_MHZ(x) (((x) & 0x1F) << 0) /* Rx Tune BBBW MHz<4::0> */ + +/* +* REG_RX_BBBW_KHZ +*/ +#define RX_TUNE_BBBW_KHZ(x) (((x) & 0x7F) << 0) /* Rx Tune BBBW kHz<6:0> */ + +/* +* REG_RX_PFD_CONFIG +*/ +#define BYPASS_LD_SYNTH (1 << 0) /* Bypass Ld Synth */ + +/* +* REG_RX_INTEGER_BYTE_1 +*/ +#define SYNTH_INTEGER_WORD(x) (((x) & 0x7) << 0) /* Synthesizer Integer Word<10:8> */ + +/* +* REG_RX_FRACT_BYTE_2 +*/ +#define SYNTH_FRACT_WORD(x) (((x) & 0x7F) << 0) /* Synthesizer Fractional Word <22:16> */ + +/* +* REG_RX_FORCE_VCO_TUNE_1 +*/ +#define VCO_CAL_OFFSET(x) (((x) & 0xF) << 3) /* VCO Cal Offset<3:0> */ + +/* +* REG_RX_ALC_VARACTOR +*/ +#define INIT_ALC_VALUE(x) (((x) & 0xF) << 4) /* Init ALC Value<3:0> */ +#define VCO_VARACTOR(x) (((x) & 0xF) << 0) /* VCO Varactor<3:0> */ + +/* +* REG_RX_VCO_OUTPUT +*/ +#define PORB_VCO_LOGIC (1 << 6) /* PORb VCO Logic */ +#define VCO_OUTPUT_LEVEL(x) (((x) & 0xF) << 0) /* VCO Output Level<3:0> */ + +/* +* REG_RX_CP_CURRENT +*/ +#define CHARGE_PUMP_CURRENT(x) (((x) & 0x3F) << 0) /* Charge Pump Current<5:0> */ + +/* +* REG_RX_CP_OFFSET +*/ +#define SYNTH_RECAL (1 << 7) /* Synth Re-Cal */ + +/* +* REG_RX_CP_CONFIG +*/ +#define HALF_VCO_CAL_CLK (1 << 7) /* Half Vco Cal Clk */ +#define CP_OFFSET_OFF (1 << 4) /* CP Offset Off */ +#define F_CPCAL (1 << 3) /* F Cpcal */ +#define CP_CAL_ENABLE (1 << 2) /* Cp Cal Enable */ + +/* +* REG_RX_LOOP_FILTER_1 +*/ +#define LOOP_FILTER_C2(x) (((x) & 0xF) << 4) /* Loop Filter C2<3:0> */ +#define LOOP_FILTER_C1(x) (((x) & 0xF) << 0) /* Loop Filter C1<3:0> */ + +/* +* REG_RX_LOOP_FILTER_2 +*/ +#define LOOP_FILTER_R1(x) (((x) & 0xF) << 4) /* Loop Filter R1<3:0> */ +#define LOOP_FILTER_C3(x) (((x) & 0xF) << 0) /* Loop Filter C3<3:0> */ + +/* +* REG_RX_LOOP_FILTER_3 +*/ +#define LOOP_FILTER_BYPASS_R3 (1 << 7) /* Loop Filter Bypass R3 */ +#define LOOP_FILTER_BYPASS_R1 (1 << 6) /* Loop Filter Bypass R1 */ +#define LOOP_FILTER_BYPASS_C2 (1 << 5) /* Loop Filter Bypass C2 */ +#define LOOP_FILTER_BYPASS_C1 (1 << 4) /* Loop Filter Bypass C1 */ +#define LOOP_FILTER_R3(x) (((x) & 0xF) << 0) /* Loop Filter R3<3:0> */ + +/* +* REG_RX_DITHERCP_CAL +*/ +#define FORCED_CP_CAL_WORD(x) (((x) & 0xF) << 0) /* Forced CP Cal Word<3:0> */ + +/* +* REG_RX_VCO_BIAS_1 +*/ +#define VCO_BIAS_TCF(x) (((x) & 0x3) << 3) /* VCO Bias Tcf<1:0> */ +#define VCO_BIAS_REF(x) (((x) & 0x7) << 0) /* VCO Bias Ref<2:0> */ + +/* +* REG_RX_CAL_STATUS +*/ +#define CP_CAL_VALID (1 << 7) /* CP Cal Valid */ +#define CP_CAL_DONE (1 << 5) /* CP Cal Done */ +#define VCO_CAL_BUSY (1 << 4) /* VCO Cal Busy */ +#define CP_CAL_WORD(x) (((x) & 0xF) << 0) /* CP Cal Word<3:0> */ + +/* +* REG_RX_VCO_CAL_REF +*/ +#define VCO_CAL_REF_TCF(x) (((x) & 0x7) << 0) /* VCO Cal Ref Tcf<2:0> */ + +/* +* REG_RX_VCO_PD_OVERRIDES +*/ +#define POWER_DOWN_VARACTOR_REF (1 << 3) /* Power Down Varactor Ref */ +#define PWR_DOWN_VARACT_REF_TCF (1 << 2) /* Pwr Down Varact Ref Tcf */ +#define POWER_DOWN_CAL_TCF (1 << 1) /* Power Down Cal Tcf */ +#define POWER_DOWN_VCO_BUFFFER (1 << 0) /* Power Down VCO Bufffer */ + +/* +* REG_RX_CP_OVERRANGE_VCO_LOCK +*/ +#define CP_OVRG_HIGH (1 << 7) /* CP Ovrg High */ +#define CP_OVRG_LOW (1 << 6) /* CP Ovrg Low */ +#define VCO_LOCK (1 << 1) /* Lock */ + +/* +* REG_RX_VCO_LDO +*/ +#define VCO_LDO_BYPASS (1 << 7) /* VCO LDO Bypass */ +#define VCO_LDO_INRUSH(x) (((x) & 0x3) << 5) /* VCO LDO Inrush<1:0> */ +#define VCO_LDO_SEL(x) (((x) & 0x7) << 2) /* VCO LDO Sel<2:0> */ +#define VCO_LDO_VDROP_SEL(x) (((x) & 0x3) << 0) /* VCO LDO Vdrop Sel<1:0> */ + +/* +* REG_RX_VCO_CAL +*/ +#define VCO_CAL_EN (1 << 7) /* VCO Cal En */ +#define VCO_CAL_ALC_WAIT(x) (((x) & 0x7) << 4) /* VCO Cal ALC Wait <2:0> */ +#define VCO_CAL_COUNT(x) (((x) & 0x3) << 2) /* VCO Cal Count <1:0> */ + +/* +* REG_RX_LOCK_DETECT_CONFIG +*/ +#define LOCK_DETECT_COUNT(x) (((x) & 0x3) << 2) /* Lock Detect Count<1:0> */ +#define LOCK_DETECT_MODE(x) (((x) & 0x3) << 0) /* Lock Detect Mode<1:0> */ + +/* +* REG_RX_CP_LEVEL_DETECT +*/ +#define CP_LEVEL_DETECT_POWER_DOWN (1 << 6) /* CP Level Detect Power Down */ +#define CP_LEVEL_THRESH_LOW(x) (((x) & 0x7) << 3) /* CP Level Threshold Low<2:0> */ +#define CP_LEVEL_THRESH_HIGH(x) (((x) & 0x7) << 0) /* CP Level Threshold High<2:0> */ + +/* +* REG_RX_DSM_SETUP_0 +*/ +#define DSM_PROG(x) (((x) & 0xF) << 0) /* DSM Prog<3:0> */ + +/* +* REG_RX_DSM_SETUP_1 +*/ +#define SIF_CLOCK (1 << 6) /* SIF clock */ +#define SIF_RESET_BAR (1 << 5) /* SIF Reset Bar */ +#define SIF_ADDR(x) (((x) & 0x1F) << 0) /* SIF Addr<4:0> */ + +/* +* REG_RX_CORRECTION_WORD0 +*/ +#define UPDATE_FREQ_WORD (1 << 7) /* Update Freq Word */ +#define READ_EFFECTIVE_TUNING_WORD (1 << 5) /* Read Effective Tuning Word */ +#define FREQ_CORRECTION_WORD_MSB(x) (((x) & 0x1F) << 0) /* Frequency Correction Word<11:7> */ + +/* +* REG_RX_CORRECTION_WORD1 +*/ +#define UPDATE_FREQ_WORD (1 << 7) /* Update Freq Word */ +#define FREQ_CORRECTION_WORD_LSB(x) (((x) & 0x7F) << 0) /* Frequency Correction Word<6:0> */ + +/* +* REG_RX_VCO_VARACTOR_CTRL_0 +*/ +#define VCO_VARACTOR_REFERENCE_TCF(x) (((x) & 0x7) << 4) /* VCO Varactor Reference Tcf<2:0> */ +#define VCO_VARACTOR_OFFSET(x) (((x) & 0xF) << 0) /* VCO Varactor Offset<3:0> */ + +/* +* REG_RX_VCO_VARACTOR_CTRL_1 +*/ +#define VCO_VARACTOR_REFERENCE(x) (((x) & 0xF) << 0) /* VCO Varactor Reference<3:0> */ + +/* +* REG_RX_FAST_LOCK_SETUP +*/ +#define RX_FAST_LOCK_LOAD_SYNTH (1 << 3) /* Rx Fast Lock Load Synth */ +#define RX_FAST_LOCK_PROFILE_INIT (1 << 2) /* Rx Fast Lock Profile Init */ +#define RX_FAST_LOCK_PROFILE_PIN_SELECT (1 << 1) /* Rx Fast Lock Profile Pin Select */ +#define RX_FAST_LOCK_MODE_ENABLE (1 << 0) /* Rx Fast Lock Mode Enable */ +#define RX_FAST_LOCK_PROFILE(x) (((x) & 0x7) << 5) /* Rx Fast Lock Profile<2:0> */ + +/* +* REG_RX_FAST_LOCK_PROGRAM_ADDR +*/ +#define RX_FAST_LOCK_PROFILE_ADDR(x) (((x) & 0x7) << 4) /* Rx Fast Lock Profile<2:0> */ +#define RX_FAST_LOCK_PROFILE_WORD(x) (((x) & 0xF) << 0) /* Configuration Word <3:0> */ + + +/* +* REG_RX_FAST_LOCK_PROGRAM_CTRL +*/ +#define RX_FAST_LOCK_PROGRAM_WRITE (1 << 1) /* Rx Fast Lock Program Write */ +#define RX_FAST_LOCK_PROGRAM_CLOCK_ENABLE (1 << 0) /* Rx Fast Lock Program Clock Enable */ + +#define RX_FAST_LOCK_CONFIG_WORD_NUM 16 + +/* +* REG_RX_LO_GEN_POWER_MODE +*/ +#define RX_LO_GEN_POWER_MODE(x) (((x) & 0x3) << 4) /* Power Mode<3:0> */ + +/* +* REG_TX_PFD_CONFIG +*/ +#define DIV_TEST_EN (1 << 5) /* Div Test En */ +#define PFD_CLK_EDGE (1 << 1) /* PFD Clk Edge */ +#define BYPASS_LD_SYNTH (1 << 0) /* Bypass Ld Synth */ +#define PFD_WIDTH(x) (((x) & 0x3) << 2) /* PFD Width <1:0> */ + +/* +* REG_TX_INTEGER_BYTE_1 +*/ +#define SDM_BYPASS (1 << 7) /* SDM Bypass */ +#define SDM_POWER_DOWN (1 << 6) /* SDM Power Down */ +#define SYNTH_INTEGER_WORD(x) (((x) & 0x7) << 0) /* Synthesizer Integer Word<10:8> */ + +/* +* REG_TX_FRACT_BYTE_2 +*/ +#define SYNTH_FRACT_WORD(x) (((x) & 0x7F) << 0) /* Synthesizer Fractional Word <22:16> */ + +/* +* REG_TX_FORCE_ALC +*/ +#define FORCE_ALC_ENABLE (1 << 7) /* Force ALC Enable */ +#define FORCE_ALC_WORD(x) (((x) & 0x7F) << 0) /* Force ALC Word<6:0> */ + +/* +* REG_TX_FORCE_VCO_TUNE_1 +*/ +#define BYPASS_LOAD_DELAY (1 << 7) /* Bypass Load Delay */ +#define FORCE_VCO_TUNE_ENABLE (1 << 1) /* Force VCO Tune Enable */ +#define FORCE_VCO_TUNE (1 << 0) /* Force VCO Tune */ +#define VCO_CAL_OFFSET(x) (((x) & 0xF) << 3) /* VCO Cal Offset<3:0> */ + +/* +* REG_TX_ALCVARACT_OR +*/ +#define INIT_ALC_VALUE(x) (((x) & 0xF) << 4) /* Init ALC Value<3:0> */ +#define VCO_VARACTOR(x) (((x) & 0xF) << 0) /* VCO Varactor<3:0> */ + +/* +* REG_TX_VCO_OUTPUT +*/ +#define PORB_VCO_LOGIC (1 << 6) /* PORb VCO Logic */ +#define VCO_OUTPUT_LEVEL(x) (((x) & 0xF) << 0) /* VCO Output Level<3:0> */ + +/* +* REG_TX_CP_CURRENT +*/ +#define TX_CP_CURRENT_DFLT (1 << 7) /* Set to 1 */ +#define VTUNE_FORCE (1 << 6) /* Vtune Force */ +#define CHARGE_PUMP_CURRENT(x) (((x) & 0x3F) << 0) /* Charge Pump Current<5:0> */ + +/* +* REG_TX_CP_OFFSET +*/ +#define SYNTH_RECAL (1 << 7) /* Synth Re-Cal */ +#define CHARGE_PUMP_OFFSET(x) (((x) & 0x3F) << 0) /* Charge Pump Offset<5:0> */ + +/* +* REG_TX_CP_CONFIG +*/ +#define HALF_VCO_CAL_CLK (1 << 7) /* Half Vco Cal Clk */ +#define DITHER_MODE (1 << 6) /* Dither Mode */ +#define CP_OFFSET_OFF (1 << 4) /* Cp Offset Off */ +#define F_CPCAL (1 << 3) /* F Cpcal */ +#define CP_CAL_ENABLE (1 << 2) /* Cp Cal Enable */ +#define CP_TEST(x) (((x) & 0x3) << 0) /* Cp Test <1:0> */ + +/* +* REG_TX_LOOP_FILTER_1 +*/ +#define LOOP_FILTER_C2(x) (((x) & 0xF) << 4) /* Loop Filter C2<3:0> */ +#define LOOP_FILTER_C1(x) (((x) & 0xF) << 0) /* Loop Filter C1<3:0> */ + +/* +* REG_TX_LOOP_FILTER_2 +*/ +#define LOOP_FILTER_R1(x) (((x) & 0xF) << 4) /* Loop Filter R1<3:0> */ +#define LOOP_FILTER_C3(x) (((x) & 0xF) << 0) /* Loop Filter C3<3:0> */ + +/* +* REG_TX_LOOP_FILTER_3 +*/ +#define LOOP_FILTER_BYPASS_R3 (1 << 7) /* Loop Filter Bypass R3 */ +#define LOOP_FILTER_BYPASS_R1 (1 << 6) /* Loop Filter Bypass R1 */ +#define LOOP_FILTER_BYPASS_C2 (1 << 5) /* Loop Filter Bypass C2 */ +#define LOOP_FILTER_BYPASS_C1 (1 << 4) /* Loop Filter Bypass C1 */ +#define LOOP_FILTER_R3(x) (((x) & 0xF) << 0) /* Loop Filter R3<3:0> */ + +/* +* REG_TX_DITHERCP_CAL +*/ +#define NUMBER_SDM_DITHER_BITS(x) (((x) & 0xF) << 4) /* Number SDM Dither Bits<3:0> */ +#define FORCED_CP_CAL_WORD(x) (((x) & 0xF) << 0) /* Forced CP Cal Word<3:0> */ + +/* +* REG_TX_VCO_BIAS_1 +*/ +#define MUST_BE_ZEROS(x) (((x) & 0x3) << 5) /* Must be zeros */ +#define VCO_BIAS_TCF(x) (((x) & 0x3) << 3) /* VCO Bias Tcf<1:0> */ +#define VCO_BIAS_REF(x) (((x) & 0x7) << 0) /* VCO Bias Ref<2:0> */ + +/* +* REG_TX_VCO_BIAS_2 +*/ +#define VCO_BYPASS_BIAS_DAC_R (1 << 7) /* VCO Bypass Bias DAC R */ +#define VCO_COMP_BYPASS_BIAS_R (1 << 4) /* VCO Comp Bypass Bias R */ +#define BYPASS_PRESCALE_R (1 << 3) /* Bypass Prescale R */ +#define LAST_ALC_ENABLE (1 << 2) /* Last ALC Enable */ +#define PRESCALE_BIAS(x) (((x) & 0x3) << 0) /* Prescale Bias <1:0> */ + +/* +* REG_TX_CAL_STATUS +*/ +#define CP_CAL_VALID (1 << 7) /* CP Cal Valid */ +#define COMP_OUT (1 << 6) /* Comp Out */ +#define CP_CAL_DONE (1 << 5) /* CP Cal Done */ +#define VCO_CAL_BUSY (1 << 4) /* VCO Cal Busy */ +#define CP_CAL_WORD(x) (((x) & 0xF) << 0) /* CP Cal Word<3:0> */ + +/* +* REG_TX_VCO_CAL_REF +*/ +#define VCO_CAL_REF_MONITOR (1 << 3) /* VCO Cal Ref Monitor */ +#define VCO_CAL_REF_TCF(x) (((x) & 0x7) << 0) /* VCO Cal Ref Tcf<2:0> */ + +/* +* REG_TX_VCO_PD_OVERRIDES +*/ +#define POWER_DOWN_VARACTOR_REF (1 << 3) /* Power Down Varactor Ref */ +#define POWER_DOWN_VARACT_REF_TCF (1 << 2) /* Power Down Varact Ref Tcf */ +#define POWER_DOWN_CAL_TCF (1 << 1) /* Power Down Cal Tcf */ +#define POWER_DOWN_VCO_BUFFFER (1 << 0) /* Power Down VCO Bufffer */ + +/* +* REG_TX_CP_OVERRANGE_VCO_LOCK +*/ +#define CP_OVRG_HIGH (1 << 7) /* CP Ovrg High */ +#define CP_OVRG_LOW (1 << 6) /* CP Ovrg Low */ +#define VCO_LOCK (1 << 1) /* Lock */ + +/* +* REG_TX_VCO_LDO +*/ +#define VCO_LDO_BYPASS (1 << 7) /* VCO LDO Bypass */ +#define VCO_LDO_INRUSH(x) (((x) & 0x3) << 5) /* VCO LDO Inrush<1:0> */ +#define VCO_LDO_VOUT_SEL(x) (((x) & 0x7) << 2) /* VCO LDO Vout Sel<2:0> */ +#define VCO_LDO_VDROP_SEL(x) (((x) & 0x3) << 0) /* VCO LDO Vdrop Sel<1:0> */ + +/* +* REG_TX_VCO_CAL +*/ +#define VCO_CAL_EN (1 << 7) /* VCO Cal En */ +#define VCO_CAL_ALC_WAIT(x) (((x) & 0x7) << 4) /* VCO Cal ALC Wait<2:0) */ +#define VCO_CAL_COUNT(x) (((x) & 0x3) << 2) /* VCO Cal Count<1:0> */ +#define FB_CLOCK_ADV(x) (((x) & 0x3) << 0) /* FB Clock Adv<1:0> */ + +/* +* REG_TX_LOCK_DETECT_CONFIG +*/ +#define LOCK_DETECT_COUNT(x) (((x) & 0x3) << 2) /* Lock Detect Count<1:0> */ +#define LOCK_DETECT_MODE(x) (((x) & 0x3) << 0) /* Lock Detect Mode<1:0> */ + +/* +* REG_TX_CP_LEVEL_DETECT +*/ +#define CP_LEVEL_DETECT_POWER_DOWN (1 << 6) /* CP Level Detect Power Down */ +#define CP_LEVEL_DETECT_THRESH_LOW(x) (((x) & 0x7) << 3) /* CP Level Detect Threshold Low<2:0> */ +#define CP_LEVEL_DETECT_THRESH_HIGH(x) (((x) & 0x7) << 0) /* CP Level Detect Threshold High<2:0> */ + +/* +* REG_TX_DSM_SETUP_0 +*/ +#define DSM_PROG(x) (((x) & 0xF) << 0) /* DSM Prog<3:0> */ + +/* +* REG_TX_DSM_SETUP_1 +*/ +#define SIF_CLOCK (1 << 6) /* SIF clock */ +#define SIF_RESET_BAR (1 << 5) /* SIF Reset Bar */ +#define SIF_ADDR(x) (((x) & 0x1F) << 0) /* SIF Addr<4:0> */ + +/* +* REG_TX_CORRECTION_WORD0 +*/ +#define UPDATE_FREQ_WORD (1 << 7) /* Update Freq Word */ +#define READ_EFFECTIVE_TUNING_WORD (1 << 5) /* Read Effective Tuning Word */ +#define FREQ_CORRECTION_WORD_MSB(x) (((x) & 0x1F) << 0) /* Frequency Correction Word<11:7> */ + +/* +* REG_TX_CORRECTION_WORD1 +*/ +#define UPDATE_FREQ_WORD (1 << 7) /* Update Freq Word */ +#define FREQ_CORRECTION_WORD_LSB(x) (((x) & 0x7F) << 0) /* Frequency Correction Word<6:0> */ + +/* +* REG_TX_VCO_VARACTOR_CTRL_0 +*/ +#define VCO_VARACTOR_REFERENCE_TCF(x) (((x) & 0x7) << 4) /* VCO Varactor Reference Tcf<2:0> */ +#define VCO_VARACTOR_OFFSET(x) (((x) & 0xF) << 0) /* VCO Varactor Offset<3:0> */ + +/* +* REG_TX_VCO_VARACTOR_CTRL_1 +*/ +#define VCO_VARACTOR_REFERENCE(x) (((x) & 0xF) << 0) /* VCO Varactor Reference<3:0> */ + +/* +* REG_DCXO_COARSE_TUNE +*/ +#define DCXO_TUNE_COARSE(x) (((x) & 0x3F) << 0) /* DCXO Tune Coarse<5:0> */ + +/* +* REG_DCXO_FINE_TUNE_LOW +*/ +#define DCXO_TUNE_FINE_LOW(x) (((x) & 0x1F) << 3) /* DCXO Tune Fine<4:0> */ + +/* +* REG_DCXO_FINE_TUNE_HIGH +*/ +#define DCXO_TUNE_FINE_HIGH(x) ((x) >> 5) /* DCXO Tune Fine<12:5> */ + +/* +* REG_DCXO_CONFIG +*/ +#define MUST_BE_ZERO (1 << 7) /* Must be zero */ +#define DCXO_RTAIL(x) (((x) & 0x7) << 4) /* DCXO Rtail<2:0> */ +#define DCXO_RD(x) (((x) & 0x3) << 2) /* DCXO Rd<1:0> */ + +/* +* REG_DCXO_TEMPCO_ADDR +*/ +#define DCXO_TEMPCO_EN (1 << 7) /* DCXO Tempco En */ +#define DCXO_TEMPCO_CLK (1 << 6) /* DCXO Tempco Clk */ +#define DCXO_TEMPERATURE_COEF_ADDRESS(x) (((x) & 0x3F) << 0) /* DCXO Temperature Coefficient Address<5:0> */ + +/* +* REG_TX_FAST_LOCK_SETUP +*/ +#define TX_FAST_LOCK_LOAD_SYNTH (1 << 3) /* Tx Fast Lock Load Synth */ +#define TX_FAST_LOCK_PROFILE_INIT (1 << 2) /* Tx Fast Lock Profile Init */ +#define TX_FAST_LOCK_PROFILE_PIN_SELECT (1 << 1) /* Tx Fast Lock Profile Pin Select */ +#define TX_FAST_LOCK_MODE_ENABLE (1 << 0) /* Tx Fast Lock Mode Enable */ +#define TX_FAST_LOCK_PROFILE(x) (((x) & 0x7) << 5) /* Tx Fast Lock Profile<2:0> */ + +/* +* REG_TX_FAST_LOCK_PROGRAM_CTRL +*/ +#define TX_FAST_LOCK_PROGRAM_WRITE (1 << 1) /* Tx Fast Lock Program Write */ +#define TX_FAST_LOCK_PROGRAM_CLOCK_ENABLE (1 << 0) /* Tx Fast Lock Program Clock Enable */ + +/* +* REG_TX_LO_GEN_POWER_MODE +*/ +#define TX_LO_GEN_POWER_MODE(x) (((x) & 0xF) << 4) /* Power Mode<3:0> */ + +/* +* REG_BANDGAP_CONFIG0 +*/ +#define POWER_DOWN_BANDGAP_REF (1 << 7) /* Power Down Bandgap Ref */ +#define MASTER_BIAS_FILTER_BYPASS (1 << 6) /* Master Bias Filter Bypass */ +#define MASTER_BIAS_REF_SEL (1 << 5) /* Master Bias Ref Sel */ +#define MASTER_BIAS_TRIM(x) (((x) & 0x1F) << 0) /* Master Bias Trim<4:0> */ + +/* +* REG_BANDGAP_CONFIG1 +*/ +#define VCO_LDO_FILTER_BYPASS (1 << 7) /* VCO LDO Filter Bypass */ +#define VCO_LDO_REF_SEL (1 << 6) /* VCO LDO Ref Sel */ +#define BANDGAP_REF_RESET (1 << 5) /* Bandgap Ref Reset */ +#define BANDGAP_TEMP_TRIM(x) (((x) & 0x1F) << 0) /* Bandgap Temp Trim<4:0> */ + +/* +* REG_REF_DIVIDE_CONFIG_1 +*/ +#define REF_DIVIDE_CONFIG_1_DFLT (1 << 2) /* Set to 1 */ +#define RX_REF_RESET_BAR (1 << 1) /* Rx Ref Reset Bar */ +#define RX_REF_DIVIDER_MSB (1 << 0) /* Rx Ref Divider<1> */ + +/* +* REG_REF_DIVIDE_CONFIG_2 +*/ +#define RX_REF_DIVIDER_LSB (1 << 7) /* Rx Ref Divider< 0> */ +#define TX_REF_RESET_BAR (1 << 4) /* Tx Ref Reset Bar */ +#define RX_REF_DOUBLER_FB_DELAY(x) (((x) & 0x3) << 5) /* Rx Ref Doubler FB Delay<1:0> */ +#define TX_REF_DIVIDER(x) (((x) & 0x3) << 2) /* Tx Ref Divider<1:0> */ +#define TX_REF_DOUBLER_FB_DELAY(x) (((x) & 0x3) << 0) /* Tx Ref Doubler FB Delay<1:0> */ + +/* +* REG_GAIN_RX1,2 +*/ +#define FULL_TABLE_GAIN_INDEX(x) (((x) & 0x7F) << 0) /* Full Table Gain Index Rx1/LMT Gain Rx1<6:0> */ + +/* +* REG_LPF_GAIN_RX1,2 +*/ +#define LPF_GAIN_RX(x) (((x) & 0x1F) << 0) /* LPF gain Rx1<4:0> */ + +/* +* REG_DIG_GAIN_RX1,2 +*/ +#define DIGITAL_GAIN_RX(x) (((x) & 0x1F) << 0) /* Digital gain Rx1<4:0> */ + +/* +* REG_FAST_ATTACK_STATE +*/ +#define FAST_ATTACK_STATE_RX2(x) (((x) & 0x7) << 4) /* Fast Attack State Rx2<2:0> */ +#define FAST_ATTACK_STATE_RX1(x) (((x) & 0x7) << 0) /* Fast Attack State Rx1<2:0> */ +#define FAST_ATK_MASK 0x7 +#define RX1_FAST_ATK_SHIFT 0 +#define RX2_FAST_ATK_SHIFT 4 +#define FAST_ATK_RESET 0 +#define FAST_ATK_PEAK_DETECT 1 +#define FAST_ATK_PWR_MEASURE 2 +#define FAST_ATK_FINAL_SETTELING 3 +#define FAST_ATK_FINAL_OVER 4 +#define FAST_ATK_GAIN_LOCKED 5 + +/* +* REG_SLOW_LOOP_STATE +*/ +#define SLOW_LOOP_STATE_RX2(x) (((x) & 0x7) << 4) /* Slow Loop State Rx2<2:0> */ +#define SLOW_LOOP_STATE_RX1(x) (((x) & 0x7) << 0) /* Slow Loop State Rx1<2:0> */ + + +/* +* REG_OVRG_SIGS_RX1,2 +*/ +#define GAIN_LOCK_1 (1 << 6) /* Gain Lock 1 */ +#define LOW_POWER_1 (1 << 5) /* Low Power 1 */ +#define LARGE_LMT_OL (1 << 4) /* Large LMT OL */ +#define SMALL_LMT_OL (1 << 3) /* Small LMT OL */ +#define LARGE_ADC_OL (1 << 2) /* Large ADC OL */ +#define SMALL_ADC_OL (1 << 1) /* Small ADC OL */ +#define DIG_SAT (1 << 0) /* Dig Sat */ +/* +* REG_CTRL +*/ +#define CTRL_ENABLE (1 << 0) /* Set to 1 */ + +/* +* REG_BIST_CONFIG +*/ +#define TONE_PRBS (1 << 1) /* Tone/ PRBS */ +#define BIST_ENABLE (1 << 0) /* BIST Enable */ +#define TONE_FREQ(x) (((x) & 0x3) << 6) /* Tone Frequency<1:0> */ +#define TONE_LEVEL(x) (((x) & 0x3) << 4) /* Tone Level<1:0> */ +#define BIST_CTRL_POINT(x) (((x) & 0x3) << 2) /* BIST Control Point <1:0> */ + +/* +* REG_OBSERVE_CONFIG +*/ +#define DATA_PORT_SP_HD_LOOP_TEST_OE (1 << 7) /* Data Port SP, HD Loop Test OE */ +#define RX_MASK (1 << 6) /* Rx Mask */ +#define CHANNEL (1 << 5) /* Channel */ +#define DATA_PORT_LOOP_TEST_ENABLE (1 << 0) /* Data Port Loop Test Enable */ +#define OBSERVATION_POINT(x) (((x) & 0xF) << 1) /* Observation Point<2:0> */ + +/* +* REG_BIST_AND_DATA_PORT_TEST_CONFIG +*/ +#define BIST_MASK_CHANNEL_2_Q_DATA (1 << 5) /* BIST Mask Channel 2 Q data */ +#define BIST_MASK_CHANNEL_2_I_DATA (1 << 4) /* BIST Mask Channel 2 I data */ +#define BIST_MASK_CHANNEL_1_Q_DATA (1 << 3) /* BIST Mask Channel 1 Q data */ +#define BIST_MASK_CHANNEL_1_I_DATA (1 << 2) /* BIST Mask Channel 1 I data */ +#define DATA_PORT_HILOW (1 << 1) /* Data Port Hi/Low */ +#define USE_DATA_PORT (1 << 0) /* Use Data Port */ +#define TEMP_SENSE_VBE_TEST(x) (((x) & 0x3) << 6) /* Temp Sense Vbe Test<1:0> */ + +/* +* REG_DAC_TEST_2 +*/ +#define DAC_TEST_ENABLE (1 << 7) /* DAC Test Enable */ +#define DAC_TEST_WORD(x) (((x) & 0x7F) << 0) /* DAC test Word <22:16> */ + +/* +* SPI Comm Helpers +*/ +#define AD_READ (0 << 15) +#define AD_WRITE (1 << 15) +#define AD_CNT(x) ((((x) - 1) & 0x7) << 12) +#define AD_ADDR(x) ((x) & 0x3FF) + + +/* +* AD9361 Limits +*/ + +#define RSSI_MULTIPLIER 100 +#define RSSI_RESOLUTION ((int) (0.25 * RSSI_MULTIPLIER)) +#define RSSI_MAX_WEIGHT 255 + +#define MAX_LMT_INDEX 40 +#define MAX_LPF_GAIN 24 +#define MAX_DIG_GAIN 31 + +#define MAX_BBPLL_FREF 70007000UL /* 70 MHz + 100ppm */ +#define MIN_BBPLL_FREQ 714928500UL /* 715 MHz - 100ppm */ +#define MAX_BBPLL_FREQ 1430143000UL /* 1430 MHz + 100ppm */ +#define MAX_BBPLL_DIV 64 +#define MIN_BBPLL_DIV 2 + +/* + * The ADC minimum and maximum operating output data rates + * are 25MHz and 640MHz respectively. + * For more information see here: https://ez.analog.com/docs/DOC-12763 + */ + +#define MIN_ADC_CLK 25000000UL /* 25 MHz */ +//#define MIN_ADC_CLK (MIN_BBPLL_FREQ / MAX_BBPLL_DIV) /* 11.17MHz */ +#define MAX_ADC_CLK 640000000UL /* 640 MHz */ +#define MAX_DAC_CLK (MAX_ADC_CLK / 2) + +/* Associated with outputs of stage */ +#define MAX_RX_HB1 245760000UL +#define MAX_RX_HB2 320000000UL +#define MAX_RX_HB3 640000000UL +/* Associated with inputs of stage */ +#define MAX_TX_HB1 160000000UL +#define MAX_TX_HB2 320000000UL +#define MAX_TX_HB3 320000000UL + +#define MAX_BASEBAND_RATE 61440000UL + +#define MAX_MBYTE_SPI 8 + +#define RFPLL_MODULUS 8388593UL +#define BBPLL_MODULUS 2088960UL + +#define MAX_SYNTH_FREF 80008000UL /* 80 MHz + 100ppm */ +#define MIN_SYNTH_FREF 9999000UL /* 10 MHz - 100ppm */ +#define MIN_VCO_FREQ_HZ 6000000000ULL +#define MAX_CARRIER_FREQ_HZ 6000000000ULL +#define MIN_RX_CARRIER_FREQ_HZ 70000000ULL +#define MIN_TX_CARRIER_FREQ_HZ 46875001ULL + +#define AD9363A_MAX_CARRIER_FREQ_HZ 3800000000ULL +#define AD9363A_MIN_CARRIER_FREQ_HZ 325000000ULL + +#define MAX_TX_ATTENUATION_DB 89750 + +/* +* Driver +*/ + +enum rx_gain_table_type { + RXGAIN_FULL_TBL, + RXGAIN_SPLIT_TBL, +}; + +enum rx_gain_table_name { + TBL_200_1300_MHZ, + TBL_1300_4000_MHZ, + TBL_4000_6000_MHZ, + RXGAIN_TBLS_END, +}; + +struct gain_table_info { + uint64_t start; + uint64_t end; + uint8_t max_index; + uint8_t split_table; + int8_t *abs_gain_tbl; + uint8_t (*tab)[3]; +}; + +enum fir_dest { + FIR_TX1 = 0x01, + FIR_TX2 = 0x02, + FIR_TX1_TX2 = 0x03, + FIR_RX1 = 0x81, + FIR_RX2 = 0x82, + FIR_RX1_RX2 = 0x83, + FIR_IS_RX = 0x80, +}; + +struct rf_gain_ctrl { + uint32_t ant; + uint8_t mode; +}; + +enum rf_gain_ctrl_mode { + RF_GAIN_MGC, + RF_GAIN_FASTATTACK_AGC, + RF_GAIN_SLOWATTACK_AGC, + RF_GAIN_HYBRID_AGC +}; + +enum f_agc_target_gain_index_type { + MAX_GAIN, + SET_GAIN, + OPTIMIZED_GAIN, + NO_GAIN_CHANGE, +}; + +struct gain_control { + enum rf_gain_ctrl_mode rx1_mode; + enum rf_gain_ctrl_mode rx2_mode; + + /* Common */ + uint8_t adc_ovr_sample_size; /* 1..8 Sum x samples, AGC_CONFIG_3 */ + uint8_t adc_small_overload_thresh; /* 0..255, 0x105 */ + uint8_t adc_large_overload_thresh; /* 0..255, 0x104 */ + + uint16_t lmt_overload_high_thresh; /* 16..800 mV, 0x107 */ + uint16_t lmt_overload_low_thresh; /* 16..800 mV, 0x108 */ + uint16_t dec_pow_measuremnt_duration; /* Samples, 0x15C */ + uint8_t low_power_thresh; /* -64..0 dBFS, 0x114 */ + bool use_rx_fir_out_for_dec_pwr_meas; /* clears 0x15C:6 USE_HB1_OUT_FOR_DEC_PWR_MEAS */ + + bool dig_gain_en; /* should be turned off, since ADI GT doesn't use dig gain */ + uint8_t max_dig_gain; /* 0..31 */ + + /* MGC */ + bool mgc_rx1_ctrl_inp_en; /* Enables Pin control on RX1 default SPI ctrl */ + bool mgc_rx2_ctrl_inp_en; /* Enables Pin control on RX2 default SPI ctrl */ + + uint8_t mgc_inc_gain_step; /* 1..8 */ + uint8_t mgc_dec_gain_step; /* 1..8 */ + uint8_t mgc_split_table_ctrl_inp_gain_mode; /* 0=AGC determine this, 1=only in LPF, 2=only in LMT */ + + /* AGC */ + uint8_t agc_attack_delay_extra_margin_us; /* 0..31 us */ + + uint8_t agc_outer_thresh_high; + uint8_t agc_outer_thresh_high_dec_steps; + uint8_t agc_inner_thresh_high; + uint8_t agc_inner_thresh_high_dec_steps; + uint8_t agc_inner_thresh_low; + uint8_t agc_inner_thresh_low_inc_steps; + uint8_t agc_outer_thresh_low; + uint8_t agc_outer_thresh_low_inc_steps; + + uint8_t adc_small_overload_exceed_counter; /* 0..15, 0x122 */ + uint8_t adc_large_overload_exceed_counter; /* 0..15, 0x122 */ + uint8_t adc_large_overload_inc_steps; /* 0..15, 0x106 */ + + bool adc_lmt_small_overload_prevent_gain_inc; /* 0x120 */ + + uint8_t lmt_overload_large_exceed_counter; /* 0..15, 0x121 */ + uint8_t lmt_overload_small_exceed_counter; /* 0..15, 0x121 */ + uint8_t lmt_overload_large_inc_steps; /* 0..7, 0x121 */ + + uint8_t dig_saturation_exceed_counter; /* 0..15, 0x128 */ + uint8_t dig_gain_step_size; /* 1..8, 0x100 */ + bool sync_for_gain_counter_en; /* 0x128:4 !Hybrid */ + + uint32_t gain_update_interval_us; /* in us */ + bool immed_gain_change_if_large_adc_overload; /* 0x123:3 */ + bool immed_gain_change_if_large_lmt_overload; /* 0x123:7 */ + + /* + * Fast AGC + */ + uint32_t f_agc_dec_pow_measuremnt_duration; /* Samples, 0x15C */ + uint32_t f_agc_state_wait_time_ns; /* 0x117 0..31 RX samples -> time_ns */ + /* Fast AGC - Low Power */ + bool f_agc_allow_agc_gain_increase; /* 0x110:1 */ + uint8_t f_agc_lp_thresh_increment_time; /* 0x11B RX samples */ + uint8_t f_agc_lp_thresh_increment_steps; /* 0x117 1..8 */ + + /* Fast AGC - Lock Level */ + uint8_t f_agc_lock_level; /* NOT USED: 0x101 0..-127 dBFS same as agc_inner_thresh_high */ + bool f_agc_lock_level_lmt_gain_increase_en; /* 0x111:6 */ + uint8_t f_agc_lock_level_gain_increase_upper_limit; /* 0x118 0..63 */ + /* Fast AGC - Peak Detectors and Final Settling */ + uint8_t f_agc_lpf_final_settling_steps; /* 0x112:6 0..3 (Post Lock Level Step)*/ + uint8_t f_agc_lmt_final_settling_steps; /* 0x113:6 0..3 (Post Lock Level Step)*/ + uint8_t f_agc_final_overrange_count; /* 0x116:5 0..7 */ + /* Fast AGC - Final Power Test */ + bool f_agc_gain_increase_after_gain_lock_en; /* 0x110:7 */ + /* Fast AGC - Unlocking the Gain */ + /* 0 = MAX Gain, 1 = Set Gain, 2 = Optimized Gain */ + enum f_agc_target_gain_index_type + f_agc_gain_index_type_after_exit_rx_mode; /* 0x110:[4,2] */ + bool f_agc_use_last_lock_level_for_set_gain_en; /* 0x111:7 */ + uint8_t f_agc_optimized_gain_offset; /*0x116 0..15 steps */ + bool f_agc_rst_gla_stronger_sig_thresh_exceeded_en; /* 0x110:~6 */ + uint8_t f_agc_rst_gla_stronger_sig_thresh_above_ll; /*0x113 0..63 dbFS */ + bool f_agc_rst_gla_engergy_lost_sig_thresh_exceeded_en; /* 0x110:6 */ + bool f_agc_rst_gla_engergy_lost_goto_optim_gain_en; /* 0x110:6 */ + uint8_t f_agc_rst_gla_engergy_lost_sig_thresh_below_ll; /* 0x112:6 */ + uint8_t f_agc_energy_lost_stronger_sig_gain_lock_exit_cnt; /* 0x119 0..63 RX samples */ + bool f_agc_rst_gla_large_adc_overload_en; /*0x110:~1 and 0x114:~7 */ + bool f_agc_rst_gla_large_lmt_overload_en; /*0x110:~1 */ + bool f_agc_rst_gla_en_agc_pulled_high_en; + /* 0 = Max Gain, 1 = Set Gain, 2 = Optimized Gain, 3 = No Gain Change */ + + enum f_agc_target_gain_index_type + f_agc_rst_gla_if_en_agc_pulled_high_mode; /* 0x0FB, 0x111 */ + uint8_t f_agc_power_measurement_duration_in_state5; /* 0x109, 0x10a RX samples 0..524288*/ + uint8_t f_agc_large_overload_inc_steps; /* 0x106 [D6:D4] 0..7 */ +}; + +struct auxdac_control { + uint16_t dac1_default_value; + uint16_t dac2_default_value; + + bool auxdac_manual_mode_en; + + bool dac1_in_rx_en; + bool dac1_in_tx_en; + bool dac1_in_alert_en; + + bool dac2_in_rx_en; + bool dac2_in_tx_en; + bool dac2_in_alert_en; + + uint8_t dac1_rx_delay_us; + uint8_t dac1_tx_delay_us; + uint8_t dac2_rx_delay_us; + uint8_t dac2_tx_delay_us; +}; + +enum rssi_restart_mode { + AGC_IN_FAST_ATTACK_MODE_LOCKS_THE_GAIN, + EN_AGC_PIN_IS_PULLED_HIGH, + ENTERS_RX_MODE, + GAIN_CHANGE_OCCURS, + SPI_WRITE_TO_REGISTER, + GAIN_CHANGE_OCCURS_OR_EN_AGC_PIN_PULLED_HIGH, +}; + +struct rssi_control { + enum rssi_restart_mode restart_mode; + bool rssi_unit_is_rx_samples; /* default unit is time */ + uint32_t rssi_delay; + uint32_t rssi_wait; + uint32_t rssi_duration; +}; + +struct rx_gain_info { + enum rx_gain_table_type tbl_type; + int32_t starting_gain_db; + int32_t max_gain_db; + int32_t gain_step_db; + int32_t max_idx; + int32_t idx_step_offset; +}; + +struct port_control { + uint8_t pp_conf[3]; + uint8_t rx_clk_data_delay; + uint8_t tx_clk_data_delay; + uint8_t digital_io_ctrl; + uint8_t lvds_bias_ctrl; + uint8_t lvds_invert[2]; +}; + +struct ctrl_outs_control { + uint8_t index; + uint8_t en_mask; +}; + +struct elna_control { + uint16_t gain_mdB; + uint16_t bypass_loss_mdB; + uint32_t settling_delay_ns; + bool elna_1_control_en; /* GPO0 */ + bool elna_2_control_en; /* GPO1 */ + bool elna_in_gaintable_all_index_en; +}; + +struct auxadc_control { + int8_t offset; + uint32_t temp_time_inteval_ms; + uint32_t temp_sensor_decimation; + bool periodic_temp_measuremnt; + uint32_t auxadc_clock_rate; + uint32_t auxadc_decimation; +}; + +struct gpo_control { + uint32_t gpo_manual_mode_enable_mask; + bool gpo_manual_mode_en; + bool gpo0_inactive_state_high_en; + bool gpo1_inactive_state_high_en; + bool gpo2_inactive_state_high_en; + bool gpo3_inactive_state_high_en; + bool gpo0_slave_rx_en; + bool gpo0_slave_tx_en; + bool gpo1_slave_rx_en; + bool gpo1_slave_tx_en; + bool gpo2_slave_rx_en; + bool gpo2_slave_tx_en; + bool gpo3_slave_rx_en; + bool gpo3_slave_tx_en; + uint8_t gpo0_rx_delay_us; + uint8_t gpo0_tx_delay_us; + uint8_t gpo1_rx_delay_us; + uint8_t gpo1_tx_delay_us; + uint8_t gpo2_rx_delay_us; + uint8_t gpo2_tx_delay_us; + uint8_t gpo3_rx_delay_us; + uint8_t gpo3_tx_delay_us; +}; + +struct tx_monitor_control { + bool tx_mon_track_en; + bool one_shot_mode_en; + uint32_t low_high_gain_threshold_mdB; + uint8_t low_gain_dB; + uint8_t high_gain_dB; + uint16_t tx_mon_delay; + uint16_t tx_mon_duration; + uint8_t tx1_mon_front_end_gain; + uint8_t tx2_mon_front_end_gain; + uint8_t tx1_mon_lo_cm; + uint8_t tx2_mon_lo_cm; +}; + +enum ad9361_pdata_rx_freq { + BBPLL_FREQ, + ADC_FREQ, + R2_FREQ, + R1_FREQ, + CLKRF_FREQ, + RX_SAMPL_FREQ, + NUM_RX_CLOCKS, +}; + +enum ad9361_pdata_tx_freq { + IGNORE, + DAC_FREQ, + T2_FREQ, + T1_FREQ, + CLKTF_FREQ, + TX_SAMPL_FREQ, + NUM_TX_CLOCKS, +}; + +enum ad9361_clkout { + CLKOUT_DISABLE, + BUFFERED_XTALN_DCXO, + ADC_CLK_DIV_2, + ADC_CLK_DIV_3, + ADC_CLK_DIV_4, + ADC_CLK_DIV_8, + ADC_CLK_DIV_16, +}; + +struct ad9361_phy_platform_data { + bool rx2tx2; + bool fdd; + bool fdd_independent_mode; + bool split_gt; + bool use_extclk; + bool ensm_pin_pulse_mode; + bool ensm_pin_ctrl; + bool debug_mode; + bool tdd_use_dual_synth; + bool tdd_skip_vco_cal; + bool use_ext_rx_lo; + bool use_ext_tx_lo; + bool rx1rx2_phase_inversion_en; + bool qec_tracking_slow_mode_en; + uint8_t dc_offset_update_events; + uint8_t dc_offset_attenuation_high; + uint8_t dc_offset_attenuation_low; + uint8_t rf_dc_offset_count_high; + uint8_t rf_dc_offset_count_low; + uint8_t dig_interface_tune_skipmode; + uint8_t dig_interface_tune_fir_disable; + uint8_t lo_powerdown_managed_en; + uint32_t dcxo_coarse; + uint32_t dcxo_fine; + uint32_t rf_rx_input_sel; + uint32_t rf_tx_output_sel; + uint32_t rx1tx1_mode_use_rx_num; + uint32_t rx1tx1_mode_use_tx_num; + uint32_t rx_path_clks[NUM_RX_CLOCKS]; + uint32_t tx_path_clks[NUM_TX_CLOCKS]; + uint32_t trx_synth_max_fref; + uint64_t rx_synth_freq; + uint64_t tx_synth_freq; + uint32_t rf_rx_bandwidth_Hz; + uint32_t rf_tx_bandwidth_Hz; + int32_t tx_atten; + bool update_tx_gain_via_alert; + uint32_t rx_fastlock_delay_ns; + uint32_t tx_fastlock_delay_ns; + bool trx_fastlock_pinctrl_en[2]; + + enum ad9361_clkout ad9361_clkout_mode; + + struct gain_control gain_ctrl; + struct rssi_control rssi_ctrl; + struct port_control port_ctrl; + struct ctrl_outs_control ctrl_outs_ctrl; + struct elna_control elna_ctrl; + struct auxadc_control auxadc_ctrl; + struct auxdac_control auxdac_ctrl; + struct gpo_control gpo_ctrl; + struct tx_monitor_control txmon_ctrl; +}; + +struct rf_rx_gain { + uint32_t ant; /* Antenna number to read gain */ + int32_t gain_db; /* gain value in dB */ + uint32_t fgt_lmt_index; /* Full Gain Table / LNA-MIXER-TIA gain index */ + uint32_t lmt_gain; /* LNA-MIXER-TIA gain in dB (Split GT mode only)*/ + uint32_t lpf_gain; /* Low pass filter gain in dB / index (Split GT mode only)*/ + uint32_t digital_gain; /* Digital gain in dB / index */ + /* Debug only */ + uint32_t lna_index; /* LNA Index (Split GT mode only) */ + uint32_t tia_index; /* TIA Index (Split GT mode only) */ + uint32_t mixer_index; /* MIXER Index (Split GT mode only) */ + +}; +struct rf_rssi { + uint32_t ant; /* Antenna number for which RSSI is reported */ + uint32_t symbol; /* Runtime RSSI */ + uint32_t preamble; /* Initial RSSI */ + int32_t multiplier; /* Multiplier to convert reported RSSI */ + uint8_t duration; /* Duration to be considered for measuring */ +}; + +struct SynthLUT { + uint16_t VCO_MHz; + uint8_t VCO_Output_Level; + uint8_t VCO_Varactor; + uint8_t VCO_Bias_Ref; + uint8_t VCO_Bias_Tcf; + uint8_t VCO_Cal_Offset; + uint8_t VCO_Varactor_Reference; + uint8_t Charge_Pump_Current; + uint8_t LF_C2; + uint8_t LF_C1; + uint8_t LF_R1; + uint8_t LF_C3; + uint8_t LF_R3; +}; + +enum { + LUT_FTDD_40, + LUT_FTDD_60, + LUT_FTDD_80, + LUT_FTDD_ENT, +}; + +enum ad9361_clocks { + BB_REFCLK, + RX_REFCLK, + TX_REFCLK, + BBPLL_CLK, + ADC_CLK, + R2_CLK, + R1_CLK, + CLKRF_CLK, + RX_SAMPL_CLK, + DAC_CLK, + T2_CLK, + T1_CLK, + CLKTF_CLK, + TX_SAMPL_CLK, + RX_RFPLL_INT, + TX_RFPLL_INT, + RX_RFPLL_DUMMY, + TX_RFPLL_DUMMY, + RX_RFPLL, + TX_RFPLL, + NUM_AD9361_CLKS, + EXT_REF_CLK, +}; + +struct ad9361_debugfs_entry { + struct ad9361_rf_phy *phy; + const char *propname; + void *out_value; + uint32_t val; + uint8_t size; + uint8_t cmd; +}; + +struct ad9361_fastlock_entry { +#define FASTLOOK_INIT 1 + uint8_t flags; + uint8_t alc_orig; + uint8_t alc_written; +}; + +struct ad9361_fastlock { + uint8_t save_profile; + uint8_t current_profile[2]; + struct ad9361_fastlock_entry entry[2][8]; +}; + +enum dig_tune_flags { + BE_VERBOSE = 1, + BE_MOREVERBOSE = 2, + DO_IDELAY = 4, + DO_ODELAY = 8, + SKIP_STORE_RESULT = 16, + RESTORE_DEFAULT = 32, +}; + +enum ad9361_bist_mode { + BIST_DISABLE, + BIST_INJ_TX, + BIST_INJ_RX, +}; + +enum synth_pd_ctrl { + LO_DONTCARE, + LO_OFF, + LO_ON, +}; + +enum dev_id { + ID_AD9361, + ID_AD9364, + ID_AD9363A +}; + +struct ad9361_rf_phy { + enum dev_id dev_sel; + struct spi_desc *spi; + struct gpio_desc *gpio_desc_resetb; + struct gpio_desc *gpio_desc_sync; + struct gpio_desc *gpio_desc_cal_sw1; + struct gpio_desc *gpio_desc_cal_sw2; +#ifndef AXI_ADC_NOT_PRESENT + struct axi_adc *rx_adc; + struct axi_dac *tx_dac; +#endif + struct clk *clk_refin; + struct clk *clks[NUM_AD9361_CLKS]; + struct refclk_scale *ref_clk_scale[NUM_AD9361_CLKS]; + uint32_t (*ad9361_rfpll_ext_recalc_rate)(struct refclk_scale *clk_priv); + int32_t (*ad9361_rfpll_ext_round_rate)(struct refclk_scale *clk_priv, + uint32_t rate); + int32_t (*ad9361_rfpll_ext_set_rate)(struct refclk_scale *clk_priv, + uint32_t rate); + struct ad9361_phy_platform_data *pdata; + uint8_t prev_ensm_state; + uint8_t curr_ensm_state; + uint8_t cached_rx_rfpll_div; + uint8_t cached_tx_rfpll_div; + uint8_t cached_synth_pd[2]; + int32_t tx_quad_lpf_tia_match; + uint32_t current_table; + struct gain_table_info *gt_info; + bool ensm_pin_ctl_en; + + bool auto_cal_en; + bool manual_tx_quad_cal_en; + uint64_t last_tx_quad_cal_freq; + uint32_t last_tx_quad_cal_phase; + uint64_t current_tx_lo_freq; + uint64_t current_rx_lo_freq; + bool current_tx_use_tdd_table; + bool current_rx_use_tdd_table; + uint32_t current_rx_path_clks[NUM_RX_CLOCKS]; + uint32_t current_tx_path_clks[NUM_TX_CLOCKS]; + uint32_t flags; + uint32_t cal_threshold_freq; + uint32_t current_rx_bw_Hz; + uint32_t current_tx_bw_Hz; + uint32_t rxbbf_div; + uint32_t rate_governor; + bool bypass_rx_fir; + bool bypass_tx_fir; + bool rx_eq_2tx; + bool filt_valid; + uint32_t filt_rx_path_clks[NUM_RX_CLOCKS]; + uint32_t filt_tx_path_clks[NUM_TX_CLOCKS]; + uint32_t filt_rx_bw_Hz; + uint32_t filt_tx_bw_Hz; + uint8_t tx_fir_int; + uint8_t tx_fir_ntaps; + uint8_t rx_fir_dec; + uint8_t rx_fir_ntaps; + uint8_t agc_mode[2]; + bool rfdc_track_en; + bool bbdc_track_en; + bool quad_track_en; + bool txmon_tdd_en; + uint16_t auxdac1_value; + uint16_t auxdac2_value; + uint32_t tx1_atten_cached; + uint32_t tx2_atten_cached; + struct ad9361_fastlock fastlock; + struct axiadc_converter *adc_conv; + struct axiadc_state *adc_state; + int32_t bist_loopback_mode; + int32_t bist_config; + enum ad9361_bist_mode bist_prbs_mode; + enum ad9361_bist_mode bist_tone_mode; + uint32_t bist_tone_freq_Hz; + uint32_t bist_tone_level_dB; + uint32_t bist_tone_mask; + bool bbpll_initialized; +}; + +struct refclk_scale { + struct spi_desc *spi; + struct ad9361_rf_phy *phy; + uint32_t mult; + uint32_t div; + enum ad9361_clocks source; + enum ad9361_clocks parent_source; +}; + +enum debugfs_cmd { + DBGFS_NONE, + DBGFS_INIT, + DBGFS_LOOPBACK, + DBGFS_BIST_PRBS, + DBGFS_BIST_TONE, + DBGFS_BIST_DT_ANALYSIS, + DBGFS_RXGAIN_1, + DBGFS_RXGAIN_2, +}; + +/******************************************************************************/ +/************************ Functions Declarations ******************************/ +/******************************************************************************/ +int32_t ad9361_spi_readm(struct spi_desc *spi, uint32_t reg, + uint8_t *rbuf, uint32_t num); +int32_t ad9361_spi_read(struct spi_desc *spi, uint32_t reg); +int32_t ad9361_spi_write(struct spi_desc *spi, + uint32_t reg, uint32_t val); +int32_t ad9361_reset(struct ad9361_rf_phy *phy); +int32_t ad9361_register_clocks(struct ad9361_rf_phy *phy); +int32_t ad9361_unregister_clocks(struct ad9361_rf_phy *phy); +uint32_t ad9361_gt(struct ad9361_rf_phy *phy); +int32_t ad9361_init_gain_tables(struct ad9361_rf_phy *phy); +int32_t ad9361_setup(struct ad9361_rf_phy *phy); +int32_t ad9361_post_setup(struct ad9361_rf_phy *phy); +int32_t ad9361_set_ensm_mode(struct ad9361_rf_phy *phy, bool fdd, bool pinctrl); +int32_t ad9361_ensm_set_state(struct ad9361_rf_phy *phy, uint8_t ensm_state, + bool pinctrl); +int32_t ad9361_set_rx_gain(struct ad9361_rf_phy *phy, + uint32_t rx_id, struct rf_rx_gain *rx_gain); +int32_t ad9361_get_rx_gain(struct ad9361_rf_phy *phy, + uint32_t rx_id, struct rf_rx_gain *rx_gain); +int32_t ad9361_update_rf_bandwidth(struct ad9361_rf_phy *phy, + uint32_t rf_rx_bw, uint32_t rf_tx_bw); +int32_t ad9361_calculate_rf_clock_chain(struct ad9361_rf_phy *phy, + uint32_t tx_sample_rate, + uint32_t rate_gov, + uint32_t *rx_path_clks, + uint32_t *tx_path_clks); +int32_t ad9361_set_trx_clock_chain(struct ad9361_rf_phy *phy, + uint32_t *rx_path_clks, + uint32_t *tx_path_clks); +int32_t ad9361_get_trx_clock_chain(struct ad9361_rf_phy *phy, + uint32_t *rx_path_clks, + uint32_t *tx_path_clks); +uint32_t ad9361_to_clk(uint64_t freq); +uint64_t ad9361_from_clk(uint32_t freq); +int32_t ad9361_read_rssi(struct ad9361_rf_phy *phy, struct rf_rssi *rssi); +int32_t ad9361_set_gain_ctrl_mode(struct ad9361_rf_phy *phy, + struct rf_gain_ctrl *gain_ctrl); +int32_t ad9361_load_fir_filter_coef(struct ad9361_rf_phy *phy, + enum fir_dest dest, int32_t gain_dB, + uint32_t ntaps, short *coef); +int32_t ad9361_validate_enable_fir(struct ad9361_rf_phy *phy); +int32_t ad9361_set_tx_atten(struct ad9361_rf_phy *phy, uint32_t atten_mdb, + bool tx1, bool tx2, bool immed); +int32_t ad9361_get_tx_atten(struct ad9361_rf_phy *phy, uint32_t tx_num); +uint32_t ad9361_clk_factor_recalc_rate(struct refclk_scale *clk_priv, + uint32_t parent_rate); +int32_t ad9361_clk_factor_round_rate(struct refclk_scale *clk_priv, + uint32_t rate, + uint32_t *prate); +int32_t ad9361_clk_factor_set_rate(struct refclk_scale *clk_priv, uint32_t rate, + uint32_t parent_rate); +uint32_t ad9361_bbpll_recalc_rate(struct refclk_scale *clk_priv, + uint32_t parent_rate); +int32_t ad9361_bbpll_round_rate(struct refclk_scale *clk_priv, uint32_t rate, + uint32_t *prate); +int32_t ad9361_bbpll_set_rate(struct refclk_scale *clk_priv, uint32_t rate, + uint32_t parent_rate); +uint32_t ad9361_rfpll_int_recalc_rate(struct refclk_scale *clk_priv, + uint32_t parent_rate); +int32_t ad9361_rfpll_int_round_rate(struct refclk_scale *clk_priv, + uint32_t rate, + uint32_t *prate); +int32_t ad9361_rfpll_int_set_rate(struct refclk_scale *clk_priv, uint32_t rate, + uint32_t parent_rate); +uint32_t ad9361_rfpll_dummy_recalc_rate(struct refclk_scale *clk_priv); +int32_t ad9361_rfpll_dummy_set_rate(struct refclk_scale *clk_priv, + uint32_t rate); +uint32_t ad9361_rfpll_recalc_rate(struct refclk_scale *clk_priv); +int32_t ad9361_rfpll_round_rate(struct refclk_scale *clk_priv, uint32_t rate); +int32_t ad9361_rfpll_set_rate(struct refclk_scale *clk_priv, uint32_t rate); +int32_t ad9361_clk_mux_set_parent(struct refclk_scale *clk_priv, uint8_t index); +int32_t ad9361_tracking_control(struct ad9361_rf_phy *phy, bool bbdc_track, + bool rfdc_track, bool rxquad_track); +int32_t ad9361_bist_loopback(struct ad9361_rf_phy *phy, int32_t mode); +void ad9361_get_bist_loopback(struct ad9361_rf_phy *phy, int32_t *mode); +int32_t ad9361_bist_prbs(struct ad9361_rf_phy *phy, enum ad9361_bist_mode mode); +void ad9361_get_bist_prbs(struct ad9361_rf_phy *phy, + enum ad9361_bist_mode *mode); +int32_t ad9361_bist_tone(struct ad9361_rf_phy *phy, + enum ad9361_bist_mode mode, uint32_t freq_Hz, + uint32_t level_dB, uint32_t mask); +void ad9361_get_bist_tone(struct ad9361_rf_phy *phy, + enum ad9361_bist_mode *mode, uint32_t *freq_Hz, + uint32_t *level_dB, uint32_t *mask); +int32_t ad9361_rf_port_setup(struct ad9361_rf_phy *phy, bool is_out, + uint32_t rx_inputs, uint32_t txb); +int32_t ad9361_mcs(struct ad9361_rf_phy *phy, int32_t step); +int32_t ad9361_do_calib_run(struct ad9361_rf_phy *phy, uint32_t cal, + int32_t arg); +int32_t ad9361_fastlock_store(struct ad9361_rf_phy *phy, bool tx, + uint32_t profile); +int32_t ad9361_fastlock_recall(struct ad9361_rf_phy *phy, bool tx, + uint32_t profile); +int32_t ad9361_fastlock_load(struct ad9361_rf_phy *phy, bool tx, + uint32_t profile, uint8_t *values); +int32_t ad9361_fastlock_save(struct ad9361_rf_phy *phy, bool tx, + uint32_t profile, uint8_t *values); +void ad9361_ensm_force_state(struct ad9361_rf_phy *phy, uint8_t ensm_state); +uint8_t ad9361_ensm_get_state(struct ad9361_rf_phy *phy); +void ad9361_ensm_restore_state(struct ad9361_rf_phy *phy, uint8_t ensm_state); +void ad9361_ensm_restore_prev_state(struct ad9361_rf_phy *phy); +int32_t ad9361_set_trx_clock_chain_freq(struct ad9361_rf_phy *phy, + uint32_t freq); +int32_t ad9361_find_opt(uint8_t *field, uint32_t size, uint32_t *ret_start); +int32_t ad9361_hdl_loopback(struct ad9361_rf_phy *phy, bool enable); +int32_t ad9361_dig_interface_timing_analysis(struct ad9361_rf_phy *phy, + char *buf, int32_t buflen); +int32_t ad9361_dig_tune(struct ad9361_rf_phy *phy, uint32_t max_freq, + enum dig_tune_flags flags); +int32_t ad9361_en_dis_tx(struct ad9361_rf_phy *phy, uint32_t tx_if, + uint32_t enable); +int32_t ad9361_en_dis_rx(struct ad9361_rf_phy *phy, uint32_t rx_if, + uint32_t enable); +int32_t ad9361_1rx1tx_channel_map(struct ad9361_rf_phy *phy, bool tx, + int32_t channel); +int32_t ad9361_rssi_gain_step_calib(struct ad9361_rf_phy *phy); +int32_t ad9361_set_dcxo_tune(struct ad9361_rf_phy *phy, + uint32_t coarse, uint32_t fine); +int32_t ad9361_tx_mute(struct ad9361_rf_phy *phy, uint32_t state); +uint32_t ad9361_validate_rf_bw(struct ad9361_rf_phy *phy, uint32_t bw); +int32_t ad9361_get_temp(struct ad9361_rf_phy *phy); +int ad9361_synth_lo_powerdown(struct ad9361_rf_phy *phy, + enum synth_pd_ctrl rx, + enum synth_pd_ctrl tx); +void ad9361_clear_state(struct ad9361_rf_phy *phy); +#endif diff --git a/df_datalink_sp/src/drivers/rf-transceiver/ad9361/ad9361_api.c b/df_datalink_sp/src/drivers/rf-transceiver/ad9361/ad9361_api.c new file mode 100644 index 0000000..12fc513 --- /dev/null +++ b/df_datalink_sp/src/drivers/rf-transceiver/ad9361/ad9361_api.c @@ -0,0 +1,2157 @@ +/***************************************************************************//** + * @file ad9361_api.c + * @brief Implementation of AD9361 API Driver. + * @author DBogdan (dragos.bogdan@analog.com) +******************************************************************************** + * Copyright 2013(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ +#include +#include "ad9361.h" +#include "ad9361_api.h" +#include "delay.h" +#include "spi.h" +#include "util.h" +#include "../../../config/app_config.h" + +/******************************************************************************/ +/************************ Constants Definitions *******************************/ +/******************************************************************************/ + +extern struct gain_table_info ad9361_adi_gt_info[]; + +/** + * Initialize the AD9361 part. + * @param ad9361_phy The AD9361 device structure. + * @param init_param The structure that contains the AD9361 initial parameters. + * @return 0 in case of success, negative error code otherwise. + * + * Note: This function will/may affect the data path. + */ +int32_t ad9361_init (struct ad9361_rf_phy **ad9361_phy, + AD9361_InitParam *init_param) +{ + struct ad9361_rf_phy *phy; + int32_t ret = 0; + int32_t rev = 0; + int32_t i = 0; + + phy = (struct ad9361_rf_phy *)zmalloc(sizeof(*phy)); + if (!phy) { + return -ENOMEM; + } + + phy->clk_refin = (struct clk *)zmalloc(sizeof(*phy->clk_refin)); + if (!phy->clk_refin) { + return -ENOMEM; + } + + phy->pdata = (struct ad9361_phy_platform_data *)zmalloc(sizeof(*phy->pdata)); + if (!phy->pdata) { + return -ENOMEM; + } + + /* Device selection */ + phy->dev_sel = init_param->dev_sel; + + /* Reference Clock */ + phy->clk_refin->rate = init_param->reference_clk_rate; + + /* Base Configuration */ + phy->pdata->fdd = init_param->frequency_division_duplex_mode_enable; + phy->pdata->fdd_independent_mode = + init_param->frequency_division_duplex_independent_mode_enable; + phy->pdata->rx2tx2 = init_param->two_rx_two_tx_mode_enable; + phy->pdata->rx1tx1_mode_use_rx_num = init_param->one_rx_one_tx_mode_use_rx_num; + phy->pdata->rx1tx1_mode_use_tx_num = init_param->one_rx_one_tx_mode_use_tx_num; + phy->pdata->tdd_use_dual_synth = init_param->tdd_use_dual_synth_mode_enable; + phy->pdata->tdd_skip_vco_cal = init_param->tdd_skip_vco_cal_enable; + phy->pdata->rx_fastlock_delay_ns = init_param->rx_fastlock_delay_ns; + phy->pdata->tx_fastlock_delay_ns = init_param->tx_fastlock_delay_ns; + phy->pdata->trx_fastlock_pinctrl_en[0] = + init_param->rx_fastlock_pincontrol_enable; + phy->pdata->trx_fastlock_pinctrl_en[1] = + init_param->tx_fastlock_pincontrol_enable; + if (phy->dev_sel == ID_AD9363A) { + phy->pdata->use_ext_rx_lo = false; + phy->pdata->use_ext_tx_lo = false; + } else { + phy->pdata->use_ext_rx_lo = init_param->external_rx_lo_enable; + phy->pdata->use_ext_tx_lo = init_param->external_tx_lo_enable; + } + phy->pdata->dc_offset_update_events = + init_param->dc_offset_tracking_update_event_mask; + phy->pdata->dc_offset_attenuation_high = + init_param->dc_offset_attenuation_high_range; + phy->pdata->dc_offset_attenuation_low = + init_param->dc_offset_attenuation_low_range; + phy->pdata->rf_dc_offset_count_high = init_param->dc_offset_count_high_range; + phy->pdata->rf_dc_offset_count_low = init_param->dc_offset_count_low_range; + phy->pdata->split_gt = init_param->split_gain_table_mode_enable; + phy->pdata->trx_synth_max_fref = + init_param->trx_synthesizer_target_fref_overwrite_hz; + phy->pdata->qec_tracking_slow_mode_en = + init_param->qec_tracking_slow_mode_enable; + + /* ENSM Control */ + phy->pdata->ensm_pin_pulse_mode = init_param->ensm_enable_pin_pulse_mode_enable; + phy->pdata->ensm_pin_ctrl = init_param->ensm_enable_txnrx_control_enable; + + /* LO Control */ + phy->pdata->rx_synth_freq = init_param->rx_synthesizer_frequency_hz; + phy->pdata->tx_synth_freq = init_param->tx_synthesizer_frequency_hz; + phy->pdata->lo_powerdown_managed_en = + init_param->tx_lo_powerdown_managed_enable; + + /* Rate & BW Control */ + for(i = 0; i < 6; i++) { + phy->pdata->rx_path_clks[i] = init_param->rx_path_clock_frequencies[i]; + } + for(i = 0; i < 6; i++) { + phy->pdata->tx_path_clks[i] = init_param->tx_path_clock_frequencies[i]; + } + phy->pdata->rf_rx_bandwidth_Hz = init_param->rf_rx_bandwidth_hz; + phy->pdata->rf_tx_bandwidth_Hz = init_param->rf_tx_bandwidth_hz; + + /* RF Port Control */ + phy->pdata->rf_rx_input_sel = init_param->rx_rf_port_input_select; + phy->pdata->rf_tx_output_sel = init_param->tx_rf_port_input_select; + + /* TX Attenuation Control */ + phy->pdata->tx_atten = init_param->tx_attenuation_mdB; + phy->pdata->update_tx_gain_via_alert = + init_param->update_tx_gain_in_alert_enable; + + /* Reference Clock Control */ + switch (phy->dev_sel) { + case ID_AD9363A: + phy->pdata->use_extclk = true; + break; + default: + phy->pdata->use_extclk = init_param->xo_disable_use_ext_refclk_enable; + } + phy->pdata->dcxo_coarse = init_param->dcxo_coarse_and_fine_tune[0]; + phy->pdata->dcxo_fine = init_param->dcxo_coarse_and_fine_tune[1]; + phy->pdata->ad9361_clkout_mode = (enum ad9361_clkout) + init_param->clk_output_mode_select; + + /* Gain Control */ + phy->pdata->gain_ctrl.rx1_mode = (enum rf_gain_ctrl_mode) + init_param->gc_rx1_mode; + phy->pdata->gain_ctrl.rx2_mode = (enum rf_gain_ctrl_mode) + init_param->gc_rx2_mode; + phy->pdata->gain_ctrl.adc_large_overload_thresh = + init_param->gc_adc_large_overload_thresh; + phy->pdata->gain_ctrl.adc_ovr_sample_size = init_param->gc_adc_ovr_sample_size; + phy->pdata->gain_ctrl.adc_small_overload_thresh = + init_param->gc_adc_small_overload_thresh; + phy->pdata->gain_ctrl.dec_pow_measuremnt_duration = + init_param->gc_dec_pow_measurement_duration; + phy->pdata->gain_ctrl.dig_gain_en = init_param->gc_dig_gain_enable; + phy->pdata->gain_ctrl.lmt_overload_high_thresh = + init_param->gc_lmt_overload_high_thresh; + phy->pdata->gain_ctrl.lmt_overload_low_thresh = + init_param->gc_lmt_overload_low_thresh; + phy->pdata->gain_ctrl.low_power_thresh = init_param->gc_low_power_thresh; + phy->pdata->gain_ctrl.max_dig_gain = init_param->gc_max_dig_gain; + phy->pdata->gain_ctrl.use_rx_fir_out_for_dec_pwr_meas = + init_param->gc_use_rx_fir_out_for_dec_pwr_meas_enable; + + /* Gain MGC Control */ + phy->pdata->gain_ctrl.mgc_dec_gain_step = init_param->mgc_dec_gain_step; + phy->pdata->gain_ctrl.mgc_inc_gain_step = init_param->mgc_inc_gain_step; + phy->pdata->gain_ctrl.mgc_rx1_ctrl_inp_en = init_param->mgc_rx1_ctrl_inp_enable; + phy->pdata->gain_ctrl.mgc_rx2_ctrl_inp_en = init_param->mgc_rx2_ctrl_inp_enable; + phy->pdata->gain_ctrl.mgc_split_table_ctrl_inp_gain_mode = + init_param->mgc_split_table_ctrl_inp_gain_mode; + + /* Gain AGC Control */ + phy->pdata->gain_ctrl.adc_large_overload_exceed_counter = + init_param->agc_adc_large_overload_exceed_counter; + phy->pdata->gain_ctrl.adc_large_overload_inc_steps = + init_param->agc_adc_large_overload_inc_steps; + phy->pdata->gain_ctrl.adc_lmt_small_overload_prevent_gain_inc = + init_param->agc_adc_lmt_small_overload_prevent_gain_inc_enable; + phy->pdata->gain_ctrl.adc_small_overload_exceed_counter = + init_param->agc_adc_small_overload_exceed_counter; + phy->pdata->gain_ctrl.dig_gain_step_size = init_param->agc_dig_gain_step_size; + phy->pdata->gain_ctrl.dig_saturation_exceed_counter = + init_param->agc_dig_saturation_exceed_counter; + phy->pdata->gain_ctrl.gain_update_interval_us = + init_param->agc_gain_update_interval_us; + phy->pdata->gain_ctrl.immed_gain_change_if_large_adc_overload = + init_param->agc_immed_gain_change_if_large_adc_overload_enable; + phy->pdata->gain_ctrl.immed_gain_change_if_large_lmt_overload = + init_param->agc_immed_gain_change_if_large_lmt_overload_enable; + phy->pdata->gain_ctrl.agc_inner_thresh_high = init_param->agc_inner_thresh_high; + phy->pdata->gain_ctrl.agc_inner_thresh_high_dec_steps = + init_param->agc_inner_thresh_high_dec_steps; + phy->pdata->gain_ctrl.agc_inner_thresh_low = init_param->agc_inner_thresh_low; + phy->pdata->gain_ctrl.agc_inner_thresh_low_inc_steps = + init_param->agc_inner_thresh_low_inc_steps; + phy->pdata->gain_ctrl.lmt_overload_large_exceed_counter = + init_param->agc_lmt_overload_large_exceed_counter; + phy->pdata->gain_ctrl.lmt_overload_large_inc_steps = + init_param->agc_lmt_overload_large_inc_steps; + phy->pdata->gain_ctrl.lmt_overload_small_exceed_counter = + init_param->agc_lmt_overload_small_exceed_counter; + phy->pdata->gain_ctrl.agc_outer_thresh_high = init_param->agc_outer_thresh_high; + phy->pdata->gain_ctrl.agc_outer_thresh_high_dec_steps = + init_param->agc_outer_thresh_high_dec_steps; + phy->pdata->gain_ctrl.agc_outer_thresh_low = init_param->agc_outer_thresh_low; + phy->pdata->gain_ctrl.agc_outer_thresh_low_inc_steps = + init_param->agc_outer_thresh_low_inc_steps; + phy->pdata->gain_ctrl.agc_attack_delay_extra_margin_us = + init_param->agc_attack_delay_extra_margin_us; + phy->pdata->gain_ctrl.sync_for_gain_counter_en = + init_param->agc_sync_for_gain_counter_enable; + + /* Fast AGC */ + phy->pdata->gain_ctrl.f_agc_dec_pow_measuremnt_duration = + init_param->fagc_dec_pow_measuremnt_duration; + phy->pdata->gain_ctrl.f_agc_state_wait_time_ns = + init_param->fagc_state_wait_time_ns; + /* Fast AGC - Low Power */ + phy->pdata->gain_ctrl.f_agc_allow_agc_gain_increase = + init_param->fagc_allow_agc_gain_increase; + phy->pdata->gain_ctrl.f_agc_lp_thresh_increment_time = + init_param->fagc_lp_thresh_increment_time; + phy->pdata->gain_ctrl.f_agc_lp_thresh_increment_steps = + init_param->fagc_lp_thresh_increment_steps; + /* Fast AGC - Lock Level (Lock Level is set via slow AGC inner high threshold) */ + phy->pdata->gain_ctrl.f_agc_lock_level_lmt_gain_increase_en = + init_param->fagc_lock_level_lmt_gain_increase_en; + phy->pdata->gain_ctrl.f_agc_lock_level_gain_increase_upper_limit = + init_param->fagc_lock_level_gain_increase_upper_limit; + /* Fast AGC - Peak Detectors and Final Settling */ + phy->pdata->gain_ctrl.f_agc_lpf_final_settling_steps = + init_param->fagc_lpf_final_settling_steps; + phy->pdata->gain_ctrl.f_agc_lmt_final_settling_steps = + init_param->fagc_lmt_final_settling_steps; + phy->pdata->gain_ctrl.f_agc_final_overrange_count = + init_param->fagc_final_overrange_count; + /* Fast AGC - Final Power Test */ + phy->pdata->gain_ctrl.f_agc_gain_increase_after_gain_lock_en = + init_param->fagc_gain_increase_after_gain_lock_en; + /* Fast AGC - Unlocking the Gain */ + phy->pdata->gain_ctrl.f_agc_gain_index_type_after_exit_rx_mode = + (enum f_agc_target_gain_index_type) + init_param->fagc_gain_index_type_after_exit_rx_mode; + phy->pdata->gain_ctrl.f_agc_use_last_lock_level_for_set_gain_en = + init_param->fagc_use_last_lock_level_for_set_gain_en; + phy->pdata->gain_ctrl.f_agc_rst_gla_stronger_sig_thresh_exceeded_en = + init_param->fagc_rst_gla_stronger_sig_thresh_exceeded_en; + phy->pdata->gain_ctrl.f_agc_optimized_gain_offset = + init_param->fagc_optimized_gain_offset; + phy->pdata->gain_ctrl.f_agc_rst_gla_stronger_sig_thresh_above_ll = + init_param->fagc_rst_gla_stronger_sig_thresh_above_ll; + phy->pdata->gain_ctrl.f_agc_rst_gla_engergy_lost_sig_thresh_exceeded_en = + init_param->fagc_rst_gla_engergy_lost_sig_thresh_exceeded_en; + phy->pdata->gain_ctrl.f_agc_rst_gla_engergy_lost_goto_optim_gain_en = + init_param->fagc_rst_gla_engergy_lost_goto_optim_gain_en; + phy->pdata->gain_ctrl.f_agc_rst_gla_engergy_lost_sig_thresh_below_ll = + init_param->fagc_rst_gla_engergy_lost_sig_thresh_below_ll; + phy->pdata->gain_ctrl.f_agc_energy_lost_stronger_sig_gain_lock_exit_cnt = + init_param->fagc_energy_lost_stronger_sig_gain_lock_exit_cnt; + phy->pdata->gain_ctrl.f_agc_rst_gla_large_adc_overload_en = + init_param->fagc_rst_gla_large_adc_overload_en; + phy->pdata->gain_ctrl.f_agc_rst_gla_large_lmt_overload_en = + init_param->fagc_rst_gla_large_lmt_overload_en; + phy->pdata->gain_ctrl.f_agc_rst_gla_en_agc_pulled_high_en = + init_param->fagc_rst_gla_en_agc_pulled_high_en; + phy->pdata->gain_ctrl.f_agc_rst_gla_if_en_agc_pulled_high_mode = + (enum f_agc_target_gain_index_type) + init_param->fagc_rst_gla_if_en_agc_pulled_high_mode; + phy->pdata->gain_ctrl.f_agc_power_measurement_duration_in_state5 = + init_param->fagc_power_measurement_duration_in_state5; + phy->pdata->gain_ctrl.f_agc_large_overload_inc_steps = + init_param->fagc_large_overload_inc_steps; + + /* RSSI Control */ + phy->pdata->rssi_ctrl.rssi_delay = init_param->rssi_delay; + phy->pdata->rssi_ctrl.rssi_duration = init_param->rssi_duration; + phy->pdata->rssi_ctrl.restart_mode = (enum rssi_restart_mode) + init_param->rssi_restart_mode; + phy->pdata->rssi_ctrl.rssi_unit_is_rx_samples = + init_param->rssi_unit_is_rx_samples_enable; + phy->pdata->rssi_ctrl.rssi_wait = init_param->rssi_wait; + + /* Aux ADC Control */ + phy->pdata->auxadc_ctrl.auxadc_decimation = init_param->aux_adc_decimation; + phy->pdata->auxadc_ctrl.auxadc_clock_rate = init_param->aux_adc_rate; + + /* AuxDAC Control */ + phy->pdata->auxdac_ctrl.auxdac_manual_mode_en = + init_param->aux_dac_manual_mode_enable; + phy->pdata->auxdac_ctrl.dac1_default_value = + init_param->aux_dac1_default_value_mV; + phy->pdata->auxdac_ctrl.dac1_in_rx_en = + init_param->aux_dac1_active_in_rx_enable; + phy->pdata->auxdac_ctrl.dac1_in_tx_en = + init_param->aux_dac1_active_in_tx_enable; + phy->pdata->auxdac_ctrl.dac1_in_alert_en = + init_param->aux_dac1_active_in_alert_enable; + phy->pdata->auxdac_ctrl.dac1_rx_delay_us = init_param->aux_dac1_rx_delay_us; + phy->pdata->auxdac_ctrl.dac1_tx_delay_us = init_param->aux_dac1_tx_delay_us; + phy->pdata->auxdac_ctrl.dac2_default_value = + init_param->aux_dac2_default_value_mV; + phy->pdata->auxdac_ctrl.dac2_in_rx_en = + init_param->aux_dac2_active_in_rx_enable; + phy->pdata->auxdac_ctrl.dac2_in_tx_en = + init_param->aux_dac2_active_in_tx_enable; + phy->pdata->auxdac_ctrl.dac2_in_alert_en = + init_param->aux_dac2_active_in_alert_enable; + phy->pdata->auxdac_ctrl.dac2_rx_delay_us = init_param->aux_dac2_rx_delay_us; + phy->pdata->auxdac_ctrl.dac2_tx_delay_us = init_param->aux_dac2_tx_delay_us; + + /* Temperature Sensor Control */ + phy->pdata->auxadc_ctrl.temp_sensor_decimation = + init_param->temp_sense_decimation; + phy->pdata->auxadc_ctrl.temp_time_inteval_ms = + init_param->temp_sense_measurement_interval_ms; + phy->pdata->auxadc_ctrl.offset = init_param->temp_sense_offset_signed; + phy->pdata->auxadc_ctrl.periodic_temp_measuremnt = + init_param->temp_sense_periodic_measurement_enable; + + /* Control Out Setup */ + phy->pdata->ctrl_outs_ctrl.en_mask = init_param->ctrl_outs_enable_mask; + phy->pdata->ctrl_outs_ctrl.index = init_param->ctrl_outs_index; + + /* External LNA Control */ + phy->pdata->elna_ctrl.settling_delay_ns = init_param->elna_settling_delay_ns; + phy->pdata->elna_ctrl.gain_mdB = init_param->elna_gain_mdB; + phy->pdata->elna_ctrl.bypass_loss_mdB = init_param->elna_bypass_loss_mdB; + phy->pdata->elna_ctrl.elna_1_control_en = + init_param->elna_rx1_gpo0_control_enable; + phy->pdata->elna_ctrl.elna_2_control_en = + init_param->elna_rx2_gpo1_control_enable; + phy->pdata->elna_ctrl.elna_in_gaintable_all_index_en = + init_param->elna_gaintable_all_index_enable; + + /* Digital Interface Control */ + phy->pdata->dig_interface_tune_skipmode = + (init_param->digital_interface_tune_skip_mode); + phy->pdata->dig_interface_tune_fir_disable = + (init_param->digital_interface_tune_fir_disable); + phy->pdata->port_ctrl.pp_conf[0] = (init_param->pp_tx_swap_enable << 7); + phy->pdata->port_ctrl.pp_conf[0] |= (init_param->pp_rx_swap_enable << 6); + phy->pdata->port_ctrl.pp_conf[0] |= (init_param->tx_channel_swap_enable << 5); + phy->pdata->port_ctrl.pp_conf[0] |= (init_param->rx_channel_swap_enable << 4); + phy->pdata->port_ctrl.pp_conf[0] |= (init_param->rx_frame_pulse_mode_enable << + 3); + phy->pdata->port_ctrl.pp_conf[0] |= (init_param->two_t_two_r_timing_enable << + 2); + phy->pdata->port_ctrl.pp_conf[0] |= (init_param->invert_data_bus_enable << 1); + phy->pdata->port_ctrl.pp_conf[0] |= (init_param->invert_data_clk_enable << 0); + phy->pdata->port_ctrl.pp_conf[1] = (init_param->fdd_alt_word_order_enable << 7); + phy->pdata->port_ctrl.pp_conf[1] |= (init_param->invert_rx_frame_enable << 2); + phy->pdata->port_ctrl.pp_conf[2] = (init_param->fdd_rx_rate_2tx_enable << 7); + phy->pdata->port_ctrl.pp_conf[2] |= (init_param->swap_ports_enable << 6); + phy->pdata->port_ctrl.pp_conf[2] |= (init_param->single_data_rate_enable << 5); + phy->pdata->port_ctrl.pp_conf[2] |= (init_param->lvds_mode_enable << 4); + phy->pdata->port_ctrl.pp_conf[2] |= (init_param->half_duplex_mode_enable << 3); + phy->pdata->port_ctrl.pp_conf[2] |= (init_param->single_port_mode_enable << 2); + phy->pdata->port_ctrl.pp_conf[2] |= (init_param->full_port_enable << 1); + phy->pdata->port_ctrl.pp_conf[2] |= (init_param->full_duplex_swap_bits_enable << + 0); + phy->pdata->port_ctrl.pp_conf[1] |= (init_param->delay_rx_data & 0x3); + phy->pdata->port_ctrl.rx_clk_data_delay = DATA_CLK_DELAY( + init_param->rx_data_clock_delay); + phy->pdata->port_ctrl.rx_clk_data_delay |= RX_DATA_DELAY( + init_param->rx_data_delay); + phy->pdata->port_ctrl.tx_clk_data_delay = FB_CLK_DELAY( + init_param->tx_fb_clock_delay); + phy->pdata->port_ctrl.tx_clk_data_delay |= TX_DATA_DELAY( + init_param->tx_data_delay); + phy->pdata->port_ctrl.lvds_bias_ctrl = ((init_param->lvds_bias_mV - 75) / 75) & + 0x7; + phy->pdata->port_ctrl.lvds_bias_ctrl |= + (init_param->lvds_rx_onchip_termination_enable << 5); + phy->pdata->rx1rx2_phase_inversion_en = init_param->rx1rx2_phase_inversion_en; + + /* GPO Control */ + phy->pdata->gpo_ctrl.gpo_manual_mode_en = + init_param->gpo_manual_mode_enable; + phy->pdata->gpo_ctrl.gpo_manual_mode_enable_mask = + init_param->gpo_manual_mode_enable_mask; + phy->pdata->gpo_ctrl.gpo0_inactive_state_high_en = + init_param->gpo0_inactive_state_high_enable; + phy->pdata->gpo_ctrl.gpo1_inactive_state_high_en = + init_param->gpo1_inactive_state_high_enable; + phy->pdata->gpo_ctrl.gpo2_inactive_state_high_en = + init_param->gpo2_inactive_state_high_enable; + phy->pdata->gpo_ctrl.gpo3_inactive_state_high_en = + init_param->gpo3_inactive_state_high_enable; + + phy->pdata->gpo_ctrl.gpo0_slave_rx_en = init_param->gpo0_slave_rx_enable; + phy->pdata->gpo_ctrl.gpo0_slave_tx_en = init_param->gpo0_slave_tx_enable; + phy->pdata->gpo_ctrl.gpo1_slave_rx_en = init_param->gpo1_slave_rx_enable; + phy->pdata->gpo_ctrl.gpo1_slave_tx_en = init_param->gpo1_slave_tx_enable; + phy->pdata->gpo_ctrl.gpo2_slave_rx_en = init_param->gpo2_slave_rx_enable; + phy->pdata->gpo_ctrl.gpo2_slave_tx_en = init_param->gpo2_slave_tx_enable; + phy->pdata->gpo_ctrl.gpo3_slave_rx_en = init_param->gpo3_slave_rx_enable; + phy->pdata->gpo_ctrl.gpo3_slave_tx_en = init_param->gpo3_slave_tx_enable; + + phy->pdata->gpo_ctrl.gpo0_rx_delay_us = init_param->gpo0_rx_delay_us; + phy->pdata->gpo_ctrl.gpo0_tx_delay_us = init_param->gpo0_tx_delay_us; + phy->pdata->gpo_ctrl.gpo1_rx_delay_us = init_param->gpo1_rx_delay_us; + phy->pdata->gpo_ctrl.gpo1_tx_delay_us = init_param->gpo1_tx_delay_us; + phy->pdata->gpo_ctrl.gpo2_rx_delay_us = init_param->gpo2_rx_delay_us; + phy->pdata->gpo_ctrl.gpo2_tx_delay_us = init_param->gpo2_tx_delay_us; + phy->pdata->gpo_ctrl.gpo3_rx_delay_us = init_param->gpo3_rx_delay_us; + phy->pdata->gpo_ctrl.gpo3_tx_delay_us = init_param->gpo3_tx_delay_us; + + /* Tx Monitor Control */ + phy->pdata->txmon_ctrl.low_high_gain_threshold_mdB = + init_param->low_high_gain_threshold_mdB; + phy->pdata->txmon_ctrl.low_gain_dB = init_param->low_gain_dB; + phy->pdata->txmon_ctrl.high_gain_dB = init_param->high_gain_dB; + phy->pdata->txmon_ctrl.tx_mon_track_en = init_param->tx_mon_track_en; + phy->pdata->txmon_ctrl.one_shot_mode_en = init_param->one_shot_mode_en; + phy->pdata->txmon_ctrl.tx_mon_delay = init_param->tx_mon_delay; + phy->pdata->txmon_ctrl.tx_mon_duration = init_param->tx_mon_duration; + phy->pdata->txmon_ctrl.tx1_mon_front_end_gain = + init_param->tx1_mon_front_end_gain; + phy->pdata->txmon_ctrl.tx2_mon_front_end_gain = + init_param->tx2_mon_front_end_gain; + phy->pdata->txmon_ctrl.tx1_mon_lo_cm = init_param->tx1_mon_lo_cm; + phy->pdata->txmon_ctrl.tx2_mon_lo_cm = init_param->tx2_mon_lo_cm; + + phy->pdata->debug_mode = true; + + gpio_get(&phy->gpio_desc_resetb, &init_param->gpio_resetb); + /* Optional: next three GPIOs are used for MCS synchronization */ + gpio_get_optional(&phy->gpio_desc_sync, &init_param->gpio_sync); + gpio_get_optional(&phy->gpio_desc_cal_sw1, &init_param->gpio_cal_sw1); + gpio_get_optional(&phy->gpio_desc_cal_sw2, &init_param->gpio_cal_sw2); + + gpio_direction_output(phy->gpio_desc_resetb, 0); + + spi_init(&phy->spi, &init_param->spi_param); + + phy->pdata->port_ctrl.digital_io_ctrl = 0; + phy->pdata->port_ctrl.lvds_invert[0] = init_param->lvds_invert1_control; + phy->pdata->port_ctrl.lvds_invert[1] = init_param->lvds_invert2_control; + + if (AD9364_DEVICE) { + phy->pdata->rx2tx2 = false; + phy->pdata->rx1tx1_mode_use_rx_num = 1; + phy->pdata->rx1tx1_mode_use_tx_num = 1; + } + + phy->rx_eq_2tx = false; + + phy->current_table = -1; + phy->bypass_tx_fir = true; + phy->bypass_rx_fir = true; + phy->rate_governor = 1; + phy->rfdc_track_en = true; + phy->bbdc_track_en = true; + phy->quad_track_en = true; + + phy->gt_info = ad9361_adi_gt_info; + + phy->bist_loopback_mode = 0; + phy->bist_config = 0; + phy->bist_prbs_mode = BIST_DISABLE; + phy->bist_tone_mode = BIST_DISABLE; + phy->bist_tone_freq_Hz = 0; + phy->bist_tone_level_dB = 0; + phy->bist_tone_mask = 0; + + ad9361_reset(phy); + + ret = ad9361_spi_read(phy->spi, REG_PRODUCT_ID); + if ((ret & PRODUCT_ID_MASK) != PRODUCT_ID_9361) { + printf("%s : Unsupported PRODUCT_ID 0x%X", __func__, (unsigned int)ret); + ret = -ENODEV; + goto out; + } + rev = ret & REV_MASK; + + phy->ad9361_rfpll_ext_recalc_rate = init_param->ad9361_rfpll_ext_recalc_rate; + phy->ad9361_rfpll_ext_round_rate = init_param->ad9361_rfpll_ext_round_rate; + phy->ad9361_rfpll_ext_set_rate = init_param->ad9361_rfpll_ext_set_rate; + + ret = ad9361_register_clocks(phy); + if (ret < 0) + goto out; + + ret = ad9361_setup(phy); + if (ret < 0) + goto out_clk; + + printf("%s : AD936x Rev %d successfully initialized\n", __func__, (int)rev); + + *ad9361_phy = phy; + + return 0; + +out_clk: + ad9361_unregister_clocks(phy); +out: + free(phy->clk_refin); + free(phy->pdata); + free(phy); + printf("%s : AD936x initialization error\n", __func__); + + return -ENODEV; +} + +/** + * Free the allocated resources. + * @param phy The AD9361 current state structure. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_remove(struct ad9361_rf_phy *phy) +{ + ad9361_unregister_clocks(phy); + spi_remove(phy->spi); + gpio_remove(phy->gpio_desc_resetb); + gpio_remove(phy->gpio_desc_sync); + gpio_remove(phy->gpio_desc_cal_sw1); + gpio_remove(phy->gpio_desc_cal_sw2); + free(phy->clk_refin); + free(phy->pdata); + free(phy); + + return 0; +} + +/** + * Set the Enable State Machine (ENSM) mode. + * @param phy The AD9361 current state structure. + * @param mode The ENSM mode. + * Accepted values: + * ENSM_MODE_TX + * ENSM_MODE_RX + * ENSM_MODE_ALERT + * ENSM_MODE_FDD + * ENSM_MODE_WAIT + * ENSM_MODE_SLEEP + * ENSM_MODE_PINCTRL + * ENSM_MODE_PINCTRL_FDD_INDEP + * @return 0 in case of success, negative error code otherwise. + * + * Note: This function will/may affect the data path. + */ +int32_t ad9361_set_en_state_machine_mode (struct ad9361_rf_phy *phy, + uint32_t mode) +{ + int32_t ret; + uint8_t ensm_state; + bool pinctrl = false; + + phy->pdata->fdd_independent_mode = false; + + switch (mode) { + case ENSM_MODE_TX: + ensm_state = ENSM_STATE_TX; + break; + case ENSM_MODE_RX: + ensm_state = ENSM_STATE_RX; + break; + case ENSM_MODE_ALERT: + ensm_state = ENSM_STATE_ALERT; + break; + case ENSM_MODE_FDD: + ensm_state = ENSM_STATE_FDD; + break; + case ENSM_MODE_WAIT: + ensm_state = ENSM_STATE_SLEEP_WAIT; + break; + case ENSM_MODE_SLEEP: + ensm_state = ENSM_STATE_SLEEP; + break; + case ENSM_MODE_PINCTRL: + ensm_state = ENSM_STATE_SLEEP_WAIT; + pinctrl = true; + break; + case ENSM_MODE_PINCTRL_FDD_INDEP: + ensm_state = ENSM_STATE_FDD; + phy->pdata->fdd_independent_mode = true; + break; + default: + return -EINVAL; + } + + ad9361_set_ensm_mode(phy, phy->pdata->fdd, pinctrl); + ret = ad9361_ensm_set_state(phy, ensm_state, pinctrl); + + return ret; +} + +/** + * Get the Enable State Machine (ENSM) mode. + * @param phy The AD9361 current state structure. + * @param mode A variable to store the selected ENSM mode. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_get_en_state_machine_mode (struct ad9361_rf_phy *phy, + uint32_t *mode) +{ + uint8_t ensm_state; + bool pinctrl = false; + int32_t ret; + + ensm_state = ad9361_spi_read(phy->spi, REG_STATE); + ensm_state &= ENSM_STATE(~0); + ret = ad9361_spi_read(phy->spi, REG_ENSM_CONFIG_1); + if ((ret & ENABLE_ENSM_PIN_CTRL) == ENABLE_ENSM_PIN_CTRL) + pinctrl = true; + + switch (ensm_state) { + case ENSM_STATE_TX: + *mode = ENSM_MODE_TX; + break; + case ENSM_STATE_RX: + *mode = ENSM_MODE_RX; + break; + case ENSM_STATE_ALERT: + *mode = ENSM_MODE_ALERT; + break; + case ENSM_STATE_FDD: + if (phy->pdata->fdd_independent_mode) + *mode = ENSM_MODE_PINCTRL_FDD_INDEP; + else + *mode = ENSM_MODE_FDD; + break; + case ENSM_STATE_SLEEP_WAIT: + if (pinctrl) + *mode = ENSM_MODE_PINCTRL; + else + *mode = ENSM_MODE_WAIT; + break; + case ENSM_STATE_SLEEP: + *mode = ENSM_MODE_SLEEP; + break; + default: + return -EINVAL; + } + + return 0; +} + +/** + * Set the receive RF gain for the selected channel. + * @param phy The AD9361 current state structure. + * @param ch The desired channel number (RX1, RX2). + * Accepted values in 2x2 mode: + * RX1 (0) + * RX2 (1) + * Accepted values in 1x1 mode: + * RX1 (0) + * @param gain_db The RF gain (dB). + * Example: + * 10 (10 dB) + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_set_rx_rf_gain (struct ad9361_rf_phy *phy, + uint8_t ch, int32_t gain_db) +{ + struct rf_rx_gain rx_gain = {0, 0, 0, 0, 0, 0, 0, 0, 0}; + int32_t ret = 0; + + rx_gain.gain_db = gain_db; + ret = ad9361_set_rx_gain(phy, + ad9361_1rx1tx_channel_map(phy, false, + ch + 1), &rx_gain); + + return ret; +} + +/** + * Get current receive RF gain for the selected channel. + * @param phy The AD9361 current state structure. + * @param ch The desired channel number (RX1, RX2). + * Accepted values in 2x2 mode: + * RX1 (0) + * RX2 (1) + * Accepted values in 1x1 mode: + * RX1 (0) + * @param gain_db A variable to store the RF gain (dB). + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_get_rx_rf_gain (struct ad9361_rf_phy *phy, + uint8_t ch, int32_t *gain_db) +{ + struct rf_rx_gain rx_gain = {0, 0, 0, 0, 0, 0, 0, 0, 0}; + int32_t ret = 0; + + ret = ad9361_get_rx_gain(phy, ad9361_1rx1tx_channel_map(phy, + false, ch + 1), &rx_gain); + + *gain_db = rx_gain.gain_db; + + return ret; +} + +/** + * Set the RX RF bandwidth. + * @param phy The AD9361 current state structure. + * @param bandwidth_hz The desired bandwidth (Hz). + * Example: + * 18000000 (18 MHz) + * @return 0 in case of success, negative error code otherwise. + * + * Note: This function will/may affect the data path. + */ +int32_t ad9361_set_rx_rf_bandwidth (struct ad9361_rf_phy *phy, + uint32_t bandwidth_hz) +{ + int32_t ret = 0; + + bandwidth_hz = ad9361_validate_rf_bw(phy, bandwidth_hz); + + if (phy->current_rx_bw_Hz != bandwidth_hz) + ret = ad9361_update_rf_bandwidth(phy, bandwidth_hz, + phy->current_tx_bw_Hz); + else + ret = 0; + + return ret; +} + +/** + * Get the RX RF bandwidth. + * @param phy The AD9361 current state structure. + * @param bandwidth_hz A variable to store the bandwidth value (Hz). + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_get_rx_rf_bandwidth (struct ad9361_rf_phy *phy, + uint32_t *bandwidth_hz) +{ + *bandwidth_hz = phy->current_rx_bw_Hz; + + return 0; +} + +/** + * Set the RX sampling frequency. + * @param phy The AD9361 current state structure. + * @param sampling_freq_hz The desired frequency (Hz). + * Example: + * 30720000 (30.72 MHz) + * @return 0 in case of success, negative error code otherwise. + * + * Note: This function will/may affect the data path. + */ +int32_t ad9361_set_rx_sampling_freq (struct ad9361_rf_phy *phy, + uint32_t sampling_freq_hz) +{ + int32_t ret; + uint32_t rx[6], tx[6]; + + ret = ad9361_calculate_rf_clock_chain(phy, sampling_freq_hz, + phy->rate_governor, rx, tx); + if (ret < 0) + return ret; + + ad9361_set_trx_clock_chain(phy, rx, tx); + + ret = ad9361_update_rf_bandwidth(phy, phy->current_rx_bw_Hz, + phy->current_tx_bw_Hz); + + return ret; +} + +/** + * Get current RX sampling frequency. + * @param phy The AD9361 current state structure. + * @param sampling_freq_hz A variable to store the frequency value (Hz). + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_get_rx_sampling_freq (struct ad9361_rf_phy *phy, + uint32_t *sampling_freq_hz) +{ + *sampling_freq_hz = (uint32_t)clk_get_rate(phy, + phy->ref_clk_scale[RX_SAMPL_CLK]); + + return 0; +} + +/** + * Set the RX LO frequency. + * @param phy The AD9361 current state structure. + * @param lo_freq_hz The desired frequency (Hz). + * Example: + * 2400000000 (2.4 GHz) + * @return 0 in case of success, negative error code otherwise. + * + * Note: This function will/may affect the data path. + */ +int32_t ad9361_set_rx_lo_freq (struct ad9361_rf_phy *phy, + uint64_t lo_freq_hz) +{ + int32_t ret; + + ret = clk_set_rate(phy, phy->ref_clk_scale[RX_RFPLL], + ad9361_to_clk(lo_freq_hz)); + + return ret; +} + +/** + * Get current RX LO frequency. + * @param phy The AD9361 current state structure. + * @param lo_freq_hz A variable to store the frequency value (Hz). + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_get_rx_lo_freq (struct ad9361_rf_phy *phy, + uint64_t *lo_freq_hz) +{ + *lo_freq_hz = ad9361_from_clk(clk_get_rate(phy, + phy->ref_clk_scale[RX_RFPLL])); + + return 0; +} + +/** + * Switch between internal and external LO. + * @param phy The AD9361 state structure. + * @param int_ext The selected lo (INT_LO, EXT_LO). + * Accepted values: + * INT_LO + * EXT_LO + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_set_rx_lo_int_ext(struct ad9361_rf_phy *phy, uint8_t int_ext) +{ + if ((phy->dev_sel == ID_AD9363A) && (int_ext == EXT_LO)) { + printf("%s : EXT_LO is not supported by AD9363!\n", __func__); + return -1; + } + + phy->pdata->use_ext_rx_lo = int_ext; + + return ad9361_clk_mux_set_parent(phy->ref_clk_scale[RX_RFPLL], int_ext); +} + +/** + * Get the RSSI for the selected channel. + * @param phy The AD9361 current state structure. + * @param ch The desired channel (RX1, RX2). + * Accepted values in 2x2 mode: + * RX1 (0) + * RX2 (1) + * Accepted values in 1x1 mode: + * RX1 (0) + * @param rssi A variable to store the RSSI. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_get_rx_rssi (struct ad9361_rf_phy *phy, + uint8_t ch, struct rf_rssi *rssi) +{ + int32_t ret; + + rssi->ant = ad9361_1rx1tx_channel_map(phy, false, ch + 1); + rssi->duration = 1; + ret = ad9361_read_rssi(phy, rssi); + + return ret; +} + +/** + * Set the gain control mode for the selected channel. + * @param phy The AD9361 current state structure. + * @param ch The desired channel (RX1, RX2). + * Accepted values in 2x2 mode: + * RX1 (0) + * RX2 (1) + * Accepted values in 1x1 mode: + * RX1 (0) + * @param gc_mode The gain control mode (manual, fast_attack, slow_attack, + * hybrid). + * Accepted values: + * RF_GAIN_MGC (manual) + * RF_GAIN_FASTATTACK_AGC (fast_attack) + * RF_GAIN_SLOWATTACK_AGC (slow_attack) + * RF_GAIN_HYBRID_AGC (hybrid) + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_set_rx_gain_control_mode (struct ad9361_rf_phy *phy, + uint8_t ch, uint8_t gc_mode) +{ + struct rf_gain_ctrl gc = {0, 0}; + + gc.ant = ad9361_1rx1tx_channel_map(phy, false, ch + 1); + gc.mode = phy->agc_mode[ch] = gc_mode; + + ad9361_set_gain_ctrl_mode(phy, &gc); + + return 0; +} + +/** + * Get the gain control mode for the selected channel. + * @param phy The AD9361 current state structure. + * @param ch The desired channel (RX1, RX2). + * Accepted values: + * RX1 (0) + * RX2 (1) + * @param gc_mode A variable to store the gain control mode. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_get_rx_gain_control_mode (struct ad9361_rf_phy *phy, + uint8_t ch, uint8_t *gc_mode) +{ + *gc_mode = phy->agc_mode[ch]; + + return 0; +} + +/** + * Set the RX FIR filter configuration. + * @param phy The AD9361 current state structure. + * @param fir_cfg FIR filter configuration. + * @return 0 in case of success, negative error code otherwise. + * + * Note: This function will/may affect the data path. + */ +int32_t ad9361_set_rx_fir_config (struct ad9361_rf_phy *phy, + AD9361_RXFIRConfig fir_cfg) +{ + int32_t ret; + + phy->rx_fir_dec = fir_cfg.rx_dec; + ret = ad9361_load_fir_filter_coef(phy, (enum fir_dest)(fir_cfg.rx | FIR_IS_RX), + fir_cfg.rx_gain, fir_cfg.rx_coef_size, fir_cfg.rx_coef); + + return ret; +} + +/** + * Get the RX FIR filter configuration. + * @param phy The AD9361 current state structure. + * @param rx_ch The selected RX channel (RX1, RX2). + * Accepted values: + * RX1 (0) + * RX2 (1) + * @param fir_cfg FIR filter configuration output file. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_get_rx_fir_config(struct ad9361_rf_phy *phy, uint8_t rx_ch, + AD9361_RXFIRConfig *fir_cfg) +{ + int32_t ret; + uint32_t fir_conf; + uint8_t index; + + rx_ch += 1; + + ret = ad9361_spi_read(phy->spi, REG_RX_FILTER_CONFIG); + if(ret < 0) + return ret; + fir_conf = ret; + + fir_cfg->rx_coef_size = (((fir_conf & FIR_NUM_TAPS(7)) >> 5) + 1) * 16; + + ret = ad9361_spi_read(phy->spi, REG_RX_FILTER_GAIN); + if(ret < 0) + return ret; + fir_cfg->rx_gain = -6 * (ret & FILTER_GAIN(3)) + 6; + fir_cfg->rx = rx_ch; + + fir_conf &= ~FIR_SELECT(3); + fir_conf |= FIR_SELECT(rx_ch) | FIR_START_CLK; + ad9361_spi_write(phy->spi, REG_RX_FILTER_CONFIG, fir_conf); + + for(index = 0; index < 128; index++) { + ad9361_spi_write(phy->spi, REG_RX_FILTER_COEF_ADDR, index); + ret = ad9361_spi_read(phy->spi, REG_RX_FILTER_COEF_READ_DATA_1); + if(ret < 0) + return ret; + fir_cfg->rx_coef[index] = ret; + ret = ad9361_spi_read(phy->spi, REG_RX_FILTER_COEF_READ_DATA_2); + if(ret < 0) + return ret; + fir_cfg->rx_coef[index] |= (ret << 8); + } + + fir_conf &= ~FIR_START_CLK; + ad9361_spi_write(phy->spi, REG_RX_FILTER_CONFIG, fir_conf); + + fir_cfg->rx_dec = phy->rx_fir_dec; + + return 0; +} + +/** + * Enable/disable the RX FIR filter. + * @param phy The AD9361 current state structure. + * @param en_dis The option (ENABLE, DISABLE). + * Accepted values: + * ENABLE (1) + * DISABLE (0) + * @return 0 in case of success, negative error code otherwise. + * + * Note: This function will/may affect the data path. + */ +int32_t ad9361_set_rx_fir_en_dis (struct ad9361_rf_phy *phy, + uint8_t en_dis) +{ + int32_t ret = 0; + + if(phy->bypass_rx_fir == !en_dis) + return ret; + + phy->bypass_rx_fir = !en_dis; + ret = ad9361_validate_enable_fir(phy); + if (ret < 0) { + phy->bypass_rx_fir = true; + } + + return ret; +} + +/** + * Get the status of the RX FIR filter. + * @param phy The AD9361 current state structure. + * @param en_dis The enable/disable status buffer. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_get_rx_fir_en_dis (struct ad9361_rf_phy *phy, + uint8_t *en_dis) +{ + *en_dis = !phy->bypass_rx_fir; + + return 0; +} + +/** + * Enable/disable the RX RFDC Tracking. + * @param phy The AD9361 current state structure. + * @param en_dis The option (ENABLE, DISABLE). + * Accepted values: + * ENABLE (1) + * DISABLE (0) + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_set_rx_rfdc_track_en_dis (struct ad9361_rf_phy *phy, + uint8_t en_dis) +{ + int32_t ret = 0; + + if(phy->rfdc_track_en == en_dis) + return ret; + + phy->rfdc_track_en = en_dis; + ret = ad9361_tracking_control(phy, phy->bbdc_track_en, + phy->rfdc_track_en, phy->quad_track_en); + + return ret; +} + +/** + * Get the status of the RX RFDC Tracking. + * @param phy The AD9361 current state structure. + * @param en_dis The enable/disable status buffer. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_get_rx_rfdc_track_en_dis (struct ad9361_rf_phy *phy, + uint8_t *en_dis) +{ + *en_dis = phy->rfdc_track_en; + + return 0; +} + +/** + * Enable/disable the RX BasebandDC Tracking. + * @param phy The AD9361 current state structure. + * @param en_dis The option (ENABLE, DISABLE). + * Accepted values: + * ENABLE (1) + * DISABLE (0) + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_set_rx_bbdc_track_en_dis (struct ad9361_rf_phy *phy, + uint8_t en_dis) +{ + int32_t ret = 0; + + if(phy->bbdc_track_en == en_dis) + return ret; + + phy->bbdc_track_en = en_dis; + ret = ad9361_tracking_control(phy, phy->bbdc_track_en, + phy->rfdc_track_en, phy->quad_track_en); + + return ret; +} + +/** + * Get the status of the RX BasebandDC Tracking. + * @param phy The AD9361 current state structure. + * @param en_dis The enable/disable status buffer. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_get_rx_bbdc_track_en_dis (struct ad9361_rf_phy *phy, + uint8_t *en_dis) +{ + *en_dis = phy->bbdc_track_en; + + return 0; +} + +/** + * Enable/disable the RX Quadrature Tracking. + * @param phy The AD9361 current state structure. + * @param en_dis The option (ENABLE, DISABLE). + * Accepted values: + * ENABLE (1) + * DISABLE (0) + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_set_rx_quad_track_en_dis (struct ad9361_rf_phy *phy, + uint8_t en_dis) +{ + int32_t ret = 0; + + if(phy->quad_track_en == en_dis) + return ret; + + phy->quad_track_en = en_dis; + ret = ad9361_tracking_control(phy, phy->bbdc_track_en, + phy->rfdc_track_en, phy->quad_track_en); + + return ret; +} + +/** + * Get the status of the RX Quadrature Tracking. + * @param phy The AD9361 current state structure. + * @param en_dis The enable/disable status buffer. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_get_rx_quad_track_en_dis (struct ad9361_rf_phy *phy, + uint8_t *en_dis) +{ + *en_dis = phy->quad_track_en; + + return 0; +} + +/** + * Set the RX RF input port. + * @param phy The AD9361 current state structure. + * @param mode The RF port. + * Accepted values: + * A_BALANCED (0 - (RX1A_N & RX1A_P) and (RX2A_N & RX2A_P) enabled; balanced) + * B_BALANCED (1 - (RX1B_N & RX1B_P) and (RX2B_N & RX2B_P) enabled; balanced) + * C_BALANCED (2 - (RX1C_N & RX1C_P) and (RX2C_N & RX2C_P) enabled; balanced) + * A_N (3 - RX1A_N and RX2A_N enabled; unbalanced) + * A_P (4 - RX1A_P and RX2A_P enabled; unbalanced) + * B_N (5 - RX1B_N and RX2B_N enabled; unbalanced) + * B_P (6 - RX1B_P and RX2B_P enabled; unbalanced) + * C_N (7 - RX1C_N and RX2C_N enabled; unbalanced) + * C_P (8 - RX1C_P and RX2C_P enabled; unbalanced) + * TX_MON1 (9 - TX_MONITOR1) + * TX_MON2 (10 - TX_MONITOR2) + * TX_MON1_2 (11 - TX_MONITOR1 & TX_MONITOR2) + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_set_rx_rf_port_input (struct ad9361_rf_phy *phy, + uint32_t mode) +{ + int32_t ret; + + phy->pdata->rf_rx_input_sel = mode; + + ret = ad9361_rf_port_setup(phy, false, + phy->pdata->rf_rx_input_sel, + phy->pdata->rf_tx_output_sel); + + return ret; +} + +/** + * Get the selected RX RF input port. + * @param phy The AD9361 current state structure. + * @param mode The RF port. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_get_rx_rf_port_input (struct ad9361_rf_phy *phy, + uint32_t *mode) +{ + *mode = phy->pdata->rf_rx_input_sel; + + return 0; +} + +/** + * Store RX fastlock profile. + * To create a profile tune the synthesizer (ad9361_set_rx_lo_freq()) and then + * call this function specifying the target profile number. + * @param phy The AD9361 state structure. + * @param profile The profile number (0 - 7). + * Accepted values: + * 0 - 7 + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_rx_fastlock_store(struct ad9361_rf_phy *phy, uint32_t profile) +{ + return ad9361_fastlock_store(phy, 0, profile); +} + +/** + * Recall specified RX fastlock profile. + * When in fastlock pin select mode (init_param->rx_fastlock_pincontrol_enable), + * the function needs to be called before then the pin-control can be used. + * @param phy The AD9361 state structure. + * @param profile The profile number (0 - 7). + * Accepted values: + * 0 - 7 + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_rx_fastlock_recall(struct ad9361_rf_phy *phy, uint32_t profile) +{ + return ad9361_fastlock_recall(phy, 0, profile); +} + +/** + * Load RX fastlock profile. A previously saved profile can be loaded in any + * of the 8 available slots. + * @param phy The AD9361 state structure. + * @param profile The profile number (0 - 7). + * Accepted values: + * 0 - 7 + * @param values Fastlock profile program data. + * Example: + * val0,val1,val2,…,val15 + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_rx_fastlock_load(struct ad9361_rf_phy *phy, uint32_t profile, + uint8_t *values) +{ + return ad9361_fastlock_load(phy, 0, profile, values); +} + +/** + * Save RX fastlock profile. In order to use more than 8 Profiles, an existing + * profile can be read back and stored by the user application. + * @param phy The AD9361 state structure. + * @param profile The profile number (0 - 7). + * Accepted values: + * 0 - 7 + * @param values Fastlock profile program data. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_rx_fastlock_save(struct ad9361_rf_phy *phy, uint32_t profile, + uint8_t *values) +{ + return ad9361_fastlock_save(phy, 0, profile, values); +} + +/** + * Power down the RX Local Oscillator. + * @param phy The AD9361 state structure. + * @param option The option (ON, OFF). + * Accepted values: + * ON (0) + * OFF (1) + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_rx_lo_powerdown(struct ad9361_rf_phy *phy, uint8_t option) +{ + return ad9361_synth_lo_powerdown(phy, option ? LO_OFF : LO_ON, LO_DONTCARE); +} + +/** + * Get the RX Local Oscillator power status. + * @param phy The AD9361 state structure. + * @param option Store the option (ON, OFF). + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_get_rx_lo_power(struct ad9361_rf_phy *phy, uint8_t *option) +{ + *option = !(phy->cached_synth_pd[1] & RX_LO_POWER_DOWN) ? OFF : ON; + + return 0; +} + +/** + * Set the transmit attenuation for the selected channel. + * @param phy The AD9361 current state structure. + * @param ch The desired channel number (TX1, TX2). + * Accepted values in 2x2 mode: + * TX1 (0) + * TX2 (1) + * Accepted values in 1x1 mode: + * TX1 (0) + * @param attenuation_mdb The attenuation (mdB). + * Example: + * 10000 (10 dB) + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_set_tx_attenuation (struct ad9361_rf_phy *phy, + uint8_t ch, uint32_t attenuation_mdb) +{ + int32_t ret; + int32_t channel; + + channel = ad9361_1rx1tx_channel_map(phy, true, ch); + ret = ad9361_set_tx_atten(phy, attenuation_mdb, + channel == 0, channel == 1, + !phy->pdata->update_tx_gain_via_alert); + + return ret; +} + +/** + * Get current transmit attenuation for the selected channel. + * @param phy The AD9361 current state structure. + * @param ch The desired channel number (TX1, TX2). + * Accepted values in 2x2 mode: + * TX1 (0) + * TX2 (1) + * Accepted values in 1x1 mode: + * TX1 (0) + * @param attenuation_mdb A variable to store the attenuation value (mdB). + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_get_tx_attenuation (struct ad9361_rf_phy *phy, + uint8_t ch, uint32_t *attenuation_mdb) +{ + int32_t ret; + + ret = ad9361_get_tx_atten(phy, + ad9361_1rx1tx_channel_map(phy, true, + ch + 1)); + + if(ret < 0) + return ret; + *attenuation_mdb = ret; + + return 0; +} + +/** + * Set the TX RF bandwidth. + * @param phy The AD9361 current state structure. + * @param bandwidth_hz The desired bandwidth (Hz). + * Example: + * 18000000 (18 MHz) + * @return 0 in case of success, negative error code otherwise. + * + * Note: This function will/may affect the data path. + */ +int32_t ad9361_set_tx_rf_bandwidth (struct ad9361_rf_phy *phy, + uint32_t bandwidth_hz) +{ + int32_t ret = 0; + + bandwidth_hz = ad9361_validate_rf_bw(phy, bandwidth_hz); + + if (phy->current_tx_bw_Hz != bandwidth_hz) + ret = ad9361_update_rf_bandwidth(phy, + phy->current_rx_bw_Hz, bandwidth_hz); + else + ret = 0; + + return ret; +} + +/** + * Get the TX RF bandwidth. + * @param phy The AD9361 current state structure. + * @param bandwidth_hz A variable to store the bandwidth value (Hz). + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_get_tx_rf_bandwidth (struct ad9361_rf_phy *phy, + uint32_t *bandwidth_hz) +{ + *bandwidth_hz = phy->current_tx_bw_Hz; + + return 0; +} + +/** + * Set the TX sampling frequency. + * @param phy The AD9361 current state structure. + * @param sampling_freq_hz The desired frequency (Hz). + * Example: + * 30720000 (30.72 MHz) + * @return 0 in case of success, negative error code otherwise. + * + * Note: This function will/may affect the data path. + */ +int32_t ad9361_set_tx_sampling_freq (struct ad9361_rf_phy *phy, + uint32_t sampling_freq_hz) +{ + int32_t ret; + uint32_t rx[6], tx[6]; + + ret = ad9361_calculate_rf_clock_chain(phy, sampling_freq_hz, + phy->rate_governor, rx, tx); + if (ret < 0) + return ret; + + ad9361_set_trx_clock_chain(phy, rx, tx); + + ret = ad9361_update_rf_bandwidth(phy, phy->current_rx_bw_Hz, + phy->current_tx_bw_Hz); + + return ret; +} + +/** + * Get current TX sampling frequency. + * @param phy The AD9361 current state structure. + * @param sampling_freq_hz A variable to store the frequency value (Hz). + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_get_tx_sampling_freq (struct ad9361_rf_phy *phy, + uint32_t *sampling_freq_hz) +{ + *sampling_freq_hz = (uint32_t)clk_get_rate(phy, + phy->ref_clk_scale[TX_SAMPL_CLK]); + + return 0; +} + +/** + * Set the TX LO frequency. + * @param phy The AD9361 current state structure. + * @param lo_freq_hz The desired frequency (Hz). + * Example: + * 2400000000 (2.4 GHz) + * @return 0 in case of success, negative error code otherwise. + * + * Note: This function will/may affect the data path. + */ +int32_t ad9361_set_tx_lo_freq (struct ad9361_rf_phy *phy, + uint64_t lo_freq_hz) +{ + int32_t ret; + + ret = clk_set_rate(phy, phy->ref_clk_scale[TX_RFPLL], + ad9361_to_clk(lo_freq_hz)); + + return ret; +} + +/** + * Get current TX LO frequency. + * @param phy The AD9361 current state structure. + * @param lo_freq_hz A variable to store the frequency value (Hz). + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_get_tx_lo_freq (struct ad9361_rf_phy *phy, + uint64_t *lo_freq_hz) +{ + *lo_freq_hz = ad9361_from_clk(clk_get_rate(phy, + phy->ref_clk_scale[TX_RFPLL])); + + return 0; +} + +/** + * Switch between internal and external LO. + * @param phy The AD9361 state structure. + * @param int_ext The selected lo (INT_LO, EXT_LO). + * Accepted values: + * INT_LO + * EXT_LO + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_set_tx_lo_int_ext(struct ad9361_rf_phy *phy, uint8_t int_ext) +{ + if ((phy->dev_sel == ID_AD9363A) && (int_ext == EXT_LO)) { + printf("%s : EXT_LO is not supported by AD9363!\n", __func__); + return -1; + } + + phy->pdata->use_ext_tx_lo = int_ext; + + return ad9361_clk_mux_set_parent(phy->ref_clk_scale[TX_RFPLL], int_ext); +} + +/** + * Set the TX FIR filter configuration. + * @param phy The AD9361 current state structure. + * @param fir_cfg FIR filter configuration. + * @return 0 in case of success, negative error code otherwise. + * + * Note: This function will/may affect the data path. + */ +int32_t ad9361_set_tx_fir_config (struct ad9361_rf_phy *phy, + AD9361_TXFIRConfig fir_cfg) +{ + int32_t ret; + + phy->tx_fir_int = fir_cfg.tx_int; + ret = ad9361_load_fir_filter_coef(phy, (enum fir_dest)fir_cfg.tx, + fir_cfg.tx_gain, fir_cfg.tx_coef_size, fir_cfg.tx_coef); + + return ret; +} + +/** + * Get the TX FIR filter configuration. + * @param phy The AD9361 current state structure. + * @param tx_ch The selected TX channel (TX1, TX2). + * Accepted values: + * TX1 (0) + * TX2 (1) + * @param fir_cfg FIR filter configuration output file. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_get_tx_fir_config(struct ad9361_rf_phy *phy, uint8_t tx_ch, + AD9361_TXFIRConfig *fir_cfg) +{ + int32_t ret; + uint32_t fir_conf; + uint8_t index; + + tx_ch += 1; + + ret = ad9361_spi_read(phy->spi, REG_TX_FILTER_CONF); + if(ret < 0) + return ret; + fir_conf = ret; + fir_cfg->tx_coef_size = (((fir_conf & FIR_NUM_TAPS(7)) >> 5) + 1) * 16; + fir_cfg->tx_gain = -6 * (fir_conf & TX_FIR_GAIN_6DB); + fir_cfg->tx = tx_ch; + + fir_conf &= ~FIR_SELECT(3); + fir_conf |= FIR_SELECT(tx_ch) | FIR_START_CLK; + ad9361_spi_write(phy->spi, REG_TX_FILTER_CONF, fir_conf); + + for(index = 0; index < 128; index++) { + ad9361_spi_write(phy->spi, REG_TX_FILTER_COEF_ADDR, index); + ret = ad9361_spi_read(phy->spi, REG_TX_FILTER_COEF_READ_DATA_1); + if(ret < 0) + return ret; + fir_cfg->tx_coef[index] = ret; + ret = ad9361_spi_read(phy->spi, REG_TX_FILTER_COEF_READ_DATA_2); + if(ret < 0) + return ret; + fir_cfg->tx_coef[index] |= (ret << 8); + } + + fir_conf &= ~FIR_START_CLK; + ad9361_spi_write(phy->spi, REG_TX_FILTER_CONF, fir_conf); + + fir_cfg->tx_int = phy->tx_fir_int; + + return 0; +} + +/** + * Enable/disable the TX FIR filter. + * @param phy The AD9361 current state structure. + * @param en_dis The option (ENABLE, DISABLE). + * Accepted values: + * ENABLE (1) + * DISABLE (0) + * @return 0 in case of success, negative error code otherwise. + * + * Note: This function will/may affect the data path. + */ +int32_t ad9361_set_tx_fir_en_dis (struct ad9361_rf_phy *phy, + uint8_t en_dis) +{ + int32_t ret = 0; + + if(phy->bypass_tx_fir == !en_dis) + return ret; + + phy->bypass_tx_fir = !en_dis; + ret = ad9361_validate_enable_fir(phy); + if (ret < 0) { + phy->bypass_tx_fir = true; + } + + return ret; +} + +/** + * Get the status of the TX FIR filter. + * @param phy The AD9361 current state structure. + * @param en_dis The enable/disable status buffer. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_get_tx_fir_en_dis (struct ad9361_rf_phy *phy, + uint8_t *en_dis) +{ + *en_dis = !phy->bypass_tx_fir; + + return 0; +} + +/** + * Get the TX RSSI for the selected channel (TX_MON should be enabled). + * @param phy The AD9361 current state structure. + * @param ch The desired channel (TX1, TX2). + * Accepted values: + * TX1 (0) + * TX2 (1) + * @param rssi_db_x_1000 A variable to store the RSSI. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_get_tx_rssi (struct ad9361_rf_phy *phy, + uint8_t ch, + uint32_t *rssi_db_x_1000) +{ + uint8_t reg_val_buf[3]; + uint32_t val; + int32_t ret; + + ret = ad9361_spi_readm(phy->spi, REG_TX_RSSI_LSB, + reg_val_buf, ARRAY_SIZE(reg_val_buf)); + if (ret < 0) { + return ret; + } + + switch (ch) { + case 0: + val = (reg_val_buf[2] << 1) | (reg_val_buf[0] & TX_RSSI_1); + break; + case 1: + val = (reg_val_buf[1] << 1) | ((reg_val_buf[0] & TX_RSSI_2) >> 1); + break; + default: + return -EINVAL; + } + + val *= RSSI_RESOLUTION; + + *rssi_db_x_1000 = ((val / RSSI_MULTIPLIER) * 1000) + + (val % RSSI_MULTIPLIER); + + return 0; +} + +/** + * Set the TX RF output port. + * @param phy The AD9361 current state structure. + * @param mode The RF port. + * Accepted values: + * TXA (0) + * TXB (1) + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_set_tx_rf_port_output (struct ad9361_rf_phy *phy, + uint32_t mode) +{ + int32_t ret; + + phy->pdata->rf_tx_output_sel = mode; + + ret = ad9361_rf_port_setup(phy, true, + phy->pdata->rf_rx_input_sel, + phy->pdata->rf_tx_output_sel); + + return ret; +} + +/** + * Get the selected TX RF output port. + * @param phy The AD9361 current state structure. + * @param mode The RF port. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_get_tx_rf_port_output (struct ad9361_rf_phy *phy, + uint32_t *mode) +{ + *mode = phy->pdata->rf_tx_output_sel; + + return 0; +} + +/** + * Enable/disable the auto calibration. + * @param phy The AD9361 current state structure. + * @param en_dis The option (ENABLE, DISABLE). + * Accepted values: + * ENABLE (1) + * DISABLE (0) + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_set_tx_auto_cal_en_dis (struct ad9361_rf_phy *phy, + uint8_t en_dis) +{ + if (en_dis == 0) + phy->auto_cal_en = 0; + else + phy->auto_cal_en = 1; + + return 0; +} + +/** + * Get the status of the auto calibration flag. + * @param phy The AD9361 current state structure. + * @param en_dis The enable/disable status buffer. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_get_tx_auto_cal_en_dis (struct ad9361_rf_phy *phy, + uint8_t *en_dis) +{ + *en_dis = phy->auto_cal_en; + + return 0; +} + +/** + * Store TX fastlock profile. + * To create a profile tune the synthesizer (ad9361_set_tx_lo_freq()) and then + * call this function specifying the target profile number. + * @param phy The AD9361 state structure. + * @param profile The profile number (0 - 7). + * Accepted values: + * 0 - 7 + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_tx_fastlock_store(struct ad9361_rf_phy *phy, uint32_t profile) +{ + return ad9361_fastlock_store(phy, 1, profile); +} + +/** + * Recall specified TX fastlock profile. + * When in fastlock pin select mode (init_param->tx_fastlock_pincontrol_enable), + * the function needs to be called before then the pin-control can be used. + * @param phy The AD9361 state structure. + * @param profile The profile number (0 - 7). + * Accepted values: + * 0 - 7 + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_tx_fastlock_recall(struct ad9361_rf_phy *phy, uint32_t profile) +{ + return ad9361_fastlock_recall(phy, 1, profile); +} + +/** + * Load TX fastlock profile. A previously saved profile can be loaded in any + * of the 8 available slots. + * @param phy The AD9361 state structure. + * @param profile The profile number (0 - 7). + * Accepted values: + * 0 - 7 + * @param values Fastlock profile program data. + * Example: + * val0,val1,val2,…,val15 + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_tx_fastlock_load(struct ad9361_rf_phy *phy, uint32_t profile, + uint8_t *values) +{ + return ad9361_fastlock_load(phy, 1, profile, values); +} + +/** + * Save TX fastlock profile. In order to use more than 8 Profiles, an existing + * profile can be read back and stored by the user application. + * @param phy The AD9361 state structure. + * @param profile The profile number (0 - 7). + * Accepted values: + * 0 - 7 + * @param values Fastlock profile program data. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_tx_fastlock_save(struct ad9361_rf_phy *phy, uint32_t profile, + uint8_t *values) +{ + return ad9361_fastlock_save(phy, 1, profile, values); +} + +/** + * Power down the TX Local Oscillator. + * @param phy The AD9361 state structure. + * @param option The option (ON, OFF). + * Accepted values: + * ON (0) + * OFF (1) + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_tx_lo_powerdown(struct ad9361_rf_phy *phy, uint8_t option) +{ + return ad9361_synth_lo_powerdown(phy, LO_DONTCARE, option ? LO_OFF : LO_ON); +} + +/** + * Get the TX Local Oscillator power status. + * @param phy The AD9361 state structure. + * @param option Store the option (ON, OFF). + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_get_tx_lo_power(struct ad9361_rf_phy *phy, uint8_t *option) +{ + *option = !(phy->cached_synth_pd[0] & TX_LO_POWER_DOWN) ? OFF : ON; + + return 0; +} + +/** + * Set the RX and TX path rates. + * @param phy The AD9361 state structure. + * @param rx_path_clks RX path rates buffer. + * @param tx_path_clks TX path rates buffer. + * @return 0 in case of success, negative error code otherwise. + * + * Note: This function will/may affect the data path. + */ +int32_t ad9361_set_trx_path_clks(struct ad9361_rf_phy *phy, + uint32_t *rx_path_clks, + uint32_t *tx_path_clks) +{ + int32_t ret; + + ret = ad9361_set_trx_clock_chain(phy, rx_path_clks, tx_path_clks); + if (ret < 0) + return ret; + + ret = ad9361_update_rf_bandwidth(phy, phy->current_rx_bw_Hz, + phy->current_tx_bw_Hz); + + return ret; +} + +/** + * Get the RX and TX path rates. + * @param phy The AD9361 state structure. + * @param rx_path_clks RX path rates buffer. + * @param tx_path_clks TX path rates buffer. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_get_trx_path_clks(struct ad9361_rf_phy *phy, + uint32_t *rx_path_clks, + uint32_t *tx_path_clks) +{ + return ad9361_get_trx_clock_chain(phy, rx_path_clks, tx_path_clks); +} + +/** + * Set the number of channels mode. + * @param phy The AD9361 state structure. + * Note: This function also resets the device, some additional + * configurations might be necessary + * @param no_ch_mode Number of channels mode (MODE_1x1, MODE_2x2). + * Accepted values: + * MODE_1x1 (1) + * MODE_2x2 (2) + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_set_no_ch_mode(struct ad9361_rf_phy *phy, uint8_t no_ch_mode) +{ + switch (no_ch_mode) { + case 1: + phy->pdata->rx2tx2 = 0; + break; + case 2: + phy->pdata->rx2tx2 = 1; + break; + default: + return -EINVAL; + } + + ad9361_reset(phy); + ad9361_spi_write(phy->spi, REG_SPI_CONF, SOFT_RESET | _SOFT_RESET); + ad9361_spi_write(phy->spi, REG_SPI_CONF, 0x0); + + ad9361_clear_state(phy); + + phy->clks[TX_REFCLK]->rate = ad9361_clk_factor_recalc_rate( + phy->ref_clk_scale[TX_REFCLK], phy->clk_refin->rate); + phy->clks[TX_REFCLK]->rate = ad9361_clk_factor_recalc_rate( + phy->ref_clk_scale[TX_REFCLK], phy->clk_refin->rate); + phy->clks[RX_REFCLK]->rate = ad9361_clk_factor_recalc_rate( + phy->ref_clk_scale[RX_REFCLK], phy->clk_refin->rate); + phy->clks[BB_REFCLK]->rate = ad9361_clk_factor_recalc_rate( + phy->ref_clk_scale[BB_REFCLK], phy->clk_refin->rate); + phy->clks[BBPLL_CLK]->rate = ad9361_bbpll_recalc_rate( + phy->ref_clk_scale[BBPLL_CLK], phy->clks[BB_REFCLK]->rate); + phy->clks[ADC_CLK]->rate = ad9361_clk_factor_recalc_rate( + phy->ref_clk_scale[ADC_CLK], phy->clks[BBPLL_CLK]->rate); + phy->clks[R2_CLK]->rate = ad9361_clk_factor_recalc_rate( + phy->ref_clk_scale[R2_CLK], phy->clks[ADC_CLK]->rate); + phy->clks[R1_CLK]->rate = ad9361_clk_factor_recalc_rate( + phy->ref_clk_scale[R1_CLK], phy->clks[R2_CLK]->rate); + phy->clks[CLKRF_CLK]->rate = ad9361_clk_factor_recalc_rate( + phy->ref_clk_scale[CLKRF_CLK], phy->clks[R1_CLK]->rate); + phy->clks[RX_SAMPL_CLK]->rate = ad9361_clk_factor_recalc_rate( + phy->ref_clk_scale[RX_SAMPL_CLK], phy->clks[CLKRF_CLK]->rate); + phy->clks[DAC_CLK]->rate = ad9361_clk_factor_recalc_rate( + phy->ref_clk_scale[DAC_CLK], phy->clks[ADC_CLK]->rate); + phy->clks[T2_CLK]->rate = ad9361_clk_factor_recalc_rate( + phy->ref_clk_scale[T2_CLK], phy->clks[DAC_CLK]->rate); + phy->clks[T1_CLK]->rate = ad9361_clk_factor_recalc_rate( + phy->ref_clk_scale[T1_CLK], phy->clks[T2_CLK]->rate); + phy->clks[CLKTF_CLK]->rate = ad9361_clk_factor_recalc_rate( + phy->ref_clk_scale[CLKTF_CLK], phy->clks[T1_CLK]->rate); + phy->clks[TX_SAMPL_CLK]->rate = ad9361_clk_factor_recalc_rate( + phy->ref_clk_scale[TX_SAMPL_CLK], phy->clks[CLKTF_CLK]->rate); + phy->clks[RX_RFPLL_INT]->rate = ad9361_rfpll_int_recalc_rate( + phy->ref_clk_scale[RX_RFPLL_INT], phy->clks[RX_REFCLK]->rate); + phy->clks[TX_RFPLL_INT]->rate = ad9361_rfpll_int_recalc_rate( + phy->ref_clk_scale[TX_RFPLL_INT], phy->clks[TX_REFCLK]->rate); + phy->clks[RX_RFPLL_DUMMY]->rate = ad9361_rfpll_dummy_recalc_rate( + phy->ref_clk_scale[RX_RFPLL_DUMMY]); + phy->clks[TX_RFPLL_DUMMY]->rate = ad9361_rfpll_dummy_recalc_rate( + phy->ref_clk_scale[TX_RFPLL_DUMMY]); + phy->clks[RX_RFPLL]->rate = ad9361_rfpll_recalc_rate( + phy->ref_clk_scale[RX_RFPLL]); + phy->clks[TX_RFPLL]->rate = ad9361_rfpll_recalc_rate( + phy->ref_clk_scale[TX_RFPLL]); + + ad9361_setup(phy); +#ifndef AXI_ADC_NOT_PRESENT + /* platform specific wrapper to call ad9361_post_setup() */ + ad9361_post_setup(phy); +#endif + + return 0; +} + +/** + * Do multi chip synchronization. + * @param phy_master The AD9361 Master state structure. + * @param phy_slave The AD9361 Slave state structure. + * @return 0 in case of success, negative error code otherwise. + * + * Note: This function will/may affect the data path. + */ +int32_t ad9361_do_mcs(struct ad9361_rf_phy *phy_master, + struct ad9361_rf_phy *phy_slave) +{ + uint32_t ensm_mode; + int32_t step; + int32_t reg; + + if ((phy_master->dev_sel == ID_AD9363A) || + (phy_slave->dev_sel == ID_AD9363A)) { + printf("%s : MCS is not supported by AD9363!\n", __func__); + return -1; + } + + reg = ad9361_spi_read(phy_master->spi, REG_RX_CLOCK_DATA_DELAY); + ad9361_spi_write(phy_slave->spi, REG_RX_CLOCK_DATA_DELAY, reg); + reg = ad9361_spi_read(phy_master->spi, REG_TX_CLOCK_DATA_DELAY); + ad9361_spi_write(phy_slave->spi, REG_TX_CLOCK_DATA_DELAY, reg); + + ad9361_get_en_state_machine_mode(phy_master, &ensm_mode); + + ad9361_set_en_state_machine_mode(phy_master, ENSM_MODE_ALERT); + ad9361_set_en_state_machine_mode(phy_slave, ENSM_MODE_ALERT); + + for (step = 0; step <= 5; step++) { + ad9361_mcs(phy_slave, step); + ad9361_mcs(phy_master, step); + mdelay(100); + } + + ad9361_set_en_state_machine_mode(phy_master, ensm_mode); + ad9361_set_en_state_machine_mode(phy_slave, ensm_mode); + + return 0; +} + +/** + * Enable/disable the TRX FIR filters. + * @param phy The AD9361 current state structure. + * @param en_dis The option (ENABLE, DISABLE). + * Accepted values: + * ENABLE (1) + * DISABLE (0) + * @return 0 in case of success, negative error code otherwise. + * + * Note: This function will/may affect the data path. + */ +int32_t ad9361_set_trx_fir_en_dis (struct ad9361_rf_phy *phy, + uint8_t en_dis) +{ + int32_t ret = 0; + + if ((phy->bypass_rx_fir == phy->bypass_tx_fir) && + (phy->bypass_rx_fir == !en_dis)) + return ret; + + phy->bypass_rx_fir = !en_dis; + phy->bypass_tx_fir = !en_dis; + ret = ad9361_validate_enable_fir(phy); + if (ret < 0) { + phy->bypass_rx_fir = true; + phy->bypass_tx_fir = true; + } + + return ret; +} + +/** + * Set the OSR rate governor. + * @param phy The AD9361 current state structure. + * @param rate_gov OSR rate governor (highest, nominal). + * Accepted values: + * HIGHEST_OSR (0 - highest OSR) + * NOMINAL_OSR (1 - nominal) + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_set_trx_rate_gov (struct ad9361_rf_phy *phy, uint32_t rate_gov) +{ + if (rate_gov == 0) + phy->rate_governor = 0; + else + phy->rate_governor = 1; + + return 0; +} + +/** + * Get the OSR rate governor. + * @param phy The AD9361 current state structure. + * @param rate_gov Option buffer. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_get_trx_rate_gov (struct ad9361_rf_phy *phy, uint32_t *rate_gov) +{ + *rate_gov = phy->rate_governor; + + return 0; +} + +/** + * Perform the selected calibration. + * @param phy The AD9361 state structure. + * @param cal The selected calibration (TX_QUAD_CAL, RFDC_CAL). + * Accepted values: + * TX_QUAD_CAL + * RFDC_CAL + * @param arg For TX_QUAD_CAL - the optional RX phase value overwrite (set to zero). + * @return 0 in case of success, negative error code otherwise. + * + * Note: This function will/may affect the data path. + */ +int32_t ad9361_do_calib(struct ad9361_rf_phy *phy, uint32_t cal, int32_t arg) +{ + return ad9361_do_calib_run(phy, cal, arg); +} + +/** + * Load and enable TRX FIR filters configurations. + * @param phy The AD9361 current state structure. + * @param rx_fir_cfg RX FIR filter configuration. + * @param tx_fir_cfg TX FIR filter configuration. + * @return 0 in case of success, negative error code otherwise. + * + * Note: This function will/may affect the data path. + */ +int32_t ad9361_trx_load_enable_fir(struct ad9361_rf_phy *phy, + AD9361_RXFIRConfig rx_fir_cfg, + AD9361_TXFIRConfig tx_fir_cfg) +{ + int32_t rtx = -1, rrx = -1; + + phy->filt_rx_bw_Hz = 0; + phy->filt_tx_bw_Hz = 0; + phy->filt_valid = false; + + if (tx_fir_cfg.tx_path_clks[TX_SAMPL_FREQ]) { + memcpy(phy->filt_tx_path_clks, tx_fir_cfg.tx_path_clks, + sizeof(phy->filt_tx_path_clks)); + rtx = 0; + } + + if (rx_fir_cfg.rx_path_clks[RX_SAMPL_FREQ]) { + memcpy(phy->filt_rx_path_clks, rx_fir_cfg.rx_path_clks, + sizeof(phy->filt_rx_path_clks)); + rrx = 0; + } + + if (tx_fir_cfg.tx_bandwidth) { + phy->filt_tx_bw_Hz = tx_fir_cfg.tx_bandwidth; + } + + if (rx_fir_cfg.rx_bandwidth) { + phy->filt_rx_bw_Hz = rx_fir_cfg.rx_bandwidth; + } + + ad9361_set_tx_fir_config(phy, tx_fir_cfg); + ad9361_set_rx_fir_config(phy, rx_fir_cfg); + + if (!(rrx | rtx)) + phy->filt_valid = true; + + ad9361_set_trx_fir_en_dis(phy, 1); + + return 0; +} + +/** + * Do DCXO coarse tuning. + * @param phy The AD9361 current state structure. + * @param coarse The DCXO coarse tuning value. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_do_dcxo_tune_coarse(struct ad9361_rf_phy *phy, + uint32_t coarse) +{ + phy->pdata->dcxo_coarse = coarse; + + return ad9361_set_dcxo_tune(phy, phy->pdata->dcxo_coarse, + phy->pdata->dcxo_fine); +} + +/** + * Do DCXO fine tuning. + * @param phy The AD9361 current state structure. + * @param fine The DCXO fine tuning value. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_do_dcxo_tune_fine(struct ad9361_rf_phy *phy, + uint32_t fine) +{ + phy->pdata->dcxo_fine = fine; + + return ad9361_set_dcxo_tune(phy, phy->pdata->dcxo_coarse, + phy->pdata->dcxo_fine); +} + +/** + * Get the temperature. + * @param phy The AD9361 current state structure. + * @param temp The temperature (degrees C * 1000). + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_get_temperature(struct ad9361_rf_phy *phy, + int32_t *temp) +{ + *temp = ad9361_get_temp(phy); + return 0; +} diff --git a/df_datalink_sp/src/drivers/rf-transceiver/ad9361/ad9361_api.h b/df_datalink_sp/src/drivers/rf-transceiver/ad9361/ad9361_api.h new file mode 100644 index 0000000..4879c60 --- /dev/null +++ b/df_datalink_sp/src/drivers/rf-transceiver/ad9361/ad9361_api.h @@ -0,0 +1,552 @@ +/***************************************************************************//** + * @file ad9361_api.h + * @brief Header file of AD9361 API Driver. + * @author DBogdan (dragos.bogdan@analog.com) +******************************************************************************** + * Copyright 2013(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ +#ifndef AD9361_API_H_ +#define AD9361_API_H_ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ +#include "ad9361_util.h" +#include "gpio.h" +#include "spi.h" + +/******************************************************************************/ +/*************************** Types Declarations *******************************/ +/******************************************************************************/ +typedef struct { + /* Device selection */ + enum dev_id dev_sel; + /* Reference Clock */ + uint32_t reference_clk_rate; + /* Base Configuration */ + uint8_t two_rx_two_tx_mode_enable; /* adi,2rx-2tx-mode-enable */ + uint8_t one_rx_one_tx_mode_use_rx_num; /* adi,1rx-1tx-mode-use-rx-num */ + uint8_t one_rx_one_tx_mode_use_tx_num; /* adi,1rx-1tx-mode-use-tx-num */ + uint8_t frequency_division_duplex_mode_enable; /* adi,frequency-division-duplex-mode-enable */ + uint8_t frequency_division_duplex_independent_mode_enable; /* adi,frequency-division-duplex-independent-mode-enable */ + uint8_t tdd_use_dual_synth_mode_enable; /* adi,tdd-use-dual-synth-mode-enable */ + uint8_t tdd_skip_vco_cal_enable; /* adi,tdd-skip-vco-cal-enable */ + uint32_t tx_fastlock_delay_ns; /* adi,tx-fastlock-delay-ns */ + uint32_t rx_fastlock_delay_ns; /* adi,rx-fastlock-delay-ns */ + uint8_t rx_fastlock_pincontrol_enable; /* adi,rx-fastlock-pincontrol-enable */ + uint8_t tx_fastlock_pincontrol_enable; /* adi,tx-fastlock-pincontrol-enable */ + uint8_t external_rx_lo_enable; /* adi,external-rx-lo-enable */ + uint8_t external_tx_lo_enable; /* adi,external-tx-lo-enable */ + uint8_t dc_offset_tracking_update_event_mask; /* adi,dc-offset-tracking-update-event-mask */ + uint8_t dc_offset_attenuation_high_range; /* adi,dc-offset-attenuation-high-range */ + uint8_t dc_offset_attenuation_low_range; /* adi,dc-offset-attenuation-low-range */ + uint8_t dc_offset_count_high_range; /* adi,dc-offset-count-high-range */ + uint8_t dc_offset_count_low_range; /* adi,dc-offset-count-low-range */ + uint8_t split_gain_table_mode_enable; /* adi,split-gain-table-mode-enable */ + uint32_t trx_synthesizer_target_fref_overwrite_hz; /* adi,trx-synthesizer-target-fref-overwrite-hz */ + uint8_t qec_tracking_slow_mode_enable; /* adi,qec-tracking-slow-mode-enable */ + /* ENSM Control */ + uint8_t ensm_enable_pin_pulse_mode_enable; /* adi,ensm-enable-pin-pulse-mode-enable */ + uint8_t ensm_enable_txnrx_control_enable; /* adi,ensm-enable-txnrx-control-enable */ + /* LO Control */ + uint64_t rx_synthesizer_frequency_hz; /* adi,rx-synthesizer-frequency-hz */ + uint64_t tx_synthesizer_frequency_hz; /* adi,tx-synthesizer-frequency-hz */ + uint8_t tx_lo_powerdown_managed_enable; /* adi,tx-lo-powerdown-managed-enable */ + /* Rate & BW Control */ + uint32_t rx_path_clock_frequencies[6]; /* adi,rx-path-clock-frequencies */ + uint32_t tx_path_clock_frequencies[6]; /* adi,tx-path-clock-frequencies */ + uint32_t rf_rx_bandwidth_hz; /* adi,rf-rx-bandwidth-hz */ + uint32_t rf_tx_bandwidth_hz; /* adi,rf-tx-bandwidth-hz */ + /* RF Port Control */ + uint32_t rx_rf_port_input_select; /* adi,rx-rf-port-input-select */ + uint32_t tx_rf_port_input_select; /* adi,tx-rf-port-input-select */ + /* TX Attenuation Control */ + int32_t tx_attenuation_mdB; /* adi,tx-attenuation-mdB */ + uint8_t update_tx_gain_in_alert_enable; /* adi,update-tx-gain-in-alert-enable */ + /* Reference Clock Control */ + uint8_t xo_disable_use_ext_refclk_enable; /* adi,xo-disable-use-ext-refclk-enable */ + uint32_t dcxo_coarse_and_fine_tune[2]; /* adi,dcxo-coarse-and-fine-tune */ + uint32_t clk_output_mode_select; /* adi,clk-output-mode-select */ + /* Gain Control */ + uint8_t gc_rx1_mode; /* adi,gc-rx1-mode */ + uint8_t gc_rx2_mode; /* adi,gc-rx2-mode */ + uint8_t gc_adc_large_overload_thresh; /* adi,gc-adc-large-overload-thresh */ + uint8_t gc_adc_ovr_sample_size; /* adi,gc-adc-ovr-sample-size */ + uint8_t gc_adc_small_overload_thresh; /* adi,gc-adc-small-overload-thresh */ + uint16_t gc_dec_pow_measurement_duration; /* adi,gc-dec-pow-measurement-duration */ + uint8_t gc_dig_gain_enable; /* adi,gc-dig-gain-enable */ + uint16_t gc_lmt_overload_high_thresh; /* adi,gc-lmt-overload-high-thresh */ + uint16_t gc_lmt_overload_low_thresh; /* adi,gc-lmt-overload-low-thresh */ + uint8_t gc_low_power_thresh; /* adi,gc-low-power-thresh */ + uint8_t gc_max_dig_gain; /* adi,gc-max-dig-gain */ + uint8_t gc_use_rx_fir_out_for_dec_pwr_meas_enable; /* adi,gc-use-rx-fir-out-for-dec-pwr-meas-enable */ + /* Gain MGC Control */ + uint8_t mgc_dec_gain_step; /* adi,mgc-dec-gain-step */ + uint8_t mgc_inc_gain_step; /* adi,mgc-inc-gain-step */ + uint8_t mgc_rx1_ctrl_inp_enable; /* adi,mgc-rx1-ctrl-inp-enable */ + uint8_t mgc_rx2_ctrl_inp_enable; /* adi,mgc-rx2-ctrl-inp-enable */ + uint8_t mgc_split_table_ctrl_inp_gain_mode; /* adi,mgc-split-table-ctrl-inp-gain-mode */ + /* Gain AGC Control */ + uint8_t agc_adc_large_overload_exceed_counter; /* adi,agc-adc-large-overload-exceed-counter */ + uint8_t agc_adc_large_overload_inc_steps; /* adi,agc-adc-large-overload-inc-steps - Name is misleading should be dec-steps*/ + uint8_t agc_adc_lmt_small_overload_prevent_gain_inc_enable; /* adi,agc-adc-lmt-small-overload-prevent-gain-inc-enable */ + uint8_t agc_adc_small_overload_exceed_counter; /* adi,agc-adc-small-overload-exceed-counter */ + uint8_t agc_dig_gain_step_size; /* adi,agc-dig-gain-step-size */ + uint8_t agc_dig_saturation_exceed_counter; /* adi,agc-dig-saturation-exceed-counter */ + uint32_t agc_gain_update_interval_us; /* adi,agc-gain-update-interval-us */ + uint8_t agc_immed_gain_change_if_large_adc_overload_enable; /* adi,agc-immed-gain-change-if-large-adc-overload-enable */ + uint8_t agc_immed_gain_change_if_large_lmt_overload_enable; /* adi,agc-immed-gain-change-if-large-lmt-overload-enable */ + uint8_t agc_inner_thresh_high; /* adi,agc-inner-thresh-high */ + uint8_t agc_inner_thresh_high_dec_steps; /* adi,agc-inner-thresh-high-dec-steps */ + uint8_t agc_inner_thresh_low; /* adi,agc-inner-thresh-low */ + uint8_t agc_inner_thresh_low_inc_steps; /* adi,agc-inner-thresh-low-inc-steps */ + uint8_t agc_lmt_overload_large_exceed_counter; /* adi,agc-lmt-overload-large-exceed-counter */ + uint8_t agc_lmt_overload_large_inc_steps; /* adi,agc-lmt-overload-large-inc-steps */ + uint8_t agc_lmt_overload_small_exceed_counter; /* adi,agc-lmt-overload-small-exceed-counter */ + uint8_t agc_outer_thresh_high; /* adi,agc-outer-thresh-high */ + uint8_t agc_outer_thresh_high_dec_steps; /* adi,agc-outer-thresh-high-dec-steps */ + uint8_t agc_outer_thresh_low; /* adi,agc-outer-thresh-low */ + uint8_t agc_outer_thresh_low_inc_steps; /* adi,agc-outer-thresh-low-inc-steps */ + uint32_t agc_attack_delay_extra_margin_us; /* adi,agc-attack-delay-extra-margin-us */ + uint8_t agc_sync_for_gain_counter_enable; /* adi,agc-sync-for-gain-counter-enable */ + /* Fast AGC */ + uint32_t fagc_dec_pow_measuremnt_duration; /* adi,fagc-dec-pow-measurement-duration */ + uint32_t fagc_state_wait_time_ns; /* adi,fagc-state-wait-time-ns */ + /* Fast AGC - Low Power */ + uint8_t fagc_allow_agc_gain_increase; /* adi,fagc-allow-agc-gain-increase-enable */ + uint32_t fagc_lp_thresh_increment_time; /* adi,fagc-lp-thresh-increment-time */ + uint32_t fagc_lp_thresh_increment_steps; /* adi,fagc-lp-thresh-increment-steps */ + /* Fast AGC - Lock Level (Lock Level is set via slow AGC inner high threshold) */ + uint8_t fagc_lock_level_lmt_gain_increase_en; /* adi,fagc-lock-level-lmt-gain-increase-enable */ + uint32_t fagc_lock_level_gain_increase_upper_limit; /* adi,fagc-lock-level-gain-increase-upper-limit */ + /* Fast AGC - Peak Detectors and Final Settling */ + uint32_t fagc_lpf_final_settling_steps; /* adi,fagc-lpf-final-settling-steps */ + uint32_t fagc_lmt_final_settling_steps; /* adi,fagc-lmt-final-settling-steps */ + uint32_t fagc_final_overrange_count; /* adi,fagc-final-overrange-count */ + /* Fast AGC - Final Power Test */ + uint8_t fagc_gain_increase_after_gain_lock_en; /* adi,fagc-gain-increase-after-gain-lock-enable */ + /* Fast AGC - Unlocking the Gain */ + uint32_t fagc_gain_index_type_after_exit_rx_mode; /* adi,fagc-gain-index-type-after-exit-rx-mode */ + uint8_t fagc_use_last_lock_level_for_set_gain_en; /* adi,fagc-use-last-lock-level-for-set-gain-enable */ + uint8_t fagc_rst_gla_stronger_sig_thresh_exceeded_en; /* adi,fagc-rst-gla-stronger-sig-thresh-exceeded-enable */ + uint32_t fagc_optimized_gain_offset; /* adi,fagc-optimized-gain-offset */ + uint32_t fagc_rst_gla_stronger_sig_thresh_above_ll; /* adi,fagc-rst-gla-stronger-sig-thresh-above-ll */ + uint8_t fagc_rst_gla_engergy_lost_sig_thresh_exceeded_en; /* adi,fagc-rst-gla-engergy-lost-sig-thresh-exceeded-enable */ + uint8_t fagc_rst_gla_engergy_lost_goto_optim_gain_en; /* adi,fagc-rst-gla-engergy-lost-goto-optim-gain-enable */ + uint32_t fagc_rst_gla_engergy_lost_sig_thresh_below_ll; /* adi,fagc-rst-gla-engergy-lost-sig-thresh-below-ll */ + uint32_t fagc_energy_lost_stronger_sig_gain_lock_exit_cnt; /* adi,fagc-energy-lost-stronger-sig-gain-lock-exit-cnt */ + uint8_t fagc_rst_gla_large_adc_overload_en; /* adi,fagc-rst-gla-large-adc-overload-enable */ + uint8_t fagc_rst_gla_large_lmt_overload_en; /* adi,fagc-rst-gla-large-lmt-overload-enable */ + uint8_t fagc_rst_gla_en_agc_pulled_high_en; /* adi,fagc-rst-gla-en-agc-pulled-high-enable */ + uint32_t fagc_rst_gla_if_en_agc_pulled_high_mode; /* adi,fagc-rst-gla-if-en-agc-pulled-high-mode */ + uint32_t fagc_power_measurement_duration_in_state5; /* adi,fagc-power-measurement-duration-in-state5 */ + uint32_t fagc_large_overload_inc_steps; /* adi,fagc-adc-large-overload-inc-steps - Name is misleading should be dec-steps */ + /* RSSI Control */ + uint32_t rssi_delay; /* adi,rssi-delay */ + uint32_t rssi_duration; /* adi,rssi-duration */ + uint8_t rssi_restart_mode; /* adi,rssi-restart-mode */ + uint8_t rssi_unit_is_rx_samples_enable; /* adi,rssi-unit-is-rx-samples-enable */ + uint32_t rssi_wait; /* adi,rssi-wait */ + /* Aux ADC Control */ + uint32_t aux_adc_decimation; /* adi,aux-adc-decimation */ + uint32_t aux_adc_rate; /* adi,aux-adc-rate */ + /* AuxDAC Control */ + uint8_t aux_dac_manual_mode_enable; /* adi,aux-dac-manual-mode-enable */ + uint32_t aux_dac1_default_value_mV; /* adi,aux-dac1-default-value-mV */ + uint8_t aux_dac1_active_in_rx_enable; /* adi,aux-dac1-active-in-rx-enable */ + uint8_t aux_dac1_active_in_tx_enable; /* adi,aux-dac1-active-in-tx-enable */ + uint8_t aux_dac1_active_in_alert_enable; /* adi,aux-dac1-active-in-alert-enable */ + uint32_t aux_dac1_rx_delay_us; /* adi,aux-dac1-rx-delay-us */ + uint32_t aux_dac1_tx_delay_us; /* adi,aux-dac1-tx-delay-us */ + uint32_t aux_dac2_default_value_mV; /* adi,aux-dac2-default-value-mV */ + uint8_t aux_dac2_active_in_rx_enable; /* adi,aux-dac2-active-in-rx-enable */ + uint8_t aux_dac2_active_in_tx_enable; /* adi,aux-dac2-active-in-tx-enable */ + uint8_t aux_dac2_active_in_alert_enable; /* adi,aux-dac2-active-in-alert-enable */ + uint32_t aux_dac2_rx_delay_us; /* adi,aux-dac2-rx-delay-us */ + uint32_t aux_dac2_tx_delay_us; /* adi,aux-dac2-tx-delay-us */ + /* Temperature Sensor Control */ + uint32_t temp_sense_decimation; /* adi,temp-sense-decimation */ + uint16_t temp_sense_measurement_interval_ms; /* adi,temp-sense-measurement-interval-ms */ + int8_t temp_sense_offset_signed; /* adi,temp-sense-offset-signed */ + uint8_t temp_sense_periodic_measurement_enable; /* adi,temp-sense-periodic-measurement-enable */ + /* Control Out Setup */ + uint8_t ctrl_outs_enable_mask; /* adi,ctrl-outs-enable-mask */ + uint8_t ctrl_outs_index; /* adi,ctrl-outs-index */ + /* External LNA Control */ + uint32_t elna_settling_delay_ns; /* adi,elna-settling-delay-ns */ + uint32_t elna_gain_mdB; /* adi,elna-gain-mdB */ + uint32_t elna_bypass_loss_mdB; /* adi,elna-bypass-loss-mdB */ + uint8_t elna_rx1_gpo0_control_enable; /* adi,elna-rx1-gpo0-control-enable */ + uint8_t elna_rx2_gpo1_control_enable; /* adi,elna-rx2-gpo1-control-enable */ + uint8_t elna_gaintable_all_index_enable; /* adi,elna-gaintable-all-index-enable */ + /* Digital Interface Control */ + uint8_t digital_interface_tune_skip_mode; /* adi,digital-interface-tune-skip-mode */ + uint8_t digital_interface_tune_fir_disable; /* adi,digital-interface-tune-fir-disable */ + uint8_t pp_tx_swap_enable; /* adi,pp-tx-swap-enable */ + uint8_t pp_rx_swap_enable; /* adi,pp-rx-swap-enable */ + uint8_t tx_channel_swap_enable; /* adi,tx-channel-swap-enable */ + uint8_t rx_channel_swap_enable; /* adi,rx-channel-swap-enable */ + uint8_t rx_frame_pulse_mode_enable; /* adi,rx-frame-pulse-mode-enable */ + uint8_t two_t_two_r_timing_enable; /* adi,2t2r-timing-enable */ + uint8_t invert_data_bus_enable; /* adi,invert-data-bus-enable */ + uint8_t invert_data_clk_enable; /* adi,invert-data-clk-enable */ + uint8_t fdd_alt_word_order_enable; /* adi,fdd-alt-word-order-enable */ + uint8_t invert_rx_frame_enable; /* adi,invert-rx-frame-enable */ + uint8_t fdd_rx_rate_2tx_enable; /* adi,fdd-rx-rate-2tx-enable */ + uint8_t swap_ports_enable; /* adi,swap-ports-enable */ + uint8_t single_data_rate_enable; /* adi,single-data-rate-enable */ + uint8_t lvds_mode_enable; /* adi,lvds-mode-enable */ + uint8_t half_duplex_mode_enable; /* adi,half-duplex-mode-enable */ + uint8_t single_port_mode_enable; /* adi,single-port-mode-enable */ + uint8_t full_port_enable; /* adi,full-port-enable */ + uint8_t full_duplex_swap_bits_enable; /* adi,full-duplex-swap-bits-enable */ + uint32_t delay_rx_data; /* adi,delay-rx-data */ + uint32_t rx_data_clock_delay; /* adi,rx-data-clock-delay */ + uint32_t rx_data_delay; /* adi,rx-data-delay */ + uint32_t tx_fb_clock_delay; /* adi,tx-fb-clock-delay */ + uint32_t tx_data_delay; /* adi,tx-data-delay */ + uint32_t lvds_bias_mV; /* adi,lvds-bias-mV */ + uint8_t lvds_rx_onchip_termination_enable; /* adi,lvds-rx-onchip-termination-enable */ + uint8_t rx1rx2_phase_inversion_en; /* adi,rx1-rx2-phase-inversion-enable */ + uint8_t lvds_invert1_control; /* adi,lvds-invert1-control */ + uint8_t lvds_invert2_control; /* adi,lvds-invert2-control */ + /* GPO Control */ + uint8_t gpo_manual_mode_enable; /* adi,gpo-manual-mode-enable */ + uint32_t gpo_manual_mode_enable_mask; /* adi,gpo-manual-mode-enable-mask */ + uint8_t gpo0_inactive_state_high_enable; /* adi,gpo0-inactive-state-high-enable */ + uint8_t gpo1_inactive_state_high_enable; /* adi,gpo1-inactive-state-high-enable */ + uint8_t gpo2_inactive_state_high_enable; /* adi,gpo2-inactive-state-high-enable */ + uint8_t gpo3_inactive_state_high_enable; /* adi,gpo3-inactive-state-high-enable */ + uint8_t gpo0_slave_rx_enable; /* adi,gpo0-slave-rx-enable */ + uint8_t gpo0_slave_tx_enable; /* adi,gpo0-slave-tx-enable */ + uint8_t gpo1_slave_rx_enable; /* adi,gpo1-slave-rx-enable */ + uint8_t gpo1_slave_tx_enable; /* adi,gpo1-slave-tx-enable */ + uint8_t gpo2_slave_rx_enable; /* adi,gpo2-slave-rx-enable */ + uint8_t gpo2_slave_tx_enable; /* adi,gpo2-slave-tx-enable */ + uint8_t gpo3_slave_rx_enable; /* adi,gpo3-slave-rx-enable */ + uint8_t gpo3_slave_tx_enable; /* adi,gpo3-slave-tx-enable */ + uint8_t gpo0_rx_delay_us; /* adi,gpo0-rx-delay-us */ + uint8_t gpo0_tx_delay_us; /* adi,gpo0-tx-delay-us */ + uint8_t gpo1_rx_delay_us; /* adi,gpo1-rx-delay-us */ + uint8_t gpo1_tx_delay_us; /* adi,gpo1-tx-delay-us */ + uint8_t gpo2_rx_delay_us; /* adi,gpo2-rx-delay-us */ + uint8_t gpo2_tx_delay_us; /* adi,gpo2-tx-delay-us */ + uint8_t gpo3_rx_delay_us; /* adi,gpo3-rx-delay-us */ + uint8_t gpo3_tx_delay_us; /* adi,gpo3-tx-delay-us */ + /* Tx Monitor Control */ + uint32_t low_high_gain_threshold_mdB; /* adi,txmon-low-high-thresh */ + uint32_t low_gain_dB; /* adi,txmon-low-gain */ + uint32_t high_gain_dB; /* adi,txmon-high-gain */ + uint8_t tx_mon_track_en; /* adi,txmon-dc-tracking-enable */ + uint8_t one_shot_mode_en; /* adi,txmon-one-shot-mode-enable */ + uint32_t tx_mon_delay; /* adi,txmon-delay */ + uint32_t tx_mon_duration; /* adi,txmon-duration */ + uint32_t tx1_mon_front_end_gain; /* adi,txmon-1-front-end-gain */ + uint32_t tx2_mon_front_end_gain; /* adi,txmon-2-front-end-gain */ + uint32_t tx1_mon_lo_cm; /* adi,txmon-1-lo-cm */ + uint32_t tx2_mon_lo_cm; /* adi,txmon-2-lo-cm */ + /* GPIO definitions */ + struct gpio_init_param gpio_resetb; /* reset-gpios */ + /* MCS Sync */ + struct gpio_init_param gpio_sync; /* sync-gpios */ + struct gpio_init_param gpio_cal_sw1; /* cal-sw1-gpios */ + struct gpio_init_param gpio_cal_sw2; /* cal-sw2-gpios */ + + struct spi_init_param spi_param; + + /* External LO clocks */ + uint32_t (*ad9361_rfpll_ext_recalc_rate)(struct refclk_scale *clk_priv); + int32_t (*ad9361_rfpll_ext_round_rate)(struct refclk_scale *clk_priv, + uint32_t rate); + int32_t (*ad9361_rfpll_ext_set_rate)(struct refclk_scale *clk_priv, + uint32_t rate); + +} AD9361_InitParam; + +typedef struct { + uint32_t rx; /* 1, 2, 3(both) */ + int32_t rx_gain; /* -12, -6, 0, 6 */ + uint32_t rx_dec; /* 1, 2, 4 */ + int16_t rx_coef[128]; + uint8_t rx_coef_size; + uint32_t rx_path_clks[6]; + uint32_t rx_bandwidth; +} AD9361_RXFIRConfig; + +typedef struct { + uint32_t tx; /* 1, 2, 3(both) */ + int32_t tx_gain; /* -6, 0 */ + uint32_t tx_int; /* 1, 2, 4 */ + int16_t tx_coef[128]; + uint8_t tx_coef_size; + uint32_t tx_path_clks[6]; + uint32_t tx_bandwidth; +} AD9361_TXFIRConfig; + +enum ad9361_ensm_mode { + ENSM_MODE_TX, + ENSM_MODE_RX, + ENSM_MODE_ALERT, + ENSM_MODE_FDD, + ENSM_MODE_WAIT, + ENSM_MODE_SLEEP, + ENSM_MODE_PINCTRL, + ENSM_MODE_PINCTRL_FDD_INDEP, +}; + +#define ENABLE 1 +#define DISABLE 0 + +#define RX1 0 +#define RX2 1 + +#define TX1 0 +#define TX2 1 + +#define A_BALANCED 0 +#define B_BALANCED 1 +#define C_BALANCED 2 +#define A_N 3 +#define A_P 4 +#define B_N 5 +#define B_P 6 +#define C_N 7 +#define C_P 8 +#define TX_MON1 9 +#define TX_MON2 10 +#define TX_MON1_2 11 + +#define TXA 0 +#define TXB 1 + +#define MODE_1x1 1 +#define MODE_2x2 2 + +#define HIGHEST_OSR 0 +#define NOMINAL_OSR 1 + +#define INT_LO 0 +#define EXT_LO 1 + +#define ON 0 +#define OFF 1 + +/******************************************************************************/ +/************************ Functions Declarations ******************************/ +/******************************************************************************/ +/* Initialize the AD9361 part. */ +int32_t ad9361_init (struct ad9361_rf_phy **ad9361_phy, + AD9361_InitParam *init_param); +/* Free the allocated resources. */ +int32_t ad9361_remove(struct ad9361_rf_phy *phy); +/* Set the Enable State Machine (ENSM) mode. */ +int32_t ad9361_set_en_state_machine_mode (struct ad9361_rf_phy *phy, + uint32_t mode); +/* Get the Enable State Machine (ENSM) mode. */ +int32_t ad9361_get_en_state_machine_mode (struct ad9361_rf_phy *phy, + uint32_t *mode); +/* Set the receive RF gain for the selected channel. */ +int32_t ad9361_set_rx_rf_gain (struct ad9361_rf_phy *phy, uint8_t ch, + int32_t gain_db); +/* Get current receive RF gain for the selected channel. */ +int32_t ad9361_get_rx_rf_gain (struct ad9361_rf_phy *phy, uint8_t ch, + int32_t *gain_db); +/* Set the RX RF bandwidth. */ +int32_t ad9361_set_rx_rf_bandwidth (struct ad9361_rf_phy *phy, + uint32_t bandwidth_hz); +/* Get the RX RF bandwidth. */ +int32_t ad9361_get_rx_rf_bandwidth (struct ad9361_rf_phy *phy, + uint32_t *bandwidth_hz); +/* Set the RX sampling frequency. */ +int32_t ad9361_set_rx_sampling_freq (struct ad9361_rf_phy *phy, + uint32_t sampling_freq_hz); +/* Get current RX sampling frequency. */ +int32_t ad9361_get_rx_sampling_freq (struct ad9361_rf_phy *phy, + uint32_t *sampling_freq_hz); +/* Set the RX LO frequency. */ +int32_t ad9361_set_rx_lo_freq (struct ad9361_rf_phy *phy, uint64_t lo_freq_hz); +/* Get current RX LO frequency. */ +int32_t ad9361_get_rx_lo_freq (struct ad9361_rf_phy *phy, uint64_t *lo_freq_hz); +/* Switch between internal and external LO. */ +int32_t ad9361_set_rx_lo_int_ext(struct ad9361_rf_phy *phy, uint8_t int_ext); +/* Get the RSSI for the selected channel. */ +int32_t ad9361_get_rx_rssi (struct ad9361_rf_phy *phy, uint8_t ch, + struct rf_rssi *rssi); +/* Set the gain control mode for the selected channel. */ +int32_t ad9361_set_rx_gain_control_mode (struct ad9361_rf_phy *phy, uint8_t ch, + uint8_t gc_mode); +/* Get the gain control mode for the selected channel. */ +int32_t ad9361_get_rx_gain_control_mode (struct ad9361_rf_phy *phy, uint8_t ch, + uint8_t *gc_mode); +/* Set the RX FIR filter configuration. */ +int32_t ad9361_set_rx_fir_config (struct ad9361_rf_phy *phy, + AD9361_RXFIRConfig fir_cfg); +/* Get the RX FIR filter configuration. */ +int32_t ad9361_get_rx_fir_config(struct ad9361_rf_phy *phy, uint8_t rx_ch, + AD9361_RXFIRConfig *fir_cfg); +/* Enable/disable the RX FIR filter. */ +int32_t ad9361_set_rx_fir_en_dis (struct ad9361_rf_phy *phy, uint8_t en_dis); +/* Get the status of the RX FIR filter. */ +int32_t ad9361_get_rx_fir_en_dis (struct ad9361_rf_phy *phy, uint8_t *en_dis); +/* Enable/disable the RX RFDC Tracking. */ +int32_t ad9361_set_rx_rfdc_track_en_dis (struct ad9361_rf_phy *phy, + uint8_t en_dis); +/* Get the status of the RX RFDC Tracking. */ +int32_t ad9361_get_rx_rfdc_track_en_dis (struct ad9361_rf_phy *phy, + uint8_t *en_dis); +/* Enable/disable the RX BasebandDC Tracking. */ +int32_t ad9361_set_rx_bbdc_track_en_dis (struct ad9361_rf_phy *phy, + uint8_t en_dis); +/* Get the status of the RX BasebandDC Tracking. */ +int32_t ad9361_get_rx_bbdc_track_en_dis (struct ad9361_rf_phy *phy, + uint8_t *en_dis); +/* Enable/disable the RX Quadrature Tracking. */ +int32_t ad9361_set_rx_quad_track_en_dis (struct ad9361_rf_phy *phy, + uint8_t en_dis); +/* Get the status of the RX Quadrature Tracking. */ +int32_t ad9361_get_rx_quad_track_en_dis (struct ad9361_rf_phy *phy, + uint8_t *en_dis); +/* Set the RX RF input port. */ +int32_t ad9361_set_rx_rf_port_input (struct ad9361_rf_phy *phy, uint32_t mode); +/* Get the selected RX RF input port. */ +int32_t ad9361_get_rx_rf_port_input (struct ad9361_rf_phy *phy, uint32_t *mode); +/* Store RX fastlock profile. */ +int32_t ad9361_rx_fastlock_store(struct ad9361_rf_phy *phy, uint32_t profile); +/* Recall RX fastlock profile. */ +int32_t ad9361_rx_fastlock_recall(struct ad9361_rf_phy *phy, uint32_t profile); +/* Load RX fastlock profile. */ +int32_t ad9361_rx_fastlock_load(struct ad9361_rf_phy *phy, uint32_t profile, + uint8_t *values); +/* Save RX fastlock profile. */ +int32_t ad9361_rx_fastlock_save(struct ad9361_rf_phy *phy, uint32_t profile, + uint8_t *values); +/* Power down the RX Local Oscillator. */ +int32_t ad9361_rx_lo_powerdown(struct ad9361_rf_phy *phy, uint8_t option); +/* Get the RX Local Oscillator power status. */ +int32_t ad9361_get_rx_lo_power(struct ad9361_rf_phy *phy, uint8_t *option); +/* Set the transmit attenuation for the selected channel. */ +int32_t ad9361_set_tx_attenuation (struct ad9361_rf_phy *phy, uint8_t ch, + uint32_t attenuation_mdb); +/* Get current transmit attenuation for the selected channel. */ +int32_t ad9361_get_tx_attenuation (struct ad9361_rf_phy *phy, uint8_t ch, + uint32_t *attenuation_mdb); +/* Set the TX RF bandwidth. */ +int32_t ad9361_set_tx_rf_bandwidth (struct ad9361_rf_phy *phy, + uint32_t bandwidth_hz); +/* Get the TX RF bandwidth. */ +int32_t ad9361_get_tx_rf_bandwidth (struct ad9361_rf_phy *phy, + uint32_t *bandwidth_hz); +/* Set the TX sampling frequency. */ +int32_t ad9361_set_tx_sampling_freq (struct ad9361_rf_phy *phy, + uint32_t sampling_freq_hz); +/* Get current TX sampling frequency. */ +int32_t ad9361_get_tx_sampling_freq (struct ad9361_rf_phy *phy, + uint32_t *sampling_freq_hz); +/* Set the TX LO frequency. */ +int32_t ad9361_set_tx_lo_freq (struct ad9361_rf_phy *phy, uint64_t lo_freq_hz); +/* Get current TX LO frequency. */ +int32_t ad9361_get_tx_lo_freq (struct ad9361_rf_phy *phy, uint64_t *lo_freq_hz); +/* Switch between internal and external LO. */ +int32_t ad9361_set_tx_lo_int_ext(struct ad9361_rf_phy *phy, uint8_t int_ext); +/* Set the TX FIR filter configuration. */ +int32_t ad9361_set_tx_fir_config (struct ad9361_rf_phy *phy, + AD9361_TXFIRConfig fir_cfg); +/* Get the TX FIR filter configuration. */ +int32_t ad9361_get_tx_fir_config(struct ad9361_rf_phy *phy, uint8_t tx_ch, + AD9361_TXFIRConfig *fir_cfg); +/* Enable/disable the TX FIR filter. */ +int32_t ad9361_set_tx_fir_en_dis (struct ad9361_rf_phy *phy, uint8_t en_dis); +/* Get the status of the TX FIR filter. */ +int32_t ad9361_get_tx_fir_en_dis (struct ad9361_rf_phy *phy, uint8_t *en_dis); +/* Get the TX RSSI for the selected channel. */ +int32_t ad9361_get_tx_rssi (struct ad9361_rf_phy *phy, uint8_t ch, + uint32_t *rssi_db_x_1000); +/* Set the TX RF output port. */ +int32_t ad9361_set_tx_rf_port_output (struct ad9361_rf_phy *phy, uint32_t mode); +/* Get the selected TX RF output port. */ +int32_t ad9361_get_tx_rf_port_output (struct ad9361_rf_phy *phy, + uint32_t *mode); +/* Enable/disable the auto calibration. */ +int32_t ad9361_set_tx_auto_cal_en_dis (struct ad9361_rf_phy *phy, + uint8_t en_dis); +/* Get the status of the auto calibration flag. */ +int32_t ad9361_get_tx_auto_cal_en_dis (struct ad9361_rf_phy *phy, + uint8_t *en_dis); +/* Store TX fastlock profile. */ +int32_t ad9361_tx_fastlock_store(struct ad9361_rf_phy *phy, uint32_t profile); +/* Recall TX fastlock profile. */ +int32_t ad9361_tx_fastlock_recall(struct ad9361_rf_phy *phy, uint32_t profile); +/* Load TX fastlock profile. */ +int32_t ad9361_tx_fastlock_load(struct ad9361_rf_phy *phy, uint32_t profile, + uint8_t *values); +/* Save TX fastlock profile. */ +int32_t ad9361_tx_fastlock_save(struct ad9361_rf_phy *phy, uint32_t profile, + uint8_t *values); +/* Power down the TX Local Oscillator. */ +int32_t ad9361_tx_lo_powerdown(struct ad9361_rf_phy *phy, uint8_t option); +/* Get the TX Local Oscillator power status. */ +int32_t ad9361_get_tx_lo_power(struct ad9361_rf_phy *phy, uint8_t *option); +/* Set the RX and TX path rates. */ +int32_t ad9361_set_trx_path_clks(struct ad9361_rf_phy *phy, + uint32_t *rx_path_clks, uint32_t *tx_path_clks); +/* Get the RX and TX path rates. */ +int32_t ad9361_get_trx_path_clks(struct ad9361_rf_phy *phy, + uint32_t *rx_path_clks, uint32_t *tx_path_clks); +/* Set the number of channels mode. */ +int32_t ad9361_set_no_ch_mode(struct ad9361_rf_phy *phy, uint8_t no_ch_mode); +/* Do multi chip synchronization. */ +int32_t ad9361_do_mcs(struct ad9361_rf_phy *phy_master, + struct ad9361_rf_phy *phy_slave); +/* Enable/disable the TRX FIR filters. */ +int32_t ad9361_set_trx_fir_en_dis (struct ad9361_rf_phy *phy, uint8_t en_dis); +/* Set the OSR rate governor. */ +int32_t ad9361_set_trx_rate_gov (struct ad9361_rf_phy *phy, uint32_t rate_gov); +/* Get the OSR rate governor. */ +int32_t ad9361_get_trx_rate_gov (struct ad9361_rf_phy *phy, uint32_t *rate_gov); +/* Perform the selected calibration. */ +int32_t ad9361_do_calib(struct ad9361_rf_phy *phy, uint32_t cal, int32_t arg); +/* Load and enable TRX FIR filters configurations. */ +int32_t ad9361_trx_load_enable_fir(struct ad9361_rf_phy *phy, + AD9361_RXFIRConfig rx_fir_cfg, + AD9361_TXFIRConfig tx_fir_cfg); +/* Do DCXO coarse tuning. */ +int32_t ad9361_do_dcxo_tune_coarse(struct ad9361_rf_phy *phy, + uint32_t coarse); +/* Do DCXO fine tuning. */ +int32_t ad9361_do_dcxo_tune_fine(struct ad9361_rf_phy *phy, + uint32_t fine); +/* Get the temperature. */ +int32_t ad9361_get_temperature(struct ad9361_rf_phy *phy, + int32_t *temp); +#endif diff --git a/df_datalink_sp/src/drivers/rf-transceiver/ad9361/ad9361_conv.c b/df_datalink_sp/src/drivers/rf-transceiver/ad9361/ad9361_conv.c new file mode 100644 index 0000000..bbcfee5 --- /dev/null +++ b/df_datalink_sp/src/drivers/rf-transceiver/ad9361/ad9361_conv.c @@ -0,0 +1,86 @@ + +/***************************************************************************//** + * @file ad9361_conv.c + * @brief Implementation of AD9361 Conv Driver. +******************************************************************************** + * Copyright 2014-2015(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ +#include +#include +#include "ad9361.h" +#include "ad9361_util.h" +#include "delay.h" +#include "../../../config/app_config.h" + +/******************************************************************************/ +/********************** Macros and Constants Definitions **********************/ +/******************************************************************************/ + +/** + * HDL loopback enable/disable. + * @param phy The AD9361 state structure. + * @param enable Enable/disable option. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_hdl_loopback(struct ad9361_rf_phy *phy, bool enable) +{ + return -ENODEV; +} + +/** + * Digital tune. + * @param phy The AD9361 state structure. + * @param max_freq Maximum frequency. + * @param flags Flags: BE_VERBOSE, BE_MOREVERBOSE, DO_IDELAY, DO_ODELAY. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_dig_tune(struct ad9361_rf_phy *phy, uint32_t max_freq, + enum dig_tune_flags flags) +{ + return 0; +} + +/** +* Setup the AD9361 device. +* @param phy The AD9361 state structure. +* @return 0 in case of success, negative error code otherwise. +*/ +int32_t ad9361_post_setup(struct ad9361_rf_phy *phy) +{ + return 0; +} diff --git a/df_datalink_sp/src/drivers/rf-transceiver/ad9361/ad9361_util.c b/df_datalink_sp/src/drivers/rf-transceiver/ad9361/ad9361_util.c new file mode 100644 index 0000000..a49e146 --- /dev/null +++ b/df_datalink_sp/src/drivers/rf-transceiver/ad9361/ad9361_util.c @@ -0,0 +1,335 @@ +/***************************************************************************//** + * @file ad9361_util.c + * @brief AD9361 Implementation of Util Driver. + * @author DBogdan (dragos.bogdan@analog.com) +******************************************************************************** + * Copyright 2013(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ +#include +#include "ad9361_util.h" +#include "../../../include/delay.h" + +/******************************************************************************/ +/*************************** Macros Definitions *******************************/ +/******************************************************************************/ +#define BITS_PER_LONG 32 + +/***************************************************************************//** + * @brief clk_prepare_enable +*******************************************************************************/ +int32_t clk_prepare_enable(struct clk *clk) +{ + if (clk) { + // Unused variable - fix compiler warning + } + + return 0; +} + +/***************************************************************************//** + * @brief clk_get_rate +*******************************************************************************/ +uint32_t clk_get_rate(struct ad9361_rf_phy *phy, + struct refclk_scale *clk_priv) +{ + uint32_t rate = 0; + uint32_t source; + + source = clk_priv->source; + + switch (source) { + case TX_REFCLK: + case RX_REFCLK: + case BB_REFCLK: + rate = ad9361_clk_factor_recalc_rate(clk_priv, + phy->clk_refin->rate); + break; + case TX_RFPLL_INT: + case RX_RFPLL_INT: + rate = ad9361_rfpll_int_recalc_rate(clk_priv, + phy->clks[clk_priv->parent_source]->rate); + break; + case RX_RFPLL_DUMMY: + case TX_RFPLL_DUMMY: + rate = ad9361_rfpll_dummy_recalc_rate(clk_priv); + break; + case TX_RFPLL: + case RX_RFPLL: + rate = ad9361_rfpll_recalc_rate(clk_priv); + break; + case BBPLL_CLK: + rate = ad9361_bbpll_recalc_rate(clk_priv, + phy->clks[clk_priv->parent_source]->rate); + break; + case ADC_CLK: + case R2_CLK: + case R1_CLK: + case CLKRF_CLK: + case RX_SAMPL_CLK: + case DAC_CLK: + case T2_CLK: + case T1_CLK: + case CLKTF_CLK: + case TX_SAMPL_CLK: + rate = ad9361_clk_factor_recalc_rate(clk_priv, + phy->clks[clk_priv->parent_source]->rate); + break; + default: + break; + } + + return rate; +} + +/***************************************************************************//** + * @brief clk_set_rate +*******************************************************************************/ +int32_t clk_set_rate(struct ad9361_rf_phy *phy, + struct refclk_scale *clk_priv, + uint32_t rate) +{ + uint32_t source; + int32_t i; + uint32_t round_rate; + + source = clk_priv->source; + if(phy->clks[source]->rate != rate) + { + switch (source) { + case TX_REFCLK: + case RX_REFCLK: + case BB_REFCLK: + round_rate = ad9361_clk_factor_round_rate(clk_priv, rate, + &phy->clk_refin->rate); + ad9361_clk_factor_set_rate(clk_priv, round_rate, + phy->clk_refin->rate); + phy->clks[source]->rate = ad9361_clk_factor_recalc_rate(clk_priv, + phy->clk_refin->rate); + break; + case TX_RFPLL_INT: + case RX_RFPLL_INT: + round_rate = ad9361_rfpll_int_round_rate(clk_priv, rate, + &phy->clks[clk_priv->parent_source]->rate); + ad9361_rfpll_int_set_rate(clk_priv, round_rate, + phy->clks[clk_priv->parent_source]->rate); + phy->clks[source]->rate = ad9361_rfpll_int_recalc_rate(clk_priv, + phy->clks[clk_priv->parent_source]->rate); + break; + case RX_RFPLL_DUMMY: + case TX_RFPLL_DUMMY: + ad9361_rfpll_dummy_set_rate(clk_priv, rate); + break; + case TX_RFPLL: + case RX_RFPLL: + round_rate = ad9361_rfpll_round_rate(clk_priv, rate); + ad9361_rfpll_set_rate(clk_priv, round_rate); + phy->clks[source]->rate = ad9361_rfpll_recalc_rate(clk_priv); + break; + case BBPLL_CLK: + round_rate = ad9361_bbpll_round_rate(clk_priv, rate, + &phy->clks[clk_priv->parent_source]->rate); + ad9361_bbpll_set_rate(clk_priv, round_rate, + phy->clks[clk_priv->parent_source]->rate); + phy->clks[source]->rate = ad9361_bbpll_recalc_rate(clk_priv, + phy->clks[clk_priv->parent_source]->rate); + phy->bbpll_initialized = true; + break; + case ADC_CLK: + case R2_CLK: + case R1_CLK: + case CLKRF_CLK: + case RX_SAMPL_CLK: + case DAC_CLK: + case T2_CLK: + case T1_CLK: + case CLKTF_CLK: + case TX_SAMPL_CLK: + round_rate = ad9361_clk_factor_round_rate(clk_priv, rate, + &phy->clks[clk_priv->parent_source]->rate); + ad9361_clk_factor_set_rate(clk_priv, round_rate, + phy->clks[clk_priv->parent_source]->rate); + phy->clks[source]->rate = ad9361_clk_factor_recalc_rate(clk_priv, + phy->clks[clk_priv->parent_source]->rate); + break; + default: + break; + } + for(i = BB_REFCLK; i < BBPLL_CLK; i++) + { + phy->clks[i]->rate = ad9361_clk_factor_recalc_rate(phy->ref_clk_scale[i], + phy->clk_refin->rate); + } + phy->clks[BBPLL_CLK]->rate = ad9361_bbpll_recalc_rate(phy->ref_clk_scale[BBPLL_CLK], + phy->clks[phy->ref_clk_scale[BBPLL_CLK]->parent_source]->rate); + for(i = ADC_CLK; i < RX_RFPLL_INT; i++) + { + phy->clks[i]->rate = ad9361_clk_factor_recalc_rate(phy->ref_clk_scale[i], + phy->clks[phy->ref_clk_scale[i]->parent_source]->rate); + } + for(i = RX_RFPLL_INT; i < RX_RFPLL_DUMMY; i++) + { + phy->clks[i]->rate = ad9361_rfpll_int_recalc_rate(phy->ref_clk_scale[i], + phy->clks[phy->ref_clk_scale[i]->parent_source]->rate); + } + for(i = RX_RFPLL_DUMMY; i < RX_RFPLL; i++) + { + phy->clks[i]->rate = ad9361_rfpll_dummy_recalc_rate(phy->ref_clk_scale[i]); + } + for(i = RX_RFPLL; i < NUM_AD9361_CLKS; i++) + { + phy->clks[i]->rate = ad9361_rfpll_recalc_rate(phy->ref_clk_scale[i]); + } + } else { + if ((source == BBPLL_CLK) && !phy->bbpll_initialized) { + round_rate = ad9361_bbpll_round_rate(clk_priv, rate, + &phy->clks[clk_priv->parent_source]->rate); + ad9361_bbpll_set_rate(clk_priv, round_rate, + phy->clks[clk_priv->parent_source]->rate); + phy->clks[source]->rate = ad9361_bbpll_recalc_rate(clk_priv, + phy->clks[clk_priv->parent_source]->rate); + phy->bbpll_initialized = true; + } + } + + return 0; +} + +/***************************************************************************//** + * @brief int_sqrt +*******************************************************************************/ +uint32_t int_sqrt(uint32_t x) +{ + uint32_t b, m, y = 0; + + if (x <= 1) + return x; + + m = 1UL << (BITS_PER_LONG - 2); + while (m != 0) { + b = y + m; + y >>= 1; + + if (x >= b) { + x -= b; + y += m; + } + m >>= 2; + } + + return y; +} + +/***************************************************************************//** + * @brief ilog2 +*******************************************************************************/ +int32_t ilog2(int32_t x) +{ + int32_t A = !(!(x >> 16)); + int32_t count = 0; + int32_t x_copy = x; + + count = count + (A << 4); + + x_copy = (((~A + 1) & (x >> 16)) + (~(~A + 1) & x)); + + A = !(!(x_copy >> 8)); + count = count + (A << 3); + x_copy = (((~A + 1) & (x_copy >> 8)) + (~(~A + 1) & x_copy)); + + A = !(!(x_copy >> 4)); + count = count + (A << 2); + x_copy = (((~A + 1) & (x_copy >> 4)) + (~(~A + 1) & x_copy)); + + A = !(!(x_copy >> 2)); + count = count + (A << 1); + x_copy = (((~A + 1) & (x_copy >> 2)) + (~(~A + 1) & x_copy)); + + A = !(!(x_copy >> 1)); + count = count + A; + + return count; +} + +/***************************************************************************//** + * @brief find_first_bit +*******************************************************************************/ +uint32_t find_first_bit(uint32_t word) +{ + int32_t num = 0; + + if ((word & 0xffff) == 0) { + num += 16; + word >>= 16; + } + if ((word & 0xff) == 0) { + num += 8; + word >>= 8; + } + if ((word & 0xf) == 0) { + num += 4; + word >>= 4; + } + if ((word & 0x3) == 0) { + num += 2; + word >>= 2; + } + if ((word & 0x1) == 0) + num += 1; + return num; +} + +/***************************************************************************//** + * @brief ERR_PTR +*******************************************************************************/ +void * ERR_PTR(long error) +{ + return (void *) error; +} + +/***************************************************************************//** + * @brief zmalloc +*******************************************************************************/ +void *zmalloc(size_t size) +{ + void *ptr = malloc(size); + if (ptr) + memset(ptr, 0, size); + mdelay(1); + + return ptr; +} diff --git a/df_datalink_sp/src/drivers/rf-transceiver/ad9361/ad9361_util.h b/df_datalink_sp/src/drivers/rf-transceiver/ad9361/ad9361_util.h new file mode 100644 index 0000000..cabb6dc --- /dev/null +++ b/df_datalink_sp/src/drivers/rf-transceiver/ad9361/ad9361_util.h @@ -0,0 +1,120 @@ +/***************************************************************************//** + * @file ad9361_util.h + * @brief AD9361 Header file of Util driver. + * @author DBogdan (dragos.bogdan@analog.com) +******************************************************************************** + * Copyright 2013(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ +#ifndef __AD9361_UTIL_H__ +#define __AD9361_UTIL_H__ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ +#include +#include +#include +#include +#include "ad9361.h" +#include "common.h" + +/******************************************************************************/ +/********************** Macros and Constants Definitions **********************/ +/******************************************************************************/ +#define CLK_IGNORE_UNUSED BIT(3) +#define CLK_GET_RATE_NOCACHE BIT(6) + +#if defined(HAVE_VERBOSE_MESSAGES) +#define dev_err(dev, format, ...) ({printf(format, ## __VA_ARGS__);printf("\n"); }) +#define dev_warn(dev, format, ...) ({printf(format, ## __VA_ARGS__);printf("\n"); }) +#if defined(HAVE_DEBUG_MESSAGES) +#define dev_dbg(dev, format, ...) ({printf(format, ## __VA_ARGS__);printf("\n"); }) +#else +#define dev_dbg(dev, format, ...) ({ if (0) printf(format, ## __VA_ARGS__); }) +#endif +#define printk(format, ...) printf(format, ## __VA_ARGS__) +#else +#define dev_err(dev, format, ...) ({ if (0) printf(format, ## __VA_ARGS__); }) +#define dev_warn(dev, format, ...) ({ if (0) printf(format, ## __VA_ARGS__); }) +#define dev_dbg(dev, format, ...) ({ if (0) printf(format, ## __VA_ARGS__); }) +#define printk(format, ...) ({ if (0) printf(format, ## __VA_ARGS__); }) +#endif + +struct device { +}; + +struct spi_device { + struct device dev; + uint8_t id_no; +}; + +struct axiadc_state { + struct ad9361_rf_phy *phy; + uint32_t pcore_version; +}; + +struct axiadc_chip_info { + char *name; + int32_t num_channels; +}; + +struct axiadc_converter { + struct axiadc_chip_info *chip_info; + uint32_t scratch_reg[16]; +}; + +#ifdef WIN32 +#include "basetsd.h" +typedef SSIZE_T ssize_t; +#define strsep(s, ct) 0 +#define snprintf(s, n, format, ...) 0 +#define __func__ __FUNCTION__ +#endif + +/******************************************************************************/ +/************************ Functions Declarations ******************************/ +/******************************************************************************/ +int32_t clk_prepare_enable(struct clk *clk); +uint32_t clk_get_rate(struct ad9361_rf_phy *phy, + struct refclk_scale *clk_priv); +int32_t clk_set_rate(struct ad9361_rf_phy *phy, + struct refclk_scale *clk_priv, + uint32_t rate); +uint32_t int_sqrt(uint32_t x); +int32_t ilog2(int32_t x); +uint32_t find_first_bit(uint32_t word); +void * ERR_PTR(long error); +void *zmalloc(size_t size); + +#endif diff --git a/df_datalink_sp/src/drivers/rf-transceiver/ad9361/common.h b/df_datalink_sp/src/drivers/rf-transceiver/ad9361/common.h new file mode 100644 index 0000000..6093230 --- /dev/null +++ b/df_datalink_sp/src/drivers/rf-transceiver/ad9361/common.h @@ -0,0 +1,66 @@ +/***************************************************************************//** + * @file common.h + * @brief Header file of Common Driver. + * @author DBogdan (dragos.bogdan@analog.com) +******************************************************************************** + * Copyright 2013(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ +#ifndef __AD9361_COMMON_H_ +#define __AD9361_COMMON_H_ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ +#include +#include "../../../include/error.h" + +/******************************************************************************/ +/*************************** Types Declarations *******************************/ +/******************************************************************************/ +#if defined (__STDC__) && (__STDC_VERSION__ >= 199901L) +#include +#else +typedef enum { false, true } bool; +#endif + +struct clk { + const char *name; + uint32_t rate; +}; + +struct clk_hw { + struct clk *clk; +}; + +#endif // __AD9361_COMMON_H_ diff --git a/df_datalink_sp/src/drivers/rf-transceiver/ad9361_reg/ad9361_reg.c b/df_datalink_sp/src/drivers/rf-transceiver/ad9361_reg/ad9361_reg.c new file mode 100644 index 0000000..7498038 --- /dev/null +++ b/df_datalink_sp/src/drivers/rf-transceiver/ad9361_reg/ad9361_reg.c @@ -0,0 +1,151 @@ +/***************************************************************************//** + * @file ad9361_reg.c + * @brief Implementation of AD9680 Driver. + * @author DBogdan (dragos.bogdan@analog.com) + ******************************************************************************** + * Copyright 2014-2016(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *******************************************************************************/ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ +#include "ad9361_reg.h" + +#include +#include +#include "../../../include/error.h" + +/***************************************************************************//** + * @brief ad9361_reg_read + *******************************************************************************/ +int32_t ad9361_reg_read(struct ad9361_reg_dev *dev, + uint16_t reg_addr, + uint8_t *reg_data) +{ + uint8_t tx_buf[2]; + uint8_t rx_buf[1]; + int32_t ret; + + tx_buf[0] = reg_addr >> 8; + tx_buf[1] = reg_addr & 0xFF; + + + ret = spi_write_and_read_3wire(dev->spi_desc, + tx_buf, rx_buf, 2, 1); + + *reg_data = rx_buf[0]; + + return ret; +} + +/***************************************************************************//** + * @brief ad9361_reg_write + *******************************************************************************/ +int32_t ad9361_reg_write(struct ad9361_reg_dev *dev, + uint16_t reg_addr, + uint8_t reg_data) +{ + uint8_t buf[3]; + + int32_t ret; + + buf[0] = 0x80 | reg_addr >> 8; + buf[1] = reg_addr & 0xFF; + buf[2] = reg_data; + + ret = spi_write_and_read_3wire(dev->spi_desc, + buf, NULL, 3, 0); + return ret; +} + +/***************************************************************************//** + * @brief ad9361_reg_init + *******************************************************************************/ +int32_t ad9361_reg_init(struct ad9361_reg_dev **device, + const struct ad9361_reg_init_param *init_param) +{ + int ret = SUCCESS; + struct ad9361_reg_dev *dev; + + dev = (struct ad9361_reg_dev *)malloc(sizeof(*dev)); + if (!dev) + return FAILURE; + + /* SPI */ + ret = spi_init(&dev->spi_desc, init_param->spi_init); + ret |= gpio_get(&dev->gpio_desc_resetb, init_param->gpio_resetb); + + gpio_direction_output(dev->gpio_desc_resetb, 0); + + ad9361_reg_reset(dev); + + *device = dev; + + return ret; +} + +/** + * AD9361 Device Reset + * @param phy The AD9361 state structure. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad9361_reg_reset(struct ad9361_reg_dev *dev) +{ + if (dev->gpio_desc_resetb) { + gpio_set_value(dev->gpio_desc_resetb, 0); + mdelay(10); + gpio_set_value(dev->gpio_desc_resetb, 1); + mdelay(10); + return 0; + } + return 0; +} + +/***************************************************************************//** + * @brief Free the resources allocated by ad9361_reg_setup(). + * + * @param dev - The device structure. + * + * @return SUCCESS in case of success, negative error code otherwise. +*******************************************************************************/ +int32_t ad9361_reg_remove(struct ad9361_reg_dev *dev) +{ + int32_t ret; + + ret = spi_remove(dev->spi_desc); + + free(dev); + + return ret; +} diff --git a/df_datalink_sp/src/drivers/rf-transceiver/ad9361_reg/ad9361_reg.h b/df_datalink_sp/src/drivers/rf-transceiver/ad9361_reg/ad9361_reg.h new file mode 100644 index 0000000..c3039c5 --- /dev/null +++ b/df_datalink_sp/src/drivers/rf-transceiver/ad9361_reg/ad9361_reg.h @@ -0,0 +1,104 @@ +/***************************************************************************//** + * @file ad9361_reg.h + * @brief Header file of ad9361_reg Driver. + * @author DBogdan (dragos.bogdan@analog.com) + ******************************************************************************** + * Copyright 2014-2016(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *******************************************************************************/ +#ifndef ad9361_reg_H_ +#define ad9361_reg_H_ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ +#include +#include "delay.h" +#include "spi.h" +#include "gpio.h" + +/******************************************************************************/ +/********************** Macros and Constants Definitions **********************/ +/******************************************************************************/ + + +/******************************************************************************/ +/*************************** Types Declarations *******************************/ +/******************************************************************************/ +struct ad9361_reg_dev { + /* SPI */ + struct spi_desc *spi_desc; + struct gpio_desc *gpio_desc_resetb; +}; + +struct ad9361_reg_init_param { + /* SPI */ + struct spi_init_param *spi_init; + struct gpio_init_param *gpio_resetb; +}; + +enum Operation_Type{ + AD9361_WRITE, + AD9361_READ, + AD9361_WAIT, + AD9361_WHEN +}; + +struct ad9361_reg_config { + int operation; + uint16_t val1; + uint16_t val2; +}; + + + +/******************************************************************************/ +/************************ Functions Declarations ******************************/ +/******************************************************************************/ + +int32_t ad9361_reg_read(struct ad9361_reg_dev *dev, + uint16_t reg_addr, + uint8_t *reg_data); + +int32_t ad9361_reg_write(struct ad9361_reg_dev *dev, + uint16_t reg_addr, + uint8_t reg_data); + +int32_t ad9361_reg_init(struct ad9361_reg_dev **device, + const struct ad9361_reg_init_param *init_param); + +int32_t ad9361_reg_reset(struct ad9361_reg_dev *dev); + +int32_t ad9361_reg_remove(struct ad9361_reg_dev *dev); + +#endif diff --git a/df_datalink_sp/src/include/axi_io.h b/df_datalink_sp/src/include/axi_io.h new file mode 100644 index 0000000..ac8b67d --- /dev/null +++ b/df_datalink_sp/src/include/axi_io.h @@ -0,0 +1,59 @@ +/***************************************************************************//** + * @file axi_io.h + * @brief Header file of AXI IO. + * @author Antoniu Miclaus (antoniu.miclaus@analog.com) +******************************************************************************** + * Copyright 2019(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ + +#ifndef _AXI_IO_H_ +#define _AXI_IO_H_ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include + +/******************************************************************************/ +/************************ Functions Declarations ******************************/ +/******************************************************************************/ + +/* AXI IO Read data */ +int32_t axi_io_read(uint32_t base, uint32_t offset, uint32_t *data); + +/* AXI IO Write data */ +int32_t axi_io_write(uint32_t base, uint32_t offset, uint32_t data); + +#endif // _AXI_IO_H_ diff --git a/df_datalink_sp/src/include/circ_queue.h b/df_datalink_sp/src/include/circ_queue.h new file mode 100644 index 0000000..a6dc655 --- /dev/null +++ b/df_datalink_sp/src/include/circ_queue.h @@ -0,0 +1,111 @@ +/*****************************************************************************/ +/** + * Description: A simple circular FIFO bounded queue + * + * Author: Fan Hao + * Date: 2023-02-23 10:29 + * LastEditors: Fan Hao + * LastEditTime: 2023-02-23 12:53 + * Revisions: Rev 0.0 + * History: + * [2023-02-23]: Initial Version. + * + * Copyright(c) 2023 Beijing Institute of Technology. + * Lab of Communication and Networking + * NOTE: Forked from https://github.com/chrismerck/rpa_queue.git + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +******************************************************************************/ + +#ifndef CIRC_QUEUE_H +#define CIRC_QUEUE_H + +#include +#include +#include + + +/** + * opaque structure + */ +typedef struct { + void **data; + volatile uint32_t nelts; /**< # elements */ + uint32_t in; /**< next empty location */ + uint32_t out; /**< next filled location */ + uint32_t bounds;/**< max size of queue */ +} CIRC_QUEUE; + + + +/** + * create a FIFO queue + * @param queue The new queue + * @param queue_capacity maximum size of the queue + * @param a pool to allocate queue from + */ +bool CircQueueCreate(CIRC_QUEUE **queue, uint32_t queue_capacity); + +/** free queue memory -- call after destroy + * @note we do not free in destroy() to follow pthreads convention +*/ +void CircQueueFree(CIRC_QUEUE * queue); + +/** + * Detects when the CIRC_QUEUE is full. This utility function is expected + * to be called from within critical sections, and is not threadsafe. + */ +bool isCircQueueFull(CIRC_QUEUE *queue); + +/** + * Detects when the CIRC_QUEUE is empty. This utility function is expected + * to be called from within critical sections, and is not threadsafe. + */ +bool isCircQueueEmpty(CIRC_QUEUE *queue); + +/** + * push/add an object to the queue, blocking if the queue is already full + * + * @param queue the queue + * @param data the data + * @returns RPA_EINTR the blocking was interrupted (try again) + * @returns RPA_EOF the queue has been terminated + * @returns RPA_SUCCESS on a successful push + */ +bool CircQueuePush(CIRC_QUEUE *queue, void *data); + + +/** + * pop/get an object from the queue, blocking if the queue is already empty + * + * @param queue the queue + * @param data the data + * @returns RPA_EINTR the blocking was interrupted (try again) + * @returns RPA_EOF if the queue has been terminated + * @returns RPA_SUCCESS on a successful pop + */ +bool CircQueuePop(CIRC_QUEUE *queue, void **data); + +/** + * returns the size of the queue. + * + * @warning this is not threadsafe, and is intended for reporting/monitoring + * of the queue. + * @param queue the queue + * @returns the size of the queue + */ +uint32_t CircQueueSize(CIRC_QUEUE *queue); + +#endif /* CIRC_QUEUE_H */ diff --git a/df_datalink_sp/src/include/common.h b/df_datalink_sp/src/include/common.h new file mode 100644 index 0000000..b5edcc2 --- /dev/null +++ b/df_datalink_sp/src/include/common.h @@ -0,0 +1,92 @@ +/*****************************************************************************/ +/** + * Description: Common definitions + * + * Date: 2023-12-21 16:32 + * LastEditors: Fan Hao + * LastEditTime: 2022-07-16 17:13 + * Revisions: Rev 0.1 + * History: + * [2023-12-21]: Ensure the code conform ISO C11 standard. + * [2022-07-16]: New branch for Dijian. + * [2021-11-16]: Initial version. + * + * Copyright(c) 2021 Beijing Institute of Technology. + * Lab of Communication and Networking + * + ******************************************************************************/ +/***************************** Include Files *********************************/ +#ifndef __COMMON_H_ +#define __COMMON_H_ +#include +#include +#include +#include +#include "util.h" +#include "error.h" +#include "../config/app_config.h" + +/************************** Constant Definitions *****************************/ +/***************** Macros (Inline Functions) Definitions *********************/ +#define __PRINT_BLOCK(block) \ + do \ + { \ + block \ + } while (0) + +#define ASSERT(exp) ((exp) ? (void)0 : AppAssert(__FILE__, __LINE__)) +#define _nop_() __asm__("nop") + +/* Stringify */ +#define STR(x) #x + +// #define _814_DEBUG_LEVEL 3 + +#if _814_DEBUG_LEVEL > 0 +#define DBG_PRINT(...) printf(__VA_ARGS__) +#endif +#if _814_DEBUG_LEVEL >= 1 +#define DBG_ERROR(...) __PRINT_BLOCK( \ + printf("in"__FILE__ \ + " #%4d [error]\t", \ + __LINE__); \ + printf(__VA_ARGS__);) +#endif +#if _814_DEBUG_LEVEL >= 2 +#define DBG_WARNING(...) __PRINT_BLOCK( \ + printf("[warning]\t"); \ + printf(__VA_ARGS__);) +#endif +#if _814_DEBUG_LEVEL >= 3 +#define DBG_INFO(...) __PRINT_BLOCK( \ + printf("[Info]\t"); \ + printf(__VA_ARGS__);) +#endif + +#ifndef DBG_ERROR +#define DBG_ERROR(...) \ + { \ + } +#endif +#ifndef DBG_WARNING +#define DBG_WARNING(...) \ + { \ + } +#endif +#ifndef DBG_INFO +#define DBG_INFO(...) \ + { \ + } +#endif +#ifndef DBG_PRINT +#define DBG_PRINT(...) \ + { \ + } +#endif +/**************************** Type Definitions *******************************/ + +/************************** Variable Definitions *****************************/ + +/************************** Function Prototypes ******************************/ +void AppAssert(const char *file, int line); +#endif /* __COMMON_H_ */ diff --git a/df_datalink_sp/src/include/delay.h b/df_datalink_sp/src/include/delay.h new file mode 100644 index 0000000..d1dee17 --- /dev/null +++ b/df_datalink_sp/src/include/delay.h @@ -0,0 +1,70 @@ +/***************************************************************************//** + * @file delay.h + * @brief Header file of Delay functions + * @author DBogdan (dragos.bogdan@analog.com) +******************************************************************************** + * Copyright 2019(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ + +#ifndef _DELAY_H_ +#define _DELAY_H_ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include + +/** + * @struct time + * @brief Structure holding time data (seconds, microseconds). + */ +struct time { + unsigned int s, us; +}; + +/******************************************************************************/ +/************************ Functions Declarations ******************************/ +/******************************************************************************/ + +/* Generate microseconds delay. */ +void udelay(uint32_t usecs); + +/* Generate miliseconds delay. */ +void mdelay(uint32_t msecs); + +/* Get current time */ +struct time get_time(void); + +#endif // _DELAY_H_ diff --git a/df_datalink_sp/src/include/error.h b/df_datalink_sp/src/include/error.h new file mode 100644 index 0000000..1e20199 --- /dev/null +++ b/df_datalink_sp/src/include/error.h @@ -0,0 +1,47 @@ +/*****************************************************************************/ +/** + * Description: Error code definitions. + * + * Author: Fan Hao + * Date: 2022-06-18 16:37 + * LastEditors: Fan Hao + * LastEditTime: 2022-06-18 17:12 + * Revisions: Rev 0.0 + * History: + * [2022-06-18]: Initial version. + * + * Copyright(c) 2022 Beijing Institute of Technology. + * Lab of Communication and Networking + * +******************************************************************************/ + +#ifndef SRC_ERROR_H_ +#define SRC_ERROR_H_ + +#include + +/******************************************************************************/ +/********************** Macros and Constants Definitions **********************/ +/******************************************************************************/ + +#ifdef SUCCESS +#undef SUCCESS +#endif +#define SUCCESS 0 +#ifdef FAILURE +#undef FAILURE +#endif +#define FAILURE -1 + +#define EPARAM -2 /*!< Data crc check failed */ +#define ECRC -3 /*!< Data crc check failed */ +#define EDINVAL -4 /*!< Device is invalid (sleep or power off) */ +#define EDCONF -5 /*!< Device confugure error */ +#define ETIMEOUT -6 /*!< Timeout error */ +#define EIGNORE -7 /*!< Received an unsupported command, and ignore it */ +#define EQUEUE -8 /*!< Queue overflow */ +#define EUNEXP -9 /*!< Encounter an unexpected error */ + +#define IS_ERR_VALUE(x) ((x) != SUCCESS) + +#endif // ERROR_H_ diff --git a/df_datalink_sp/src/include/global_timer.h b/df_datalink_sp/src/include/global_timer.h new file mode 100644 index 0000000..d0572ed --- /dev/null +++ b/df_datalink_sp/src/include/global_timer.h @@ -0,0 +1,95 @@ +#ifndef SRC_GLOBAL_TIMER_H_ +#define SRC_GLOBAL_TIMER_H_ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include + +/******************************************************************************/ +/*************************** Types Declarations *******************************/ +/******************************************************************************/ + +/** + * @struct timer_init_param + * @brief Structure holding the parameters for timer initialization + */ +struct global_timer_init_param { + /** timer ID */ + uintptr_t base_addr; + /** timer ID */ + uint16_t id; + /** timer count frequency (Hz) */ + uint32_t freq_hz; + /** counter start value */ + uint64_t load_value; +}; + +/** + * @struct timer_desc + * @brief Structure holding timer descriptor + */ +struct global_timer_desc { + /** timer ID */ + uintptr_t base_addr; + /** timer ID */ + uint16_t id; + /** timer count frequency (Hz) */ + uint32_t freq_hz; + /** counter start value */ + uint64_t load_value; +}; + +/******************************************************************************/ +/************************ Functions Declarations ******************************/ +/******************************************************************************/ + +/* Initialize hardware timer and the handler structure associated with it. */ +int32_t global_timer_init(struct global_timer_desc **desc, + struct global_timer_init_param *param); + +/* Free the memory allocated by timer_setup(). */ +int32_t global_timer_remove(struct global_timer_desc *desc); + +/* Start a timer. */ +int32_t global_timer_start(struct global_timer_desc *desc); + +/* Stop a timer from counting. */ +int32_t global_timer_stop(struct global_timer_desc *desc); + +/* Get the value of the counter register for the timer. */ +int32_t global_timer_counter_get(struct global_timer_desc *desc, uint64_t *counter); + +/* Set the timer counter register value. */ +int32_t global_timer_counter_set(struct global_timer_desc *desc, uint64_t new_val); + +/* Get the timer clock frequency. */ +int32_t global_timer_count_clk_get(struct global_timer_desc *desc, uint32_t *freq_hz); + +/* Set the timer clock frequency. */ +int32_t global_timer_count_clk_set(struct global_timer_desc *desc, uint32_t freq_hz); + +/* Enable global timer interrupt. */ +int32_t global_timer_irq_enable(struct global_timer_desc *desc); + +/* Disable global timer interrupt. */ +int32_t global_timer_irq_disable(struct global_timer_desc *desc); + +/* Implement a acknowledgment global timer interrupt. */ +int32_t global_timer_irq_ack(struct global_timer_desc *desc); + +/* Set comparator register. */ +int32_t global_timer_compara_set(struct global_timer_desc *desc, uint64_t com_val); + +/* Set auto increment register . */ +int32_t global_timer_auto_inc_set(struct global_timer_desc *desc, uint32_t inc_val); + +/* Enable global timer auto increment mode. */ +int32_t global_timer_auto_inc_enable(struct global_timer_desc *desc); + +/* Disable global timer auto increment mode. */ +int32_t global_timer_auto_inc_disable(struct global_timer_desc *desc); + +#endif /* SRC_TIMER_H_ */ + diff --git a/df_datalink_sp/src/include/gpio.h b/df_datalink_sp/src/include/gpio.h new file mode 100644 index 0000000..fb2c113 --- /dev/null +++ b/df_datalink_sp/src/include/gpio.h @@ -0,0 +1,188 @@ +/***************************************************************************//** + * @file gpio.h + * @brief Header file of GPIO Interface + * @author DBogdan (dragos.bogdan@analog.com) +******************************************************************************** + * Copyright 2019(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ + +#ifndef _GPIO_H_ +#define _GPIO_H_ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include + +/******************************************************************************/ +/********************** Macros and Constants Definitions **********************/ +/******************************************************************************/ + +#define GPIO_OUT 0x01 +#define GPIO_IN 0x00 + +/******************************************************************************/ +/*************************** Types Declarations *******************************/ +/******************************************************************************/ + +/** + * @struct gpio_platform_ops + * @brief Structure holding gpio function pointers that point to the platform + * specific function + */ +struct gpio_platform_ops ; + +/** + * @enum gpio_pull_up + * @brief Enum that holds the possible pull up/ pull down resistor configuration. + */ +enum gpio_pull_up { + PULL_NONE, + /** Strong pull up */ + PULL_UP, + /** Strong pull down */ + PULL_DOWN, + PULL_UP_WEAK, + PULL_DOWN_WEAK +}; + +/** + * @struct gpio_init_param + * @brief Structure holding the parameters for GPIO initialization. + */ +struct gpio_init_param { + /** Port number */ + int32_t port; + /** GPIO number */ + int32_t number; + /** Pull up/down resistor configuration */ + enum gpio_pull_up pull; + /** GPIO platform specific functions */ + const struct gpio_platform_ops *platform_ops; + /** GPIO extra parameters (device specific) */ + void *extra; +}; + +/** + * @struct gpio_desc + * @brief Structure holding the GPIO descriptor. + */ +struct gpio_desc { + /** Port number */ + int32_t port; + /** GPIO number */ + int32_t number; + /** Pull up/down resistor configuration */ + enum gpio_pull_up pull; + /** GPIO platform specific functions */ + const struct gpio_platform_ops *platform_ops; + /** GPIO extra parameters (device specific) */ + void *extra; +}; + +/** + * @enum gpio_values + * @brief Enum that holds the possible output states of a GPIO. + */ +enum gpio_values { + /** GPIO logic low */ + GPIO_LOW, + /** GPIO logic high */ + GPIO_HIGH, + /** GPIO high impedance */ + GPIO_HIGH_Z +}; + +/** + * @struct gpio_platform_ops + * @brief Structure holding gpio function pointers that point to the platform + * specific function + */ +struct gpio_platform_ops { + /** gpio initialization function pointer */ + int32_t (*gpio_ops_get)(struct gpio_desc **, + const struct gpio_init_param *); + /** gpio optional descriptor function pointer */ + int32_t (*gpio_ops_get_optional)(struct gpio_desc **, + const struct gpio_init_param *); + /** gpio remove function pointer */ + int32_t (*gpio_ops_remove)(struct gpio_desc *); + /** gpio direction input function pointer */ + int32_t (*gpio_ops_direction_input)(struct gpio_desc *); + /** gpio direction output function pointer */ + int32_t (*gpio_ops_direction_output)(struct gpio_desc *, uint8_t); + /** gpio get direction function pointer */ + int32_t (*gpio_ops_get_direction)(struct gpio_desc *, uint8_t *); + /** gpio set value function pointer */ + int32_t (*gpio_ops_set_value)(struct gpio_desc *, uint8_t); + /** gpio get value function pointer */ + int32_t (*gpio_ops_get_value)(struct gpio_desc *, uint8_t *); +}; + +/******************************************************************************/ +/************************ Functions Declarations ******************************/ +/******************************************************************************/ + +/* Obtain the GPIO decriptor. */ +int32_t gpio_get(struct gpio_desc **desc, + const struct gpio_init_param *param); + +/* Obtain optional GPIO descriptor. */ +int32_t gpio_get_optional(struct gpio_desc **desc, + const struct gpio_init_param *param); + +/* Free the resources allocated by gpio_get(). */ +int32_t gpio_remove(struct gpio_desc *desc); + +/* Enable the input direction of the specified GPIO. */ +int32_t gpio_direction_input(struct gpio_desc *desc); + +/* Enable the output direction of the specified GPIO. */ +int32_t gpio_direction_output(struct gpio_desc *desc, + uint8_t value); + +/* Get the direction of the specified GPIO. */ +int32_t gpio_get_direction(struct gpio_desc *desc, + uint8_t *direction); + +/* Set the value of the specified GPIO. */ +int32_t gpio_set_value(struct gpio_desc *desc, + uint8_t value); + +/* Get the value of the specified GPIO. */ +int32_t gpio_get_value(struct gpio_desc *desc, + uint8_t *value); + +#endif // _GPIO_H_ diff --git a/df_datalink_sp/src/include/i2c.h b/df_datalink_sp/src/include/i2c.h new file mode 100644 index 0000000..86284cc --- /dev/null +++ b/df_datalink_sp/src/include/i2c.h @@ -0,0 +1,134 @@ +/***************************************************************************//** + * @file i2c.h + * @brief Header file of I2C Interface + * @author DBogdan (dragos.bogdan@analog.com) +******************************************************************************** + * Copyright 2019(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ + +#ifndef _I2C_H_ +#define _I2C_H_ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include + +/******************************************************************************/ +/*************************** Types Declarations *******************************/ +/******************************************************************************/ + +/** + * @struct i2c_platform_ops + * @brief Structure holding I2C function pointers that point to the platform + * specific function + */ +struct i2c_platform_ops ; + +/** + * @struct i2c_init_param + * @brief Structure holding the parameters for I2C initialization. + */ +struct i2c_init_param { + /** Device ID */ + uint32_t device_id; + /** I2C maximum transfer speed supported */ + uint32_t max_speed_hz; + /** Slave address */ + uint8_t slave_address; + /** I2C platform specific functions */ + const struct i2c_platform_ops *platform_ops; + /** I2C extra parameters (device specific parameters) */ + void *extra; +}; + +/** + * @struct i2c_desc + * @brief Structure holding I2C descriptor + */ +struct i2c_desc { + /** Device ID */ + uint32_t device_id; + /** I2C maximum transfer speed supported */ + uint32_t max_speed_hz; + /** Slave address */ + uint8_t slave_address; + /** I2C platform specific functions */ + const struct i2c_platform_ops *platform_ops; + /** I2C extra parameters (device specific parameters) */ + void *extra; +}; + +/** + * @struct i2c_platform_ops + * @brief Structure holding i2c function pointers that point to the platform + * specific function + */ +struct i2c_platform_ops { + /** i2c initialization function pointer */ + int32_t (*i2c_ops_init)(struct i2c_desc **, + const struct i2c_init_param *); + /** i2c write function pointer */ + int32_t (*i2c_ops_write)(struct i2c_desc *, uint8_t *, uint8_t, uint8_t); + /** i2c write function pointer */ + int32_t (*i2c_ops_read)(struct i2c_desc *, uint8_t *, uint8_t, uint8_t); + /** i2c remove function pointer */ + int32_t (*i2c_ops_remove)(struct i2c_desc *); +}; + +/******************************************************************************/ +/************************ Functions Declarations ******************************/ +/******************************************************************************/ + +/* Initialize the I2C communication peripheral. */ +int32_t i2c_init(struct i2c_desc **desc, + const struct i2c_init_param *param); + +/* Free the resources allocated by i2c_init(). */ +int32_t i2c_remove(struct i2c_desc *desc); + +/* Write data to a slave device. */ +int32_t i2c_write(struct i2c_desc *desc, + uint8_t *data, + uint8_t bytes_number, + uint8_t stop_bit); + +/* Read data from a slave device. */ +int32_t i2c_read(struct i2c_desc *desc, + uint8_t *data, + uint8_t bytes_number, + uint8_t stop_bit); + +#endif // _I2C_H_ diff --git a/df_datalink_sp/src/include/irq.h b/df_datalink_sp/src/include/irq.h new file mode 100644 index 0000000..34fa6c4 --- /dev/null +++ b/df_datalink_sp/src/include/irq.h @@ -0,0 +1,235 @@ +/***************************************************************************//** + * @file irq.h + * @brief Header file of IRQ interface. + * @author Cristian Pop (cristian.pop@analog.com) +******************************************************************************** + * Copyright 2019(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ + +#ifndef _IRQ_H_ +#define _IRQ_H_ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include + +/******************************************************************************/ +/*************************** Types Declarations *******************************/ +/******************************************************************************/ + +/** + * @enum irq_uart_event_e + * @brief Possible events for uart interrupt + * @todo replace this with enum irq_event + */ +enum irq_uart_event_e { + /** Write operation finalized */ + IRQ_WRITE_DONE, + /** Read operation finalized */ + IRQ_READ_DONE, + /** An error occurred */ + IRQ_ERROR +}; + +enum irq_event { + EVT_GPIO, + EVT_UART_TX_COMPLETE, + EVT_UART_RX_COMPLETE, + EVT_UART_ERROR, + EVT_RTC, + EVT_XINT, + EVT_TIM_ELAPSED +}; + +enum irq_trig_level { + IRQ_LEVEL_LOW, + IRQ_LEVEL_HIGH, + IRQ_EDGE_FALLING, + IRQ_EDGE_RISING, + IRQ_EDGE_BOTH +}; + +enum irq_peripheral { + GPIO_IRQ, + UART_IRQ, + RTC_IRQ, + TIM_IRQ +}; + +/** + * @struct irq_platform_ops + * @brief Structure holding IRQ function pointers that point to the platform + * specific function + */ +struct irq_platform_ops ; + +/** + * @struct irq_init_param + * @brief Structure holding the initial parameters for Interrupt Request. + */ +struct irq_init_param { + /** Interrupt request controller ID. */ + uint32_t irq_ctrl_id; + /** Platform specific IRQ platform ops structure. */ + const struct irq_platform_ops *platform_ops; + /** + * This is intended to store irq controller specific configurations, + * it should not be a reference to any peripheral descriptor. + */ + void *extra; +}; + +/** + * @struct irq_desc + * @brief Structure for Interrupt Request descriptor. + */ +struct irq_ctrl_desc { + /** Interrupt request controller ID. */ + uint32_t irq_ctrl_id; + /** Platform specific IRQ platform ops structure. */ + const struct irq_platform_ops *platform_ops; + /** + * This is intended to store irq controller specific configurations, + * it should not be a reference to any peripheral descriptor. + */ + void *extra; +}; + +/** + * @struct callback_desc + * @brief Structure describing a callback to be registered + * @todo: remove this, use struct irq_callback instead. + */ +struct callback_desc { + /** Callback to be called when the event an event occurs. */ + void (*callback)(void *context); + /** + * Callback to be called when the event an event occurs + * @param ctx - Same as \ref callback_desc.ctx + * @param event - Event that generated the callback + * @param extra - Platform specific data + */ + void (*legacy_callback)(void *ctx, uint32_t event, + void *extra); /* TODO: remove this. */ + /** Parameter to be passed when the callback is called */ + void *ctx; + /** Platform specific configuration for a callback */ + void *legacy_config; /* TODO: remove this. */ + /** Platform specific event that triggers the calling of the callback. */ + enum irq_event event; + /** Interrupt source peripheral specifier. */ + enum irq_peripheral peripheral; + /** This will be used to store HAL specific descriptors */ + void *handle; +}; + +/** + * @struct irq_platform_ops + * @brief Structure holding IRQ function pointers that point to the platform + * specific function + */ +struct irq_platform_ops { + /** Initialize a interrupt controller peripheral. */ + int32_t (*init)(struct irq_ctrl_desc **desc, + const struct irq_init_param *param); + /** Register a legacy_callback to handle the irq events */ + int32_t (*register_callback)(struct irq_ctrl_desc *desc, uint32_t irq_id, + struct callback_desc *callback); + /** Unregisters a generic IRQ handling function */ + int32_t (*unregister_callback)(struct irq_ctrl_desc *desc, + uint32_t irq_id, + struct callback_desc *callback); + /** Global interrupt enable */ + int32_t (*global_enable)(struct irq_ctrl_desc *desc); + /** Global interrupt disable */ + int32_t (*global_disable)(struct irq_ctrl_desc *desc); + /** Set interrupt trigger level. */ + int32_t (*trigger_level_set)(struct irq_ctrl_desc *desc, uint32_t irq_id, + enum irq_trig_level trig); + /** Enable specific interrupt */ + int32_t (*enable)(struct irq_ctrl_desc *desc, uint32_t irq_id); + /** Disable specific interrupt */ + int32_t (*disable)(struct irq_ctrl_desc *desc, uint32_t irq_id); + /** Set the priority level for a specific interrupt */ + int32_t (*set_priority)(struct irq_ctrl_desc *desc, uint32_t irq_id, + uint32_t priority_level); + /** IRQ remove function pointer */ + int32_t (*remove)(struct irq_ctrl_desc *desc); +}; + +/******************************************************************************/ +/************************ Functions Declarations ******************************/ +/******************************************************************************/ + +/* Initialize a interrupt controller peripheral. */ +int32_t irq_ctrl_init(struct irq_ctrl_desc **desc, + const struct irq_init_param *param); + +/* Free the resources allocated by irq_ctrl_init(). */ +int32_t irq_ctrl_remove(struct irq_ctrl_desc *desc); + +/* Register a callback to handle the irq events */ +int32_t irq_register_callback(struct irq_ctrl_desc *desc, + uint32_t irq_id, + struct callback_desc *callback_desc); + +/* Unregisters a generic IRQ handling function */ +int32_t irq_unregister_callback(struct irq_ctrl_desc *desc, + uint32_t irq_id, + struct callback_desc *callback_desc); + +/* Global interrupt enable */ +int32_t irq_global_enable(struct irq_ctrl_desc *desc); + +/* Global interrupt disable */ +int32_t irq_global_disable(struct irq_ctrl_desc *desc); + +/* Set interrupt trigger level. */ +int32_t irq_trigger_level_set(struct irq_ctrl_desc *desc, + uint32_t irq_id, + enum irq_trig_level trig); + +/* Enable specific interrupt */ +int32_t irq_enable(struct irq_ctrl_desc *desc, uint32_t irq_id); + +/* Disable specific interrupt */ +int32_t irq_disable(struct irq_ctrl_desc *desc, uint32_t irq_id); + +/** Set the priority level for a specific interrupt */ +int32_t irq_set_priority(struct irq_ctrl_desc *desc, + uint32_t irq_id, + uint32_t priority_level); +#endif // _IRQ_H_ diff --git a/df_datalink_sp/src/include/list.h b/df_datalink_sp/src/include/list.h new file mode 100644 index 0000000..517a51c --- /dev/null +++ b/df_datalink_sp/src/include/list.h @@ -0,0 +1,327 @@ +/***************************************************************************//** + * @file list.h + * @brief List library header + * @author Mihail Chindris (mihail.chindris@analog.com) +******************************************************************************** + * @copyright + * Copyright 2020(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +******************************************************************************** + * + * @section list_details Library description + * This library handles double linked lists and it expose inseart, + * read, get and delete functions. \n + * It also can be accesed using it member functions which wrapp function for + * usual list types.\n + * @subsection example Sample code + * @code{.c} + * // -- Use a generic list + * struct list_desc *list1; + * struct iterator *it; + * uint32_t a; + * // Create list list1 + * list_init(&list1, LIST_DEFAULT, NULL); + * // Add items to the list + * list_add_last(list1, 1); + * list_add_last(list1, 2); + * list_add_last(list1, 3); + * // Here the list will be: 1 -> 2 - > 3 + * + * list_read_last(list1, &a); + * printf("Last: %d\n", a); + * // 3 will be printed + * // Create an iterator on the end of the list + * iterator_init(&it, list1, 0); + * // Move the iterator backword with one position + * iterator_move(it, -1); + * // Read the data at the current position + * iterator_read(it, &a); + * printf("Current: %d\n", a); + * // 2 will be printed + * iterator_remove(it); + * list_remove(list1); + * + * // -- Use a popular list + * struct list_desc *stack; + * // Create a FIFO list + * list_init(&stack, LIST_STACK, NULL); + * // Put elements in the list + * stack->push(stack, 1); + * stack->push(stack, 2); + * stack->push(stack, 3); + * // Read from the stack + * stack->pop(stack, &a); + * printf("Last: %d\n", a); + * // 3 will be printed + * list_remove(stack); + * @endcode +*******************************************************************************/ + +#ifndef _LIST_H_ +#define _LIST_H_ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include +#include + +/******************************************************************************/ +/*************************** Types Declarations *******************************/ +/******************************************************************************/ + +/** + * @struct list_desc + * @brief Structure storing the list and function wrapper for usual list types + * + * With this structure the funtionalities of usual list types + * ( \ref adapter_type ) can be accesed with the functions referenced in this + * structure. + * For example: + * @code{.c} + * my_queue->push(my_queue, my_data); + * @endcode + */ +struct list_desc; + +/** + * @struct list_iterator + * @brief Structure used to iterate through the list using Iterator functions. + */ +struct iterator; + +/** + * @brief Prototype of the compare function. + * + * The function used to compare the elements of the liste when doing + * operations on an ordered list. + * @param data1 - First element to be compared + * @param data2 - Second element to be compared + * @return + * - -1 - If data1 < data2 + * - 0 - If data1 == data2 + * - 1 - If data1 > data2 + */ +typedef int32_t (*f_cmp)(void *data1, void *data2); + +/** + * @name Generic functions + * Each function interacting with the list have one of the following formats.\n + * Aditionaly they may have one more parametere for specific functionalities.\n + * In the Iterator functions, the list reference is replaced by the iterator's + * one. + * @{ + */ + +/** + * @brief Add an element in the list. + * + * The element of the list is created and the data field is stored in it. + * @param list_desc - Reference to the list. Created by \ref list_init. + * @param data - Data to store in a list element + * @return + * - 0 : On success + * - -1 : Otherwise + */ +typedef int32_t (*f_add)(struct list_desc *list_desc, void *data); + +/** + * @brief Edit an element in the list. The content is replaced by new_data. + * @param list_desc - Reference to the list. Created by \ref list_init. + * @param new_data - New data to replace the old one + * @return + * - 0 : On success + * - -1 : Otherwise + */ +typedef int32_t (*f_edit)(struct list_desc *list_desc, void *new_data); + +/** + * @brief Read an element from the list. + * @param list_desc - Reference to the list. Created by \ref list_init. + * @param result - If not null, result is filled with: + * @param data - Content of the list element, NULL if some error occur. + * @return \n + * - 0 : On success + * - -1 : Otherwise + * @note If the content of an element can be 0 then the result must be checked + * to see if the functions has succeded + */ +typedef int32_t (*f_read)(struct list_desc *list_desc, void **data); + +/** + * @brief Read and remove an element from the list. + * @param list_desc - Reference to the list. Created by \ref list_init. + * @param result - If not null, result is filled with: + * @param data - Content of the list element, NULL if some error occur. + * @return + * - 0 : On success + * - -1 : Otherwise + */ +typedef int32_t (*f_get)(struct list_desc *list_desc, void **data); + +/** @} */ + +/** + * @enum adapter_type + * @brief Selects functionalities for functions in \ref list_desc + */ +enum adapter_type { + /** Default type is LIST_STACK */ + LIST_DEFAULT, + /** + * Functions for a FIFO list (First-in first-out). Elements are inserted + * in one end and extracted from the other end. + * - \e Push: Insert element + * - \e Pop: Get next element (Read and remove) + * - \e Top_next: Read next element + * - \e Back: Read first element + * - \e Swap: Edit the content of the next element + */ + LIST_QUEUE, + /** + * Functions for a LIFO list (Last-in first-out). Elements are inserted + * and extracted only from the same end. + * - \e Push: Insert element + * - \e Pop: Get top element (Read and remove) + * - \e Top_next: Read top element + * - \e Back: Read bottom element + * - \e Swap: Edit the content of the top element + */ + LIST_STACK, + /** + * Functions for ordered list. The order of element is determinated + * usinge the \ref f_cmp. + * - \e Push: Insert element + * - \e Pop: Get lowest element (Read and remove) + * - \e Top_next: Read lowest element + * - \e Back: Read the biggest element + * - \e Swap: Edit the lowest element + */ + LIST_PRIORITY_LIST +}; + +struct list_desc { + /** Refer to \ref adapter_type */ + f_add push; + /** Refer to \ref adapter_type */ + f_get pop; + /** Refer to \ref adapter_type */ + f_read top_next; + /** Refer to \ref adapter_type */ + f_read back; + /** Refer to \ref adapter_type */ + f_edit swap; + /** Structure storing the list internal parameters */ + void *priv_desc; +}; + +/******************************************************************************/ +/************************ Functions Declarations ******************************/ +/******************************************************************************/ + +int32_t list_init(struct list_desc **list_desc, + enum adapter_type type, + f_cmp comparator); +int32_t list_remove(struct list_desc *list_desc); +int32_t list_get_size(struct list_desc *list_desc, + uint32_t *out_size); + +/** + * @name Iterator functions + * An iterator is used to iterate through the list. For a list, any number of + * iterators can be created. All must be removed before removing a list. + * @{ + */ +int32_t iterator_init(struct iterator **iter, + struct list_desc *list_desc, + bool start); +int32_t iterator_remove(struct iterator *iter); +int32_t iterator_move(struct iterator *iter, int32_t steps); +int32_t iterator_move_to_idx(struct iterator *iter, int32_t idx); +int32_t iterator_find(struct iterator *iter, void *cmp_data); +int32_t iterator_insert(struct iterator *iter, void *data, + bool after); +int32_t iterator_edit(struct iterator *iter, void *new_data); +int32_t iterator_read(struct iterator *iter, void **data); +int32_t iterator_get(struct iterator *iter, void **data); +/** @}*/ + +/** + * @name Operations on the ends of the list + * These functions will operate on the first or last element of the list + * @{ + */ +int32_t list_add_first(struct list_desc *list_desc, void *data); +int32_t list_edit_first(struct list_desc *list_desc, + void *new_data); +int32_t list_read_first(struct list_desc *list_desc, void **data); +int32_t list_get_first(struct list_desc *list_desc, void **data); + +int32_t list_add_last(struct list_desc *list_desc, void *data); +int32_t list_edit_last(struct list_desc *list_desc, void *new_data); +int32_t list_read_last(struct list_desc *list_desc, void **data); +int32_t list_get_last(struct list_desc *list_desc, void **data); +/** @}*/ + +/** + * @name Operations by index + * These functions use an index to identify the element in the list. + * @{ + */ +int32_t list_add_idx(struct list_desc *list_desc, void *data, + uint32_t idx); +int32_t list_edit_idx(struct list_desc *list_desc, void *new_data, + uint32_t idx); +int32_t list_read_idx(struct list_desc *list_desc, void **data, + uint32_t idx); +int32_t list_get_idx(struct list_desc *list_desc, void **data, + uint32_t idx); +/** @}*/ + +/** + * @name Operations by comparation + * These functions use the specified \ref f_cmp at \ref list_init to identify + * the element this will operate on. + * @{ + */ +int32_t list_add_find(struct list_desc *list_desc, void *data); +int32_t list_edit_find(struct list_desc *list_desc, void *new_data, + void *cmp_data); +int32_t list_read_find(struct list_desc *list_desc, void **data, + void *cmp_data); +int32_t list_get_find(struct list_desc *list_desc, void **data, + void *cmp_data); +/** @}*/ + +#endif // _LIST_H_ diff --git a/df_datalink_sp/src/include/spi.h b/df_datalink_sp/src/include/spi.h new file mode 100644 index 0000000..26d0a84 --- /dev/null +++ b/df_datalink_sp/src/include/spi.h @@ -0,0 +1,209 @@ +/***************************************************************************//** + * @file spi.h + * @brief Header file of SPI Interface + * @author DBogdan (dragos.bogdan@analog.com) +******************************************************************************** + * Copyright 2019(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ + +#ifndef _SPI_H_ +#define _SPI_H_ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include + +/******************************************************************************/ +/********************** Macros and Constants Definitions **********************/ +/******************************************************************************/ + +#define SPI_CPHA 0x01 +#define SPI_CPOL 0x02 +#define SPI_3WIRE 0x04 + +/******************************************************************************/ +/*************************** Types Declarations *******************************/ +/******************************************************************************/ + +/** + * @enum spi_mode + * @brief SPI configuration for clock phase and polarity. + */ +enum spi_mode { + /** Data on rising, shift out on falling */ + SPI_MODE_0 = (0 | 0), + /** Data on falling, shift out on rising */ + SPI_MODE_1 = (0 | SPI_CPHA), + /** Data on rising, shift out on falling */ + SPI_MODE_2 = (SPI_CPOL | 0), + /** Data on falling, shift out on rising */ + SPI_MODE_3 = (SPI_CPOL | SPI_CPHA), + /** Data on rising, shift out on falling */ + SPI_MODE_4 = SPI_3WIRE +}; + +/** + * @enum spi_bit_order + * @brief SPI configuration for bit order (MSB/LSB). + */ +enum spi_bit_order { + /** Most-significant bit (MSB) first */ + SPI_BIT_ORDER_MSB_FIRST = 0, + /** Least-significant bit (LSB) first */ + SPI_BIT_ORDER_LSB_FIRST = 1, +}; + +/** + * @struct spi_msg_list + * @brief List item describing a SPI transfer + */ +struct spi_msg { + /** Buffer with data to send. If NULL, 0x00 will be sent */ + uint8_t *tx_buff; + /** Buffer where to store data. If NULL, incoming data won't be saved */ + uint8_t *rx_buff; + /** Length of buffers. Must have equal size. */ + uint32_t bytes_number; + /** If set, CS will be deasserted after the transfer */ + uint8_t cs_change; + /** + * Minimum delay (in us) between the CS de-assert event of the current message + * and the assert of the next one. + */ + uint32_t cs_change_delay; + /** Delay (in us) between the CS assert and the first SCLK edge. */ + uint32_t cs_delay_first; + /** Delay (in us) between the last SCLK edge and the CS deassert */ + uint32_t cs_delay_last; +}; + +/** + * @struct spi_platform_ops + * @brief Structure holding SPI function pointers that point to the platform + * specific function + */ +struct spi_platform_ops ; + +/** + * @struct spi_init_param + * @brief Structure holding the parameters for SPI initialization + */ +struct spi_init_param { + /** Device ID */ + uint32_t device_id; + /** maximum transfer speed */ + uint32_t max_speed_hz; + /** SPI chip select */ + uint8_t chip_select; + /** SPI mode */ + enum spi_mode mode; + /** SPI bit order */ + enum spi_bit_order bit_order; + const struct spi_platform_ops *platform_ops; + /** SPI extra parameters (device specific) */ + void *extra; + /** Parent of the device */ + struct spi_desc *parent; +}; + +/** + * @struct spi_desc + * @brief Structure holding SPI descriptor. + */ +struct spi_desc { + /** Device ID */ + uint32_t device_id; + /** maximum transfer speed */ + uint32_t max_speed_hz; + /** SPI chip select */ + uint8_t chip_select; + /** SPI mode */ + enum spi_mode mode; + /** SPI bit order */ + enum spi_bit_order bit_order; + const struct spi_platform_ops *platform_ops; + /** SPI extra parameters (device specific) */ + void *extra; + /** Parent of the device */ + struct spi_desc *parent; +}; + +/** + * @struct spi_platform_ops + * @brief Structure holding SPI function pointers that point to the platform + * specific function + */ +struct spi_platform_ops { + /** SPI initialization function pointer */ + int32_t (*init)(struct spi_desc **, const struct spi_init_param *); + /** SPI write/read function pointer */ + int32_t (*write_and_read)(struct spi_desc *, uint8_t *, uint16_t); + /** SPI write function pointer */ + int32_t (*write_and_read_3wire)(struct spi_desc *, uint8_t *,uint8_t *,uint16_t, uint16_t); + /** Iterate over the spi_msg array and send all messages at once */ + int32_t (*transfer)(struct spi_desc *, struct spi_msg *, uint32_t); + /** SPI remove function pointer */ + int32_t (*remove)(struct spi_desc *); +}; + +/******************************************************************************/ +/************************ Functions Declarations ******************************/ +/******************************************************************************/ + +/* Initialize the SPI communication peripheral. */ +int32_t spi_init(struct spi_desc **desc, + const struct spi_init_param *param); + +/* Free the resources allocated by spi_init(). */ +int32_t spi_remove(struct spi_desc *desc); + +/* Write and read data to/from SPI. */ +int32_t spi_write_and_read(struct spi_desc *desc, + uint8_t *data, + uint16_t bytes_number); +int32_t spi_write_and_read_3wire(struct spi_desc *desc, + uint8_t *write_data, + uint8_t *read_data, + uint16_t write_bytes_number, + uint16_t read_bytes_number); + +/* Iterate over the spi_msg array and send all messages at once */ +int32_t spi_transfer(struct spi_desc *desc, + struct spi_msg *msgs, + uint32_t len); + + +#endif // _SPI_H_ diff --git a/df_datalink_sp/src/include/timer.h b/df_datalink_sp/src/include/timer.h new file mode 100644 index 0000000..99ee4f4 --- /dev/null +++ b/df_datalink_sp/src/include/timer.h @@ -0,0 +1,159 @@ +/***************************************************************************//** +* @file timer.h +* @brief Timer control module header. +* @author Andrei Drimbarean (andrei.drimbarean@analog.com) +******************************************************************************** +* Copyright 2019(c) Analog Devices, Inc. +* +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* - Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* - Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in +* the documentation and/or other materials provided with the +* distribution. +* - Neither the name of Analog Devices, Inc. nor the names of its +* contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* - The use of this software may or may not infringe the patent rights +* of one or more patent holders. This license does not release you +* from the requirement that you obtain separate licenses from these +* patent holders to use this software. +* - Use of the software either in source or binary form, must be run +* on or directly connected to an Analog Devices Inc. component. +* +* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY +* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ + +#ifndef _SRC_TIMER_H_ +#define _SRC_TIMER_H_ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include + +/******************************************************************************/ +/*************************** Types Declarations *******************************/ +/******************************************************************************/ + +/** + * @struct timer_desc + * @brief Structure holding timer descriptor + */ +struct timer_desc { + /** timer ID */ + uint16_t id; + /** timer count frequency (Hz) */ + uint32_t freq_hz; + /** the number of ticks the timer counts until it resets */ + uint32_t ticks_count; + /** Timer platform operations */ + const struct timer_platform_ops *platform_ops; + /** timer extra parameters (device specific) */ + void *extra; +}; + +/** + * @struct timer_platform_ops + * @brief Structure holding timer function pointers that point to the platform + * specific function + */ +struct timer_platform_ops ; + +/** + * @struct timer_init_param + * @brief Structure holding the parameters for timer initialization + */ +struct timer_init_param { + /** timer ID */ + uint16_t id; + /** timer count frequency (Hz) */ + uint32_t freq_hz; + /** the number of ticks the timer counts until it resets */ + uint32_t ticks_count; + /** Timer platform operations */ + const struct timer_platform_ops *platform_ops; + /** timer extra parameters (device specific) */ + void *extra; +}; + +/** + * @struct timer_platform_ops + * @brief Structure holding timer function pointers that point to the platform + * specific function + */ +struct timer_platform_ops { + /** timer initialization function pointer */ + int32_t (*init)(struct timer_desc **, + const struct timer_init_param *); + /** timer start function pointer */ + int32_t (*start)(struct timer_desc *); + /** timer stop function pointer */ + int32_t (*stop)(struct timer_desc *); + /** timer get counter function pointer */ + int32_t (*counter_get)(struct timer_desc *, uint32_t *counter); + /** timer set counter function pointer */ + int32_t (*counter_set)(struct timer_desc *, uint32_t new_val); + /** timer get clock frequency function pointer */ + int32_t (*count_clk_get)(struct timer_desc *, uint32_t *freq_hz); + /** timer set clock frequency function pointer */ + int32_t (*count_clk_set)(struct timer_desc *, uint32_t freq_hz); + /** timer get elapsed time in nsec */ + int32_t (*get_elapsed_time_nsec)(struct timer_desc *, + uint64_t *elapsed_time); + /** timer remove function pointer */ + int32_t (*remove)(struct timer_desc *); +}; + +/******************************************************************************/ +/************************ Functions Declarations ******************************/ +/******************************************************************************/ + +/* Initialize hardware timer and the handler structure associated with it. */ +int32_t timer_init(struct timer_desc **desc, + struct timer_init_param *param); + +/* Free the memory allocated by timer_setup(). */ +int32_t timer_remove(struct timer_desc *desc); + +/* Start a timer. */ +int32_t timer_start(struct timer_desc *desc); + +/* Stop a timer from counting. */ +int32_t timer_stop(struct timer_desc *desc); + +/* Get the value of the counter register for the timer. */ +int32_t timer_counter_get(struct timer_desc *desc, + uint32_t *counter); + +/* Set the timer counter register value. */ +int32_t timer_counter_set(struct timer_desc *desc, + uint32_t new_val); + +/* Get the timer clock frequency. */ +int32_t timer_count_clk_get(struct timer_desc *desc, + uint32_t *freq_hz); + +/* Set the timer clock frequency. */ +int32_t timer_count_clk_set(struct timer_desc *desc, + uint32_t freq_hz); + +/* Get the elapsed time in nsec for the timer. */ +int32_t timer_get_elapsed_time_nsec(struct timer_desc *desc, + uint64_t *elapsed_time); + +#endif // _SRC_TIMER_H_ diff --git a/df_datalink_sp/src/include/trng.h b/df_datalink_sp/src/include/trng.h new file mode 100644 index 0000000..1c469b3 --- /dev/null +++ b/df_datalink_sp/src/include/trng.h @@ -0,0 +1,115 @@ +/***************************************************************************//** + * @file trng.h + * @brief Header file of true random number generator + * @author Mihail Chindris (mihail.chindris@analog.com) +******************************************************************************** + * @copyright + * Copyright 2020(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ + +#ifndef _TRNG_H_ +#define _TRNG_H_ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include + +/******************************************************************************/ +/*************************** Types Declarations *******************************/ +/******************************************************************************/ + +/** + * @struct trng_platform_ops + * @brief Structure holding TRNG function pointers that point to the platform + * specific function + */ +struct trng_platform_ops; + +/** + * @struct trng_desc + * @brief TRNG Descriptor + */ +struct trng_desc { + /** Platform ops */ + const struct trng_platform_ops *platform_ops; + /** Platform specific parameters */ + void *extra; +}; + +/** + * @struct trng_init_param + * @brief Init parameter for TRNG + */ +struct trng_init_param { + /** Device id */ + uint32_t dev_id; + /** Platform specific parameter */ + void *extra; + /** Platform ops */ + const struct trng_platform_ops *platform_ops; +}; + +/** + * @struct trng_platform_ops + * @brief Structure holding TRNG function pointers that point to the platform + * specific function + */ +struct trng_platform_ops { + /** TRNG initialization function pointer */ + int (*init)(struct trng_desc **, + const struct trng_init_param *); + /** Fill buffer with random numbers */ + int (*fill_buffer)(struct trng_desc *, uint8_t *, uint32_t); + /** TRNG remove function pointer */ + int (*remove)(struct trng_desc *); +}; + +/******************************************************************************/ +/************************ Functions Declarations ******************************/ +/******************************************************************************/ + +/* Initialize descriptor */ +int trng_init(struct trng_desc **desc, + const struct trng_init_param *param); + +/* Free resources allocated in descriptor */ +int trng_remove(struct trng_desc *desc); + +/* Fill buffer with random numbers */ +int trng_fill_buffer(struct trng_desc *desc, uint8_t *buff, + uint32_t len); + +#endif // _TRNG_H_ diff --git a/df_datalink_sp/src/include/util.h b/df_datalink_sp/src/include/util.h new file mode 100644 index 0000000..a4a4608 --- /dev/null +++ b/df_datalink_sp/src/include/util.h @@ -0,0 +1,195 @@ +/******************************************************************************* + * @file util.h + * @brief Implementation of utility functions. + * @author DBogdan (dragos.bogdan@analog.com) +******************************************************************************** + * Copyright 2018(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ +#ifndef __UTIL_H_ +#define __UTIL_H_ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ +#include +#include +#include +/******************************************************************************/ +/********************** Macros and Constants Definitions **********************/ +/******************************************************************************/ +// #define __CRC_LSB +#define __BITSWAP_TABLE +#define __CRC_LSB +#define CRC16_INIT 0x0000 +#define CRC8_INIT 0x00 + +#define BIT(x) (1 << (x)) + +#define ARRAY_SIZE(x) \ + (sizeof(x) / sizeof((x)[0])) + +#define DIV_ROUND_UP(x, y) \ + (((x) + (y)-1) / (y)) +#define DIV_ROUND_CLOSEST(x, y) \ + (((x) + (y) / 2) / (y)) +#define DIV_ROUND_CLOSEST_ULL(x, y) \ + DIV_ROUND_CLOSEST(x, y) + +#define min(x, y) \ + (((x) < (y)) ? (x) : (y)) +#define min_t(type, x, y) \ + (type) min((type)(x), (type)(y)) + +#define max(x, y) \ + (((x) > (y)) ? (x) : (y)) +#define max_t(type, x, y) \ + (type) max((type)(x), (type)(y)) + +#define clamp(val, min_val, max_val) \ + (max(min((val), (max_val)), (min_val))) +#define clamp_t(type, val, min_val, max_val) \ + (type) clamp((type)(val), (type)(min_val), (type)(max_val)) + +#define swap(x, y) \ + { \ + typeof(x) _tmp_ = (x); \ + (x) = (y); \ + (y) = _tmp_; \ + } + +#define round_up(x, y) \ + (((x) + (y)-1) / (y)) + +#define BITS_PER_LONG 32 + +#define GENMASK(h, l) ({ \ + uint32_t t = (uint32_t)(~0UL); \ + t = t << (BITS_PER_LONG - (h - l + 1)); \ + t = t >> (BITS_PER_LONG - (h + 1)); \ + t; \ +}) + +#define bswap_constant_32(x) \ + ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \ + (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) + +#define bswap_constant_16(x) ((((x) & (uint16_t)0xff00) >> 8) | \ + (((x) & (uint16_t)0x00ff) << 8)) + +#define bit_swap_constant_8(x) \ + ((((x) & 0x80) >> 7) | \ + (((x) & 0x40) >> 5) | \ + (((x) & 0x20) >> 3) | \ + (((x) & 0x10) >> 1) | \ + (((x) & 0x08) << 1) | \ + (((x) & 0x04) << 3) | \ + (((x) & 0x02) << 5) | \ + (((x) & 0x01) << 7)) + +#define U16_MAX ((uint16_t)~0U) +#define S16_MAX ((int16_t)(U16_MAX >> 1)) + +#define DIV_U64(x, y) (x / y) + +#define UNUSED_PARAM(x) ((void)x) + +#define shift_right(x, s) ((x) < 0 ? -(-(x) >> (s)) : (x) >> (s)) + +/******************************************************************************/ +/************************ Functions Declarations ******************************/ +/******************************************************************************/ + +void IO_Out32(uintptr_t addr, uint32_t value); +uint32_t IO_In32(uintptr_t addr); + +/* flip a byte left to right*/ +uint8_t byte_bit_swap(uint8_t byte); + +/* flip a 32bit word left to right */ +uint32_t word_bit_swap(uint32_t word); + +/* Returns the number of 1-bits in digit. */ +uint32_t count_ones(uint32_t word); + +/* convert a fixed number to a double. */ +double fix2double(int32_t val, uint8_t frac_bits); + +/* Find first set bit in word. */ +uint32_t find_first_set_bit(uint32_t word); +/* Find last set bit in word. */ +uint32_t find_last_set_bit(uint32_t word); +/* Locate the closest element in an array. */ +uint32_t find_closest(int32_t val, + const int32_t *array, + uint32_t size); +/* Shift the value and apply the specified mask. */ +uint32_t field_prep(uint32_t mask, uint32_t val); +/* Get a field specified by a mask from a word. */ +uint32_t field_get(uint32_t mask, uint32_t word); +/* Log base 2 of the given number. */ +int32_t log_base_2(uint32_t x); +/* Find greatest common divisor of the given two numbers. */ +uint32_t greatest_common_divisor(uint32_t a, + uint32_t b); +/* Calculate best rational approximation for a given fraction. */ +void rational_best_approximation(uint32_t given_numerator, + uint32_t given_denominator, + uint32_t max_numerator, + uint32_t max_denominator, + uint32_t *best_numerator, + uint32_t *best_denominator); +/* Calculate the number of set bits. */ +uint32_t hweight8(uint32_t word); +/* Calculate the quotient and the remainder of an integer division. */ +uint64_t do_div(uint64_t *n, + uint64_t base); +/* Unsigned 64bit divide with 64bit divisor and remainder */ +uint64_t div64_u64_rem(uint64_t dividend, uint64_t divisor, + uint64_t *remainder); +/* Unsigned 64bit divide with 32bit divisor with remainder */ +uint64_t div_u64_rem(uint64_t dividend, uint32_t divisor, uint32_t *remainder); +int64_t div_s64_rem(int64_t dividend, int32_t divisor, int32_t *remainder); +/* Unsigned 64bit divide with 32bit divisor */ +uint64_t div_u64(uint64_t dividend, uint32_t divisor); +int64_t div_s64(int64_t dividend, int32_t divisor); +/* Converts from string to int32_t */ +int32_t str_to_int32(const char *str); +/* Converts from string to uint32_t */ +uint32_t srt_to_uint32(const char *str); + +int crc16_gen(uint8_t *buffPtr, uint32_t dataLen, uint16_t poly, uint16_t *crcVal); +bool crc16_check(uint8_t *buffPtr, uint32_t dataLen, uint32_t crcOffset, uint16_t poly); +int crc8_gen(uint8_t *buffPtr, uint32_t dataLen, uint16_t poly, uint8_t *crcVal); +bool crc8_check(uint8_t *buffPtr, uint32_t dataLen, uint32_t crcOffset, uint16_t poly); +#endif // __UTIL_H_ diff --git a/df_datalink_sp/src/lscript.ld b/df_datalink_sp/src/lscript.ld new file mode 100644 index 0000000..9db1bc1 --- /dev/null +++ b/df_datalink_sp/src/lscript.ld @@ -0,0 +1,291 @@ +/*******************************************************************/ +/* */ +/* This file is automatically generated by linker script generator.*/ +/* */ +/* Version: 2019.1.3 */ +/* */ +/* Copyright (c) 2010-2016 Xilinx, Inc. All rights reserved. */ +/* */ +/* Description : Cortex-A9 Linker Script */ +/* */ +/*******************************************************************/ + +_STACK_SIZE = DEFINED(_STACK_SIZE) ? _STACK_SIZE : 0x40000; +_HEAP_SIZE = DEFINED(_HEAP_SIZE) ? _HEAP_SIZE : 0x800000; + +_ABORT_STACK_SIZE = DEFINED(_ABORT_STACK_SIZE) ? _ABORT_STACK_SIZE : 1024; +_SUPERVISOR_STACK_SIZE = DEFINED(_SUPERVISOR_STACK_SIZE) ? _SUPERVISOR_STACK_SIZE : 2048; +_IRQ_STACK_SIZE = DEFINED(_IRQ_STACK_SIZE) ? _IRQ_STACK_SIZE : 1024; +_FIQ_STACK_SIZE = DEFINED(_FIQ_STACK_SIZE) ? _FIQ_STACK_SIZE : 1024; +_UNDEF_STACK_SIZE = DEFINED(_UNDEF_STACK_SIZE) ? _UNDEF_STACK_SIZE : 1024; + +/* Define Memories in the system */ + +MEMORY +{ + phy_data_interface_phy_rx_buff_axi_bram_ctrl_Mem0 : ORIGIN = 0x40000000, LENGTH = 0x1000 + phy_data_interface_phy_tx_buff_axi_bram_ctrl_Mem0 : ORIGIN = 0x42000000, LENGTH = 0x1000 + phy_data_interface_ant_config_axi_bram_ctrl_Mem0 : ORIGIN = 0x44000000, LENGTH = 0x2000 + ps7_ddr_0 : ORIGIN = 0x100000, LENGTH = 0x1FF00000 + ps7_qspi_linear_0 : ORIGIN = 0xFC000000, LENGTH = 0x1000000 + ps7_ram_0 : ORIGIN = 0x0, LENGTH = 0x30000 + ps7_ram_1 : ORIGIN = 0xFFFF0000, LENGTH = 0xFE00 +} + +/* Specify the default entry point to the program */ + +ENTRY(_vector_table) + +/* Define the sections, and where they are mapped in memory */ + +SECTIONS +{ +.text : { + KEEP (*(.vectors)) + *(.boot) + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + *(.plt) + *(.gnu_warning) + *(.gcc_execpt_table) + *(.glue_7) + *(.glue_7t) + *(.vfp11_veneer) + *(.ARM.extab) + *(.gnu.linkonce.armextab.*) +} > ps7_ddr_0 + +.init : { + KEEP (*(.init)) +} > ps7_ddr_0 + +.fini : { + KEEP (*(.fini)) +} > ps7_ddr_0 + +.rodata : { + __rodata_start = .; + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + __rodata_end = .; +} > ps7_ddr_0 + +.rodata1 : { + __rodata1_start = .; + *(.rodata1) + *(.rodata1.*) + __rodata1_end = .; +} > ps7_ddr_0 + +.sdata2 : { + __sdata2_start = .; + *(.sdata2) + *(.sdata2.*) + *(.gnu.linkonce.s2.*) + __sdata2_end = .; +} > ps7_ddr_0 + +.sbss2 : { + __sbss2_start = .; + *(.sbss2) + *(.sbss2.*) + *(.gnu.linkonce.sb2.*) + __sbss2_end = .; +} > ps7_ddr_0 + +.data : { + __data_start = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + *(.jcr) + *(.got) + *(.got.plt) + __data_end = .; +} > ps7_ddr_0 + +.data1 : { + __data1_start = .; + *(.data1) + *(.data1.*) + __data1_end = .; +} > ps7_ddr_0 + +.got : { + *(.got) +} > ps7_ddr_0 + +.ctors : { + __CTOR_LIST__ = .; + ___CTORS_LIST___ = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE(*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + __CTOR_END__ = .; + ___CTORS_END___ = .; +} > ps7_ddr_0 + +.dtors : { + __DTOR_LIST__ = .; + ___DTORS_LIST___ = .; + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE(*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + __DTOR_END__ = .; + ___DTORS_END___ = .; +} > ps7_ddr_0 + +.fixup : { + __fixup_start = .; + *(.fixup) + __fixup_end = .; +} > ps7_ddr_0 + +.eh_frame : { + *(.eh_frame) +} > ps7_ddr_0 + +.eh_framehdr : { + __eh_framehdr_start = .; + *(.eh_framehdr) + __eh_framehdr_end = .; +} > ps7_ddr_0 + +.gcc_except_table : { + *(.gcc_except_table) +} > ps7_ddr_0 + +.mmu_tbl (ALIGN(16384)) : { + __mmu_tbl_start = .; + *(.mmu_tbl) + __mmu_tbl_end = .; +} > ps7_ddr_0 + +.ARM.exidx : { + __exidx_start = .; + *(.ARM.exidx*) + *(.gnu.linkonce.armexidix.*.*) + __exidx_end = .; +} > ps7_ddr_0 + +.preinit_array : { + __preinit_array_start = .; + KEEP (*(SORT(.preinit_array.*))) + KEEP (*(.preinit_array)) + __preinit_array_end = .; +} > ps7_ddr_0 + +.init_array : { + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; +} > ps7_ddr_0 + +.fini_array : { + __fini_array_start = .; + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array)) + __fini_array_end = .; +} > ps7_ddr_0 + +.ARM.attributes : { + __ARM.attributes_start = .; + *(.ARM.attributes) + __ARM.attributes_end = .; +} > ps7_ddr_0 + +.sdata : { + __sdata_start = .; + *(.sdata) + *(.sdata.*) + *(.gnu.linkonce.s.*) + __sdata_end = .; +} > ps7_ddr_0 + +.sbss (NOLOAD) : { + __sbss_start = .; + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.sb.*) + __sbss_end = .; +} > ps7_ddr_0 + +.tdata : { + __tdata_start = .; + *(.tdata) + *(.tdata.*) + *(.gnu.linkonce.td.*) + __tdata_end = .; +} > ps7_ddr_0 + +.tbss : { + __tbss_start = .; + *(.tbss) + *(.tbss.*) + *(.gnu.linkonce.tb.*) + __tbss_end = .; +} > ps7_ddr_0 + +.bss (NOLOAD) : { + __bss_start = .; + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + __bss_end = .; +} > ps7_ddr_0 + +_SDA_BASE_ = __sdata_start + ((__sbss_end - __sdata_start) / 2 ); + +_SDA2_BASE_ = __sdata2_start + ((__sbss2_end - __sdata2_start) / 2 ); + +/* Generate Stack and Heap definitions */ + +.heap (NOLOAD) : { + . = ALIGN(16); + _heap = .; + HeapBase = .; + _heap_start = .; + . += _HEAP_SIZE; + _heap_end = .; + HeapLimit = .; +} > ps7_ddr_0 + +.stack (NOLOAD) : { + . = ALIGN(16); + _stack_end = .; + . += _STACK_SIZE; + . = ALIGN(16); + _stack = .; + __stack = _stack; + . = ALIGN(16); + _irq_stack_end = .; + . += _IRQ_STACK_SIZE; + . = ALIGN(16); + __irq_stack = .; + _supervisor_stack_end = .; + . += _SUPERVISOR_STACK_SIZE; + . = ALIGN(16); + __supervisor_stack = .; + _abort_stack_end = .; + . += _ABORT_STACK_SIZE; + . = ALIGN(16); + __abort_stack = .; + _fiq_stack_end = .; + . += _FIQ_STACK_SIZE; + . = ALIGN(16); + __fiq_stack = .; + _undef_stack_end = .; + . += _UNDEF_STACK_SIZE; + . = ALIGN(16); + __undef_stack = .; +} > ps7_ddr_0 + +_end = .; +} + diff --git a/df_datalink_sp/src/main.c b/df_datalink_sp/src/main.c new file mode 100644 index 0000000..e4f3273 --- /dev/null +++ b/df_datalink_sp/src/main.c @@ -0,0 +1,777 @@ +/*****************************************************************************/ +/** + * Description: main.c + * + + * Date: 2023-05-07 13:19 + * Last Edit Time: [2023-05-07 20:32] + * + * Revisions: Rev 0.0 + * History: + * [2023-05-07]: Initial edition. + * + * Copyright(c) 2021 Beijing Institute of Technology. + * + ******************************************************************************/ + +/***************************** Include Files *********************************/ +// Standard +#include +#include +#include +// Xilinx +#include "sleep.h" +#include "xil_cache.h" +#include "xscugic.h" +#include "xscutimer.h" +#include "xgpiops.h" +#include "drivers/platform/xilinx_irq.h" +#include "drivers/platform/xilinx_timer.h" +#include "drivers/rf-transceiver/ad9361/ad9361_api.h" +#include "drivers/axi_core/spi_engine/spi_engine.h" +// App +#include "common.h" +#include "error.h" +#include "timer.h" +#include "config/app_config.h" +#include "dev_profile/dev_profile.h" +#include "systembus/systembus.h" +#include "networking/phy_layer/phy_layer.h" +#include "networking/link_layer/link_layer.h" + +/************************** Function Prototypes ******************************/ +int32_t SetupInterruptSystem(struct irq_ctrl_desc *descPtr); +void Phy_IntrHandler(void *context); +void ScuTimer_IntrHandler(void *context); +void Systembus_RxIntrHandler(void *context); +/************************** Constant Definitions *****************************/ +struct callback_desc phy_callback_desc = { + .callback = Phy_IntrHandler, + .ctx = NULL}; + +struct callback_desc sysbus_rx_callback_desc = { + .callback = Systembus_RxIntrHandler, + .ctx = NULL}; + +struct callback_desc sysbus_tx_callback_desc = { + .callback = Systembus_RxIntrHandler, + .ctx = NULL}; + +struct callback_desc scutm_callback_desc = { + .callback = ScuTimer_IntrHandler, + .ctx = NULL}; + +static PHY_CONFIG phyConfig = { + .devId = 0, + .baseAddr = PHY_BASEADDR, + .antBramId = PHY_ANTCONFIG_BRAM_DEVICE_ID, + .txBramId = PHY_TXBUFF_BRAM_DEVICE_ID, + .rxBramId = PHY_RXBUFF_BRAM_DEVICE_ID, + .hwXadcId = PHY_HW_XADC_DEVICE_ID}; + +static L2_CONFIG linkConfig = { + .myType = L2_HEAD_NODE, + .myId = 1, + .headId = 1, + .netScale = 2, + .phyInstRef = NULL // pyhsical layer reference +}; + +// static L2_CONFIG linkConfig = { +// .myType = L2_MEMBER_NODE, +// .myId = 2, +// .headId = 1, +// .netScale = 2, +// .phyInstRef = NULL // pyhsical layer reference +// }; + +static SYSBUS_CONFIG sysbusConfig = { + .baseAddr = SYSBUS_BASE_ADDR, + .txQueueMax = 16, + .rxQueueMax = 16}; +/*********************** Driver Instance Definitions **************************/ +static struct irq_ctrl_desc *intcDescPtr; // General interrupt controller descriptor +static struct timer_desc *logTmPtr; +static SYSBUS *sysbusDescPtr; +static PHY_INST *phyInstPtr; +static L2_INST *linkInstPtr; + +static struct hmc7044_dev *hmc7044_inst; +static struct ad9361_reg_dev *ad9361_1_reg_inst; +static struct ad9361_reg_dev *ad9361_2_reg_inst; +// static struct ad9361_rf_phy *ad9361_phy; +// static struct ad9361_rf_phy *ad9361_2_phy; +/****************************************************************************/ +/** + * This function is responsible for initializing the SCUGIC instance, looking + * for the device configuration based on the unique device ID, initializing a + * SCUGIC instance, and initialize the interrupt at IRQ_F2P[0:0] + * + * @param intcDesc A pointer to INTC descriptor + * + * @return SUCCESS if initialize successful. + * FAILURE if initialization failed. + * + *****************************************************************************/ +int32_t SetupInterruptSystem(struct irq_ctrl_desc *descPtr) +{ + int32_t Status; + struct xil_irq_desc *xil_dev; + + Status = irq_ctrl_init(&descPtr, &intc_init_param); + if (Status != SUCCESS) + { + DBG_ERROR("Intc Init FAILED, ErrorCode: %ld.\n", Status); + return Status; + } + + xil_dev = (struct xil_irq_desc *)(descPtr->extra); + + // Clear any pending interrupt flags + uint32_t intrState = XScuGic_CPUReadReg((XScuGic *)(xil_dev->instance), XSCUGIC_INT_ACK_OFFSET); + XScuGic_CPUWriteReg((XScuGic *)(xil_dev->instance), XSCUGIC_EOI_OFFSET, intrState); + + /* Initialize physical layer interrupt. */ + Status = irq_trigger_level_set(descPtr, PHY_INTR_ID, IRQ_EDGE_RISING); + if (Status != SUCCESS) + { + DBG_ERROR("PHY_INTR trigger level set FAILED, ErrorCode: %ld.\n", Status); + return Status; + } + // Set highest interrupt priority + Status = irq_set_priority(descPtr, PHY_INTR_ID, 0x00); + if (Status != SUCCESS) + { + DBG_ERROR("PHY_INTR priority level set FAILED, ErrorCode: %ld.\n", Status); + return Status; + } + // Connect the interrupt service routine isr1 to the interrupt controller + Status = irq_register_callback(descPtr, PHY_INTR_ID, &phy_callback_desc); + if (Status != SUCCESS) + { + DBG_ERROR("PHY_INTR register callback FAILED, ErrorCode: %ld.\n", Status); + return Status; + } + + /* Initialize system bus interrupt. */ + Status = irq_trigger_level_set(descPtr, SYSBUS_TX_INTR_ID, IRQ_EDGE_RISING); + if (Status != SUCCESS) + { + DBG_ERROR("PHY_INTR trigger level set FAILED, ErrorCode: %ld.\n", Status); + return Status; + } + // Set interrupt priority + Status = irq_set_priority(descPtr, SYSBUS_TX_INTR_ID, 0x08); + if (Status != SUCCESS) + { + DBG_ERROR("PHY_INTR priority level set FAILED, ErrorCode: %ld.\n", Status); + return Status; + } + + // Connect the interrupt service routine isr1 to the interrupt controller + Status = irq_register_callback(descPtr, SYSBUS_TX_INTR_ID, &sysbus_tx_callback_desc); + if (Status != SUCCESS) + { + DBG_ERROR("PHY_INTR register callback FAILED, ErrorCode: %ld.\n", Status); + return Status; + } + Status = irq_trigger_level_set(descPtr, SYSBUS_RX_INTR_ID, IRQ_EDGE_RISING); + if (Status != SUCCESS) + { + DBG_ERROR("PHY_INTR trigger level set FAILED, ErrorCode: %ld.\n", Status); + return Status; + } + // Set interrupt priority + Status = irq_set_priority(descPtr, SYSBUS_RX_INTR_ID, 0x10); + if (Status != SUCCESS) + { + DBG_ERROR("PHY_INTR priority level set FAILED, ErrorCode: %ld.\n", Status); + return Status; + } + + // Connect the interrupt service routine isr1 to the interrupt controller + Status = irq_register_callback(descPtr, SYSBUS_RX_INTR_ID, &sysbus_rx_callback_desc); + if (Status != SUCCESS) + { + DBG_ERROR("PHY_INTR register callback FAILED, ErrorCode: %ld.\n", Status); + return Status; + } + + /* Initialize Scu timer interrupt. */ + // Connect the interrupt service routine isr1 to the interrupt controller + Status = irq_register_callback(descPtr, SCUTIMER_INTR_ID, &scutm_callback_desc); + if (Status != SUCCESS) + { + DBG_ERROR("PHY_INTR register callback FAILED, ErrorCode: %ld.\n", Status); + return Status; + } + + // Enable interrupts + irq_enable(descPtr, PHY_INTR_ID); + irq_enable(descPtr, SYSBUS_RX_INTR_ID); + irq_enable(descPtr, SYSBUS_TX_INTR_ID); + irq_enable(descPtr, SCUTIMER_INTR_ID); + + // Enable Exceptions + Status = irq_global_enable(descPtr); + if (Status != SUCCESS) + { + DBG_ERROR("IRQ global enable FAILED, ErrorCode: %ld.\n", Status); + return Status; + } + return SUCCESS; +} // SetupInterruptSystem + +/****************************************************************************/ +/** + * This function is a interrupt service routine for IRQ_F2P[1:1], IRQ_F2P[1:1] + * tells CPU that the data in OCM is ready! + * + * @param context + * + * @return None. + * + *****************************************************************************/ +void Phy_IntrHandler(void *context) +{ + int32_t Status; + Status = Linklayer_Proc(linkInstPtr); + if (Status != SUCCESS) + { + DBG_ERROR("Link layer runs failed, with error code: %ld\n", Status); + _nop_(); + } +} // PhyIntr_Handler + +/*****************************************************************************/ +/** + * @brief Handler of System Bus RX done interrupt. + * + * @param context + * + * @return None. + * + ******************************************************************************/ +void Systembus_RxIntrHandler(void *context) +{ + int32_t Status; + Status = SystemBus_RxIntrHandler(sysbusDescPtr); + if (Status != SUCCESS) + { + DBG_ERROR("SystemBus_RxIntrHandler exit with error code %ld,\n", Status); + } +} + +/*****************************************************************************/ +/** + * @brief Handler of System Bus TX done interrupt. + * + * @param context + * + * @return None. + * + ******************************************************************************/ +void Systembus_TxIntrHandler(void *context) +{ + int32_t Status; + Status = SystemBus_TxIntrHandler(sysbusDescPtr); + if (Status != SUCCESS) + { + DBG_ERROR("SystemBus_TxIntrHandler exit with error code %ld,\n", Status); + } +} + +/*****************************************************************************/ +/** + * @brief Handler of ScuTimer interrupt. + * + * @param context + * + * @return None. + * + ******************************************************************************/ +void ScuTimer_IntrHandler(void *context) +{ + struct xil_timer_desc *xdesc; + xdesc = (struct xil_timer_desc *)(logTmPtr->extra); + if (XScuTimer_IsExpired((XScuTimer *)xdesc->instance)) + { + // Update log + Phy_UpdateHwSate(phyInstPtr); + XScuTimer_ClearInterruptStatus((XScuTimer *)xdesc->instance); + } + else + { + DBG_WARNING("UNEXPECTED CALL of ScuTimer_IntrHandler\n"); + } +} + +/*****************************************************************************/ +/** + * @brief Hardware_SwitchFreq + * + * @param dev + * @param freq + * + * @return None. + * + ******************************************************************************/ +int Hardware_SwitchFreq(struct ad9361_reg_dev *dev, ad9361TxFreq freq) +{ + int32_t status = 0; + uint8_t value = 0; + int32_t time_out_cnt = 0; + + switch (freq) + { + case TX_FREQ_125: + { + //************************************************************ + // Setup Tx Frequency-Dependent Syntheisizer Registers + //************************************************************ + status = ad9361_reg_write(dev, 0x027A, 0x4A); // Set VCO Output level[3:0] + status = ad9361_reg_write(dev, 0x0279, 0xC1); // Set Init ALC Value[3:0] and VCO Varactor[3:0] + status = ad9361_reg_write(dev, 0x0282, 0x0E); // Set VCO Bias Tcf[1:0] and VCO Bias Ref[2:0] + status = ad9361_reg_write(dev, 0x0278, 0x78); // Set VCO Cal Offset[3:0] + status = ad9361_reg_write(dev, 0x0285, 0x00); // Set VCO Cal Ref Tcf[2:0] + status = ad9361_reg_write(dev, 0x0291, 0x0B); // Set VCO Varactor Reference[3:0] + status = ad9361_reg_write(dev, 0x0290, 0x70); // Set VCO Varactor Ref Tcf[2:0] and VCO Varactor Offset[3:0] + status = ad9361_reg_write(dev, 0x027B, 0x94); // Set Synth Loop Filter charge pump current (Icp) + status = ad9361_reg_write(dev, 0x027E, 0xF4); // Set Synth Loop Filter C2 and C1 + status = ad9361_reg_write(dev, 0x027F, 0xDF); // Set Synth Loop Filter R1 and C3 + status = ad9361_reg_write(dev, 0x0280, 0x0A); // Set Synth Loop Filter R3 + + //************************************************************ + // Write Tx Frequency Words + //************************************************************ + status = ad9361_reg_write(dev, 0x0273, 0x00); // Write Tx Synth Fractional Freq Word[7:0] + status = ad9361_reg_write(dev, 0x0274, 0x00); // Write Tx Synth Fractional Freq Word[15:8] + status = ad9361_reg_write(dev, 0x0275, 0x00); // Write Tx Synth Fractional Freq Word[22:16] + status = ad9361_reg_write(dev, 0x0272, 0x00); // Write Tx Synth Integer Freq Word[10:8] + status = ad9361_reg_write(dev, 0x0271, 0xA0); // Write Tx Synth Integer Freq Word[7:0] (starts VCO cal) + status = ad9361_reg_write(dev, 0x0005, 0x57); // Set LO divider setting + + //************************************************************ + // Tx Quadrature Calibration Settings + //************************************************************ + status = ad9361_reg_write(dev, 0x00A0, 0x75); // Set TxQuadcal NCO frequency + status = ad9361_reg_write(dev, 0x00A3, 0xC0); // Set TxQuadcal NCO frequency (Only update bits [7:6]) + status = ad9361_reg_write(dev, 0x00A1, 0x7B); // Tx Quad Cal Configuration, Phase and Gain Cal Enable + status = ad9361_reg_write(dev, 0x00A9, 0xFF); // Set Tx Quad Cal Count + status = ad9361_reg_write(dev, 0x00A2, 0x7F); // Set Tx Quad Cal Kexp + status = ad9361_reg_write(dev, 0x00A5, 0x01); // Set Tx Quad Cal Magnitude Threshhold + status = ad9361_reg_write(dev, 0x00A6, 0x01); // Set Tx Quad Cal Magnitude Threshhold + status = ad9361_reg_write(dev, 0x00AA, 0x22); // Set Tx Quad Cal Gain Table index + status = ad9361_reg_write(dev, 0x00A4, 0xF0); // Set Tx Quad Cal Settle Count + status = ad9361_reg_write(dev, 0x00AE, 0x00); // Set Tx Quad Cal LPF Gain index incase Split table mode used + + status = ad9361_reg_write(dev, 0x0169, 0xC0); // Disable Rx Quadrature Calibration before Running Tx Quadrature Calibration + status = ad9361_reg_write(dev, 0x0016, 0x10); // Start Tx Quad cal + + break; + } + case TX_FREQ_126: + { + //************************************************************ + // Setup Tx Frequency-Dependent Syntheisizer Registers + //************************************************************ + status = ad9361_reg_write(dev, 0x027A, 0x4A); // Set VCO Output level[3:0] + status = ad9361_reg_write(dev, 0x0279, 0xC1); // Set Init ALC Value[3:0] and VCO Varactor[3:0] + status = ad9361_reg_write(dev, 0x0282, 0x0E); // Set VCO Bias Tcf[1:0] and VCO Bias Ref[2:0] + status = ad9361_reg_write(dev, 0x0278, 0x78); // Set VCO Cal Offset[3:0] + status = ad9361_reg_write(dev, 0x0285, 0x00); // Set VCO Cal Ref Tcf[2:0] + status = ad9361_reg_write(dev, 0x0291, 0x0B); // Set VCO Varactor Reference[3:0] + status = ad9361_reg_write(dev, 0x0290, 0x70); // Set VCO Varactor Ref Tcf[2:0] and VCO Varactor Offset[3:0] + status = ad9361_reg_write(dev, 0x027B, 0x93); // Set Synth Loop Filter charge pump current (Icp) + status = ad9361_reg_write(dev, 0x027E, 0xF4); // Set Synth Loop Filter C2 and C1 + status = ad9361_reg_write(dev, 0x027F, 0xDF); // Set Synth Loop Filter R1 and C3 + status = ad9361_reg_write(dev, 0x0280, 0x0A); // Set Synth Loop Filter R3 + + //************************************************************ + // Write Tx Frequency Words + //************************************************************ + status = ad9361_reg_write(dev, 0x0273, 0x06); // Write Tx Synth Fractional Freq Word[7:0] + status = ad9361_reg_write(dev, 0x0274, 0xD7); // Write Tx Synth Fractional Freq Word[15:8] + status = ad9361_reg_write(dev, 0x0275, 0x23); // Write Tx Synth Fractional Freq Word[22:16] + status = ad9361_reg_write(dev, 0x0272, 0x00); // Write Tx Synth Integer Freq Word[10:8] + status = ad9361_reg_write(dev, 0x0271, 0xA1); // Write Tx Synth Integer Freq Word[7:0] (starts VCO cal) + status = ad9361_reg_write(dev, 0x0005, 0x57); // Set LO divider setting + + //************************************************************ + // Tx Quadrature Calibration Settings + //************************************************************ + status = ad9361_reg_write(dev, 0x00A0, 0x75); // Set TxQuadcal NCO frequency + status = ad9361_reg_write(dev, 0x00A3, 0xC0); // Set TxQuadcal NCO frequency (Only update bits [7:6]) + status = ad9361_reg_write(dev, 0x00A1, 0x7B); // Tx Quad Cal Configuration, Phase and Gain Cal Enable + status = ad9361_reg_write(dev, 0x00A9, 0xFF); // Set Tx Quad Cal Count + status = ad9361_reg_write(dev, 0x00A2, 0x7F); // Set Tx Quad Cal Kexp + status = ad9361_reg_write(dev, 0x00A5, 0x01); // Set Tx Quad Cal Magnitude Threshhold + status = ad9361_reg_write(dev, 0x00A6, 0x01); // Set Tx Quad Cal Magnitude Threshhold + status = ad9361_reg_write(dev, 0x00AA, 0x22); // Set Tx Quad Cal Gain Table index + status = ad9361_reg_write(dev, 0x00A4, 0xF0); // Set Tx Quad Cal Settle Count + status = ad9361_reg_write(dev, 0x00AE, 0x00); // Set Tx Quad Cal LPF Gain index incase Split table mode used + + status = ad9361_reg_write(dev, 0x0169, 0xC0); // Disable Rx Quadrature Calibration before Running Tx Quadrature Calibration + status = ad9361_reg_write(dev, 0x0016, 0x10); // Start Tx Quad cal + + break; + } + case TX_FREQ_4125: + { + //************************************************************ + // Setup Tx Frequency-Dependent Syntheisizer Registers + //************************************************************ + status = ad9361_reg_write(dev, 0x027A, 0x4A); // Set VCO Output level[3:0] + status = ad9361_reg_write(dev, 0x0279, 0xC1); // Set Init ALC Value[3:0] and VCO Varactor[3:0] + status = ad9361_reg_write(dev, 0x0282, 0x0E); // Set VCO Bias Tcf[1:0] and VCO Bias Ref[2:0] + status = ad9361_reg_write(dev, 0x0278, 0x78); // Set VCO Cal Offset[3:0] + status = ad9361_reg_write(dev, 0x0285, 0x00); // Set VCO Cal Ref Tcf[2:0] + status = ad9361_reg_write(dev, 0x0291, 0x0B); // Set VCO Varactor Reference[3:0] + status = ad9361_reg_write(dev, 0x0290, 0x70); // Set VCO Varactor Ref Tcf[2:0] and VCO Varactor Offset[3:0] + status = ad9361_reg_write(dev, 0x027B, 0x93); // Set Synth Loop Filter charge pump current (Icp) + status = ad9361_reg_write(dev, 0x027E, 0xF4); // Set Synth Loop Filter C2 and C1 + status = ad9361_reg_write(dev, 0x027F, 0xDF); // Set Synth Loop Filter R1 and C3 + status = ad9361_reg_write(dev, 0x0280, 0x0A); // Set Synth Loop Filter R3 + + //************************************************************ + // Write Rx Frequency Words + //************************************************************ + status = ad9361_reg_write(dev, 0x0273, 0x00); // Write Tx Synth Fractional Freq Word[7:0] + status = ad9361_reg_write(dev, 0x0274, 0x00); // Write Tx Synth Fractional Freq Word[15:8] + status = ad9361_reg_write(dev, 0x0275, 0x00); // Write Tx Synth Fractional Freq Word[22:16] + status = ad9361_reg_write(dev, 0x0272, 0x00); // Write Tx Synth Integer Freq Word[10:8] + status = ad9361_reg_write(dev, 0x0271, 0xA5); // Write Tx Synth Integer Freq Word[7:0] (starts VCO cal) + status = ad9361_reg_write(dev, 0x0005, 0x07); // Set LO divider setting + + //************************************************************ + // Tx Quadrature Calibration Settings + //************************************************************ + status = ad9361_reg_write(dev, 0x00A0, 0x75); // Set TxQuadcal NCO frequency + status = ad9361_reg_write(dev, 0x00A3, 0xC0); // Set TxQuadcal NCO frequency (Only update bits [7:6]) + status = ad9361_reg_write(dev, 0x00A1, 0x7B); // Tx Quad Cal Configuration, Phase and Gain Cal Enable + status = ad9361_reg_write(dev, 0x00A9, 0xFF); // Set Tx Quad Cal Count + status = ad9361_reg_write(dev, 0x00A2, 0x7F); // Set Tx Quad Cal Kexp + status = ad9361_reg_write(dev, 0x00A5, 0x01); // Set Tx Quad Cal Magnitude Threshhold + status = ad9361_reg_write(dev, 0x00A6, 0x01); // Set Tx Quad Cal Magnitude Threshhold + status = ad9361_reg_write(dev, 0x00AA, 0x28); // Set Tx Quad Cal Gain Table index + status = ad9361_reg_write(dev, 0x00A4, 0xF0); // Set Tx Quad Cal Settle Count + status = ad9361_reg_write(dev, 0x00AE, 0x04); // Set Tx Quad Cal LPF Gain index incase Split table mode used + + status = ad9361_reg_write(dev, 0x0169, 0xC0); // Disable Rx Quadrature Calibration before Running Tx Quadrature Calibration + status = ad9361_reg_write(dev, 0x0016, 0x10); // Start Tx Quad cal + + break; + } + + // Wait for cal to complete (Done when 0x016[4]==0) + time_out_cnt = 0; + do + { + status |= ad9361_reg_read(dev, 0x0016, &value); + mdelay(1); // Wait 1ms + time_out_cnt++; + } while ((value & 0x10) != 0x00 && time_out_cnt <= AD9361_TIMEOUT_TH); + } + + return status; +} + +/*****************************************************************************/ +/** + * @brief Hardware_Init + * + * @param none. + * + * @return None. + * + ******************************************************************************/ +int Hardware_Init(void) +{ + int32_t Status; + XGpioPs Gpio; + XGpioPs_Config *ConfigPtr; + ConfigPtr = XGpioPs_LookupConfig(AD9361_GPIO_DEVICE_ID); + Status = XGpioPs_CfgInitialize(&Gpio, ConfigPtr, ConfigPtr->BaseAddr); + if (Status != SUCCESS) + { + return FAILURE; + } + + /**********************************************************/ + /****************** HMC7044 Configuration *****************/ + /**********************************************************/ + Status = hmc7044_init(&hmc7044_inst, &hmc7044_default_init_param); + if (Status != SUCCESS) + { + DBG_ERROR("hmc7044_init() error: %ld\n", Status); + return FAILURE; + } + + /**********************************************************/ + /***************** AD9361-1 Configuration *****************/ + /**********************************************************/ + XGpioPs_SetDirectionPin(&Gpio, AD9361_1_TXNRX, AD9361_GPIO_OUTPUT); + XGpioPs_SetDirectionPin(&Gpio, AD9361_1_ENABLE, AD9361_GPIO_OUTPUT); + XGpioPs_SetDirectionPin(&Gpio, AD9361_1_EN_AGC, AD9361_GPIO_OUTPUT); + XGpioPs_SetDirectionPin(&Gpio, AD9361_1_RESET_B, AD9361_GPIO_OUTPUT); + + ad9361_reg_init(&ad9361_1_reg_inst, &ad9361_1_reg_default_init_param); + XGpioPs_WritePin(&Gpio, AD9361_1_ENABLE, 0); + ad9361_reg_config(ad9361_1_reg_inst); + XGpioPs_WritePin(&Gpio, AD9361_1_ENABLE, 1); + + // Status = ad9361_init(&ad9361_phy, &ad9361_default_init_param); + // if (Status != XST_SUCCESS){ + // return XST_FAILURE; + // }else{ + // printf("Configurate AD9361 Completely!\n"); + // } + // ad9361_set_tx_fir_config(ad9361_phy, tx_fir_config); + // ad9361_set_rx_fir_config(ad9361_phy, rx_fir_config); + + /**********************************************************/ + /***************** AD9361-2 Configuration *****************/ + /**********************************************************/ + XGpioPs_SetDirectionPin(&Gpio, AD9361_2_TXNRX, AD9361_GPIO_OUTPUT); + XGpioPs_SetDirectionPin(&Gpio, AD9361_2_ENABLE, AD9361_GPIO_OUTPUT); + XGpioPs_SetDirectionPin(&Gpio, AD9361_2_EN_AGC, AD9361_GPIO_OUTPUT); + XGpioPs_SetDirectionPin(&Gpio, AD9361_2_RESET_B, AD9361_GPIO_OUTPUT); + + ad9361_reg_init(&ad9361_2_reg_inst, &ad9361_2_reg_default_init_param); + XGpioPs_WritePin(&Gpio, AD9361_2_ENABLE, 0); + ad9361_reg_config(ad9361_2_reg_inst); + XGpioPs_WritePin(&Gpio, AD9361_2_ENABLE, 1); + + // uint8_t rd_back; + // Status = ad9361_reg_read(ad9361_1_reg_inst, 0x0002, &rd_back); + // Status = ad9361_reg_read(ad9361_2_reg_inst, 0x0002, &rd_back); + + /**********************************************************/ + /******* AD9361 Baseband Multichip Synchronization ********/ + /**********************************************************/ + XGpioPs_SetDirectionPin(&Gpio, AD9361_SYNC, AD9361_GPIO_OUTPUT); + XGpioPs_SetDirectionPin(&Gpio, AD9361_RX_FIFO_RST, AD9361_GPIO_OUTPUT); + + // SYNC BBPLL and DIGITAL SAMPLING CLOCKS + ad9361_reg_write(ad9361_1_reg_inst, 0x0001, 0x0D); // MCS RF Enable; MCS BBPLL Enable; MCS BB Enable + ad9361_reg_write(ad9361_2_reg_inst, 0x0001, 0x0D); + ad9361_reg_write(ad9361_1_reg_inst, 0x0047, 0x80); // MCS refclk Scale Enable + ad9361_reg_write(ad9361_2_reg_inst, 0x0047, 0x80); + XGpioPs_WritePin(&Gpio, AD9361_SYNC, 0); + mdelay(20); + XGpioPs_WritePin(&Gpio, AD9361_SYNC, 1); // Input a rising-edge pulse to the SYNC_IN pin + mdelay(500); + XGpioPs_WritePin(&Gpio, AD9361_SYNC, 0); + mdelay(2000); + ad9361_reg_write(ad9361_1_reg_inst, 0x0001, 0x0B); // MCS RF Enable; MCS Digital CLK Enable ; MCS BB Enable + ad9361_reg_write(ad9361_2_reg_inst, 0x0001, 0x0B); + XGpioPs_WritePin(&Gpio, AD9361_SYNC, 1); // Input another rising-edge pulse to the SYNC_IN pin + mdelay(500); + XGpioPs_WritePin(&Gpio, AD9361_SYNC, 0); + ad9361_reg_write(ad9361_1_reg_inst, 0x0001, 0x08); // clear MCS bits + ad9361_reg_write(ad9361_2_reg_inst, 0x0001, 0x08); + + XGpioPs_WritePin(&Gpio, AD9361_RX_FIFO_RST, 0); + mdelay(20); + XGpioPs_WritePin(&Gpio, AD9361_RX_FIFO_RST, 1); + mdelay(20); + XGpioPs_WritePin(&Gpio, AD9361_RX_FIFO_RST, 0); + + /**********************************************************/ + /********* AD9361 Multichip Rx Phase Calibration **********/ + /**********************************************************/ + XGpioPs_SetDirectionPin(&Gpio, AD9361_TX_SWITCH, AD9361_GPIO_OUTPUT); + XGpioPs_SetDirectionPin(&Gpio, AD9361_1_CAL_START, AD9361_GPIO_OUTPUT); + XGpioPs_SetDirectionPin(&Gpio, AD9361_1_CAL_DONE, AD9361_GPIO_INPUT); + XGpioPs_SetDirectionPin(&Gpio, AD9361_2_CAL_START, AD9361_GPIO_OUTPUT); + XGpioPs_SetDirectionPin(&Gpio, AD9361_2_CAL_DONE, AD9361_GPIO_INPUT); + + // switch to lower frequency + Status = Hardware_SwitchFreq(ad9361_1_reg_inst, TX_FREQ_126); + XGpioPs_WritePin(&Gpio, AD9361_TX_SWITCH, 1); + mdelay(20); + + // switch rx channel + Status = ad9361_reg_write(ad9361_1_reg_inst, 0x0004, 0x30); + Status = ad9361_reg_write(ad9361_2_reg_inst, 0x0004, 0x30); + + // enable dual ad9361 tx channels + Status = ad9361_reg_write(ad9361_1_reg_inst, 0x0002, 0xE4); // Setup Tx Digital Filters/ Channels + + // switch ad9361 tx channel + Status = ad9361_reg_write(ad9361_1_reg_inst, 0x0004, 0x70); // Select Rx input pin(A,B,C)/ Tx out pin (A,B) + mdelay(20); + + // begin to calibrate the 1st ad9361 + XGpioPs_WritePin(&Gpio, AD9361_1_CAL_START, 0); + XGpioPs_WritePin(&Gpio, AD9361_1_CAL_START, 1); + mdelay(1); + XGpioPs_WritePin(&Gpio, AD9361_1_CAL_START, 0); + + // read calibration status + int32_t time_out_cnt = 0; + do + { + mdelay(1); // Wait 1ms + time_out_cnt++; + } while (((XGpioPs_ReadPin(&Gpio, AD9361_1_CAL_DONE) == 0) && time_out_cnt <= AD9361_TIMEOUT_TH)); + + if (time_out_cnt == AD9361_TIMEOUT_TH) + { + return FAILURE; + } + + // begin to calibrate the 2nd ad9361 + XGpioPs_WritePin(&Gpio, AD9361_2_CAL_START, 1); + mdelay(1); + XGpioPs_WritePin(&Gpio, AD9361_2_CAL_START, 0); + + // read calibration status + time_out_cnt = 0; + do + { + mdelay(1); // Wait 1ms + time_out_cnt++; + } while (((XGpioPs_ReadPin(&Gpio, AD9361_2_CAL_DONE) == 0) && time_out_cnt <= AD9361_TIMEOUT_TH)); + + if (time_out_cnt == AD9361_TIMEOUT_TH) + { + return FAILURE; + } + + // enable single ad9361 tx channels + Status = ad9361_reg_write(ad9361_1_reg_inst, 0x0002, 0xA4); // Setup Tx Digital Filters/ Channels + + // switch ad9361 tx & rx channel + Status = ad9361_reg_write(ad9361_1_reg_inst, 0x0004, 0x03); + Status = ad9361_reg_write(ad9361_2_reg_inst, 0x0004, 0x03); + + // switch to higher frequency + Status = Hardware_SwitchFreq(ad9361_1_reg_inst, TX_FREQ_4125); + XGpioPs_WritePin(&Gpio, AD9361_TX_SWITCH, 0); + + DBG_PRINT("Done.\n"); + + return 0; +} + +/*****************************************************************************/ +/** + * @brief Main function, initialize all the device needed, initialize + * interrupt system, halt in while(1) wait for event interrupt. + * + * @param none. + * + * @return + * + ******************************************************************************/ +int main(void) +{ + int Status; + DBG_PRINT("Application Version: %2d.%2d.%4d.\n", _APP_VER_MAIN, _APP_VER_MINOR, _APP_VER_PATCH); + + /* System Monitor Initialize */ + Status = SysMonitor_Init(); + if (Status == SUCCESS) + { + DBG_PRINT("System monitor Init SUCCESS! \n"); + } + else + { + DBG_PRINT("System monitor Init FAILED! \n"); + return Status; + } + + Status = Hardware_Init(); + if (Status == SUCCESS) + { + DBG_PRINT("Hardware Init SUCCESS! \n"); + } + else + { + DBG_PRINT("Hardware Init FAILED! \n"); + return Status; + } + + /* Physical Layer Initialize */ + Status = Phy_InstInit(&phyInstPtr, &phyConfig); + if (Status == SUCCESS) + { + DBG_PRINT("Physical layer Init SUCCESS! \n"); + } + else + { + DBG_PRINT("Physical layer FAILED! \n"); + return Status; + } + + /* Link Layer Initialize */ + linkConfig.phyInstRef = phyInstPtr; + Status = Linklayer_Init(&linkInstPtr, &linkConfig); + if (Status == SUCCESS) + { + DBG_PRINT("LinkLayer Init SUCCESS! \n"); + } + else + { + DBG_PRINT("Linklayer Init FAILED! \n"); + return Status; + } + + /* System Bus Initialize */ + Status = SystemBus_Init(&sysbusDescPtr, &sysbusConfig); + if (Status != SUCCESS) + { + DBG_ERROR("Systembus init FAILED, with error code: %d\n", Status); + return Status; + } + + /* System Monitor log timer Initialize */ + Status = timer_init(&logTmPtr, &scutimer_init_param); + if (Status != SUCCESS) + { + DBG_ERROR("SCU Timer init FAILED, with error code: %d\n", Status); + return Status; + } + + /* interrupts Initialize */ + Status = SetupInterruptSystem(intcDescPtr); + if (Status == SUCCESS) + { + DBG_INFO("Interrupt system setup SUCCESS!\n"); + } + else + { + DBG_ERROR("Interrupt system setup FAILED, ErrorCode: %d.\n", Status); + return Status; + } + + // Start System Monitor logging. + timer_start(logTmPtr); + + Phy_Start(phyInstPtr); + DBG_PRINT("Physical started...\n"); + + while (true) + { + // System bus handler + if (SystemBus_IsReqPendding(sysbusDescPtr)) + { + Status = SystemBus_HandleCmd(sysbusDescPtr); + if (Status != SUCCESS) + { + DBG_ERROR("SystemBus_HandleCmd exit with ErrorCode: %d.\n", Status); + } + } + if (SystemBus_IsRsqPendding(sysbusDescPtr) && (!SystemBus_IsTxBusy(sysbusDescPtr))) + { + // FIXME: Required by 12 (CASC) + udelay(200); + Status = SystemBus_MakeResp(sysbusDescPtr); + if (Status != SUCCESS) + { + DBG_ERROR("SystemBus_HandleCmd exit with ErrorCode: %d.\n", Status); + } + } + } +} // main diff --git a/df_datalink_sp/src/networking/link_layer/framing.c b/df_datalink_sp/src/networking/link_layer/framing.c new file mode 100644 index 0000000..8341196 --- /dev/null +++ b/df_datalink_sp/src/networking/link_layer/framing.c @@ -0,0 +1,141 @@ +/*****************************************************************************/ +/** + * Description: Functions for framing operations. + * + * Date: 2022-07-16 14:17 + * LastEditors: Fan Hao + * LastEditTime: 2022-07-16 17:11 + * Revisions: Rev 0.0 + * History: + * [2022-07-16]: Description of modification. + * + * Copyright(c) 2022 Beijing Institute of Technology. + * Lab of Communication and Networking + * + ******************************************************************************/ + +/***************************** Include Files *********************************/ +#include +#include "error.h" +#include "common.h" +#include "msg_def.h" +#include "link_layer.h" +#include "../config/app_config.h" + +/************************** Constant Definitions *****************************/ + +/*****************************************************************************/ +/** + * @brief Generate crc of specified data. + * + * @param dataBuff pointer to data buffer. + * @param dataLen length of specified data. + * @param crcType type of crc + * @param crc a pointer to 32 bit crc container. + * + * @return FAILURE crc type not support. + * SUCCESS + * + ******************************************************************************/ +static int32_t L2_CrcGen(uint8_t *dataBuff, uint32_t dataLen, L2_CRC_TYPE crcType, uint32_t *crc) +{ + ASSERT(dataBuff != NULL); + int32_t Status; + switch (crcType) + { + case L2_CRC16_1021: + Status = crc16_gen(dataBuff, dataLen, 0x1021, (uint16_t *)crc); + break; + case L2_CRC16_8005: + Status = crc16_gen(dataBuff, dataLen, 0x8005, (uint16_t *)crc); + break; + case L2_CRC8_31: + Status = crc8_gen(dataBuff, dataLen, 0x31, (uint8_t *)crc); + break; + default: + Status = EPARAM; + break; + } + return Status; +} + +/*****************************************************************************/ +/** + * @brief Append a crc of specified data, to a specified position. + * + * @param dataBuff pointer to data buffer. + * @param dataLen length of specified data. + * @param crcPos position of crc insert position + * @param crcType type of crc + * + * @return FAILURE crc type not support. + * SUCCESS + * + ******************************************************************************/ +int32_t L2_CrcAppend(uint8_t *dataBuff, uint32_t dataLen, uint32_t crcPos, L2_CRC_TYPE crcType) +{ + ASSERT(dataBuff != NULL); + int32_t Status; + uint32_t crcVal; + uint8_t *crcPtr; + crcPtr = dataBuff + crcPos; + Status = L2_CrcGen(dataBuff, dataLen, crcType, &crcVal); + if (Status != SUCCESS) + { + return Status; + } + switch (crcType) + { + case L2_CRC16_1021: + *(crcPtr + 1) = (uint8_t)(crcVal >> 8); + *crcPtr = (uint8_t)(crcVal); + break; + case L2_CRC16_8005: + *(crcPtr + 1) = (uint8_t)(crcVal >> 8); + *crcPtr = (uint8_t)(crcVal); + break; + case L2_CRC8_31: + *crcPtr = (uint8_t)crcVal; + break; + default: + Status = EPARAM; + break; + } + return Status; +} + +/*****************************************************************************/ +/** + * @brief Check data validation by crc. + * + * @param dataBuff pointer to data buffer. + * @param dataLen length of specified data. + * @param crcType type of crc + * + * @return FAILURE crc type not support. + * SUCCESS + * + ******************************************************************************/ +bool L2_CrcCheck(uint8_t *dataBuff, uint32_t dataLen, L2_CRC_TYPE crcType) +{ + ASSERT(dataBuff != NULL); + int32_t Status; + uint32_t crcVal; + crcVal = 0; + Status = L2_CrcGen(dataBuff, dataLen, crcType, &crcVal); + if (Status == SUCCESS) + { + if (crcVal == 0) + { + return true; + } + else + { + return false; + } + } + else + { + return false; + } +} diff --git a/df_datalink_sp/src/networking/link_layer/geometry/coord.c b/df_datalink_sp/src/networking/link_layer/geometry/coord.c new file mode 100644 index 0000000..1ca9044 --- /dev/null +++ b/df_datalink_sp/src/networking/link_layer/geometry/coord.c @@ -0,0 +1,211 @@ +// +// Copyright (C) 2020 OpenSim Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later +// + +#include +#include "coord.h" + +const COORD COORD_NIL = {NAN, NAN, NAN}; +const COORD COORD_ZERO = {0.0, 0.0, 0.0}; +const COORD COORD_ONE = {1.0, 1.0, 1.0}; +const COORD COORD_X_AXIS = {1.0, 0.0, 0.0}; +const COORD COORD_Y_AXIS = {0.0, 1.0, 0.0}; +const COORD COORD_Z_AXIS = {0.0, 0.0, 1.0}; + +/** @brief Subtracts two coordinate vectors. */ +COORD Coord_Sub(COORD a, COORD b) +{ + COORD ret; + ret.x = a.x - b.x; + ret.y = a.y - b.y; + ret.z = a.z - b.z; + return ret; +} + +/** @brief Adds two coordinate vectors. */ +COORD Coord_Add(COORD a, COORD b) +{ + COORD ret; + ret.x = a.x + b.x; + ret.y = a.y + b.y; + ret.z = a.z + b.z; + return ret; +} + +/** @brief Multiplies a coordinate vector by a real number. */ +void Coord_ScalarMult(COORD *a, double t) +{ + a->x *= t; + a->y *= t; + a->z *= t; +} + +/** @brief Multiplies a coordinate vector by a real number. */ +COORD Coord_GetScalarMult(COORD a, double t) +{ + COORD ret; + ret.x = a.x * t; + ret.y = a.y * t; + ret.z = a.z * t; + return ret; +} + +/** @brief Divides a coordinate vector by a real number. */ +void Coord_ScalarDiv(COORD *a, double t) +{ + a->x /= t; + a->y /= t; + a->z /= t; +} + +/** @brief Divides a coordinate vector by a real number. */ +COORD Coord_GetScalarDiv(COORD a, double t) +{ + COORD ret; + ret.x = a.x / t; + ret.y = a.y / t; + ret.z = a.z / t; + return ret; +} + +/** @brief Dot product. */ +inline double Coord_Dot(COORD a, COORD b) +{ + return (a.x * b.x + a.y * b.y + a.z * b.z); +} + +/** @brief Cross product. */ +COORD Coord_Cross(COORD a, COORD b) +{ + COORD ret; + ret.x = a.y * b.z - a.z * b.y; + ret.y = a.z * b.x - a.x * b.z; + ret.z = a.x * b.y - a.y * b.x; + return ret; +} + +/** @brief Multiplies two coordinate vector in elementwise. */ +COORD Coord_ElementwiseMult(COORD a, COORD b) +{ + COORD ret; + ret.x = a.x * b.x; + ret.y = a.y * b.y; + ret.z = a.z * b.z; + return ret; +} + +/** @brief Divides two coordinate vector in elementwise. */ +COORD Coord_ElementwiseDiv(COORD a, COORD b) +{ + COORD ret; + ret.x = a.x / b.x; + ret.y = a.y / b.y; + ret.z = a.z / b.z; + return ret; +} + +/** @brief Calculate a coordinate vector length^2 (omits calling square root). */ +double Coord_SquareLength(COORD a) +{ + return (a.x * a.x + a.y * a.y + a.z * a.z); +} + +/** @brief Calculate a coordinate vector length. */ +double Coord_Length(COORD a) +{ + return sqrt(Coord_SquareLength(a)); +} + +/** @brief Calculate two coordinates' distance. */ +double Coord_Distance(COORD a, COORD b) +{ + return Coord_Length(Coord_Sub(a, b)); +} + +/** @brief Normalize coordinate vector. */ +void Coord_Normalize(COORD *a) +{ + Coord_ScalarDiv(a, Coord_Length(*a)); +} + +/** @brief Normalize coordinate vector. */ +COORD Coord_GetNormalized(COORD a) +{ + Coord_Normalize(&a); + return a; +} + +/** @brief Returns the angle between the two vectors. */ +double Coord_Angle(COORD a, COORD b) +{ + Coord_Normalize(&a); + Coord_Normalize(&b); + return acos(Coord_Dot(a, b)); +} + +// Additional Coordinates convert +// TODO: Confirm correctness +/** @brief Convert coordinate from Launch coordinate system to ECEF. */ +COORD Coord_Launch2Ecef(COORD o, COORD p, double A, double B, double lambda) +{ + COORD ret; + double sinA, cosA, sinB, cosB, sinL, cosL; + double S11, S12, S13, S21, S22, S23, S31, S32, S33; + sinA = sin(A); + cosA = cos(A); + sinB = sin(B); + cosB = cos(B); + sinL = sin(lambda); + cosL = cos(lambda); + + S11 = -sinA * sinL - cosA * sinB * cosL; + S12 = cosB * cosL; + S13 = -cosA * sinL + sinA * sinB * cosL; + + S21 = sinA * cosL - cosA * sinB * sinL; + S22 = cosB * sinL; + S23 = cosA * cosL + sinA * sinB * sinL; + + S31 = cosA * cosB; + S32 = sinB; + S33 = -sinA * cosB; + + ret.x = p.x * (S11 + S21 + S31) + o.x; + ret.y = p.y * (S12 + S22 + S32) + o.y; + ret.z = p.z * (S13 + S23 + S33) + o.z; + + return ret; +} + +/** @brief Convert coordinate from launch coordinate system to Inertia coordinate system. */ +COORD Coord_Launch2Inertia(COORD o, COORD p, double A, double B, double we, double t) +{ + COORD ret; + double OmgX, OmgY, OmgZ, sinwet, coswet; + double M11, M12, M13, M21, M22, M23, M31, M32, M33; + OmgX = cos(A) * cos(B); + OmgY = sin(B); + OmgZ = -sin(A) * cos(B); + sinwet = sin(we * t); + coswet = cos(we * t); + + M11 = 1 - (1 - OmgX * OmgX) * (1 - coswet); + M12 = OmgX * OmgY * (1 - coswet) + OmgZ * sinwet; + M13 = OmgX * OmgZ * (1 - coswet) - OmgY * sinwet; + + M21 = OmgY * OmgX * (1 - coswet) - OmgZ * sinwet; + M22 = 1 - (1 - OmgY * OmgY) * (1 - coswet); + M23 = OmgY * OmgZ * (1 - coswet) + OmgX * sinwet; + + M31 = OmgZ * OmgX * (1 - coswet) + OmgY * sinwet; + M32 = OmgZ * OmgY * (1 - coswet) - OmgX * sinwet; + M33 = 1 - (1 - OmgZ * OmgZ) * (1 - coswet); + + ret.x = p.x * (M11 + M21 + M31) + o.x; + ret.y = p.y * (M12 + M22 + M32) + o.y; + ret.z = p.z * (M13 + M23 + M33) + o.z; + + return ret; +} diff --git a/df_datalink_sp/src/networking/link_layer/geometry/coord.h b/df_datalink_sp/src/networking/link_layer/geometry/coord.h new file mode 100644 index 0000000..ee8b6a2 --- /dev/null +++ b/df_datalink_sp/src/networking/link_layer/geometry/coord.h @@ -0,0 +1,80 @@ +// +// Copyright (C) 2020 OpenSim Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later +// + +#ifndef _COORD_H +#define _COORD_H + +/** + * @brief Structure for storing 3D coordinates. + * + * Some comparison and basic arithmetic operators are implemented. + * + * @ingroup utils + */ + +typedef struct +{ + double x; + double y; + double z; +} COORD; + +extern const COORD COORD_NIL; +extern const COORD COORD_ZERO; +extern const COORD COORD_ONE; +extern const COORD COORD_X_AXIS; +extern const COORD COORD_Y_AXIS; +extern const COORD COORD_Z_AXIS; + +/** @brief Subtracts two coordinate vectors. */ +COORD Coord_Sub(COORD a, COORD b); + +/** @brief Adds two coordinate vectors. */ +COORD Coord_Add(COORD a, COORD b); + +/** @brief Multiplies a coordinate vector by a real number. */ +void Coord_ScalarMult(COORD *a, double t); + +/** @brief Multiplies a coordinate vector by a real number. */ +COORD Coord_GetScalarMult(COORD a, double t); + +/** @brief Divides a coordinate vector by a real number. */ +void Coord_ScalarDiv(COORD *a, double t); + +/** @brief Divides a coordinate vector by a real number. */ +COORD Coord_GetScalarDiv(COORD a, double t); + +/** @brief Dot product. */ +double Coord_Dot(COORD a, COORD b); + +/** @brief Cross product. */ +COORD Coord_Cross(COORD a, COORD b); + +/** @brief Multiplies two coordinate vector in elementwise. */ +COORD Coord_ElementwiseMult(COORD a, COORD b); + +/** @brief Divides two coordinate vector in elementwise. */ +COORD Coord_ElementwiseDiv(COORD a, COORD b); + +/** @brief Calculate a coordinate vector length^2 (omits calling square root). */ +double Coord_SquareLength(COORD a); + +/** @brief Calculate a coordinate vector length. */ +double Coord_Length(COORD a); + +/** @brief Calculate two coordinates' distance. */ +double Coord_Distance(COORD a, COORD b); + +/** @brief Normalize coordinate vector. */ +void Coord_Normalize(COORD *a); + +/** @brief Normalize coordinate vector. */ +COORD Coord_GetNormalized(COORD a); + +/** @brief Returns the angle between the two vectors. */ +double Coord_Angle(COORD a, COORD b); + +#endif diff --git a/df_datalink_sp/src/networking/link_layer/geometry/eulerangles.c b/df_datalink_sp/src/networking/link_layer/geometry/eulerangles.c new file mode 100644 index 0000000..8c580ec --- /dev/null +++ b/df_datalink_sp/src/networking/link_layer/geometry/eulerangles.c @@ -0,0 +1,61 @@ +// +// Copyright (C) 2020 OpenSim Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later +// + +#include +#include "eulerangles.h" + +const EULERANGLES EULERANGLES_NIL = {NAN, NAN, NAN}; +const EULERANGLES EULERANGLES_ZERO = {0.0, 0.0, 0.0}; + +/** @brief Add two EulerAngles. */ +EULERANGLES EulerAngles_Add(EULERANGLES e1, EULERANGLES e2) +{ + EULERANGLES ret; + ret.alpha = e1.alpha + e2.alpha; + ret.beta = e1.beta + e2.beta; + ret.gamma = e1.gamma + e2.gamma; + return ret; +} + +/** @brief Subtracts two EulerAngles. */ +EULERANGLES EulerAngles_Sub(EULERANGLES e1, EULERANGLES e2) +{ + EULERANGLES ret; + ret.alpha = e1.alpha - e2.alpha; + ret.beta = e1.beta - e2.beta; + ret.gamma = e1.gamma - e2.gamma; + return ret; +} + +/** @brief Multiplies EulerAngles by a real number. */ +void EulerAngles_ScalarMult(EULERANGLES *e, double f) +{ + e->alpha *= f; + e->beta *= f; + e->gamma *= f; +} + +/** @brief Multiplies EulerAngles by a real number. */ +EULERANGLES EulerAngles_GetScalarMult(EULERANGLES e, double f) +{ + EulerAngles_ScalarMult(&e, f); + return e; +} + +/** @brief Normalize EulerAngles. */ +void EulerAngles_Normalize(EULERANGLES *e) +{ + e->alpha = fmod(e->alpha, 2 * EUL_PI); + e->beta = fmod(e->beta, 2 * EUL_PI); + e->gamma = fmod(e->gamma, 2 * EUL_PI); +} + +/** @brief Normalize EulerAngles. */ +EULERANGLES EulerAngles_GetNormalize(EULERANGLES e) +{ + EulerAngles_Normalize(&e); + return e; +} diff --git a/df_datalink_sp/src/networking/link_layer/geometry/eulerangles.h b/df_datalink_sp/src/networking/link_layer/geometry/eulerangles.h new file mode 100644 index 0000000..8db0860 --- /dev/null +++ b/df_datalink_sp/src/networking/link_layer/geometry/eulerangles.h @@ -0,0 +1,55 @@ +#ifndef __EULERANGLES_H +#define __EULERANGLES_H + +#define EUL_PI 3.14159265358979323846 + +#define DEG2RAD(d) ((EUL_PI / 180.0) * d) +#define RAD2DEG(r) ((180.0 / EUL_PI) * r) + +/** + * Orientations are represented by 3D double precision Tait-Bryan (Euler) tuples + * called EulerAngles. The angles are in Z, Y', X" order that is often called + * intrinsic rotations, they are measured in radians. The default (unrotated) + * orientation is along the X axis. Conceptually, the Z axis rotation is heading, + * the Y' axis rotation is descending (negative elevation), the X" axis rotation is bank. + * For example, positive rotation along the Z axis rotates X into Y (turns left), positive + * rotation along the Y axis rotates Z into X (leans forward), positive rotation + * along the X axis rotates Y into Z (leans right). + */ +typedef struct +{ + double alpha; // unit rad + double beta; // unit rad + double gamma; // unit rad +} EULERANGLES; + +typedef enum +{ + EULERANGLES_NONE = 0, + EULERANGLES_ZYX = 1, + EULERANGLES_ZYZ = 2, + EULERANGLES_XYZ = 3, +} EULERANGLES_TYPE; + +extern const EULERANGLES EULERANGLES_ZERO; +extern const EULERANGLES EULERANGLES_NIL; + +/** @brief Add two EulerAngles. */ +EULERANGLES EulerAngles_Add(EULERANGLES e1, EULERANGLES e2); + +/** @brief Subtracts two EulerAngles. */ +EULERANGLES EulerAngles_Sub(EULERANGLES e1, EULERANGLES e2); + +/** @brief Multiplies EulerAngles by a real number. */ +void EulerAngles_ScalarMult(EULERANGLES *e, double f); + +/** @brief Multiplies EulerAngles by a real number. */ +EULERANGLES EulerAngles_GetScalarMult(EULERANGLES e, double f); + +/** @brief Normalize EulerAngles. */ +void EulerAngles_Normalize(EULERANGLES *e); + +/** @brief Normalize EulerAngles. */ +EULERANGLES EulerAngles_GetNormalize(EULERANGLES e); + +#endif diff --git a/df_datalink_sp/src/networking/link_layer/geometry/quaternion.c b/df_datalink_sp/src/networking/link_layer/geometry/quaternion.c new file mode 100644 index 0000000..be2aa52 --- /dev/null +++ b/df_datalink_sp/src/networking/link_layer/geometry/quaternion.c @@ -0,0 +1,452 @@ +// +// Copyright (C) 2014 OpenSim Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later +// + +#include +#include +#include +#include "coord.h" +#include "eulerangles.h" +#include "quaternion.h" + +typedef union +{ + float value; + uint32_t raw; +} SOFT_FLOAT; + +typedef union +{ + double value; + uint64_t raw; +} SOFT_DOUBLE; + +const SOFT_FLOAT EPS_FLOAT = {.raw = 0x34000000}; +const SOFT_DOUBLE EPS_DOUBLE = {.raw = 0x3CB0000000000000}; + +const QUATERNION QUATERNION_IDENTITY = {1.0, 0.0, 0.0, 0.0}; +const QUATERNION QUATERNION_NIL = {NAN, NAN, NAN, NAN}; +/** @brief Subtracts two quaternions. */ +QUATERNION Quaternion_Sub(QUATERNION q1, QUATERNION q2) +{ + QUATERNION ret; + ret.s = q1.s - q2.s; + ret.i = q1.i - q2.i; + ret.j = q1.j - q2.j; + ret.k = q1.k - q2.k; + return ret; +} + +/** @brief Adds two quaternions. */ +QUATERNION Quaternion_Add(QUATERNION q1, QUATERNION q2) +{ + QUATERNION ret; + ret.s = q1.s + q2.s; + ret.i = q1.i + q2.i; + ret.j = q1.j + q2.j; + ret.k = q1.k + q2.k; + return ret; +} + +/** @brief Multiplies a quaternion by a real number. */ +void Quaternion_ScalarMult(QUATERNION *q, double t) +{ + q->s *= t; + q->i *= t; + q->j *= t; + q->k *= t; +} + +/** @brief Multiplies a quaternion by a real number. */ +QUATERNION Quaternion_GetScalarMult(QUATERNION a, double t) +{ + Quaternion_ScalarMult(&a, t); + return a; +} + +/** @brief Divides a quaternion by a real number. */ +void Quaternion_ScalarDiv(QUATERNION *q, double t) +{ + q->s /= t; + q->i /= t; + q->j /= t; + q->k /= t; +} + +/** @brief Divides a quaternion by a real number. */ +QUATERNION Quaternion_GetScalarDiv(QUATERNION q, double t) +{ + Quaternion_ScalarDiv(&q, t); + return q; +} + +/** @brief Multiplies two quaternions. */ +QUATERNION Quaternion_Mult(QUATERNION q1, QUATERNION q2) +{ + QUATERNION ret; + ret.s = q1.s * q2.s - (q1.i * q2.i + q1.j * q2.j + q1.k * q2.k); + ret.i = q1.j * q2.k - q1.k * q2.j + q1.s * q2.i + q1.i * q2.s; + ret.j = q1.k * q2.i - q1.i * q2.k + q1.s * q2.j + q1.j * q2.s; + ret.k = q1.i * q2.j - q1.j * q2.i + q1.s * q2.k + q1.k * q2.s; + return ret; +} + +/** @brief Divides two quaternions. */ +QUATERNION Quaternion_Div(QUATERNION q1, QUATERNION q2) +{ + Quaternion_Inverse(&q2); + return Quaternion_Mult(q1, q2); +} + +/** @brief Dot product. */ +inline double Quaternion_Dot(QUATERNION q1, QUATERNION q2) +{ + return (q1.s * q2.s + q1.i * q2.i + q1.j * q2.j + q1.k * q2.k); +} + +/** @brief Calculate a quaternion length^2 (omits calling square root). */ +inline double Quaternion_SquareLength(QUATERNION q) +{ + return (q.s * q.s + q.i * q.i + q.j * q.j + q.k * q.k); +} + +/** @brief Calculate a quaternion length. */ +inline double Quaternion_Length(QUATERNION q) +{ + return sqrt(Quaternion_SquareLength(q)); +} + +/** @brief Normalize quaternion. */ +void Quaternion_Normalize(QUATERNION *q) +{ + Quaternion_ScalarDiv(q, Quaternion_Length(*q)); +} + +/** @brief Normalize quaternion. */ +QUATERNION Quaternion_GetNormalized(QUATERNION q) +{ + Quaternion_Normalize(&q); + return q; +} + +/** @brief Conjugated quaternion. */ +void Quaternion_Conjugated(QUATERNION *q) +{ + q->i = -q->i; + q->j = -q->j; + q->k = -q->k; +} + +/** @brief Conjugated quaternion. */ +QUATERNION Quaternion_GetConjugated(QUATERNION q) +{ + Quaternion_Conjugated(&q); + return q; +} + +/** @brief Inverse quaternion. */ +void Quaternion_Inverse(QUATERNION *q) +{ + Quaternion_Conjugated(q); + Quaternion_ScalarDiv(q, Quaternion_SquareLength(*q)); +} + +/** @brief Inverse quaternion. */ +QUATERNION Quaternion_GeInverse(QUATERNION q) +{ + Quaternion_Inverse(&q); + return q; +} + +inline double Quaternion_GetRotationAngle(QUATERNION q) +{ + return (acos(q.s) * 2); +} + +/** @brief Get axis of quaternion. */ +COORD Quaternion_GetRotationAxis(QUATERNION q) +{ + double sin_theta_inv; + COORD ret; + sin_theta_inv = 1.0 / sin(acos(q.s)); + ret.x = q.i * sin_theta_inv; + ret.y = q.j * sin_theta_inv; + ret.z = q.k * sin_theta_inv; + return ret; +} + +/** @brief Get the axis and rotate angle of a unit Quaternion */ +void Quaternion_GetRotationAxisAndAngle(QUATERNION q, COORD *axis, double *angle) +{ + double sin_theta_inv; + *angle = acos(q.s); + + // pre-compute to save time + sin_theta_inv = 1.0 / sin(*angle); + + // now the vector + axis->x = q.i * sin_theta_inv; + axis->y = q.j * sin_theta_inv; + axis->z = q.k * sin_theta_inv; + *angle = (*angle) * 2; +} + +/** @brief Decompose the rotation on to 2 parts. */ +void Quaternion_GetSwingAndTwist(QUATERNION q, COORD axis, QUATERNION *swing, QUATERNION *twist) +{ + double p; + COORD v; + v.x = q.i; + v.y = q.j; + v.z = q.k; + // return projection v1 on to v2 (parallel component) + p = Coord_Dot(v, axis); + v = Coord_GetScalarMult(axis, p); + twist->s = q.s; + twist->i = v.x; + twist->j = v.y; + twist->k = v.z; + Quaternion_Normalize(twist); + *swing = Quaternion_Mult(q, Quaternion_GetConjugated(*twist)); +} + +/** @brief rotates v by this quaternion (quaternion must be unit) */ +COORD Quaternion_Rotate(QUATERNION q, COORD v) +{ + QUATERNION temp; + COORD ret; + temp.s = 0; + temp.i = v.x; + temp.j = v.y; + temp.k = v.z; + temp = Quaternion_Mult(q, temp); + Quaternion_Conjugated(&q); + temp = Quaternion_Mult(temp, q); + ret.x = temp.i; + ret.y = temp.j; + ret.z = temp.k; + return ret; +} + +/** @brief returns the euler angles from a rotation Quaternion */ +EULERANGLES Quaternion_ToEulerAngles(QUATERNION q, EULERANGLES_TYPE type) +{ + EULERANGLES ret; + switch (type) + { + case EULERANGLES_ZYX: + { + /* Covert form matlab 2023a */ + // Cap all inputs to asin to 1, since values >1 produce complex + // results + // Since the quaternion is of unit length, this should never happen, + // but some code generation configuration seem to hit this edge case + // under some circumstances. + + double asinValue; + bool mask1, mask2; + + asinValue = -2.0 * (q.i * q.k - q.s * q.j); + mask1 = asinValue >= 1.0 - 10 * EPS_DOUBLE.value; + mask2 = asinValue <= -1.0 + 10 * EPS_DOUBLE.value; + if (mask1) + asinValue = 1; + if (mask2) + asinValue = -1; + + if (mask1 || mask2) + { + ret.alpha = (asinValue > 0) ? (-2.0 * atan2(q.i, q.s)) : (2.0 * atan2(q.i, q.s)); + ret.gamma = 0; + } + else + { + ret.alpha = atan2(2.0 * (q.i * q.j + q.s * q.k), q.s * q.s + q.i * q.i - q.j * q.j - q.k * q.k); + ret.gamma = atan2(2.0 * (q.j * q.k + q.s * q.i), q.s * q.s - q.i * q.i - q.j * q.j + q.k * q.k); + } + ret.beta = asin(asinValue); + break; + } + + case EULERANGLES_ZYZ: + { + // TODO; + ret = EULERANGLES_NIL; + break; + } + + case EULERANGLES_XYZ: + { + /* Covert form matlab 2023a */ + // Prevent singularities as done in ZYX case + // Alternative to rotm2eul(quat2rotm(q), 'XYZ') with fewer + // operations + // sin(y) = R13 = 2 * (qx*qz + qy*qw) + // tan(x) = sin(x) / cos(x) = -R23 / R33 + // = -2 * (qy*qz - qx*qw) / (1 - 2*(qx^2 + qy^2)) + // = -2 * (qy*qz - qx*qw) / (qw^2 - qx^2 - qy^2 + qz^2) + // tan(z) = sin(z) / cos(z) = -R12 / R11 + // = -2 * (qx*qy - qz*qw) / (1 - 2*(qy^2 + qz^2)) + // = -2 * (qy*qz - qx*qw) / (qw^2 + qx^2 - qy^2 - qz^2) + + double asinValue; + bool mask1, mask2; + + asinValue = 2.0 * (q.i * q.k + q.s * q.j); + mask1 = asinValue >= 1.0 - 10 * EPS_DOUBLE.value; + mask2 = asinValue <= -1.0 + 10 * EPS_DOUBLE.value; + if (mask1) + asinValue = 1; + if (mask2) + asinValue = -1; + if (mask1 || mask2) + { + ret.alpha = 0; + ret.gamma = (asinValue > 0) ? (2.0 * atan2(q.i, q.s)) : (-2.0 * atan2(q.i, q.s)); + } + else + { + ret.alpha = atan2(-2.0 * (q.j * q.k - q.s * q.i), q.s * q.s - q.i * q.i - q.j * q.j + q.k * q.k); + ret.gamma = atan2(-2.0 * (q.i * q.j - q.s * q.k), q.s * q.s + q.i * q.i - q.j * q.j - q.k * q.k); + } + ret.beta = asin(asinValue); + break; + } + + default: + ret = EULERANGLES_NIL; + } + return ret; +} + +/** @brief returns the rotation Quaternion from a euler angles */ +QUATERNION Quaternion_FromeEulerAngles(EULERANGLES e, EULERANGLES_TYPE type) +{ + QUATERNION ret; + double cosx, sinx, cosy, siny, cosz, sinz; + cosx = cos(e.alpha * 0.5); + sinx = sin(e.alpha * 0.5); + cosy = cos(e.beta * 0.5); + siny = sin(e.beta * 0.5); + cosz = cos(e.gamma * 0.5); + sinz = sin(e.gamma * 0.5); + switch (type) + { + case EULERANGLES_ZYX: + ret.s = cosx * cosy * cosz + sinx * siny * sinz; + ret.i = cosx * cosy * sinz - sinx * siny * cosz; + ret.j = cosx * siny * cosz + sinx * cosy * sinz; + ret.k = sinx * cosy * cosz - cosx * siny * sinz; + break; + case EULERANGLES_ZYZ: + ret.s = cosx * cosy * cosz - sinx * cosy * sinz; + ret.i = cosx * siny * sinz - sinx * siny * cosz; + ret.j = cosx * siny * cosz + sinx * siny * sinz; + ret.k = sinx * cosy * cosz + cosx * cosy * sinz; + break; + case EULERANGLES_XYZ: + ret.s = cosx * cosy * cosz - sinx * siny * sinz; + ret.i = sinx * cosy * cosz + cosx * siny * sinz; + ret.j = -sinx * cosy * sinz + cosx * siny * cosz; + ret.k = cosx * cosy * sinz + sinx * siny * cosz; + break; + default: + ret = QUATERNION_NIL; + break; + } + return ret; +} + +/** @brief adapted from https://svn.code.sf.net/p/irrlicht/code/trunk/include/quaternion.h */ +QUATERNION Quaternion_RotationFromTo(COORD from, COORD to) +{ + // Based on Stan Melax's article in Game Programming Gems + COORD axis; + QUATERNION ret; + double c, s; + Coord_Normalize(&from); + Coord_Normalize(&to); + + c = Coord_Dot(from, to); + + if (c >= 1.0) + { // If dot == 1, vectors are the same + return QUATERNION_IDENTITY; // identity + } + else if (c <= -1.0) + { // exactly opposite + axis = Coord_Cross(COORD_X_AXIS, from); + + if (Coord_Length(axis) == 0) + axis = Coord_Cross(COORD_Y_AXIS, from); + + // same as fromAxisAngle(axis, PI).normalize(); + ret.s = 0; + ret.i = axis.x; + ret.j = axis.y; + ret.k = axis.z; + Quaternion_Normalize(&ret); + return ret; + } + + s = sqrt((1 + c) * 2); + axis = Coord_Cross(from, to); + Coord_ScalarDiv(&axis, s); + ret.s = s * 0.5; + ret.i = axis.x; + ret.j = axis.y; + ret.k = axis.z; + Quaternion_Normalize(&ret); + return ret; +} + +/** @brief linear quaternion interpolation */ +QUATERNION Quaternion_Lerp(QUATERNION q1, QUATERNION q2, double t) +{ + QUATERNION ret; + Quaternion_ScalarMult(&q1, 1 - t); + Quaternion_ScalarMult(&q1, t); + ret = Quaternion_Add(q1, q2); + Quaternion_Normalize(&ret); + return ret; +} + +/** @brief spherical linear interpolation */ +QUATERNION Quaternion_Slerp(QUATERNION q1, QUATERNION q2, double t) +{ + double dot; + QUATERNION q3, ret; + dot = Quaternion_Dot(q1, q2); + /* dot = cos(theta) + if (dot < 0), q1 and q2 are more than 90 degrees apart, + so we can invert one to reduce spinning */ + if (dot < 0) + { + dot = -dot; + q3.s = -q2.s; + q3.i = -q2.i; + q3.j = -q2.j; + q3.k = -q2.k; + } + else + { + q3 = q2; + } + + if (dot < 0.95) + { + double angle = acos(dot); + Quaternion_ScalarMult(&q1, sin(angle * (1 - t))); + Quaternion_ScalarMult(&q3, sin(angle * t)); + ret = Quaternion_Add(q1, q3); + Quaternion_ScalarDiv(&ret, sin(angle)); + return ret; + } + // if the angle is small, use linear interpolation + else + { + return Quaternion_Lerp(q1, q3, t); + } +} diff --git a/df_datalink_sp/src/networking/link_layer/geometry/quaternion.h b/df_datalink_sp/src/networking/link_layer/geometry/quaternion.h new file mode 100644 index 0000000..7e766c4 --- /dev/null +++ b/df_datalink_sp/src/networking/link_layer/geometry/quaternion.h @@ -0,0 +1,109 @@ + +#ifndef __QUATERNION_H +#define __QUATERNION_H + +#include "coord.h" +#include "eulerangles.h" + +// borrowed and adapted from https://github.com/MegaManSE/willperone/blob/master/Math/quaternion.h +typedef struct +{ + double s; + double i; + double j; + double k; +} QUATERNION; + +extern const QUATERNION QUATERNION_IDENTITY; +extern const QUATERNION QUATERNION_NIL; + +/** @brief Subtracts two quaternions. */ +QUATERNION Quaternion_Sub(QUATERNION q1, QUATERNION q2); + +/** @brief Adds two quaternions. */ +QUATERNION Quaternion_Add(QUATERNION q1, QUATERNION q2); + +/** @brief Multiplies a quaternion by a real number. */ +void Quaternion_ScalarMult(QUATERNION *q, double t); + +/** @brief Multiplies a quaternion by a real number. */ +QUATERNION Quaternion_GetScalarMult(QUATERNION a, double t); + +/** @brief Divides a quaternion by a real number. */ +void Quaternion_ScalarDiv(QUATERNION *q, double t); + +/** @brief Divides a quaternion by a real number. */ +QUATERNION Quaternion_GetScalarDiv(QUATERNION a, double t); + +/** @brief Multiplies two quaternions. */ +QUATERNION Quaternion_Mult(QUATERNION q1, QUATERNION q2); + +/** @brief Divides two quaternions. */ +QUATERNION Quaternion_Div(QUATERNION q1, QUATERNION q2); + +/** @brief Dot product. */ +double Quaternion_Dot(QUATERNION q1, QUATERNION q2); + +/** @brief Calculate a quaternion length^2 (omits calling square root). */ +double Quaternion_SquareLength(QUATERNION q); + +/** @brief Calculate a quaternion length. */ +double Quaternion_Length(QUATERNION q); + +/** @brief Normalize quaternion. */ +void Quaternion_Normalize(QUATERNION *q); + +/** @brief Normalize quaternion. */ +QUATERNION Quaternion_GetNormalized(QUATERNION q); + +/** @brief Conjugated quaternion. */ +void Quaternion_Conjugated(QUATERNION *q); + +/** @brief Conjugated quaternion. */ +QUATERNION Quaternion_GetConjugated(QUATERNION q); + +/** @brief Inverse quaternion. */ +void Quaternion_Inverse(QUATERNION *q); + +/** @brief Inverse quaternion. */ +QUATERNION Quaternion_GeInverse(QUATERNION q); + +/** @brief Get rotate angle of quaternion. */ +double Quaternion_GetRotationAngle(QUATERNION q); + +/** @brief Get axis of quaternion. */ +COORD Quaternion_GetRotationAxis(QUATERNION q); + +/** @brief Get the axis and rotate angle of a unit Quaternion */ +void Quaternion_GetRotationAxisAndAngle(QUATERNION q, COORD *axis, double *angle); + +/** @brief Decompose the rotation on to 2 parts. + 1. Twist - rotation around the "direction" vector + 2. Swing - rotation around axis that is perpendicular to "direction" vector + The rotation can be composed back by rotation = swing * twist + + has singularity in case of swing_rotation close to 180 degrees rotation. + if the input quaternion is of non-unit length, the outputs are non-unit as well + otherwise, outputs are both unit +*/ +void Quaternion_GetSwingAndTwist(QUATERNION q, COORD axis, QUATERNION *swing, QUATERNION *twist); + +/** @brief rotates v by this quaternion (quaternion must be unit) */ +COORD Quaternion_Rotate(QUATERNION q, COORD v); + +/** @brief returns the euler angles from a rotation Quaternion */ +EULERANGLES Quaternion_ToEulerAngles(QUATERNION q, EULERANGLES_TYPE type); + +/** @brief returns the rotation Quaternion from a euler angles */ +QUATERNION Quaternion_FromeEulerAngles(EULERANGLES e, EULERANGLES_TYPE type); + +/** @brief adapted from https://svn.code.sf.net/p/irrlicht/code/trunk/include/quaternion.h */ +QUATERNION Quaternion_RotationFromTo(COORD from, COORD to); + +/** @brief linear quaternion interpolation */ +QUATERNION Quaternion_Lerp(QUATERNION q1, QUATERNION q2, double t); + +/** @brief spherical linear interpolation */ +QUATERNION Quaternion_Slerp(QUATERNION q1, QUATERNION q2, double t); + +#endif diff --git a/df_datalink_sp/src/networking/link_layer/link_layer.c b/df_datalink_sp/src/networking/link_layer/link_layer.c new file mode 100644 index 0000000..28fdba9 --- /dev/null +++ b/df_datalink_sp/src/networking/link_layer/link_layer.c @@ -0,0 +1,1234 @@ +/*****************************************************************************/ +/** + * Description: A brief description of this file + * + * Date: 2021-11-13 13:32 + * LastEditTime: 2021-11-23 10:57 + * Revisions: Rev 0.0 + * History: + * [2021-11-23]: Initial version. + * [2022-03-28]: Add bre test mode. + * + * Copyright(c) 2021 Beijing Institute of Technology. + * Lab of Communication and Networking + * + ******************************************************************************/ + +/***************************** Include Files *********************************/ +#include +#include + +#include "util.h" +#include "error.h" +#include "circ_queue.h" +#include "link_layer.h" +#include "link_layer_types.h" +#include "msg_def.h" +#include "node_list.h" +#include "../phy_layer/phy_reg.h" + +/************************** Constant Definitions *****************************/ +#define TX_QUEUE_MAX 8 +#define LINK_BROCK_THRESHOLD (3 * 200) // 3 secods +/************************** Variable Definitions *****************************/ +/***************** Macros (Inline Functions) Definitions *********************/ +/**************************** Type Definitions *******************************/ +/************************** Function Prototypes ******************************/ +static void RcdShift(L2_RCD *rcd, int32_t netxVal); +static void UpdateMainSate(L2_INST *instPtr, L2_NODE_STATE newSate); +static void SlotNoUpdate(L2_INST *instPtr, uint32_t newSlotNo); +static void FrameNoUpdate(L2_INST *instPtr, uint32_t newFrameNo); +static void DataAvailUpdate(L2_INST *instPtr, bool status); +static void EventPoolHandler(L2_INST *instPtr); + +static inline void UpdateMainSate(L2_INST *instPtr, L2_NODE_STATE newSate) +{ + ASSERT(instPtr != NULL); + DBG_INFO("MainStateUpdate: %d -> %d\n", instPtr->mainState, newSate); + instPtr->nextState = newSate; +} + +static inline void ForceUpdateMainSate(L2_INST *instPtr, L2_NODE_STATE newSate) +{ + ASSERT(instPtr != NULL); + DBG_INFO("MainState Force Update: %d -> %d\n", instPtr->mainState, newSate); + instPtr->mainState = newSate; + instPtr->nextState = newSate; +} + +/** + * @brief Update frame number, based on new next slotNo + */ +// FIXME: frame number update should effect 'last' and 'curr' frame number record. +static inline void SlotNoUpdate(L2_INST *instPtr, uint32_t newSlotNo) +{ + ASSERT(instPtr != NULL); + DBG_INFO("Update slot number to %lu\n", newSlotNo); + instPtr->slotNo.next = newSlotNo; +} + +/** + * @brief Update slot number, based on new next frameNo + */ +// TODO: slot number update should effect 'last' and 'curr' slot number record. +static inline void FrameNoUpdate(L2_INST *instPtr, uint32_t newFrameNo) +{ + ASSERT(instPtr != NULL); + DBG_INFO("Update frame number to %lu\n", newFrameNo); + instPtr->frameNo.next = newFrameNo; +} + +/** + * @brief Update l2 frame buffer state + * infer that if there is a new valid l2 frame up. + */ +static inline void DataAvailUpdate(L2_INST *instPtr, bool status) +{ + ASSERT(instPtr != NULL); + instPtr->dataAvail = status; +} + +L2_NODE_STATE L2_GetMainState(L2_INST *instPtr) +{ + ASSERT(instPtr != NULL); + return instPtr->mainState; +} + +/** + * @brief Check if there is a valid l2 frame. + */ +inline bool L2_isDataAvail(L2_INST *instPtr) +{ + ASSERT(instPtr != NULL); + return instPtr->dataAvail; +} + +/** + * @brief Check if node is connected to the network + */ +inline bool L2_isCxn2Net(L2_INST *instPtr) +{ + ASSERT(instPtr != NULL); + return instPtr->cxn2Net; +} + +/** + * @brief Get last frame number. + */ +inline uint32_t L2_GetLastFrameNo(L2_INST *instPtr) +{ + ASSERT(instPtr != NULL); + return instPtr->frameNo.last; +} + +/** + * @brief Get last slot number. + */ +inline uint32_t L2_GetLastSlotNo(L2_INST *instPtr) +{ + ASSERT(instPtr != NULL); + return instPtr->slotNo.last; +} + +/** + * @brief Get current frame number. + */ +inline uint32_t L2_GetCurrentFrameNo(L2_INST *instPtr) +{ + ASSERT(instPtr != NULL); + return instPtr->frameNo.curr; +} + +/** + * @brief Get current slot number. + */ +inline uint32_t L2_GetCurrentSlotNo(L2_INST *instPtr) +{ + ASSERT(instPtr != NULL); + return instPtr->slotNo.curr; +} + +/** + * @brief Get next frame number. + */ +inline uint32_t L2_GetNextFrameNo(L2_INST *instPtr) +{ + ASSERT(instPtr != NULL); + return instPtr->frameNo.next; +} +/** + * @brief Get next slot number. + */ +inline uint32_t L2_GetNextSlotNo(L2_INST *instPtr) +{ + ASSERT(instPtr != NULL); + return instPtr->slotNo.next; +} + +/*****************************************************************************/ +/** + * @brief Creat a new schedule envent, register event in schedule event pool. + * + * @param event event type of the new schedule event. + * + * @return NULL error occurred + * Pointer to schedule event. + * + ******************************************************************************/ +L2_SCHD_EVENT *L2_CreatNewSchdEvent(L2_INST *instPtr, L2_EVENT_TYPE event) +{ + ASSERT(instPtr != NULL); + L2_SCHD_EVENT *schdEventPtr = NULL; + if (instPtr->schdEventCnt >= L2_SCHD_EVENT_MAX) + { + DBG_ERROR("Schedule event number exceeds the max, no more schedule event can be created.\n"); + return NULL; + } + schdEventPtr = (L2_SCHD_EVENT *)malloc(sizeof(L2_SCHD_EVENT)); + if (schdEventPtr == NULL) + { + free(schdEventPtr); + return NULL; + } + if (event < L2_EV_SCAN_PROC_DONE || event > L2_ROUTINE_UPDATE) + { + DBG_ERROR("Unknown event type: %d.\n", event); + return NULL; + } + schdEventPtr->eventId = instPtr->schdEventCnt; + schdEventPtr->l2Event.msg = NULL; + schdEventPtr->isSchd = false; + schdEventPtr->schdSlot = L2_SLOTNO_NONE; + schdEventPtr->schdFrame = L2_FRAMENO_NONE; + instPtr->schdEventPool[instPtr->schdEventCnt] = schdEventPtr; + instPtr->schdEventCnt++; + return schdEventPtr; +} + +/*****************************************************************************/ +/** + * @brief Delete a schedule event, remove the event from event pool, + * release memory, release event ID. + * + * @param schdEvent pointer to the schedule event which is aboute to be deleted. + * + * @return SUCCESS + * error code + * + ******************************************************************************/ +int32_t L2_DeletSchdEvent(L2_INST *instPtr, L2_SCHD_EVENT *schdEvent) +{ + ASSERT(instPtr != NULL); + ASSERT(schdEvent != NULL); + free(schdEvent->l2Event.msg); + for (int32_t i = schdEvent->eventId; i < instPtr->schdEventCnt; i++) + { + if (i == instPtr->schdEventCnt - 1) + { + instPtr->schdEventPool[i] = NULL; + } + else + { + instPtr->schdEventPool[i] = instPtr->schdEventPool[i + 1]; + } + } + free(schdEvent); + instPtr->schdEventCnt--; + return SUCCESS; +} + +/*****************************************************************************/ +/** + * @brief Append extra message content to specific schedule event. + * + * @param schdEvent pointer to the schedule event. + * msg pointer to the append content. + * + * @return SUCCESS. + * error code. + * + ******************************************************************************/ +inline int32_t L2_SchdEventAppendMsg(L2_SCHD_EVENT *schdEvent, void *msg) +{ + ASSERT(schdEvent != NULL); + schdEvent->l2Event.msg = msg; + return SUCCESS; +} + +/*****************************************************************************/ +/** + * @brief Check if the event was scheduled. + * + * @param schdEvent pointer to the schedule event. + * + * @return true. + * false. + * + ******************************************************************************/ +inline bool L2_isEventScheduled(L2_SCHD_EVENT *schdEvent) +{ + ASSERT(schdEvent != NULL); + return schdEvent->isSchd; +} + +/*****************************************************************************/ +/** + * @brief Schedule a event at a specific time(indexed by frame and slot number) + * + * @param schdEvent pointer to the schedule event. + * @param frameNo schedule frame number + * @param slotNo schedule slot number + * + * @return FAILURE, event has already been scheduled/schedule time not allowed. + * SUCCESS + * + ******************************************************************************/ +int32_t L2_ScheduleEventAt(L2_INST *instPtr, L2_SCHD_EVENT *schdEvent, uint32_t frameNo, uint32_t slotNo) +{ + ASSERT(schdEvent != NULL); + if (L2_isEventScheduled(schdEvent) == true) + { + DBG_ERROR("Event %d has already been scheduled.\n", schdEvent->eventId); + return FAILURE; + } + if (frameNo <= L2_GetCurrentFrameNo(instPtr) && slotNo < L2_GetCurrentSlotNo(instPtr)) + { + DBG_ERROR("Cannot schedule event %d to the past(current: [%ld-%ld], schedule: [%lu-%lu]).\n", + schdEvent->eventId, L2_GetCurrentFrameNo(instPtr), L2_GetCurrentSlotNo(instPtr), frameNo, slotNo); + return FAILURE; + } + schdEvent->isSchd = true; + schdEvent->schdFrame = frameNo; + schdEvent->schdSlot = slotNo; + return SUCCESS; +} + +/*****************************************************************************/ +/** + * @brief Schedule a event after a specific time period. + * + * @param schdEvent pointer to the schedule event. + * @param numSlots how many slot later the event should be scheduled + * + * @return FAILURE, event has already been scheduled/schedule time not allowed. + * SUCCESS + * + ******************************************************************************/ +int32_t L2_ScheduleEventAfter(L2_INST *instPtr, L2_SCHD_EVENT *schdEvent, uint32_t numSlots) +{ + ASSERT(schdEvent != NULL); + if (L2_isEventScheduled(schdEvent) == true) + { + DBG_ERROR("Event %d has already been scheduled.\n", schdEvent->eventId); + return FAILURE; + } + uint32_t frameNo = L2_GetCurrentFrameNo(instPtr) + (numSlots / L2_SLOTS_PER_FRAME); + uint32_t slotNo = L2_GetCurrentSlotNo(instPtr) + (numSlots % L2_SLOTS_PER_FRAME); + return L2_ScheduleEventAt(instPtr, schdEvent, frameNo, slotNo); +} + +/*****************************************************************************/ +/** + * @brief Reschedule a event at a specific time(indexed by frame and slot number) + * + * @param schdEvent pointer to the schedule event. + * @param frameNo schedule frame number + * @param slotNo schedule slot number + * + * @return FAILURE, event has already been scheduled/schedule time not allowed. + * SUCCESS + * + ******************************************************************************/ +int32_t L2_RecheduleEventAt(L2_INST *instPtr, L2_SCHD_EVENT *schdEvent, uint32_t frameNo, uint32_t slotNo) +{ + ASSERT(schdEvent != NULL); + if (schdEvent->isSchd == false) + { + DBG_WARNING("Event %d has not been scheduled yet.\n", schdEvent->eventId); + } + schdEvent->isSchd = false; + return L2_ScheduleEventAt(instPtr, schdEvent, frameNo, slotNo); +} + +/*****************************************************************************/ +/** + * @brief Rechedule a event after a specific time period. + * + * @param schdEvent pointer to the schedule event. + * @param numSlots how many slot later the event should be scheduled + * + * @return FAILURE, event has already been scheduled/schedule time not allowed. + * SUCCESS + * + * @return NONE. + * + ******************************************************************************/ +int32_t L2_RecheduleEventAfter(L2_INST *instPtr, L2_SCHD_EVENT *schdEvent, uint32_t numSlots) +{ + ASSERT(schdEvent != NULL); + if (schdEvent->isSchd == false) + { + DBG_WARNING("Event %d has not been scheduled yet.\n", schdEvent->eventId); + } + return L2_ScheduleEventAfter(instPtr, schdEvent, numSlots); +} + +/*****************************************************************************/ +/** + * @brief Cancel a scheduled event. + * + * @param schdEvent pointer to the schedule event. + * + * @return SUCCESS. + * + ******************************************************************************/ +int32_t L2_CancelEvent(L2_SCHD_EVENT *schdEvent) +{ + ASSERT(schdEvent != NULL); + if (schdEvent->isSchd == false) + { + DBG_WARNING("Event %d has not been scheduled yet.\n", schdEvent->eventId); + } + schdEvent->isSchd = false; + return SUCCESS; +} + +/*****************************************************************************/ +/** + * @brief Check and excute schedule event in event pool illiterate. + * + * @param NONE. + * + * @return NONE. + * + ******************************************************************************/ +static void EventPoolHandler(L2_INST *instPtr) +{ + ASSERT(instPtr != NULL); + for (int32_t i = 0; i < instPtr->schdEventCnt; i++) + { + if (instPtr->schdEventPool[i]->isSchd == true) + { + if (instPtr->schdEventPool[i]->schdFrame == instPtr->frameNo.curr && instPtr->schdEventPool[i]->schdSlot == instPtr->slotNo.curr) + { + AssertL2Event(instPtr, &(instPtr->schdEventPool[i]->l2Event)); + } + } + } +} +/*****************************************************************************/ +/** + * @brief Shift L2 status record.(newval->next->curr->last) + * + * @param instPtr A pointer to physical layer control instance. + * + * @return NONE. + * + ******************************************************************************/ +static inline void RcdShift(L2_RCD *rcd, int32_t netxVal) +{ + ASSERT(rcd != NULL); + rcd->last = rcd->curr; + rcd->curr = rcd->next; + rcd->next = netxVal; +} + +/*****************************************************************************/ +/** + * @brief Get the valid frame data type received in last slot. + * + * @param NONE. + * + * @return NONE. + * + ******************************************************************************/ + +L2_FRAME_TYPE L2_GetLastRcvFrameType(L2_INST *instPtr) +{ + if (instPtr->dataAvail == false) + { + return L2_NONE_FRAME; + } + else + { + return instPtr->frame.last; + } +} + +/*****************************************************************************/ +/** + * @brief Update L2 frame state, check if there is any valid L2 frame data in + * data buffer, update receive frame status. + * + * @param NONE. + * + * @return NONE. + * + ******************************************************************************/ +void L2_FrameStateUpdate(L2_INST *instPtr) +{ + ASSERT(instPtr != NULL); + PHY_INST *phyRef = instPtr->config.phyInstRef; + bool isRecved, isValid; + + // Update Phisical layer state + Phy_UpdateState(instPtr->config.phyInstRef); + + // Frame types shift (last <- curr <- next) + RcdShift(&(instPtr->frame), L2_NONE_FRAME); + RcdShift(&(instPtr->torState), L2_TOR_SUSPEND); + + if (Phy_IsFrameValid(instPtr->config.phyInstRef)) + { + if (Phy_RetrieveRecvData(phyRef, instPtr->recvPktData) != SUCCESS) + { + ASSERT(false); + } + } + + // Update frame state. + switch (instPtr->frame.last) + { + case L2_SCAN_FRAME: + isRecved = Phy_IsFrameDetected(instPtr->config.phyInstRef); + isValid = isRecved; + break; + case L2_SVC_FRAME: + isRecved = Phy_IsFrameValid(instPtr->config.phyInstRef); + if (isRecved == true) + { +#ifndef DATALINK_ENABLE_BERTEST + isValid = L2_CrcCheck(instPtr->recvPktData, SVC_PACK_LEN, L2_CRC16_1021); +#else + isValid = true; +#endif + } + else + { + isValid = false; + } + break; + case L2_INFO_FRAME: + isRecved = Phy_IsFrameValid(instPtr->config.phyInstRef); + if (isRecved == true) + { + isValid = L2_CrcCheck(instPtr->recvPktData, RSP_PACK_LEN, L2_CRC16_1021); + } + else + { + isValid = false; + } + break; + default: + isRecved = false; + isValid = false; + break; + } + instPtr->recvCnt = (isRecved == true) ? instPtr->recvCnt + 1 : instPtr->recvCnt; + instPtr->recvFineCnt = (isValid == true) ? instPtr->recvFineCnt + 1 : instPtr->recvFineCnt; + DataAvailUpdate(instPtr, isValid); + if (isRecved == true) + { + DBG_INFO("Frame received type: %ld, validation: %d.\n", instPtr->frame.last, isValid); + } + // Logging status. + // -- send slot status + if (instPtr->torState.last == L2_TOR_RX) + { + instPtr->rxSlotLog.tuNo = instPtr->frameNo.last; + instPtr->rxSlotLog.slotNo = instPtr->slotNo.last; + instPtr->rxSlotLog.frameType = instPtr->frame.last; + instPtr->rxSlotLog.srcId = instPtr->config.myId; + instPtr->rxSlotLog.dstId = (instPtr->config.myType == L2_HEAD_NODE) ? L2_MEMBER_NODE_ID : L2_HEAD_NODE_ID; + // TODO: baseInfo[18]; + memset(instPtr->rxSlotLog.payload, 0x00, sizeof(instPtr->rxSlotLog.payload)); + if (isValid == true) + { + memcpy(instPtr->rxSlotLog.payload, + instPtr->recvPktData, + Phy_GetFrameLen(L2_L2frame2L1frame(instPtr->frame.last))); + instPtr->rxSlotLog.tmStamp = PhyRead(instPtr->config.phyInstRef, FSTIME_L); + instPtr->rxSlotLog.tmStamp |= ((uint64_t)PhyRead(instPtr->config.phyInstRef, FSTIME_H)) << 32; + + // Log time deviation. + int64_t devi; + devi = 0; + if (L2_TimeSync_GetDeviatoion(instPtr, &devi) == SUCCESS) + { + if (devi <= INT32_MAX && devi >= INT32_MIN) + { + instPtr->txSlotLog.tmDevi = (int32_t)devi; + } + instPtr->txSlotLog.tmDevi = (int32_t)devi; + } + // Log frequency deviation + instPtr->rxSlotLog.freqDevi = Phy_GetFreqEst(instPtr->config.phyInstRef); + } + else + { + instPtr->rxSlotLog.tmStamp = 0; + instPtr->rxSlotLog.tmDevi = 0; + instPtr->rxSlotLog.freqDevi = 0; + } + SysMonitor_UpdateRecvSlotLog(&(instPtr->rxSlotLog)); + } + // -- send slot status + if (instPtr->torState.curr == L2_TOR_TX) + { + instPtr->txSlotLog.tuNo = instPtr->frameNo.curr; + instPtr->txSlotLog.slotNo = instPtr->slotNo.curr; + instPtr->txSlotLog.frameType = instPtr->frame.curr; + instPtr->txSlotLog.srcId = instPtr->config.myId; + instPtr->txSlotLog.dstId = (instPtr->config.myType == L2_HEAD_NODE) ? L2_MEMBER_NODE_ID : L2_HEAD_NODE_ID; + // TODO: baseInfo[18]; + memset(instPtr->rxSlotLog.payload, 0x00, sizeof(instPtr->txSlotLog.payload)); + memcpy(instPtr->txSlotLog.payload, + instPtr->recvPktData, + Phy_GetFrameLen(L2_L2frame2L1frame(instPtr->frame.curr))); + instPtr->txSlotLog.tmStamp = 0; + instPtr->txSlotLog.tmDevi = 0; + instPtr->txSlotLog.freqDevi = 0; + SysMonitor_UpdateSendSlotLog(&(instPtr->txSlotLog)); + } +} + +/*****************************************************************************/ +/** + * @brief Steer antenna beam to specified node. + * + * @param instPtr a pointer to link layer descriptor instance + * @param nodeId destination node + * + * @return Corresponding frame length + * L2_FRAME_NONE_LEN if the frame type code cannot be recognized. + * + ******************************************************************************/ +// FIXME: To Complete. +int32_t L2_SteerBeam2Node(L2_INST *instPtr, uint8_t nodeId) +{ + ASSERT(instPtr != NULL); + ASSERT(instPtr->config.phyInstRef != NULL); + int32_t Status; + + COORD myPos, dstPos, beamDir; + Status = GetNodePos(instPtr->nodeInfoList, nodeId, &dstPos); + if (Status != SUCCESS) + { + DBG_ERROR("Failed to retrieve position info of node %u, remain last configuration.\n", nodeId); + return EPARAM; + } + myPos.x = instPtr->sysInfo.posX; + myPos.y = instPtr->sysInfo.posY; + myPos.z = instPtr->sysInfo.posZ; + + // TODO Check data format + EULERANGLES attitudeEuler, antAttitudeEuler; + attitudeEuler.alpha = DEG2RAD(instPtr->sysInfo.pitch); + attitudeEuler.beta = DEG2RAD(instPtr->sysInfo.yaw); + attitudeEuler.gamma = DEG2RAD(instPtr->sysInfo.roll); + + // FIXME: confirm date source. + antAttitudeEuler.alpha = DEG2RAD(0); + antAttitudeEuler.beta = DEG2RAD(0); + antAttitudeEuler.gamma = DEG2RAD(0); + + // TODO Check data format + QUATERNION attitude, antAttitude; + attitude = Quaternion_FromeEulerAngles(attitudeEuler, EULERANGLES_XYZ); + antAttitude = Quaternion_FromeEulerAngles(antAttitudeEuler, EULERANGLES_XYZ); + + // --- --- Algorithm --- --- + // TODO Check result validation + // Compute beam direction vector + beamDir = Coord_Sub(dstPos, myPos); + + // Compute antenna attitude respect to ECEF + antAttitude = Quaternion_Mult(attitude, antAttitude); + + // Convert beam direction vector to antenna coordinate + beamDir = Quaternion_Rotate(Quaternion_GeInverse(antAttitude), beamDir); + // Normalize + Coord_Normalize(&beamDir); + + double oAxis, rAxis; + oAxis = RAD2DEG(atan2(beamDir.z, beamDir.y)); + rAxis = RAD2DEG(acos(Coord_Dot(beamDir, COORD_X_AXIS))); + Status = Phy_SetBeamAngle(instPtr->config.phyInstRef, oAxis, rAxis); + return Status; +} + +/*****************************************************************************/ +/** + * @brief Layer 2 setup next slot operation, update current operating frame. + * + * @param instPtr a pointer to link layer descriptor instance + * @param txrxMode tx/rx state for next slot + * @param frameType frame type of next slot. + * + * @return Corresponding frame length + * L2_FRAME_NONE_LEN if the frame type code cannot be recognized. + * + ******************************************************************************/ +int32_t L2_SetupNextSlot(L2_INST *instPtr, L2_TOR_TYPE txrxMode, L2_FRAME_TYPE frameType) +{ + ASSERT(instPtr != NULL); + ASSERT(instPtr->config.phyInstRef != NULL); + int32_t Status = SUCCESS; + if (frameType < L2_SCAN_FRAME || frameType > L2_INFO_FRAME) + { + return FAILURE; + } +#if _DEBUG_LEVEL == 3 + char *torStr = NULL; + char *frameStr = NULL; + switch (txrxMode) + { + case L2_TOR_SUSPEND: + torStr = "SUSPEND"; + break; + case L2_TOR_TX: + torStr = "TX"; + break; + case L2_TOR_RX: + torStr = "RX"; + break; + } + switch (frameType) + { + case L2_SCAN_FRAME: + frameStr = "Scan"; + break; + case L2_SVC_FRAME: + frameStr = "Service"; + break; + case L2_INFO_FRAME: + frameStr = "Response"; + break; + default: + frameStr = "UNKNOWN Frame"; + break; + } + DBG_INFO("# Setup Next Slot # [%lu-%lu], %s, %s.\n", + instPtr->frameNo.next, + instPtr->slotNo.next, + torStr, frameStr); +#endif + instPtr->frame.next = frameType; + PHY_TOR_TYPE tor; + switch (txrxMode) + { + case L2_TOR_SUSPEND: + tor = PHY_TOR_SUSPEND; + break; + case L2_TOR_TX: + tor = PHY_TOR_TX; + break; + case L2_TOR_RX: + tor = PHY_TOR_RX; + break; + default: + DBG_ERROR("Invalid txrx mode :%d.\n", txrxMode); + return EPARAM; + } + Status = Phy_SetupNextSlot(instPtr->config.phyInstRef, tor, L2_L2frame2L1frame(frameType), instPtr->sendPktData); + if (Status != SUCCESS) + { + DBG_ERROR("Physical setup failed, with error code: %ld\n", Status); + } + return Status; +} + +/*****************************************************************************/ +/** + * @brief Get corresponding frame length in byte of L2 frame. + * + * @param l2FrameType + * + * @return Corresponding frame length + * L2_FRAME_NONE_LEN if the frame type code cannot be recognized. + * + ******************************************************************************/ +int32_t L2_GetFrameLen(L2_FRAME_TYPE l2FrameType) +{ + return Phy_GetFrameLen(L2_L2frame2L1frame(l2FrameType)); +} + +/*****************************************************************************/ +/** + * @brief Convert L2 frame type to L1 frame type + * + * @param l2Frame + * + * @return L1 frame type. + * + ******************************************************************************/ +L1_FRAME_TYPE L2_L2frame2L1frame(L2_FRAME_TYPE l2Frame) +{ + switch (l2Frame) + { + case L2_SCAN_FRAME: + return L1_2KBPS_20MS_FRAME; + case L2_SVC_FRAME: + return L1_2KBPS_100MS_FRAME; + case L2_INFO_FRAME: + return L1_2KBPS_100MS_FRAME; + default: + return L1_NONE_FRAME; + } +} +/*****************************************************************************/ +/** + * @brief Initialize link layer fsm instance, allocate memory to storage fsm + * data. Apply the default values to fsm. + * + * @param instPtr + * @param config + * + * @return SUCCESS + * Other error code. + * + ******************************************************************************/ +int32_t Linklayer_Init(L2_INST **instPtr, L2_CONFIG *config) +{ + ASSERT(instPtr != NULL); + ASSERT(config != NULL); + int32_t Status; + (*instPtr) = (L2_INST *)malloc(sizeof(L2_INST)); + if ((*instPtr) == NULL) + { + DBG_ERROR("Allocate memory for L2_InstPtr failed.\n"); + return ENOMEM; + } + memcpy(&((*instPtr)->config), config, sizeof(L2_CONFIG)); + + (*instPtr)->cxn2Net = (config->myType == L2_HEAD_NODE) ? true : false; + (*instPtr)->dataAvail = false; + (*instPtr)->frame.last = L2_NONE_FRAME; + (*instPtr)->frame.curr = L2_NONE_FRAME; + (*instPtr)->frame.next = L2_NONE_FRAME; + (*instPtr)->torState.last = L2_TOR_SUSPEND; + (*instPtr)->torState.curr = L2_TOR_SUSPEND; + (*instPtr)->torState.next = L2_TOR_SUSPEND; + (*instPtr)->rtneConfig.rtneTable = normalTable; + (*instPtr)->rtneConfig.rtnePrd = ARRAY_SIZE(normalTable) * L2_SLOTS_PER_FRAME; + (*instPtr)->rtneConfig.rtneStep = 0; + (*instPtr)->rtneConfig.last = NULL; + (*instPtr)->rtneConfig.curr = NULL; + (*instPtr)->rtneConfig.next = NULL; + (*instPtr)->mainState = INIT_STATE; + (*instPtr)->nextState = INIT_STATE; + (*instPtr)->frameNo.last = 0; + (*instPtr)->frameNo.curr = 0; + (*instPtr)->frameNo.next = 0; + (*instPtr)->slotNo.last = 0; + (*instPtr)->slotNo.curr = 0; + (*instPtr)->slotNo.next = 0; + (*instPtr)->schdEventCnt = 0; + (*instPtr)->nodeInfoList = NULL; + (*instPtr)->txQueue = NULL; + + (*instPtr)->recvCnt = 0; + (*instPtr)->recvFineCnt = 0; + (*instPtr)->sentCnt = 0; + + memset((*instPtr)->schdEventPool, 0x00, sizeof(L2_SCHD_EVENT *) * L2_SCHD_EVENT_MAX); + + (*instPtr)->sendPktData = malloc(PACK_LEN_MAX * sizeof(uint8_t)); + if ((*instPtr)->sendPktData == NULL) + { + DBG_ERROR("Failed to allocate memory for sendPktData.\n"); + goto init_error; + } + + (*instPtr)->recvPktData = malloc(PACK_LEN_MAX * sizeof(uint8_t)); + if ((*instPtr)->recvPktData == NULL) + { + DBG_ERROR("Failed to allocate memory for recvPktData.\n"); + goto init_error; + } + + Status = NodeList_Init(&((*instPtr)->nodeInfoList)); + if (Status != SUCCESS) + { + goto init_error; + } + + Status = L2_Scan_Init(*instPtr); + if (Status != SUCCESS) + { + goto init_error; + } + + Status = L2_Service_Init(*instPtr); + if (Status != SUCCESS) + { + goto init_error; + } + + if (CircQueueCreate(&((*instPtr)->txQueue), TX_QUEUE_MAX) == false) + { + Status = ENOMEM; + goto init_error; + } + return SUCCESS; +init_error: + free((*instPtr)->recvPktData); + free((*instPtr)->sendPktData); + NodeList_Destroy((*instPtr)->nodeInfoList); + free(*instPtr); + return Status; +} + +/*****************************************************************************/ +/** + * @brief Handle l2 event called by other model. + * + * @param instPtr + * @param l2Event + * + * @return SUCCESS - Event has been successfully handled. + * FAIL - Event cannot be recognized or error occurred while process. + * + ******************************************************************************/ +int32_t Linklayer_EventHandler(L2_INST *instPtr, L2_EVENT *l2Event) +{ + switch (l2Event->event) + { + case L2_EV_FRAME_NO_UPDATE: + { + DBG_INFO("Event L2_EV_FRAME_NO_UPDATE asserted....\n"); + FrameNoUpdate(instPtr, *((uint32_t *)l2Event->msg)); + break; + } + case L2_EV_SLOT_NO_UPDATE: + { + DBG_INFO("Event L2_EV_SLOT_NO_UPDATE asserted....\n"); + SlotNoUpdate(instPtr, *((uint32_t *)l2Event->msg)); + break; + } + case L2_EV_MAIN_STATE_UPDATE: + { + DBG_INFO("Event L2_EV_MAIN_STATE_UPDATE asserted....\n"); + UpdateMainSate(instPtr, *((L2_NODE_STATE *)l2Event->msg)); + break; + } + case L2_EV_SCAN_PROC_DONE: + { + DBG_INFO("Event L2_EV_SCAN_PROC_DONE asserted....\n"); + break; + } + case L2_EV_NET_SETUP_DONE: + { + DBG_INFO("Event L2_EV_NET_SETUP_DONE asserted....\n"); + if (instPtr->config.myType != L2_HEAD_NODE) + { + instPtr->cxn2Net = true; + UpdateMainSate(instPtr, NORMAL_STATE); + } + else + { + ForceUpdateMainSate(instPtr, NORMAL_STATE); + } + + break; + } + case L2_EV_TIME_SYNC: + { + DBG_INFO("Event L2_EV_TIME_SYNC asserted....\n"); +#ifndef DATALINK_ENABLE_AUTOTIMESYNC + int64_t tmAdj; + tmAdj = *((int64_t *)l2Event->msg); + DBG_INFO("Time adjustment is: %lld.\n", tmAdj); + L2_TimeSync_LocalTimerAdd(instPtr, tmAdj); +#else + DBG_INFO("Using auto slot alignment.\n"); + L2_TimeSync_SlotAlign(instPtr); +#endif + break; + } + case L2_EV_LOST_CXN: + { + DBG_INFO("Event L2_EV_LOST_CXN asserted....\n"); + if (instPtr->config.myType == L2_HEAD_NODE) + { + DBG_ERROR("Illegal event, only None_Head node can assert L2_EV_LOST_CXN.\n"); + break; + } + DBG_WARNING("Lost connection with head node [%d].\n", instPtr->config.headId); + L2_Scan_Init(instPtr); + L2_Service_Init(instPtr); + SlotNoUpdate(instPtr, 0); + FrameNoUpdate(instPtr, 0); + instPtr->cxn2Net = false; + UpdateMainSate(instPtr, INIT_STATE); + break; + } + case L2_EV_LOST_NODE: + { + DBG_INFO("Event L2_EV_LOST_NODE asserted....\n"); + L2_Scan_Init(instPtr); + L2_Service_Init(instPtr); + SlotNoUpdate(instPtr, 0); + FrameNoUpdate(instPtr, 0); + UpdateMainSate(instPtr, INIT_STATE); + break; + } + case L2_ROUTINE_FINISH: + { + DBG_INFO("Event L2_ROUTINE_FINISH asserted....\n"); + if (instPtr->nextState == NORMAL_STATE) + { + instPtr->rtneConfig.rtneTable = normalTable; + instPtr->rtneConfig.rtnePrd = ARRAY_SIZE(normalTable) * L2_SLOTS_PER_FRAME; + instPtr->rtneConfig.rtneStep = 0; + } + else + { + DBG_WARNING("Unsupported routine state [%d], Continue withe previous routine table.\n", instPtr->nextState); + instPtr->rtneConfig.rtneStep = 0; + } + break; + } + case L2_ROUTINE_UPDATE: + { + DBG_INFO("Event L2_ROUTINE_UPDATE asserted....\n"); + L2_RTNE_CONFIG *newRtneConfig = (L2_RTNE_CONFIG *)l2Event->msg; + instPtr->rtneConfig.rtneTable = newRtneConfig->rtneTable; + instPtr->rtneConfig.rtnePrd = newRtneConfig->rtnePrd; + instPtr->rtneConfig.rtneStep = newRtneConfig->rtneStep; + break; + } + default: + { + DBG_WARNING("UNKNOWN Event %d asserted.\n", l2Event->event); + break; + } + } + return SUCCESS; +} + +/*****************************************************************************/ +/** + * @brief Handle l2 packet correctly received. + * + * @param instPtr + * + * @return Status code. + * + ******************************************************************************/ +int32_t Linklayer_PktHandler(L2_INST *instPtr) +{ + int32_t Status; + L2_FRAME_TYPE frameType; + frameType = L2_GetLastRcvFrameType(instPtr); + DBG_INFO("Link layer handling packet, type: %ld.\n", frameType); + if (instPtr->dataAvail == false) + { + return FAILURE; + } + switch (frameType) + { + case L2_SCAN_FRAME: + Status = L2_Scan_PktHandler(instPtr, instPtr->recvPktData); + break; + case L2_SVC_FRAME: + Status = L2_Service_PktHandler(instPtr, instPtr->recvPktData); + break; + case L2_INFO_FRAME: + if (instPtr->mainState == INIT_STATE) + { + Status = L2_Scan_PktHandler(instPtr, instPtr->recvPktData); + } + else + { // NORMAL_STATE + Status = L2_Service_PktHandler(instPtr, instPtr->recvPktData); + } + break; + default: + DBG_WARNING("L2FrameHandler: UNKNOWN L2-FrameType %d", frameType); + Status = FAILURE; + break; + } + return Status; +} + +static int32_t IntcNodeTTL(NODE_ENTRY *node, const void *param) +{ + if (node == NULL) + { + return FAILURE; + } + node->ttlCnt += *((uint32_t *)param); + return SUCCESS; +} + +static bool IsNodeConnected(NODE_ENTRY *node) +{ + if (node == NULL) + { + return false; + } + DBG_INFO("Node: %u, TTL: %lu.\n", node->nodeInfo.nodeId, node->ttlCnt); + if (node->ttlCnt < LINK_BROCK_THRESHOLD) + { + return true; + } + else + { + DBG_WARNING("Lost Connection to NODE %u.\n", node->nodeInfo.nodeId); + return false; + } +} +/*****************************************************************************/ +/** + * @brief Schedule next slot based on time allocate slice. + * + * @param instPtr. + * + * @return SUCCESS + * Other error code. + * + ******************************************************************************/ +static int32_t Linklayer_Routine(L2_INST *instPtr) +{ + ASSERT(instPtr != NULL); + uint32_t usedSlots, tableIndx, entryIndx; + L2_RTNE_TABLE_ENTRY rtneEntry; + + // Determine which routine entry is going to be performed. + tableIndx = (instPtr->rtneConfig.rtneStep) / L2_SLOTS_PER_FRAME; + entryIndx = (instPtr->rtneConfig.rtneStep) % L2_SLOTS_PER_FRAME; + + // Shift routine entry record. + instPtr->rtneConfig.last = instPtr->rtneConfig.curr; + instPtr->rtneConfig.curr = instPtr->rtneConfig.next; + instPtr->rtneConfig.next = &(instPtr->rtneConfig.rtneTable[tableIndx][entryIndx]); + rtneEntry = instPtr->rtneConfig.rtneTable[tableIndx][entryIndx]; + + switch (rtneEntry.slotType) + { + case L2_SLOT_IDLE: + // Skip a 5ms slot. + usedSlots = NUM_SLOTS_5MS; + Phy_SetupNextSlot(instPtr->config.phyInstRef, L2_TOR_SUSPEND, L1_NONE_FRAME, NULL); + break; + case L2_SLOT_SCAN: + usedSlots = L2_Scan_Routine(instPtr, &rtneEntry); + break; + case L2_SLOT_SERVICE ... L2_SLOT_ADVERTISE: + usedSlots = L2_Service_Routine(instPtr, &rtneEntry); + break; + default: + DBG_ERROR("UNKNOWN slot type [%d].\n", rtneEntry.slotType); + return NUM_SLOTS_NONE; + } + DBG_INFO("## Used slots: %lu, step: %lu, period: %lu.\n", usedSlots, instPtr->rtneConfig.rtneStep, instPtr->rtneConfig.rtnePrd); + + instPtr->rtneConfig.rtneStep += usedSlots; + // check if routine is finished. + if (instPtr->rtneConfig.rtneStep >= instPtr->rtneConfig.rtnePrd) + { + L2_EVENT rtneFinishEvent = {L2_ROUTINE_FINISH, &(instPtr->rtneConfig)}; + AssertL2Event(instPtr, &rtneFinishEvent); + } + + // Update TTL + IterEditNode(instPtr->nodeInfoList, &usedSlots, IntcNodeTTL); + +#ifdef DATALINK_ENABLE_AUTORECONNECT + IterDeleteNode(instPtr->nodeInfoList, IsNodeConnected); + if (GetNodeNum(instPtr->nodeInfoList) < instPtr->config.netScale - 1) + { + // reset scan process + L2_EVENT l2Event; + // Assert Net-Setup Done. + l2Event.event = (instPtr->config.myType == L2_HEAD_NODE) ? L2_EV_LOST_NODE : L2_EV_LOST_CXN; + l2Event.msg = NULL; + AssertL2Event(instPtr, &l2Event); + usedSlots = 0; // Stop scheduling + } +#endif + + return usedSlots; +} + +/*****************************************************************************/ +/** + * @brief Execute a link layer fsm process. + * + * @param instPtr. + * + * @return SUCCESS + * Other error code. + * + ******************************************************************************/ +int32_t Linklayer_Proc(L2_INST *instPtr) +{ + ASSERT(instPtr != NULL); + ASSERT(instPtr->config.myType != L2_NONE_TYPE); + uint32_t usedSlots = 0; + DBG_PRINT("######## LinkLlayer Procedure ########\n"); + // Sync System info + SysMonitor_GetSysinfo(&(instPtr->sysInfo)); + + // Update frame status. + L2_FrameStateUpdate(instPtr); + + // Handle frame received in last slot. + if (L2_isDataAvail(instPtr) == true) + { + if (Linklayer_PktHandler(instPtr) != SUCCESS) + { + DBG_ERROR("Failed to handle last received frame: %ld.\n", instPtr->frame.last); + } + } + + // Run Link layer routine, setup next slot procedure. + if (instPtr->mainState == INIT_STATE) + { + usedSlots = L2_Scan_Proc(instPtr); + } + else + { + usedSlots = Linklayer_Routine(instPtr); + } + + // Check if previous runs has error occurred. + if (usedSlots == NUM_SLOTS_NONE) + { + return FAILURE; + } + + // Check and execute scheduled event. + EventPoolHandler(instPtr); + + // Update Protocol log + instPtr->prtcLog.tmSys = instPtr->frameNo.last * L2_SLOTS_PER_FRAME + instPtr->slotNo.last; + instPtr->prtcLog.phySt = 0; // TODO: Update physical state. + instPtr->prtcLog.tmLocal = PhyRead(instPtr->config.phyInstRef, TM_LOCAL_L) >> 16; // 2^16 clk per LSB + instPtr->prtcLog.tmLocal |= PhyRead(instPtr->config.phyInstRef, TM_LOCAL_H); + instPtr->prtcLog.beamNo = instPtr->config.phyInstRef->beamNo.last; + instPtr->prtcLog.beamNo = instPtr->config.phyInstRef->beamWd.last; + instPtr->prtcLog.stage = instPtr->mainState; + instPtr->prtcLog.recvCnt = instPtr->recvCnt; + instPtr->prtcLog.recvFineCnt = instPtr->recvFineCnt; + instPtr->prtcLog.nodeCnt = instPtr->mainState; + instPtr->prtcLog.myId = instPtr->config.myId; + instPtr->prtcLog.myId = (instPtr->config.myType == L2_HEAD_NODE) ? L2_MEMBER_NODE_ID : L2_HEAD_NODE_ID; + SysMonitor_UpdateProtocolLog(&(instPtr->prtcLog)); + + // Update slot number. + RcdShift(&(instPtr->frameNo), instPtr->frameNo.next); + RcdShift(&(instPtr->slotNo), instPtr->slotNo.next); + + // Update slot number. + instPtr->slotNo.next += usedSlots; + if (instPtr->slotNo.next >= L2_SLOTS_PER_FRAME) + { // a time frame ended + instPtr->frameNo.next = (instPtr->frameNo.next + 1) % L2_FRAME_NO_MAX; + } + instPtr->slotNo.next %= L2_SLOTS_PER_FRAME; + // update link layer state. + instPtr->mainState = instPtr->nextState; + return SUCCESS; +} diff --git a/df_datalink_sp/src/networking/link_layer/link_layer.h b/df_datalink_sp/src/networking/link_layer/link_layer.h new file mode 100644 index 0000000..7380f0d --- /dev/null +++ b/df_datalink_sp/src/networking/link_layer/link_layer.h @@ -0,0 +1,145 @@ +/*****************************************************************************/ +/** + * Description: Header file for df linklayer functions + * + * Date: 2021-11-13 13:33 + * LastEditTime: 2022-07-16 10:12 + * Revisions: Rev 0.1 + * History: + * [2022-07-16]: New branch for DiJian. + * [2021-11-23]: Initial version. + * + * Copyright(c) 2021 Beijing Institute of Technology. + * Lab of Communication and Networking + * + ******************************************************************************/ + +#ifndef __LINK_LAYER_H_ +#define __LINK_LAYER_H_ + +/***************************** Include Files *********************************/ +#include +#include "circ_queue.h" +#include "link_layer_types.h" +#include "../phy_layer/phy_layer.h" +#include "../../system_monitor.h" +#include "../config/app_config.h" +#include "node_list.h" +/************************** Constant Definitions *****************************/ +#define L2_HEAD_NODE_ID 1 +#define L2_MEMBER_NODE_ID 2 +/***************** Macros (Inline Functions) Definitions *********************/ +// #define AssertL2Event(inst, event) Linklayer_EventHandler(inst, event) +/**************************** Type Definitions *******************************/ + +typedef struct +{ + L2_RTNE_TABLE_ENTRY **rtneTable; + uint32_t rtnePrd; + uint32_t rtneStep; + L2_RTNE_TABLE_ENTRY *last; + L2_RTNE_TABLE_ENTRY *curr; + L2_RTNE_TABLE_ENTRY *next; +} L2_RTNE_CONFIG; + +typedef struct +{ + L2_NODE_TYPE myType; + // bool isInterHead; + // uint8_t clustId; + uint8_t myId; + uint8_t headId; + // uint8_t bkpHeadId; + uint8_t netScale; + PHY_INST *phyInstRef; // pyhsical layer reference +} L2_CONFIG; + +typedef struct +{ + L2_CONFIG config; + bool dataAvail; // if there is a valid received frame data in rx buffer + bool cxn2Net; // if the node is connected to the network + L2_RCD frameNo; // stores the last current and next frame number. + L2_RCD slotNo; // stores the last current and next slot number. + L2_RCD frame; // stores the last current and next link layer frame type. + L2_RCD torState; // stores the last current and next link layer send/receive state. + L2_NODE_STATE mainState; // the main state of link layer state + L2_NODE_STATE nextState; // next state of link layer state, which will be applied to mainState every second. + L2_RTNE_CONFIG rtneConfig; // current routine table configuration and status. + L2_SCHD_EVENT *schdEventPool[L2_SCHD_EVENT_MAX]; + uint32_t schdEventCnt; + SCAN_FSM scanFsm; + SVC_FSM serviceFsm; + NODE_LIST *nodeInfoList; + uint8_t *sendPktData; + uint8_t *recvPktData; + // for system log + SYSINFO sysInfo; + SLOTLOG txSlotLog; + SLOTLOG rxSlotLog; + PRTCLLOG prtcLog; + CIRC_QUEUE *txQueue; + // for debug + uint32_t recvCnt; + uint32_t recvFineCnt; + uint32_t sentCnt; +} L2_INST; + +/************************** Variable Definitions *****************************/ +extern L2_RTNE_TABLE_ENTRY *normalTable[L2_RTNE_PERIOD]; +/************************** Function Prototypes ******************************/ +// Main +int32_t Linklayer_Init(L2_INST **instPtr, L2_CONFIG *config); +int32_t Linklayer_Proc(L2_INST *instPtr); +int32_t Linklayer_EventHandler(L2_INST *instPtr, L2_EVENT *l2Event); +int32_t Linklayer_PktHandler(L2_INST *instPtr); +int32_t L2_SteerBeam2Node(L2_INST *instPtr, uint8_t nodeId); +int32_t L2_SetupNextSlot(L2_INST *instPtr, L2_TOR_TYPE txrxMode, L2_FRAME_TYPE frameType); + +// Event +L2_SCHD_EVENT *L2_CreatNewSchdEvent(L2_INST *instPtr, L2_EVENT_TYPE event); +bool L2_isEventScheduled(L2_SCHD_EVENT *schdEvent); +int32_t L2_CancelEvent(L2_SCHD_EVENT *schdEvent); +int32_t L2_SchdEventAppendMsg(L2_SCHD_EVENT *schdEvent, void *msg); +int32_t L2_ScheduleEventAt(L2_INST *instPtr, L2_SCHD_EVENT *schdEvent, uint32_t frameNo, uint32_t slotNo); +int32_t L2_ScheduleEventAfter(L2_INST *instPtr, L2_SCHD_EVENT *schdEvent, uint32_t numSlots); +int32_t L2_RecheduleEventAt(L2_INST *instPtr, L2_SCHD_EVENT *schdEvent, uint32_t frameNo, uint32_t slotNo); +int32_t L2_RecheduleEventAfter(L2_INST *instPtr, L2_SCHD_EVENT *schdEvent, uint32_t numSlots); + +// Framing +void L2_FrameStateUpdate(L2_INST *instPtr); +L2_FRAME_TYPE L2_GetLastRcvFrameType(L2_INST *instPtr); +L1_FRAME_TYPE L2_L2frame2L1frame(L2_FRAME_TYPE l2Frame); +int32_t L2_CrcAppend(uint8_t *dataBuff, uint32_t dataLen, uint32_t crcPos, L2_CRC_TYPE crcType); +bool L2_CrcCheck(uint8_t *dataBuff, uint32_t dataLen, L2_CRC_TYPE crcType); + +// Miscellaneous +L2_NODE_STATE L2_GetMainState(L2_INST *instPtr); +bool L2_isDataAvail(L2_INST *instPtr); +bool L2_isCxn2Net(L2_INST *instPtr); +int32_t L2_GetFrameLen(L2_FRAME_TYPE l2FrameType); +uint32_t L2_GetLastFrameNo(L2_INST *instPtr); +uint32_t L2_GetLastSlotNo(L2_INST *instPtr); +uint32_t L2_GetCurrentFrameNo(L2_INST *instPtr); +uint32_t L2_GetCurrentSlotNo(L2_INST *instPtr); +uint32_t L2_GetNextFrameNo(L2_INST *instPtr); +uint32_t L2_GetNextSlotNo(L2_INST *instPtr); + +// Scanning +int32_t L2_Scan_Init(L2_INST *instPtr); +int32_t L2_Scan_PktHandler(L2_INST *instPtr, uint8_t *msg); +int32_t L2_Scan_Proc(L2_INST *instPtr); +int32_t L2_Scan_Routine(L2_INST *instPtr, L2_RTNE_TABLE_ENTRY *schedEntry); + +// Service +int32_t L2_Service_Init(L2_INST *instPtr); +int32_t L2_Service_PktHandler(L2_INST *instPtr, uint8_t *msg); +int32_t L2_Service_Proc(L2_INST *instPtr); +int32_t L2_Service_Routine(L2_INST *instPtr, L2_RTNE_TABLE_ENTRY *schedEntry); + +// Time Sync +int32_t L2_TimeSync_LocalTimerAdd(L2_INST *instPtr, int64_t adjustment); +int32_t L2_TimeSync_SlotAlign(L2_INST *instPtr); +int32_t L2_TimeSync_GetDeviatoion(L2_INST *instPtr, int64_t *devi); + +#endif /* __LINK_LAYER_H_ */ diff --git a/df_datalink_sp/src/networking/link_layer/link_layer_types.h b/df_datalink_sp/src/networking/link_layer/link_layer_types.h new file mode 100644 index 0000000..cbe1014 --- /dev/null +++ b/df_datalink_sp/src/networking/link_layer/link_layer_types.h @@ -0,0 +1,212 @@ +/*****************************************************************************/ +/** + * Description: A brief description of this file + * + * Date: 2022-08-28 22:53 + * LastEditTime: 2022-08-29 00:45 + * Revisions: Rev 0.0 + * History: + * [2022-08-29]: Initial version. + * + * Copyright(c) 2022 Beijing Institute of Technology. + * Lab of Communication and Networking + * + ******************************************************************************/ + +#ifndef __LINK_LAYER_DEF_H_ +#define __LINK_LAYER_DEF_H_ + +/***************************** Include Files *********************************/ +#include +#include +#include "geometry/coord.h" +#include "geometry/eulerangles.h" +#include "geometry/quaternion.h" +#include "../config/app_config.h" +#include "../phy_layer/phy_layer.h" +/************************** Constant Definitions *****************************/ +// Common node ID definition +#define BROADCAST_ID 0xFF + +// Routine configure +#define L2_RTNE_PERIOD 60 + +// Common slot number definition +#define L2_SLOTNO_NONE 0 +#define L2_FRAMENO_NONE 0 + +// Common number of slots definition +#define L2_FRAME_NO_MAX 256 +#define L2_SLOTS_PER_FRAME 200 +#define L2_SLOTS_PER_SUBFRAME 20 + +#define NUM_SLOTS_NONE UINT32_MAX +#define NUM_SLOTS_100MS 20 +#define NUM_SLOTS_20MS 4 +#define NUM_SLOTS_10MS 2 +#define NUM_SLOTS_5MS 1 +#define NUM_SLOTS_SKIP 0 + +// Common schedule event definition +#define L2_SCHD_EVENT_MAX 16 + +/***************** Macros (Inline Functions) Definitions *********************/ +#define AssertL2Event(inst, envent) Linklayer_EventHandler(inst, envent) +/**************************** Type Definitions *******************************/ + +typedef struct +{ + int32_t last; + int32_t curr; + int32_t next; +} L2_RCD; + +typedef enum +{ + L2_TOR_SUSPEND = 0, + L2_TOR_TX = 1, + L2_TOR_RX = 2 +} L2_TOR_TYPE; + +/** @name Prior information type definition + */ +typedef enum +{ + L2_NONE_TYPE = 0, + L2_HEAD_NODE = 1, + L2_MEMBER_NODE = 2, + L2_BACKUP_HEAD = 3 +} L2_NODE_TYPE; +/** @name Node state type definition + */ + +typedef enum +{ + NONE_STATE = 0, + INIT_STATE = 1, + NORMAL_STATE = 2 +} L2_NODE_STATE; + +/** @name Node information type definition + * The following types define the detail node info which needed by the link layer. + */ +typedef struct +{ + uint8_t nodeId; + uint8_t nodeType; + uint8_t beamNo; + COORD pos; + COORD speed; + QUATERNION attitude; +} L2_NODE_INFO; + +/** @name L2 event enum + * A enum of L2 event types. + */ +typedef enum +{ + L2_EV_NONE = 0, + L2_EV_SCAN_PROC_DONE = 1, + L2_EV_NET_SETUP_DONE = 2, + L2_EV_TIME_SYNC = 3, + L2_EV_LOST_CXN = 4, + L2_EV_LOST_NODE = 5, + L2_EV_FRAME_NO_UPDATE = 6, + L2_EV_SLOT_NO_UPDATE = 7, + L2_EV_MAIN_STATE_UPDATE = 8, + L2_ROUTINE_FINISH = 9, + L2_ROUTINE_UPDATE = 10 +} L2_EVENT_TYPE; + +/** @name L2 event + * A definition of L2 event instance. + */ +typedef struct +{ + L2_EVENT_TYPE event; + void *msg; +} L2_EVENT; + +/** @name L2 event + * A definition of L2 event instance. + */ +typedef struct +{ + uint8_t eventId; + bool isSchd; + L2_EVENT l2Event; + uint32_t schdFrame; + uint32_t schdSlot; +} L2_SCHD_EVENT; + +/** @name Slot types + * A definition of different slots. + */ +typedef enum +{ + L2_SLOT_NONE = 0, + L2_SLOT_IDLE = 1, + L2_SLOT_SCAN = 2, + L2_SLOT_SERVICE = 3, + L2_SLOT_ADVERTISE = 4, +} L2_SLOT_TYPE; + +/** @name Frame types + * A definition of different frame types. + */ +typedef enum +{ + L2_NONE_FRAME = 0, + L2_SCAN_FRAME = 1, + L2_SVC_FRAME = 2, + L2_INFO_FRAME = 3 +} L2_FRAME_TYPE; + +/** @name Frame types + * A definition of different frame types. + */ +typedef enum +{ + L2_CRC_NONE = 0, + L2_CRC16_1021 = 1, + L2_CRC16_8005 = 2, + L2_CRC8_31 = 3 +} L2_CRC_TYPE; + +/** @name Schedule subtable entry + * A definition of Schedule subtable entry. + */ +typedef struct +{ + L2_SLOT_TYPE slotType : 8; + uint8_t slotSeq; + uint8_t src; + uint8_t dst; +} L2_RTNE_TABLE_ENTRY; + +/** @name Scan procedure FSM + */ +typedef struct +{ + uint8_t sacanCnt; + uint8_t beamNo; +} SCAN_FSM; + +/** @name Service procedure FSM + */ +typedef struct +{ + uint32_t txSeqNum; + uint32_t rxSeqNum; + uint8_t rxLog[256]; + uint8_t txLog[256]; + uint32_t pktRecv; + uint32_t pktRecved; +#ifdef DATALINK_ENABLE_BERTEST + uint32_t bitTotal; + uint32_t bitError; +#endif +} SVC_FSM; +/************************** Variable Definitions *****************************/ + +#endif /* __LINK_LAYER_DEF_H_ */ diff --git a/df_datalink_sp/src/networking/link_layer/msg_def.h b/df_datalink_sp/src/networking/link_layer/msg_def.h new file mode 100644 index 0000000..007500d --- /dev/null +++ b/df_datalink_sp/src/networking/link_layer/msg_def.h @@ -0,0 +1,68 @@ +/*****************************************************************************/ +/** + * Description: Header of 814 linklayer messages + * + * Date: 2022-07-14 00:08 + * LastEditTime: 2022-07-14 22:52 + * Revisions: Rev 0.0 + * History: + * [2022-07-14]: Initial version. + * + * Copyright(c) 2021 Beijing Institute of Technology. + * Lab of Communication and Networking + * + ******************************************************************************/ +#ifndef __L2_MSG_DEF_H_ +#define __L2_MSG_DEF_H_ + +#define PACK_LEN_MAX 512 + +#define SVC_PACK_LEN 30 // bytes(240 bits) +#define RSP_PACK_LEN 30 // bytes(240 bits) + +// Common structure: +// [bytes] [name] +// 1 fame number +// 1 slot number +// 26 payload +// 2 crc +#define L2_MSG_FRAME_NO 0 +#define L2_MSG_SLOT_NO 1 +#define L2_MSG_PAYLOAD 2 +#define L2_MSG_CRC 28 + +// service frame structure: +// [bytes] [name] +// 1 fame number +// 1 slot number +// 3 time sync +// 23 payload +// 2 crc +#define L2_MSG_SVC_TMSYNC 2 +#define L2_MSG_SVC_TMSYNC_LEN 3 +#define L2_MSG_SVC_TMSYNC_MAX (8388607) // 0x007FFFFF +#define L2_MSG_SVC_TMSYNC_MIN (-8388608) // 0x00800000 +#define L2_MSG_SVC_SEQ_ID 5 +#define L2_MSG_SVC_PAYLOAD 6 +#define L2_MSG_SVC_PAYLOAD_LEN 22 + +// response frame structure: +// [bytes] [name] +// 1 fame number +// 1 slot number +// 4 position x +// 4 position y +// 4 position z +// 4 speed x +// 4 speed y +// 4 speed z +// 2 dummy +// 2 crc +#define L2_MSG_INFO_POSX 2 +#define L2_MSG_INFO_POSY 6 +#define L2_MSG_INFO_POSZ 10 +#define L2_MSG_INFO_SPEEDX 14 +#define L2_MSG_INFO_SPEEDY 18 +#define L2_MSG_INFO_SPEEDZ 22 +#define L2_MSG_INFO_DUMMY 26 +#endif //__L2_MSG_DEF_H_ diff --git a/df_datalink_sp/src/networking/link_layer/node_list.c b/df_datalink_sp/src/networking/link_layer/node_list.c new file mode 100644 index 0000000..987e0fc --- /dev/null +++ b/df_datalink_sp/src/networking/link_layer/node_list.c @@ -0,0 +1,527 @@ +/*****************************************************************************/ +/** + * Description: Implementations of df linklayer local record. + * + * Date: 2022-07-14 00:08 + * LastEditTime: 2022-07-14 22:52 + * Revisions: Rev 0.0 + * History: + * [2022-07-14]: Initial version. + * + * Copyright(c) 2021 Beijing Institute of Technology. + * Lab of Communication and Networking + * + ******************************************************************************/ + +/***************************** Include Files *********************************/ +#include "common.h" +#include "error.h" +#include "link_layer.h" +#include "link_layer_types.h" +#include "node_list.h" + +/************************** Constant Definitions *****************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ +inline int32_t GetNodeNum(NODE_LIST *list) +{ + ASSERT(list != NULL); + return list->nodeNum; +} +/**************************** Type Definitions *******************************/ + +/************************** Variable Definitions *****************************/ + +/************************** Function Prototypes ******************************/ + +/*****************************************************************************/ +/** + * @brief Initialize node list + * + * @param list + * + * @return SUCCESS + * ENOMEM - not enough memory. + * + ******************************************************************************/ +int32_t NodeList_Init(NODE_LIST **list) +{ + NODE_ENTRY *entry; + (*list) = malloc(sizeof(NODE_LIST)); + if (*list == NULL) + { + return ENOMEM; + } + entry = malloc(sizeof(NODE_ENTRY)); + if (entry == NULL) + { + free(*list); + return ENOMEM; + } + entry->nodeInfo.nodeId = 0; + entry->nextNode = entry; + entry->preNode = entry; + (*list)->head = entry; + (*list)->nodeNum = 0; + return SUCCESS; +} + +void NodeList_Clear(NODE_LIST *list) +{ + ASSERT(list != NULL); + NODE_ENTRY *nodeEntry, *deletEntry; + nodeEntry = list->head->nextNode; + while (nodeEntry != list->head) + { + deletEntry = nodeEntry; + nodeEntry = nodeEntry->nextNode; + deletEntry->preNode->nextNode = deletEntry->nextNode; + deletEntry->nextNode->preNode = deletEntry->preNode; + DBG_INFO("Deleting node [%d].\n", deletEntry->nodeInfo.nodeId); + free(deletEntry); + list->nodeNum--; + } +} + +void NodeList_Destroy(NODE_LIST *list) +{ + if (list == NULL) + { + return; + } + NodeList_Clear(list); + free(list->head); + free(list); +} + +/*****************************************************************************/ +/** + * @brief Get node entry frome node list base on node id. + * + * @param list + * @param nodeId + * + * @return Node entry + * NULL if node dose not exist. + * + ******************************************************************************/ +NODE_ENTRY *GetNode(NODE_LIST *list, uint32_t nodeId) +{ + ASSERT(list != NULL); + NODE_ENTRY *nodeEntry = list->head->nextNode; + while (nodeEntry != list->head) + { + if (nodeEntry->nodeInfo.nodeId == nodeId) + { + break; + } + else + { + nodeEntry = nodeEntry->nextNode; + } + } + if (nodeEntry == list->head) + { + return NULL; + } + else + { + return nodeEntry; + } +} + +/*****************************************************************************/ +/** + * @brief Check whether the node is already in the node list. + * + * @param list + * @param nodeId + * + * @return true node in the list + * false node not in the list + * + ******************************************************************************/ +inline bool IsNodeInList(NODE_LIST *list, uint8_t nodeId) +{ + ASSERT(list != NULL); + return (GetNode(list, nodeId) != NULL); +} + +/*****************************************************************************/ +/** + * @brief Append a new node entry to the node list + * + * @param list + * @param nodeId + * @param nodeType + * + * @return SUCCESS Node was added successfully. + * Other Error occurred.(Node already exist, memory alloc error ect.) + * + ******************************************************************************/ +int32_t AppendNode(NODE_LIST *list, uint8_t nodeId, L2_NODE_TYPE nodeType) +{ + ASSERT(list != NULL); + if (IsNodeInList(list, nodeId)) + { + DBG_WARNING("Node [%d] already exist.\n", nodeId); + return FAILURE; + } + DBG_INFO("Link layer appending node [%d] to node list.\n", nodeId); + NODE_ENTRY *nodeEntry = (NODE_ENTRY *)malloc(sizeof(NODE_ENTRY)); + if (nodeEntry == NULL) + { + return ENOMEM; + } + nodeEntry->nodeInfo.nodeId = nodeId; + nodeEntry->nodeInfo.nodeType = (uint8_t)nodeType; + nodeEntry->nodeInfo.pos.x = 0; + nodeEntry->nodeInfo.pos.y = 0; + nodeEntry->nodeInfo.pos.z = 0; + nodeEntry->nodeInfo.speed.x = 0; + nodeEntry->nodeInfo.speed.y = 0; + nodeEntry->nodeInfo.speed.z = 0; + nodeEntry->nodeInfo.beamNo = 0; + nodeEntry->ttlCnt = 0; + + nodeEntry->nextNode = list->head; + nodeEntry->preNode = list->head->nextNode; + list->head->nextNode = nodeEntry; + + list->nodeNum++; + return SUCCESS; +} + +/*****************************************************************************/ +/** + * @brief Delete a node in list based on node id. + * + * @param list + * @param nodeId + * + * @return SUCCESS Node has been successfully deleted. + * Other Node not exist. + * + ******************************************************************************/ +int32_t DeletNode(NODE_LIST *list, uint8_t nodeId) +{ + ASSERT(list != NULL); + NODE_ENTRY *nodeEntry = GetNode(list, nodeId); + if (nodeEntry == NULL) + { + DBG_WARNING("Node [%d] in not in node list, skip deleting process.\n", nodeId); + return SUCCESS; + } + nodeEntry->preNode->nextNode = nodeEntry->nextNode; + nodeEntry->nextNode->preNode = nodeEntry->preNode; + DBG_INFO("Deleting node [%d].\n", nodeId); + free(nodeEntry); + list->nodeNum--; + return SUCCESS; +} + +/*****************************************************************************/ +/** + * @brief Get the distance between me and the node. + * + * @param list + * @param nodeId + * @param dst A pointer to store distance. + * + * @return SUCCESS distance has been successfully store in dst + * FAILURE Node dose not exit. + * + ******************************************************************************/ + +int32_t GetDistance(NODE_LIST *list, COORD myCoord, uint8_t nodeId, double *dst) +{ + ASSERT(list != NULL); + NODE_ENTRY *nodeEntry = GetNode(list, nodeId); + if (nodeEntry == NULL) + { + return FAILURE; + } + else + { + *dst = Coord_Distance(myCoord, nodeEntry->nodeInfo.pos); + return SUCCESS; + } +} + +/*****************************************************************************/ +/** + * @brief Update node positions information. + * + * @param list + * @param nodeId + * @param newPos A structure stores the corresponding node position info. + * + * @return SUCCESS update successfully. + * FAILURE node not exist. + * + ******************************************************************************/ +int32_t UpdateNodePos(NODE_LIST *list, uint8_t nodeId, const COORD *newPos) +{ + ASSERT(list != NULL); + NODE_ENTRY *nodeEntry = GetNode(list, nodeId); + if (nodeEntry == NULL) + { + return FAILURE; + } + else + { + memcpy(&(nodeEntry->nodeInfo.pos), newPos, sizeof(COORD)); + } + return SUCCESS; +} + +/*****************************************************************************/ +/** + * @brief Get node positions information. + * + * @param list + * @param nodeId + * @param newPos A structure stores the corresponding node position info. + * + * @return SUCCESS update successfully. + * FAILURE node not exist. + * + ******************************************************************************/ +int32_t GetNodePos(NODE_LIST *list, uint8_t nodeId, COORD *pos) +{ + ASSERT(list != NULL); + NODE_ENTRY *nodeEntry = GetNode(list, nodeId); + if (nodeEntry == NULL) + { + return FAILURE; + } + else + { + memcpy(pos, &(nodeEntry->nodeInfo.pos), sizeof(COORD)); + } + return SUCCESS; +} + +/*****************************************************************************/ +/** + * @brief Update node speed information. + * + * @param list + * @param nodeId + * @param newSpeed A structure stores the corresponding node speed info. + * + * @return SUCCESS update successfully. + * FAILURE node not exist. + * + ******************************************************************************/ +int32_t UpdateNodeSpeed(NODE_LIST *list, uint8_t nodeId, const COORD *newSpeed) +{ + ASSERT(list != NULL); + NODE_ENTRY *nodeEntry = GetNode(list, nodeId); + if (nodeEntry == NULL) + { + return FAILURE; + } + else + { + memcpy(&(nodeEntry->nodeInfo.speed), newSpeed, sizeof(COORD)); + } + return SUCCESS; +} + +/*****************************************************************************/ +/** + * @brief Get node speed information. + * + * @param list + * @param nodeId + * @param newSpeed A structure stores the corresponding node speed info. + * + * @return SUCCESS update successfully. + * FAILURE node not exist. + * + ******************************************************************************/ +int32_t GetNodeSpeed(NODE_LIST *list, uint8_t nodeId, COORD *speed) +{ + ASSERT(list != NULL); + NODE_ENTRY *nodeEntry = GetNode(list, nodeId); + if (nodeEntry == NULL) + { + return FAILURE; + } + else + { + memcpy(speed, &(nodeEntry->nodeInfo.speed), sizeof(COORD)); + } + return SUCCESS; +} +/*****************************************************************************/ +/** + * @brief Update node ACK status. + * + * @param list + * @param nodeId + * @param defl + * + * @return SUCCESS update successfully. + * FAILURE Node not exist. + * + ******************************************************************************/ +int32_t UpdateNodeTimeDeviation(NODE_LIST *list, uint8_t nodeId, int32_t devi) +{ + ASSERT(list != NULL); + NODE_ENTRY *nodeEntry = GetNode(list, nodeId); + if (nodeEntry == NULL) + { + return FAILURE; + } + else + { + nodeEntry->timeDevi = devi; + } + return SUCCESS; +} + +/*****************************************************************************/ +/** + * @brief Increase TTL of specified node in the list. + * + * @param list + * @param inc cnt of slot to add + * @param nodeId + * + * @return NONE + * + ******************************************************************************/ +int32_t IncNodeTTL(NODE_LIST *list, uint8_t nodeId, uint32_t inc) +{ + ASSERT(list != NULL); + NODE_ENTRY *nodeEntry = GetNode(list, nodeId); + if (nodeEntry == NULL) + { + return FAILURE; + } + else + { + nodeEntry->ttlCnt += inc; + } + return SUCCESS; +} + +/*****************************************************************************/ +/** + * @brief Reset node TTL based on node id. + * + * @param list + * @param nodeId + * + * @return SUCCESS TTL has been successfully cleared. + * FAILURE Node not exist. + * + ******************************************************************************/ +int32_t RstNodeTTL(NODE_LIST *list, uint8_t nodeId) +{ + ASSERT(list != NULL); + NODE_ENTRY *nodeEntry = GetNode(list, nodeId); + if (nodeEntry == NULL) + { + return FAILURE; + } + else + { + nodeEntry->ttlCnt = 0; + } + return SUCCESS; +} + +/*****************************************************************************/ +/** + * @brief Get TTL of specified node in the list. + * + * @param list + * @param nodeId + * @param ttl + * + * @return NONE + * + ******************************************************************************/ +int32_t GetNodeTTL(NODE_LIST *list, uint8_t nodeId, uint32_t *ttl) +{ + ASSERT(list != NULL); + NODE_ENTRY *nodeEntry = GetNode(list, nodeId); + if (nodeEntry == NULL) + { + return FAILURE; + } + else + { + *ttl = nodeEntry->ttlCnt; + } + return SUCCESS; +} + +/*****************************************************************************/ +/** + * @brief Implements a edit operations to each node. + * + * @param list + * @param param + * @param operation A pointer to a function handled "NODE_ENTRY*" as input + * which defines the operations need to be apply. + * + * @return SUCCESS Operations has been applied successfully to all nodes. + * Other Error occurred. + * + ******************************************************************************/ +int32_t IterEditNode(NODE_LIST *list, const void *param, int32_t (*operation)(NODE_ENTRY *, const void *)) +{ + ASSERT(list != NULL); + int32_t Status = SUCCESS; + NODE_ENTRY *nodeEntry = list->head->nextNode; + while (nodeEntry != list->head) + { + Status = operation(nodeEntry, param); + if (Status != SUCCESS) + { + break; + } + nodeEntry = nodeEntry->nextNode; + } + return Status; +} + +/*****************************************************************************/ +/** + * @brief Filter all node, delete all the node not satisfied the condition. + * + * @param list + * @param condition A pointer to a function handled "NODE_ENTRY*" as input + * which defines the condition need to be verify. + * + * @return SUCCESS + * + ******************************************************************************/ +int32_t IterDeleteNode(NODE_LIST *list, bool (*condition)(NODE_ENTRY *)) +{ + ASSERT(list != NULL); + NODE_ENTRY *nodeEntry, *deletEntry; + nodeEntry = list->head->nextNode; + while (nodeEntry != list->head) + { + if (condition(nodeEntry) == false) + { + deletEntry = nodeEntry; + nodeEntry = nodeEntry->nextNode; + deletEntry->preNode->nextNode = deletEntry->nextNode; + deletEntry->nextNode->preNode = deletEntry->preNode; + DBG_INFO("Deleting node [%d].\n", deletEntry->nodeInfo.nodeId); + free(deletEntry); + list->nodeNum--; + } + else + { + nodeEntry = nodeEntry->nextNode; + } + } + return SUCCESS; +} diff --git a/df_datalink_sp/src/networking/link_layer/node_list.h b/df_datalink_sp/src/networking/link_layer/node_list.h new file mode 100644 index 0000000..518a20b --- /dev/null +++ b/df_datalink_sp/src/networking/link_layer/node_list.h @@ -0,0 +1,66 @@ +/*****************************************************************************/ +/** + * Description: Header of 814 linklayer local record. + * + * Date: 2022-07-14 00:08 + * LastEditTime: 2022-07-14 22:52 + * Revisions: Rev 0.0 + * History: + * [2022-07-14]: Initial version. + * + * Copyright(c) 2021 Beijing Institute of Technology. + * Lab of Communication and Networking + * + ******************************************************************************/ + +/***************************** Include Files *********************************/ +#ifndef __L2_LOCAL_RECORD_H_ +#define __L2_LOCAL_RECORD_H_ +#include +#include +#include +#include +#include "util.h" +#include "link_layer_types.h" + +/************************** Constant Definitions *****************************/ +/***************** Macros (Inline Functions) Definitions *********************/ +/**************************** Type Definitions *******************************/ +typedef struct NODE_LIST_ENTRY +{ + L2_NODE_INFO nodeInfo; + uint32_t ttlCnt; + int32_t timeDevi; + struct NODE_LIST_ENTRY *nextNode; + struct NODE_LIST_ENTRY *preNode; +} NODE_ENTRY; + +typedef struct +{ + uint32_t nodeNum; + NODE_ENTRY *head; +} NODE_LIST; + +/************************** Variable Definitions *****************************/ + +/************************** Function Prototypes ******************************/ +int32_t NodeList_Init(NODE_LIST **list); +void NodeList_Clear(NODE_LIST *list); +void NodeList_Destroy(NODE_LIST *list); +NODE_ENTRY *GetNode(NODE_LIST *list, uint32_t nodeId); +int32_t AppendNode(NODE_LIST *list, uint8_t nodeId, L2_NODE_TYPE nodeType); +int32_t DeletNode(NODE_LIST *list, uint8_t nodeId); +int32_t UpdateNodePos(NODE_LIST *list, uint8_t nodeId, const COORD *newPos); +int32_t GetNodePos(NODE_LIST *list, uint8_t nodeId, COORD *newPos); +int32_t UpdateNodeSpeed(NODE_LIST *list, uint8_t nodeId, const COORD *newSpeed); +int32_t GetNodeSpeed(NODE_LIST *list, uint8_t nodeId, COORD *speed); +int32_t UpdateNodeTimeDeviation(NODE_LIST *list, uint8_t nodeId, int32_t devi); +int32_t GetDistance(NODE_LIST *list, COORD myCoord, uint8_t nodeId, double *dst); +int32_t GetNodeNum(NODE_LIST *list); +int32_t RstNodeTTL(NODE_LIST *list, uint8_t nodeId); +int32_t IncNodeTTL(NODE_LIST *list, uint8_t nodeId, uint32_t inc); +int32_t GetNodeTTL(NODE_LIST *list, uint8_t nodeId, uint32_t *ttl); +bool IsNodeInList(NODE_LIST *list, uint8_t nodeId); +int32_t IterEditNode(NODE_LIST *list, const void *param, int32_t (*operation)(NODE_ENTRY *, const void *)); +int32_t IterDeleteNode(NODE_LIST *list, bool (*condition)(NODE_ENTRY *)); +#endif /* __L2_LOCAL_RECORD_H_ */ diff --git a/df_datalink_sp/src/networking/link_layer/routine_table.c b/df_datalink_sp/src/networking/link_layer/routine_table.c new file mode 100644 index 0000000..710834c --- /dev/null +++ b/df_datalink_sp/src/networking/link_layer/routine_table.c @@ -0,0 +1,928 @@ +/*****************************************************************************/ +/** + * Description: Time allocations for df datalink, + * Date: 2022-07-16 17:05 + * LastEditTime: 2022-07-16 17:05 + * Revisions: Rev 0.1 + * History: + * [2021-11-13]: Initial version. + * + * Copyright(c) 2021 Beijing Institute of Technology. + * Lab of Communication and Networking + * + ******************************************************************************/ + +#include +#include "link_layer.h" +#include "link_layer_types.h" +#include "../config/app_config.h" + +#ifndef DATALINK_ENABLE_BERTEST +L2_RTNE_TABLE_ENTRY normalSub1[L2_SLOTS_PER_FRAME] = { + // SubFrame 1 + {L2_SLOT_SERVICE, 0x01, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x02, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x03, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x04, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x05, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x06, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x07, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x08, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x09, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0A, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0B, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0C, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0D, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0E, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0F, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x10, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x11, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x12, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x13, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x14, 0x01, 0x02}, + + // SubFrame 2 + {L2_SLOT_SERVICE, 0x01, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x02, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x03, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x04, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x05, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x06, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x07, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x08, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x09, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0A, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0B, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0C, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0D, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0E, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0F, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x10, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x11, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x12, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x13, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x14, 0x01, 0x02}, + + // SubFrame 3 + {L2_SLOT_SERVICE, 0x01, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x02, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x03, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x04, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x05, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x06, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x07, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x08, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x09, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0A, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0B, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0C, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0D, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0E, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0F, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x10, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x11, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x12, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x13, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x14, 0x02, 0x01}, + + // SubFrame 4 + {L2_SLOT_SERVICE, 0x01, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x02, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x03, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x04, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x05, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x06, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x07, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x08, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x09, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0A, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0B, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0C, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0D, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0E, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0F, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x10, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x11, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x12, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x13, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x14, 0x01, 0x02}, + + // SubFrame 5 + {L2_SLOT_SERVICE, 0x01, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x02, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x03, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x04, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x05, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x06, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x07, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x08, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x09, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0A, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0B, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0C, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0D, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0E, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0F, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x10, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x11, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x12, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x13, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x14, 0x01, 0x02}, + + // SubFrame 6 + {L2_SLOT_SERVICE, 0x01, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x02, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x03, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x04, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x05, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x06, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x07, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x08, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x09, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0A, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0B, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0C, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0D, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0E, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0F, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x10, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x11, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x12, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x13, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x14, 0x02, 0x01}, + + // SubFrame 7 + {L2_SLOT_SERVICE, 0x01, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x02, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x03, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x04, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x05, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x06, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x07, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x08, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x09, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0A, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0B, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0C, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0D, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0E, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0F, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x10, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x11, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x12, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x13, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x14, 0x01, 0x02}, + + // SubFrame 8 + {L2_SLOT_SERVICE, 0x01, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x02, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x03, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x04, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x05, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x06, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x07, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x08, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x09, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0A, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0B, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0C, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0D, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0E, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0F, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x10, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x11, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x12, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x13, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x14, 0x01, 0x02}, + + // SubFrame 9 + {L2_SLOT_SERVICE, 0x01, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x02, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x03, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x04, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x05, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x06, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x07, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x08, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x09, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0A, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0B, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0C, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0D, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0E, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0F, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x10, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x11, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x12, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x13, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x14, 0x02, 0x01}, + + // SubFrame 10 + {L2_SLOT_SERVICE, 0x01, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x02, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x03, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x04, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x05, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x06, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x07, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x08, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x09, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0A, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0B, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0C, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0D, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0E, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0F, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x10, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x11, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x12, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x13, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x14, 0x01, 0x02}}; + +L2_RTNE_TABLE_ENTRY normalSub2[L2_SLOTS_PER_FRAME] = { + // SubFrame 1 + {L2_SLOT_SERVICE, 0x01, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x02, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x03, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x04, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x05, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x06, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x07, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x08, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x09, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0A, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0B, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0C, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0D, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0E, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0F, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x10, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x11, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x12, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x13, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x14, 0x01, 0x02}, + + // SubFrame 2 + {L2_SLOT_SERVICE, 0x01, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x02, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x03, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x04, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x05, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x06, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x07, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x08, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x09, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0A, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0B, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0C, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0D, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0E, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0F, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x10, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x11, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x12, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x13, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x14, 0x02, 0x01}, + + // SubFrame 3 + {L2_SLOT_SERVICE, 0x01, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x02, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x03, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x04, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x05, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x06, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x07, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x08, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x09, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0A, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0B, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0C, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0D, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0E, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0F, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x10, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x11, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x12, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x13, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x14, 0x01, 0x02}, + + // SubFrame 4 + {L2_SLOT_SERVICE, 0x01, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x02, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x03, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x04, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x05, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x06, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x07, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x08, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x09, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0A, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0B, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0C, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0D, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0E, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0F, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x10, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x11, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x12, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x13, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x14, 0x01, 0x02}, + + // SubFrame 5 + {L2_SLOT_SERVICE, 0x01, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x02, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x03, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x04, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x05, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x06, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x07, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x08, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x09, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0A, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0B, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0C, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0D, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0E, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0F, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x10, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x11, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x12, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x13, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x14, 0x02, 0x01}, + + // SubFrame 6 + {L2_SLOT_SERVICE, 0x01, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x02, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x03, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x04, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x05, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x06, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x07, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x08, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x09, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0A, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0B, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0C, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0D, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0E, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0F, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x10, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x11, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x12, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x13, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x14, 0x01, 0x02}, + + // SubFrame 7 + {L2_SLOT_SERVICE, 0x01, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x02, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x03, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x04, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x05, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x06, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x07, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x08, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x09, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0A, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0B, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0C, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0D, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0E, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0F, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x10, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x11, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x12, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x13, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x14, 0x01, 0x02}, + + // SubFrame 8 + {L2_SLOT_SERVICE, 0x01, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x02, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x03, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x04, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x05, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x06, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x07, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x08, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x09, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0A, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0B, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0C, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0D, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0E, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0F, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x10, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x11, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x12, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x13, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x14, 0x02, 0x01}, + + // SubFrame 9 + {L2_SLOT_SERVICE, 0x01, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x02, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x03, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x04, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x05, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x06, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x07, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x08, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x09, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0A, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0B, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0C, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0D, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0E, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0F, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x10, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x11, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x12, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x13, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x14, 0x01, 0x02}, + + // SubFrame 10 + {L2_SLOT_SERVICE, 0x01, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x02, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x03, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x04, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x05, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x06, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x07, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x08, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x09, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0A, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0B, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0C, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0D, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0E, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0F, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x10, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x11, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x12, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x13, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x14, 0x01, 0x02}}; + +L2_RTNE_TABLE_ENTRY normalSub3[L2_SLOTS_PER_FRAME] = { + // SubFrame 1 + {L2_SLOT_SERVICE, 0x01, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x02, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x03, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x04, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x05, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x06, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x07, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x08, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x09, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0A, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0B, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0C, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0D, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0E, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0F, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x10, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x11, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x12, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x13, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x14, 0x02, 0x01}, + + // SubFrame 2 + {L2_SLOT_SERVICE, 0x01, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x02, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x03, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x04, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x05, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x06, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x07, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x08, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x09, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0A, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0B, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0C, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0D, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0E, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0F, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x10, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x11, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x12, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x13, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x14, 0x01, 0x02}, + + // SubFrame 3 + {L2_SLOT_SERVICE, 0x01, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x02, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x03, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x04, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x05, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x06, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x07, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x08, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x09, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0A, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0B, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0C, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0D, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0E, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0F, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x10, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x11, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x12, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x13, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x14, 0x01, 0x02}, + + // SubFrame 4 + {L2_SLOT_SERVICE, 0x01, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x02, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x03, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x04, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x05, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x06, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x07, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x08, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x09, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0A, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0B, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0C, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0D, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0E, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0F, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x10, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x11, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x12, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x13, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x14, 0x02, 0x01}, + + // SubFrame 5 + {L2_SLOT_SERVICE, 0x01, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x02, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x03, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x04, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x05, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x06, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x07, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x08, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x09, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0A, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0B, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0C, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0D, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0E, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0F, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x10, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x11, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x12, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x13, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x14, 0x01, 0x02}, + + // SubFrame 6 + {L2_SLOT_SERVICE, 0x01, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x02, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x03, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x04, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x05, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x06, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x07, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x08, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x09, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0A, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0B, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0C, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0D, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0E, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0F, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x10, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x11, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x12, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x13, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x14, 0x01, 0x02}, + + // SubFrame 7 + {L2_SLOT_SERVICE, 0x01, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x02, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x03, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x04, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x05, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x06, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x07, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x08, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x09, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0A, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0B, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0C, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0D, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0E, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0F, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x10, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x11, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x12, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x13, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x14, 0x02, 0x01}, + + // SubFrame 8 + {L2_SLOT_SERVICE, 0x01, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x02, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x03, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x04, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x05, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x06, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x07, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x08, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x09, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0A, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0B, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0C, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0D, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0E, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0F, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x10, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x11, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x12, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x13, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x14, 0x01, 0x02}, + + // SubFrame 9 + {L2_SLOT_SERVICE, 0x01, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x02, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x03, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x04, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x05, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x06, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x07, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x08, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x09, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0A, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0B, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0C, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0D, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0E, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0F, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x10, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x11, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x12, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x13, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x14, 0x01, 0x02}, + + // SubFrame 10 + {L2_SLOT_SERVICE, 0x01, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x02, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x03, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x04, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x05, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x06, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x07, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x08, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x09, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0A, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0B, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0C, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0D, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0E, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0F, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x10, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x11, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x12, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x13, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x14, 0x02, 0x01}}; + +L2_RTNE_TABLE_ENTRY *normalTable[L2_RTNE_PERIOD] = { + normalSub1, normalSub2, normalSub3, normalSub1, normalSub2, normalSub3, + normalSub1, normalSub2, normalSub3, normalSub1, normalSub2, normalSub3, + normalSub1, normalSub2, normalSub3, normalSub1, normalSub2, normalSub3, + normalSub1, normalSub2, normalSub3, normalSub1, normalSub2, normalSub3, + normalSub1, normalSub2, normalSub3, normalSub1, normalSub2, normalSub3, + normalSub1, normalSub2, normalSub3, normalSub1, normalSub2, normalSub3, + normalSub1, normalSub2, normalSub3, normalSub1, normalSub2, normalSub3, + normalSub1, normalSub2, normalSub3, normalSub1, normalSub2, normalSub3, + normalSub1, normalSub2, normalSub3, normalSub1, normalSub2, normalSub3, + normalSub1, normalSub2, normalSub3, normalSub1, normalSub2, normalSub3}; +#else +L2_RTNE_TABLE_ENTRY normalSub[L2_SLOTS_PER_FRAME] = { + // SubFrame 1 + {L2_SLOT_SERVICE, 0x01, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x02, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x03, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x04, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x05, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x06, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x07, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x08, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x09, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0A, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0B, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0C, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0D, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0E, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0F, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x10, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x11, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x12, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x13, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x14, 0x01, 0x02}, + + // SubFrame 2 + {L2_SLOT_SERVICE, 0x01, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x02, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x03, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x04, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x05, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x06, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x07, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x08, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x09, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0A, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0B, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0C, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0D, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0E, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0F, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x10, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x11, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x12, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x13, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x14, 0x02, 0x01}, + + // SubFrame 3 + {L2_SLOT_SERVICE, 0x01, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x02, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x03, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x04, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x05, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x06, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x07, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x08, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x09, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0A, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0B, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0C, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0D, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0E, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0F, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x10, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x11, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x12, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x13, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x14, 0x01, 0x02}, + + // SubFrame 4 + {L2_SLOT_SERVICE, 0x01, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x02, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x03, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x04, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x05, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x06, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x07, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x08, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x09, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0A, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0B, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0C, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0D, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0E, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0F, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x10, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x11, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x12, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x13, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x14, 0x02, 0x01}, + + // SubFrame 5 + {L2_SLOT_SERVICE, 0x01, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x02, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x03, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x04, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x05, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x06, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x07, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x08, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x09, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0A, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0B, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0C, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0D, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0E, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0F, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x10, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x11, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x12, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x13, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x14, 0x01, 0x02}, + + // SubFrame 6 + {L2_SLOT_SERVICE, 0x01, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x02, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x03, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x04, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x05, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x06, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x07, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x08, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x09, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0A, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0B, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0C, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0D, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0E, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0F, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x10, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x11, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x12, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x13, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x14, 0x02, 0x01}, + + // SubFrame 7 + {L2_SLOT_SERVICE, 0x01, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x02, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x03, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x04, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x05, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x06, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x07, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x08, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x09, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0A, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0B, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0C, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0D, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0E, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0F, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x10, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x11, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x12, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x13, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x14, 0x01, 0x02}, + + // SubFrame 8 + {L2_SLOT_SERVICE, 0x01, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x02, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x03, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x04, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x05, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x06, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x07, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x08, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x09, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0A, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0B, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0C, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0D, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0E, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0F, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x10, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x11, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x12, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x13, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x14, 0x02, 0x01}, + + // SubFrame 9 + {L2_SLOT_SERVICE, 0x01, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x02, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x03, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x04, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x05, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x06, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x07, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x08, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x09, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0A, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0B, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0C, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0D, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0E, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x0F, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x10, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x11, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x12, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x13, 0x01, 0x02}, + {L2_SLOT_SERVICE, 0x14, 0x01, 0x02}, + + // SubFrame 10 + {L2_SLOT_SERVICE, 0x01, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x02, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x03, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x04, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x05, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x06, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x07, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x08, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x09, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0A, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0B, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0C, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0D, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0E, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x0F, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x10, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x11, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x12, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x13, 0x02, 0x01}, + {L2_SLOT_SERVICE, 0x14, 0x02, 0x01}}; + +L2_RTNE_TABLE_ENTRY *normalTable[L2_RTNE_PERIOD] = { + normalSub, normalSub, normalSub, normalSub, normalSub, normalSub, + normalSub, normalSub, normalSub, normalSub, normalSub, normalSub, + normalSub, normalSub, normalSub, normalSub, normalSub, normalSub, + normalSub, normalSub, normalSub, normalSub, normalSub, normalSub, + normalSub, normalSub, normalSub, normalSub, normalSub, normalSub, + normalSub, normalSub, normalSub, normalSub, normalSub, normalSub, + normalSub, normalSub, normalSub, normalSub, normalSub, normalSub, + normalSub, normalSub, normalSub, normalSub, normalSub, normalSub, + normalSub, normalSub, normalSub, normalSub, normalSub, normalSub, + normalSub, normalSub, normalSub, normalSub, normalSub, normalSub}; +#endif diff --git a/df_datalink_sp/src/networking/link_layer/scan.c b/df_datalink_sp/src/networking/link_layer/scan.c new file mode 100644 index 0000000..cc53319 --- /dev/null +++ b/df_datalink_sp/src/networking/link_layer/scan.c @@ -0,0 +1,354 @@ +/*****************************************************************************/ +/** + * Description: Implementations of df linklayer scan net. + * + * Date: 2021-11-10 19:04 + * LastEditTime: 2022-07-16 17:04 + * Revisions: Rev 0.1 + * History: + * [2022-07-16]: New branch for DiJian. + * [2021-11-10]: Initial version. + * + * Copyright(c) 2021 Beijing Institute of Technology. + * Lab of Communication and Networking + * + ******************************************************************************/ + +/***************************** Include Files *********************************/ +#include +#include "error.h" +#include "common.h" +#include "msg_def.h" +#include "link_layer.h" +#include "link_layer_types.h" +#include "../phy_layer/phy_layer.h" +#include "node_list.h" + +/************************** Constant Definitions *****************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/**************************** Type Definitions *******************************/ + +/************************** Variable Definitions *****************************/ + +/************************** Function Prototypes ******************************/ +static int32_t ScanMsg_Packing(L2_INST *instPtr, L2_FRAME_TYPE type); +/*****************************************************************************/ +/** + * @brief Packing Scan message to a bit array. + * + * @param bitarr pointer to bit array buffer. + * msgType message type. + * + * @return EPARAM + * SUCCESS + * + ******************************************************************************/ +static int32_t ScanMsg_Packing(L2_INST *instPtr, L2_FRAME_TYPE type) +{ + ASSERT(instPtr != NULL); + int32_t Status; + uint8_t *buff; + uint32_t packLen; + switch (type) + { + case L2_INFO_FRAME: + { + packLen = RSP_PACK_LEN; + SysMonitor_GetSysinfo(&(instPtr->sysInfo)); + buff = malloc(packLen); + if (buff == NULL) + { + DBG_ERROR("Not enough space, failed to pack frame...\n"); + return ENOMEM; + } + buff[L2_MSG_FRAME_NO] = L2_GetNextFrameNo(instPtr); + buff[L2_MSG_SLOT_NO] = L2_GetNextSlotNo(instPtr); + memcpy(buff + L2_MSG_INFO_POSX, &(instPtr->sysInfo.posX), sizeof(float)); + memcpy(buff + L2_MSG_INFO_POSY, &(instPtr->sysInfo.posY), sizeof(float)); + memcpy(buff + L2_MSG_INFO_POSZ, &(instPtr->sysInfo.posZ), sizeof(float)); + memcpy(buff + L2_MSG_INFO_SPEEDX, &(instPtr->sysInfo.vX), sizeof(float)); + memcpy(buff + L2_MSG_INFO_SPEEDY, &(instPtr->sysInfo.vY), sizeof(float)); + memcpy(buff + L2_MSG_INFO_SPEEDZ, &(instPtr->sysInfo.vZ), sizeof(float)); + + Status = L2_CrcAppend(buff, packLen - 2, L2_MSG_CRC, L2_CRC16_1021); + if (Status != SUCCESS) + { + DBG_ERROR("Fail to append CRC, error code: %ld.\n", Status); + return Status; + } + if (CircQueuePush(instPtr->txQueue, buff) == false) + { + DBG_ERROR("Cannot push packet to queue..\n"); + return EQUEUE; + } + break; + } + default: + { + DBG_ERROR("Unexpected frame type: %d.\n", type); + return EPARAM; + break; + } + } + return SUCCESS; +} + +/*****************************************************************************/ +/** + * @brief Initialize scan FSM. + * + * @param instPtr + * + * @return + * + ******************************************************************************/ +int32_t L2_Scan_Init(L2_INST *instPtr) +{ + ASSERT(instPtr != NULL); + instPtr->scanFsm.sacanCnt = 0; + instPtr->scanFsm.beamNo = 0; + return SUCCESS; +} + +/*****************************************************************************/ +/** + * @brief Scan net packet handler. + * + * @param msg A pointer to frame data buffer. + * + * @return + * + ******************************************************************************/ +int32_t L2_Scan_PktHandler(L2_INST *instPtr, uint8_t *msg) +{ + ASSERT(instPtr != NULL); + ASSERT(msg != NULL); + int32_t Status; + switch (instPtr->frame.last) + { + case L2_SCAN_FRAME: + { + if (instPtr->config.myType == L2_HEAD_NODE) + { + DBG_ERROR("Unexpected call from head node, Only None-Head Node can handle L2_SVC_FRAME.\n"); + Status = EUNEXP; + break; + } + Status = AppendNode(instPtr->nodeInfoList, L2_HEAD_NODE_ID, L2_HEAD_NODE); + if (Status != SUCCESS) + { + DBG_ERROR("Failed to append node %d, errorCode: %ld.\n", L2_MEMBER_NODE_ID, Status); + } + break; + } + case L2_INFO_FRAME: + { + if (instPtr->config.myType != L2_HEAD_NODE) + { + DBG_ERROR("Unexpected call from member node, Only Head Node can handle L2_SVC_FRAME.\n"); + Status = EUNEXP; + break; + } + COORD coordTemp; + float tmpVal; + Status = AppendNode(instPtr->nodeInfoList, L2_MEMBER_NODE_ID, L2_MEMBER_NODE); + if (Status != SUCCESS) + { + DBG_ERROR("Failed to append node %d, errorCode: %ld.\n", L2_MEMBER_NODE_ID, Status); + break; + } + memcpy(&tmpVal, msg + L2_MSG_INFO_POSX, sizeof(float)); + coordTemp.x = tmpVal; + memcpy(&tmpVal, msg + L2_MSG_INFO_POSY, sizeof(float)); + coordTemp.y = tmpVal; + memcpy(&tmpVal, msg + L2_MSG_INFO_POSZ, sizeof(float)); + coordTemp.z = tmpVal; + Status = UpdateNodePos(instPtr->nodeInfoList, L2_MEMBER_NODE_ID, &coordTemp); + if (Status != SUCCESS) + { + DBG_ERROR("Failed to update node %d position, errorCode: %ld.\n", L2_MEMBER_NODE_ID, Status); + } + memcpy(&tmpVal, msg + L2_MSG_INFO_SPEEDX, sizeof(float)); + coordTemp.x = tmpVal; + memcpy(&tmpVal, msg + L2_MSG_INFO_SPEEDY, sizeof(float)); + coordTemp.y = tmpVal; + memcpy(&tmpVal, msg + L2_MSG_INFO_SPEEDZ, sizeof(float)); + coordTemp.z = tmpVal; + Status = UpdateNodeSpeed(instPtr->nodeInfoList, L2_MEMBER_NODE_ID, &coordTemp); + if (Status != SUCCESS) + { + DBG_ERROR("Failed to update node %d speed, errorCode: %ld.\n", L2_MEMBER_NODE_ID, Status); + } + // Update Time deviation + int64_t devi, deviTrunc; + Status = L2_TimeSync_GetDeviatoion(instPtr, &devi); + if (Status != SUCCESS) + { + DBG_ERROR("Failed to compute slot deviation.\n"); + UpdateNodeTimeDeviation(instPtr->nodeInfoList, L2_MEMBER_NODE_ID, 0); + } + else + { + if (devi > INT32_MAX || devi < INT32_MIN) + { + DBG_ERROR("Illegal deviation value: %lld.\n", devi); + deviTrunc = 0; + } + else if (devi > L2_MSG_SVC_TMSYNC_MAX || devi < L2_MSG_SVC_TMSYNC_MIN) + { + DBG_WARNING("Deviation value: %lld is out of adjustable range.\n", devi); + deviTrunc = (int32_t)devi; + } + else + { + deviTrunc = (int32_t)devi; + } + UpdateNodeTimeDeviation(instPtr->nodeInfoList, L2_MEMBER_NODE_ID, (uint32_t)deviTrunc); + } + break; + } + default: + DBG_ERROR("Unsupported frame type: %ld.\n", instPtr->frame.last); + Status = EUNEXP; + break; + } + + // Net setup finished. + if (L2_GetMainState(instPtr) == INIT_STATE && Status == SUCCESS) + { + L2_EVENT l2Event; + L2_RTNE_CONFIG newRtneConfig; + + // Assert Net-Setup Done. + l2Event.event = L2_EV_NET_SETUP_DONE; + l2Event.msg = NULL; + AssertL2Event(instPtr, &l2Event); + + // Assert Routine Table Update... + newRtneConfig.rtneTable = normalTable; + newRtneConfig.rtnePrd = ARRAY_SIZE(normalTable) * L2_SLOTS_PER_FRAME; + newRtneConfig.rtneStep = 0; + l2Event.event = L2_ROUTINE_UPDATE; + l2Event.msg = &newRtneConfig; + AssertL2Event(instPtr, &l2Event); + } + return Status; +} + +/*****************************************************************************/ +/** + * @brief Execute a member node scan net procedure. + * + * @param instPtr A pointer to scan net fsm. + * + * @return used slot (5ms slot). + * + ******************************************************************************/ +int32_t L2_Scan_Proc(L2_INST *instPtr) +{ + int32_t Status; + /* instPtr->nextState == NORMAL_STATE indicates network set up procedure was finished. + * Skip 5ms for nodes for node configuration update. + */ + DBG_INFO("-------- Scan Process --------\n"); + if (instPtr->nextState == NORMAL_STATE) + { + DBG_INFO("NETSET DONE, halt 20ms before normal routine.\n"); + if (instPtr->config.myType != L2_HEAD_NODE) + { + Phy_SetBeamAngle(instPtr->config.phyInstRef, 0.0, 0.0); + Phy_SetBeamWidth(instPtr->config.phyInstRef, PHY_ANT_BEAM_120); + Phy_SetMode(instPtr->config.phyInstRef, PHY_MODE_SCHEDULE); + L2_SetupNextSlot(instPtr, L2_TOR_SUSPEND, L2_SCAN_FRAME); + } + else + { + DBG_ERROR("Illegal call from Head Node.\n"); + } + return NUM_SLOTS_SKIP; + } + + /* Head node implement a periodical scan pattern + * | Tx 20ms | Rx 100ms | Tx 20ms | Rx 100ms ... ... + * Send pilot signal in Tx slots with narrow beam width. + * Wait for response in Rx slots with the same beam width and beam number. + * Increase beam number after a Tx-Rx procedure pair, reset beam number when + * it reaches the boundary. + */ + if (instPtr->config.myType == L2_HEAD_NODE) + { + // Apply a scan procedure + if (instPtr->scanFsm.sacanCnt % 2 == 0) + { + // Antenna configure + Phy_SetBeamWidth(instPtr->config.phyInstRef, PHY_ANT_BEAM_8); + Phy_SetBeamNo(instPtr->config.phyInstRef, instPtr->scanFsm.beamNo); + Phy_SetMode(instPtr->config.phyInstRef, PHY_MODE_SCHEDULE); + L2_SetupNextSlot(instPtr, L2_TOR_TX, L2_SCAN_FRAME); + } + else + { + // Antenna configure + Phy_SetBeamWidth(instPtr->config.phyInstRef, PHY_ANT_BEAM_8); + Phy_SetBeamNo(instPtr->config.phyInstRef, instPtr->scanFsm.beamNo); + Phy_SetMode(instPtr->config.phyInstRef, PHY_MODE_SCHEDULE); + L2_SetupNextSlot(instPtr, L2_TOR_RX, L2_INFO_FRAME); + // Update Scan beam number + instPtr->scanFsm.beamNo = (instPtr->scanFsm.beamNo + 1) % L1_NUM_ANT_NRRW_PATTERN; + } + } + /* Member node listening the head node pilot signal with wide beam width. + * Once is received a pilot signal, physical layer will perform a response + * procedure automatically, witch should contains the basic node information + * (position, speed, etc.). + * So that, a extra datagram with the up-to-date node information is attached + * to the listening configuration. + */ + else + { + uint8_t *sendData; + // Pack node information. + Status = ScanMsg_Packing(instPtr, L2_INFO_FRAME); + if (Status != SUCCESS) + { + DBG_INFO("Failed to pack response.\n"); + } + if (CircQueuePop(instPtr->txQueue, (void **)(&sendData)) == true) + { + memcpy(instPtr->sendPktData, sendData, RSP_PACK_LEN); + free(sendData); + } + else + { + DBG_INFO("Failed to pop tx Queue.\n"); + } + // Antenna configure + Phy_SetBeamAngle(instPtr->config.phyInstRef, 0.0, 0.0); + Phy_SetBeamWidth(instPtr->config.phyInstRef, PHY_ANT_BEAM_120); + Phy_SetMode(instPtr->config.phyInstRef, PHY_MODE_LISTEN); + L2_SetupNextSlot(instPtr, L2_TOR_RX, L2_SCAN_FRAME); + } + + // Increase scan counter (for debug purpose). + instPtr->scanFsm.sacanCnt++; + return NUM_SLOTS_SKIP; +} + +/*****************************************************************************/ + +/** + * @brief Execute a scan net Routine procedure. + * + * @param schedEntry Routine configuration + * + * @return used slot (5ms slot). + * + ******************************************************************************/ +int32_t L2_Scan_Routine(L2_INST *instPtr, L2_RTNE_TABLE_ENTRY *schedEntry) +{ + DBG_INFO("-------- Scan Routine --------\n"); + ASSERT(false); // Not support. + return 0; +} diff --git a/df_datalink_sp/src/networking/link_layer/service.c b/df_datalink_sp/src/networking/link_layer/service.c new file mode 100644 index 0000000..f41435b --- /dev/null +++ b/df_datalink_sp/src/networking/link_layer/service.c @@ -0,0 +1,524 @@ +/*****************************************************************************/ +/** + * Description: Implementations for df datalink service net. + * Date: 2021-11-16 00:08 + * LastEditTime: 2022-07-16 17:04 + * Revisions: Rev 0.1 + * History: + * [2022-07-16]: New branch for DiJian. + * [2021-11-16]: Initial version. + * + * Copyright(c) 2021 Beijing Institute of Technology. + * Lab of Communication and Networking + * + ******************************************************************************/ + +/***************************** Include Files *********************************/ +#include +#include +#include "error.h" +#include "common.h" +#include "circ_queue.h" +#include "msg_def.h" +#include "link_layer.h" +#include "link_layer_types.h" +#include "../config/app_config.h" + +/************************** Constant Definitions *****************************/ +#define NUM_SERVICE_SLOTS 20 +#define NUM_RESPONSE_SLOTS 20 +#define NUM_NONE_SERVICE_SLOTS 0 +#define NUM_SERVICE_PRD_SLOTS 60 +/***************** Macros (Inline Functions) Definitions *********************/ + +/**************************** Type Definitions *******************************/ + +/************************** Function Prototypes ******************************/ +static int32_t Service_Packing(L2_INST *instPtr, L2_FRAME_TYPE type); +/************************** Variable Definitions *****************************/ + +#ifdef DATALINK_ENABLE_BERTEST +static uint8_t berTestData[SVC_PACK_LEN] = { + 0x27, 0x4E, 0xFB, 0x39, 0x11, 0xE7, 0x12, 0xDA, + 0xDF, 0xD2, 0x27, 0x8F, 0xC9, 0x42, 0xCD, 0x0C, + 0x76, 0x1C, 0x81, 0x87, 0x69, 0xC9, 0x60, 0xFD, + 0xC4, 0x27, 0xA5, 0x09, 0xE5, 0x71}; +#endif + +/*****************************************************************************/ +/** + * @brief Packing UDU Header to a bit array. + * + * @param bitarr point32_ter to bit array buffer. + * dst Destination node address. + * dataLen Length of UDU data. + * + * @return EPARAM + * SUCCESS + * + ******************************************************************************/ +static int32_t Service_Packing(L2_INST *instPtr, L2_FRAME_TYPE type) +{ +#ifndef DATALINK_ENABLE_BERTEST + ASSERT(instPtr != NULL); + int32_t Status; + uint8_t *buff; + uint32_t packLen; + switch (type) + { + case L2_SVC_FRAME: + { + const NODE_ENTRY *nodeEntry; + int32_t timeDevi; + packLen = SVC_PACK_LEN; + + buff = malloc(packLen); + if (buff == NULL) + { + DBG_ERROR("Not enough space, failed to pack frame...\n"); + return ENOMEM; + } + buff[L2_MSG_FRAME_NO] = L2_GetNextFrameNo(instPtr); + buff[L2_MSG_SLOT_NO] = L2_GetNextSlotNo(instPtr); + + // TODO: Check Pack TimeSync info, and better approch?. + nodeEntry = GetNode(instPtr->nodeInfoList, L2_MEMBER_NODE_ID); + if (nodeEntry != NULL) + { + // check if deviation info outdated. + if (nodeEntry->ttlCnt <= NUM_SERVICE_PRD_SLOTS) + { + // Member node should adjust in the opposite way. + timeDevi = -nodeEntry->timeDevi; + } + else + { + DBG_WARNING("Time deviation is outdated, omitted it.\n"); + } + } + else + { + DBG_ERROR("Fail to get time deviation...\n"); + timeDevi = 0; + } + if (timeDevi > L2_MSG_SVC_TMSYNC_MAX || timeDevi < L2_MSG_SVC_TMSYNC_MIN) + { + do + { + timeDevi /= 2; + } while (timeDevi > L2_MSG_SVC_TMSYNC_MAX || timeDevi < L2_MSG_SVC_TMSYNC_MIN); + DBG_WARNING("Deviation is out of adjustable range, truncate it to %d.\n", timeDevi); + } + memcpy(buff + L2_MSG_SVC_TMSYNC, &timeDevi, L2_MSG_SVC_TMSYNC_LEN); + + // Pack Seq ID + buff[L2_MSG_SVC_SEQ_ID] = instPtr->serviceFsm.txSeqNum; + + // Pack payload + memcpy(buff + L2_MSG_SVC_PAYLOAD, + instPtr->serviceFsm.txLog + L2_MSG_SVC_PAYLOAD_LEN * instPtr->serviceFsm.txSeqNum, + L2_MSG_SVC_PAYLOAD_LEN); + if (instPtr->config.myType == L2_HEAD_NODE) + { + // if last packet reset counting + instPtr->serviceFsm.txSeqNum = (instPtr->serviceFsm.txSeqNum >= (PAYLOAD_FLJ - 1) / L2_MSG_SVC_PAYLOAD + 1) + ? 0 + : instPtr->serviceFsm.txSeqNum + 1; + } + else + { + // if last packet reset counting + instPtr->serviceFsm.txSeqNum = (instPtr->serviceFsm.txSeqNum >= (PAYLOAD_LJ - 1) / L2_MSG_SVC_PAYLOAD + 1) + ? 0 + : instPtr->serviceFsm.txSeqNum + 1; + } + + Status = L2_CrcAppend(buff, packLen - 2, L2_MSG_CRC, L2_CRC16_1021); + if (Status != SUCCESS) + { + DBG_ERROR("Fail to append CRC...\n"); + return Status; + } + + if (CircQueuePush(instPtr->txQueue, buff) == false) + { + DBG_ERROR("Cannot push packet to queue..\n"); + return EQUEUE; + } + break; + } + case L2_INFO_FRAME: + { + packLen = RSP_PACK_LEN; + SysMonitor_GetSysinfo(&(instPtr->sysInfo)); + buff = malloc(packLen); + if (buff == NULL) + { + DBG_ERROR("Not enough space, failed to pack frame...\n"); + return ENOMEM; + } + buff[L2_MSG_FRAME_NO] = L2_GetNextFrameNo(instPtr); + buff[L2_MSG_SLOT_NO] = L2_GetNextSlotNo(instPtr); + memcpy(buff + L2_MSG_INFO_POSX, &(instPtr->sysInfo.posX), sizeof(float)); + memcpy(buff + L2_MSG_INFO_POSY, &(instPtr->sysInfo.posY), sizeof(float)); + memcpy(buff + L2_MSG_INFO_POSZ, &(instPtr->sysInfo.posZ), sizeof(float)); + memcpy(buff + L2_MSG_INFO_SPEEDX, &(instPtr->sysInfo.vX), sizeof(float)); + memcpy(buff + L2_MSG_INFO_SPEEDY, &(instPtr->sysInfo.vY), sizeof(float)); + memcpy(buff + L2_MSG_INFO_SPEEDZ, &(instPtr->sysInfo.vZ), sizeof(float)); + + Status = L2_CrcAppend(buff, packLen - 2, L2_MSG_CRC, L2_CRC16_1021); + if (Status != SUCCESS) + { + DBG_ERROR("Fail to append CRC...\n"); + return Status; + } + if (CircQueuePush(instPtr->txQueue, buff) == false) + { + DBG_ERROR("Cannot push packet to queue..\n"); + return EQUEUE; + } + break; + } + default: + { + DBG_ERROR("Unexpected frame type: %d.\n", type); + return EPARAM; + break; + } + } + return SUCCESS; +#else + DBG_ERROR("Unexpected call of Service_Packing in BER test mode.\n"); + return EUNEXP; +#endif +} + +/*****************************************************************************/ +/** + * @brief Initialize scan FSM. + * + * @param instPtr + * + * @return + * + ******************************************************************************/ +int32_t L2_Service_Init(L2_INST *instPtr) +{ + ASSERT(instPtr != NULL); + instPtr->serviceFsm.txSeqNum = 0; + instPtr->serviceFsm.rxSeqNum = 0; + memset((&instPtr->serviceFsm.rxLog), 0x00, sizeof(PAYLOAD)); + memset((&instPtr->serviceFsm.txLog), 0x00, sizeof(PAYLOAD)); + instPtr->serviceFsm.pktRecv = 0; + instPtr->serviceFsm.pktRecved = 0; +#ifdef DATALINK_ENABLE_BERTEST + instPtr->serviceFsm.bitTotal = 0; + instPtr->serviceFsm.bitError = 0; +#endif + return SUCCESS; +} + +/*****************************************************************************/ +/** + * @brief Handle service received packet. Send data up to MPC + * + * @param msg A point32_ter the the message frame. + * + * @return SUCCESS message has been successfully handled. + * other error occurred. + * + ******************************************************************************/ +int32_t L2_Service_PktHandler(L2_INST *instPtr, uint8_t *msg) +{ + ASSERT(instPtr != NULL); + ASSERT(msg != NULL); + int32_t Status; + switch (instPtr->frame.last) + { + case L2_SVC_FRAME: + { + if (instPtr->config.myType == L2_HEAD_NODE) + { + DBG_ERROR("Unexpected call, Only None-Head Node can handle L2_SVC_FRAME.\n"); + Status = EUNEXP; + break; + } + + // Implement a auto time sync. + uint32_t seqNum; + L2_EVENT l2Event; + l2Event.event = L2_EV_TIME_SYNC; + seqNum = msg[L2_MSG_SVC_SEQ_ID]; + +#ifdef DATALINK_ENABLE_AUTOTIMESYNC + l2Event.msg = NULL; + AssertL2Event(instPtr, &l2Event); +#else + int64_t timeAdj; + l2Event.msg = &timeAdj; + // Get Time Deviation + timeAdj = 0; + memcpy(&timeAdj, msg + L2_MSG_SVC_TMSYNC, L2_MSG_SVC_TMSYNC_LEN); + timeAdj |= (timeAdj & 0x0000000000800000) ? 0xFFFFFFFFFF000000 : 0x0000000000000000; + // FIXME: better approach? + // Implement a time sync procedure, first time received a time deviation in a service period. + if (seqNum % NUM_SERVICE_PRD_SLOTS == 0 || instPtr->serviceFsm.seqNum != seqNum) + { + AssertL2Event(instPtr, &l2Event); + } +#endif +#ifndef DATALINK_ENABLE_BERTEST + memcpy(instPtr->serviceFsm.rxLog + L2_MSG_SVC_PAYLOAD_LEN * seqNum, msg + L2_MSG_SVC_PAYLOAD, L2_MSG_SVC_PAYLOAD_LEN); + if (instPtr->config.myType == L2_HEAD_NODE) + { + // if last packet reset counting + if (seqNum >= (PAYLOAD_FLJ - 1) / L2_MSG_SVC_PAYLOAD + 1) + { + if (seqNum == instPtr->serviceFsm.rxSeqNum) + { + SysMonitor_UpdateRecvPayloadLJRaw(instPtr->serviceFsm.rxLog); + } + instPtr->serviceFsm.rxSeqNum = 0; + } + else + { + if (instPtr->serviceFsm.rxSeqNum == seqNum) + { + instPtr->serviceFsm.rxSeqNum++; + } + } + } + else + { + // if last packet reset counting + if (seqNum >= (PAYLOAD_LJ - 1) / L2_MSG_SVC_PAYLOAD + 1) + { + if (seqNum == instPtr->serviceFsm.rxSeqNum) + { + SysMonitor_UpdateRecvPayloadFLJRaw(instPtr->serviceFsm.rxLog); + } + instPtr->serviceFsm.rxSeqNum = 0; + } + else + { + if (instPtr->serviceFsm.rxSeqNum == seqNum) + { + instPtr->serviceFsm.rxSeqNum++; + } + } + } + +#else + for (int i = 0; i < SVC_PACK_LEN; i++) + { + instPtr->serviceFsm.bitError += count_ones(msg[i] ^ berTestData[i]); + } + instPtr->serviceFsm.bitTotal += SVC_PACK_LEN * 8; +#endif + instPtr->serviceFsm.pktRecved++; + // Reset Node TTL + Status = RstNodeTTL(instPtr->nodeInfoList, L2_HEAD_NODE_ID); + if (Status != SUCCESS) + { + DBG_ERROR("Failed to reset node %d TTL, errorCode: %ld.\n", L2_MEMBER_NODE_ID, Status); + } + break; + } + case L2_INFO_FRAME: + { + if (instPtr->config.myType != L2_HEAD_NODE) + { + DBG_ERROR("Unexpected call, Only Head Node can handle L2_SVC_FRAME.\n"); + Status = EUNEXP; + break; + } +#ifndef DATALINK_ENABLE_BERTEST + COORD coordTemp; + float tmpVal; + memcpy(&tmpVal, msg + L2_MSG_INFO_POSX, sizeof(float)); + coordTemp.x = tmpVal; + memcpy(&tmpVal, msg + L2_MSG_INFO_POSY, sizeof(float)); + coordTemp.y = tmpVal; + memcpy(&tmpVal, msg + L2_MSG_INFO_POSZ, sizeof(float)); + coordTemp.z = tmpVal; + Status = UpdateNodePos(instPtr->nodeInfoList, L2_MEMBER_NODE_ID, &coordTemp); + if (Status != SUCCESS) + { + DBG_ERROR("Failed to update node %d position, errorCode: %ld.\n", L2_MEMBER_NODE_ID, Status); + } + memcpy(&tmpVal, msg + L2_MSG_INFO_SPEEDX, sizeof(float)); + coordTemp.x = tmpVal; + memcpy(&tmpVal, msg + L2_MSG_INFO_SPEEDY, sizeof(float)); + coordTemp.y = tmpVal; + memcpy(&tmpVal, msg + L2_MSG_INFO_SPEEDZ, sizeof(float)); + coordTemp.z = tmpVal; + Status = UpdateNodeSpeed(instPtr->nodeInfoList, L2_MEMBER_NODE_ID, &coordTemp); + if (Status != SUCCESS) + { + DBG_ERROR("Failed to update node %d speed, errorCode: %ld.\n", L2_MEMBER_NODE_ID, Status); + } + + // TODO: Check + // Update Time deviation + int64_t devi, deviTrunc; + Status = L2_TimeSync_GetDeviatoion(instPtr, &devi); + if (Status != SUCCESS) + { + DBG_ERROR("Failed to compute slot deviation.\n"); + deviTrunc = 0; + } + else + { + if (devi > INT32_MAX || devi < INT32_MIN) + { + DBG_WARNING("Illegal deviation value: %lld, omit it.\n", devi); + deviTrunc = 0; + } + else if (devi > L2_MSG_SVC_TMSYNC_MAX || devi < L2_MSG_SVC_TMSYNC_MIN) + { + DBG_WARNING("Deviation value: %lld is out of adjustable range.\n", devi); + deviTrunc = (int32_t)devi; + } + else + { + deviTrunc = (int32_t)devi; + } + UpdateNodeTimeDeviation(instPtr->nodeInfoList, L2_MEMBER_NODE_ID, (uint32_t)deviTrunc); + } + Status = UpdateNodeTimeDeviation(instPtr->nodeInfoList, L2_MEMBER_NODE_ID, (uint32_t)deviTrunc); + if (Status != SUCCESS) + { + DBG_ERROR("Failed to update node %d time deviation, errorCode: %ld.\n", L2_MEMBER_NODE_ID, Status); + } +#else + for (int i = 0; i < SVC_PACK_LEN; i++) + { + instPtr->serviceFsm.bitError += count_ones(msg[i] ^ berTestData[i]); + } + instPtr->serviceFsm.bitTotal += SVC_PACK_LEN * 8; +#endif + instPtr->serviceFsm.pktRecved++; + // Reset Node TTL + Status = RstNodeTTL(instPtr->nodeInfoList, L2_MEMBER_NODE_ID); + if (Status != SUCCESS) + { + DBG_ERROR("Failed to reset node %d ttl, errorCode: %ld.\n", L2_MEMBER_NODE_ID, Status); + } + break; + } + default: + DBG_ERROR("Unsupported frame type: %ld.\n", instPtr->frame.last); + break; + } + return Status; +} + +/*****************************************************************************/ +/** + * @brief Service FSM Routine. + * + * @param instPtr + * @param schedEntry + * + * @return Slot has been used. + * + ******************************************************************************/ +int32_t L2_Service_Routine(L2_INST *instPtr, L2_RTNE_TABLE_ENTRY *schedEntry) +{ + ASSERT(instPtr != NULL); + DBG_INFO("-------- ServiceNet Routine --------\n"); + uint8_t *sendData; + int32_t usedSlots; + L2_TOR_TYPE torState; + if (schedEntry->src == instPtr->config.myId) + { + torState = L2_TOR_TX; + } + else if (schedEntry->dst == instPtr->config.myId) + { + torState = L2_TOR_RX; + instPtr->serviceFsm.pktRecv++; + } + else + { + torState = L2_TOR_SUSPEND; + } + + switch (schedEntry->slotType) + { + case L2_SLOT_SERVICE: + if (torState == L2_TOR_TX) + { +#ifndef DATALINK_ENABLE_BERTEST + if (instPtr->serviceFsm.txSeqNum == 0) + { + if (instPtr->config.myType == L2_HEAD_NODE) + { + SysMonitor_GetSendPayloadFLJRaw(instPtr->serviceFsm.txLog); + } + else + { + SysMonitor_GetSendPayloadLJRaw(instPtr->serviceFsm.txLog); + } + } + // Packing service data + Service_Packing(instPtr, L2_SVC_FRAME); + if (CircQueuePop(instPtr->txQueue, (void **)(&sendData)) == true) + { + memcpy(instPtr->sendPktData, sendData, SVC_PACK_LEN); + free(sendData); + } + else + { + DBG_ERROR("Failed to pop tx queue.\n"); + } +#else + memcpy(instPtr->config.phyInstRef->sendFrameBuff, berTestData, SVC_PACK_LEN); +#endif + } + // FIXME: Steer antenna to point to destination. + Phy_SetBeamAngle(instPtr->config.phyInstRef, 0.0, 0.0); + Phy_SetBeamWidth(instPtr->config.phyInstRef, PHY_ANT_BEAM_8); + Phy_SetMode(instPtr->config.phyInstRef, PHY_MODE_SCHEDULE); + L2_SetupNextSlot(instPtr, torState, L2_SVC_FRAME); + usedSlots = NUM_SERVICE_SLOTS; + break; +#ifndef DATALINK_ENABLE_BERTEST + case L2_SLOT_ADVERTISE: + if (torState == L2_TOR_TX) + { + // Packing response data. + Service_Packing(instPtr, L2_INFO_FRAME); + if (CircQueuePop(instPtr->txQueue, (void **)(&sendData)) == true) + { + memcpy(instPtr->sendPktData, sendData, RSP_PACK_LEN); + free(sendData); + } + else + { + DBG_ERROR("Failed to pop tx queue.\n"); + } + } + // FIXME: Steer antenna to point to destination. + Phy_SetBeamAngle(instPtr->config.phyInstRef, 0.0, 0.0); + Phy_SetBeamWidth(instPtr->config.phyInstRef, PHY_ANT_BEAM_120); + Phy_SetMode(instPtr->config.phyInstRef, PHY_MODE_SCHEDULE); + L2_SetupNextSlot(instPtr, torState, L2_INFO_FRAME); + usedSlots = NUM_RESPONSE_SLOTS; + break; +#endif + default: + DBG_ERROR("UNKNOWN slot type [%d].\n", schedEntry->slotType); + return NUM_SLOTS_NONE; + } +#ifdef DATALINK_ENABLE_BERTEST + uint32_t pktLoss; + double errorRate, lossRate; + pktLoss = instPtr->serviceFsm.pktRecv - instPtr->serviceFsm.pktRecved; + lossRate = (instPtr->serviceFsm.pktRecv == 0) ? 0 : (double)pktLoss / (double)instPtr->serviceFsm.pktRecv; + errorRate = (instPtr->serviceFsm.bitTotal == 0) ? 0 : (double)instPtr->serviceFsm.bitError / (double)instPtr->serviceFsm.bitTotal; + DBG_PRINT("Packet Loss Rate -- Total: %lu, Loss: %lu.\n", instPtr->serviceFsm.pktRecv, pktLoss); + DBG_PRINT("Bit Error Rate -- Total:%lu, Error:%lu.\n", instPtr->serviceFsm.bitTotal, instPtr->serviceFsm.bitError); +#endif + return usedSlots; +} diff --git a/df_datalink_sp/src/networking/link_layer/time_sync.c b/df_datalink_sp/src/networking/link_layer/time_sync.c new file mode 100644 index 0000000..7754a07 --- /dev/null +++ b/df_datalink_sp/src/networking/link_layer/time_sync.c @@ -0,0 +1,126 @@ +/*****************************************************************************/ +/** + * Description: Time sync implementation file. + * + * Date: 2021-12-04 16:32 + * LastEditors: FanHao + * LastEditTime: 2022-07-10 20:43 + * Revisions: Rev 0.0 + * History: + * [2022-07-10]: New branch for Dijian. + * [2021-12-04]: Initial version. + * + * Copyright(c) 2021 Beijing Institute of Technology. + * Lab of Communication and Networking + * + ******************************************************************************/ + +/***************************** Include Files *********************************/ +#include + +#include "error.h" +#include "common.h" +#include "link_layer.h" +#include "../phy_layer/phy_reg.h" +/************************** Constant Definitions *****************************/ +#define MAX_FREQ_EST_NUM 128 // 32bit word +#define SVC_FREQ_EST_NUM 512 // byte +#define MGMT_FREQ_EST_NUM 512 // byte +#define BISAR_FREQ_EST_NUM 480 // byte + +#define SYS_CLK_FREQ 192000000.0 // Hz +#define SIG_CLK_FREQ 245760000.0 // Hz +#define CXR_FREQ 3800000000.0 // Hz + +#define NORMAL_SLOT_CLK_NUM 960000.0 // 9600000= 5e-3*192e6 +#define COUNTER_10NS_MAX 500000 // how many 10ns in a 5ms + +#define LIGHT_SPPED_AIR 299702547.0 // m/s +#define LIGHT_SPPED_VAC 299792458.0 // m/s + +// #define PHY_SYNCT2FEND_200K 904052UL +// #define PHY_SYNCT2FEND_200K 924232UL + +#define PHY_SYNCT2FEND_2K_20MS 276336UL // 1.919ms +#define PHY_SYNCT2FEND_2K_100MS 11796336UL // 81.919ms + +#define PHY_LOCAL_CNT_MAX 0x0000FFFFFFFFFFFFULL +/***************** Macros (Inline Functions) Definitions *********************/ +/**************************** Type Definitions *******************************/ +/************************** Variable Definitions *****************************/ +/************************** Function Prototypes ******************************/ + +/*****************************************************************************/ +/** + * @brief Apply local time adjustment by addition. + * + * @param instPtr. + * @param adjustment + * + * @return + * + ******************************************************************************/ +inline int32_t L2_TimeSync_LocalTimerAdd(L2_INST *instPtr, int64_t adjustment) +{ + // read nextSendTime from physical layer + Phy_SetTimeWord(instPtr->config.phyInstRef, adjustment, PHY_TIME_WORD_LOCAL_ADJ); + PhyWrite(instPtr->config.phyInstRef, TM_ADJ_MODE, TM_ADJ_MODE_ADD); + return SUCCESS; +} + +/*****************************************************************************/ +/** + * @brief Align slot, base on physical layer information. + * + * @param instPtr. + * + * @return + * + ******************************************************************************/ +int32_t L2_TimeSync_SlotAlign(L2_INST *instPtr) +{ + int32_t Status; + int64_t slotAdj; + Status = L2_TimeSync_GetDeviatoion(instPtr, &slotAdj); + if (Status != SUCCESS) + { + DBG_ERROR("Failed to compute slot deviation.\n"); + return Status; + } + return L2_TimeSync_LocalTimerAdd(instPtr, slotAdj); +} + +/*****************************************************************************/ +/** + * @brief Compute slot deviation of received frame. + * + * @param instPtr. + * @param devi + * + * @return + * + ******************************************************************************/ +int32_t L2_TimeSync_GetDeviatoion(L2_INST *instPtr, int64_t *devi) +{ + // read nextSendTime from physical layer + int64_t currentTarget, lastFrameSync, slotMeasure; + currentTarget = PhyRead(instPtr->config.phyInstRef, TM_TARGET_L); + currentTarget |= ((int64_t)PhyRead(instPtr->config.phyInstRef, TM_TARGET_H)) << 32; + lastFrameSync = PhyRead(instPtr->config.phyInstRef, FSTIME_L); + lastFrameSync |= ((int64_t)PhyRead(instPtr->config.phyInstRef, FSTIME_H)) << 32; + slotMeasure = (currentTarget > lastFrameSync) ? (currentTarget - lastFrameSync) + : (currentTarget - lastFrameSync + PHY_LOCAL_CNT_MAX); + switch (Phy_GetLastDetectedFrameType(instPtr->config.phyInstRef)) + { + case L1_2KBPS_20MS_FRAME: + *devi = ((int64_t)PHY_SYNCT2FEND_2K_20MS) - slotMeasure; + break; + case L1_2KBPS_100MS_FRAME: + *devi = ((int64_t)PHY_SYNCT2FEND_2K_100MS) - slotMeasure; + break; + default: + DBG_ERROR("Unsupported frame type: %d.\n", Phy_GetLastDetectedFrameType(instPtr->config.phyInstRef)); + return EIGNORE; + } + return SUCCESS; +} diff --git a/df_datalink_sp/src/networking/phy_layer/phy_antenna.c b/df_datalink_sp/src/networking/phy_layer/phy_antenna.c new file mode 100644 index 0000000..82dce23 --- /dev/null +++ b/df_datalink_sp/src/networking/phy_layer/phy_antenna.c @@ -0,0 +1,348 @@ +/*****************************************************************************/ +/** + * Description: Antenna configuration functions. + * + * Author: Fan Hao + * Date: 2022-06-18 16:37 + * LastEditors: Fan Hao + * LastEditTime: 2022-06-18 17:15 + * Revisions: Rev 0.0 + * History: + * [2022-06-18]: Initial version. + * + * Copyright(c) 2022 Beijing Institute of Technology. + * Lab of Communication and Networking + * + ******************************************************************************/ +#include +#include +#include +#include "error.h" +#include "../config//app_config.h" +#include "phy_layer.h" + +#define ANT_PI 3.14159265358979323846 + +#define ANT_COINFO_HEAD 0xAA +#define ANT_COINFO_TAIL 0xCC + +#define CTRL_WORD_DEFAULT 0x00 + +#define ANT_MODE_BEAM_MASK 0xF0 +#define ANT_MODE_NARROR_BEAM 0x00 // 8 +#define ANT_MODE_WIDE_BEAM_1 0x10 // 25 +#define ANT_MODE_WIDE_BEAM_2 0x20 // 60 +#define ANT_MODE_WIDE_BEAM_3 0x30 // 120 + +#define ANT_MODE_HIGH_POWER 0x00 +#define ANT_MODE_LOWAPOWER 0x04 +#define ANT_MODE_STANDBY 0x0F +#define ATN_MODE_DEFAULT (ANT_MODE_WIDE_BEAM_1 | ANT_MODE_LOWAPOWER) +#define ATN_MODE_HIGH (ANT_MODE_WIDE_BEAM_1 | ANT_MODE_HIGH_POWER) + +#define DEFAULT_CENTRTAL_FREQ 0x06D7 // 26.25GHz + +#define RXTXMODE_RX 0x00 +#define RXTXMODE_TX 0x01 + +#define RXTXMODE_DEFAULT 0x00 + +#define CALIBRMODE_NORMAL 0x00 +#define CALIBRMODE_SINGLE_TR_CAL 0x01 + +#define RF_CTRL_DEFAULT 0x00 + +// Pair by regex +// Regex: (([0-9]+, ){8}) +uint16_t hopPattern_Config[L1_FRAME_MAX_HOPS] = +{ + 0 +}; + +uint16_t hopPattern_2KBPS_20MS[L1_FRAME_2KBPS_20MS_HOPS] = +{ + 1500 +}; + +// uint16_t hopPattern_2KBPS_100MS[L1_FRAME_2KBPS_100MS_HOPS] = +// { +// 0, 44, 88, 131, 175, 219, 263, 306, +// 350, 394, 438, 481, 525, 569, 613, 656, +// 700, 744, 788, 831, 875, 919, 963, 1006, +// 1050, 1094, 1138, 1181, 1225, 1269, 1313, 1356, +// 1400, 1444, 1488, 1531, 1575, 1619, 1663, 1706, +// 1750, 1794, 1838, 1881, 1925, 1969, 2013, 2056, +// 2100, 2144, 2188, 2231, 2275, 2319, 2363, 2406, +// 2450, 2494, 2538, 2581, 2625, 2669, 2713, 2756, +// 2800, 2844, 2888, 2931, 2975, 3019, 3063, 3106, +// 3150, 3194, 3238, 3281, 3325, 3369, 3413, 3456, +// 3500 +// }; + +uint16_t hopPattern_2KBPS_100MS[L1_FRAME_2KBPS_100MS_HOPS] = +{ + 1500 +}; + +uint16_t hopPattern_10KBPS_10MS[L1_FRAME_10KBPS_10MS_HOPS] = +{ + 1500 +}; + +uint16_t hopPattern_10KBPS_20MS[L1_FRAME_10KBPS_20MS_HOPS] = +{ + 1500, 1600, 1700, 1800, 1900, 2000, 1500, 1600, + 1700, 1800, 1900 +}; + +uint16_t hopPattern_40KBPS_20MS[L1_FRAME_40KBPS_20MS_HOPS] = +{ + 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, + 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, + 2400, 2400, 2400 +}; + +uint16_t hopPattern_40KBPS_10MS[L1_FRAME_40KBPS_10MS_HOPS] = +{ + 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, + 2400 +}; +uint16_t hopPattern_200KBPS_5MS[L1_FRAME_200KBPS_5MS_HOPS] = +{ + 500, 1600, 1700, 1800, 1900, 2000, 1500, 1600, + 1700, 1800, 1900, 2000, 1500, 1600, 1700, 1800, + 1900, 2000, 1500, 1500 +}; +uint16_t hopPattern_1M2BPS_5MS[L1_FRAME_1M2BPS_5MS_HOPS] = +{ + 500, 600, 700, 800, 900, 1000, 500, 600, + 700, 800, 900, 1000, 500, 600, 700, 800, + 900, 1000, 500, 500 +}; + +// Pair by regex +// Regex: ((\{\.oaxis = [0-9]+[ ,]+\.raxis = [0-9]+[ ]*\}, ){2}) +#ifdef PHY_BEAM_SET_PRESET +PHY_ANT_ANGLE antSubnrrwPattern[L1_NUM_ANT_SUBNRRW_PATTERN] = +{ + {.oaxis = 0 , .raxis = 222}, {.oaxis = 10, .raxis = 85 }, + {.oaxis = 14, .raxis = 307}, {.oaxis = 17, .raxis = 170}, + {.oaxis = 19, .raxis = 32 }, {.oaxis = 21, .raxis = 255}, + {.oaxis = 24, .raxis = 117}, {.oaxis = 25, .raxis = 340}, + {.oaxis = 27, .raxis = 202}, {.oaxis = 29, .raxis = 65 }, + {.oaxis = 31, .raxis = 287}, {.oaxis = 32, .raxis = 150}, + {.oaxis = 34, .raxis = 12 }, {.oaxis = 35, .raxis = 235}, + {.oaxis = 36, .raxis = 97 }, {.oaxis = 38, .raxis = 320}, + {.oaxis = 39, .raxis = 182}, {.oaxis = 40, .raxis = 45 }, + {.oaxis = 41, .raxis = 267}, {.oaxis = 43, .raxis = 130}, + {.oaxis = 44, .raxis = 352}, {.oaxis = 45, .raxis = 215}, + {.oaxis = 46, .raxis = 77 }, {.oaxis = 47, .raxis = 300}, + {.oaxis = 48, .raxis = 162}, {.oaxis = 49, .raxis = 25 }, + {.oaxis = 50, .raxis = 247}, {.oaxis = 51, .raxis = 110}, + {.oaxis = 52, .raxis = 332}, {.oaxis = 53, .raxis = 195}, + {.oaxis = 54, .raxis = 57 }, {.oaxis = 55, .raxis = 280}, + {.oaxis = 56, .raxis = 142}, {.oaxis = 57, .raxis = 5 }, + {.oaxis = 58, .raxis = 227}, {.oaxis = 59, .raxis = 90 }, + {.oaxis = 60, .raxis = 312} +}; +PHY_ANT_ANGLE antNrrwPattern[L1_NUM_ANT_NRRW_PATTERN] = +{ + {.oaxis = 0 , .raxis = 222}, {.oaxis = 7 , .raxis = 85 }, + {.oaxis = 10, .raxis = 307}, {.oaxis = 13, .raxis = 170}, + {.oaxis = 15, .raxis = 32 }, {.oaxis = 17, .raxis = 255}, + {.oaxis = 18, .raxis = 117}, {.oaxis = 20, .raxis = 340}, + {.oaxis = 21, .raxis = 202}, {.oaxis = 22, .raxis = 65 }, + {.oaxis = 24, .raxis = 287}, {.oaxis = 25, .raxis = 150}, + {.oaxis = 26, .raxis = 12 }, {.oaxis = 27, .raxis = 235}, + {.oaxis = 28, .raxis = 97 }, {.oaxis = 29, .raxis = 320}, + {.oaxis = 30, .raxis = 182}, {.oaxis = 31, .raxis = 45 }, + {.oaxis = 32, .raxis = 267}, {.oaxis = 33, .raxis = 130}, + {.oaxis = 34, .raxis = 352}, {.oaxis = 34, .raxis = 215}, + {.oaxis = 35, .raxis = 77 }, {.oaxis = 36, .raxis = 300}, + {.oaxis = 37, .raxis = 162}, {.oaxis = 38, .raxis = 25 }, + {.oaxis = 38, .raxis = 247}, {.oaxis = 39, .raxis = 110}, + {.oaxis = 40, .raxis = 332}, {.oaxis = 41, .raxis = 195}, + {.oaxis = 41, .raxis = 57 }, {.oaxis = 42, .raxis = 280}, + {.oaxis = 43, .raxis = 142}, {.oaxis = 44, .raxis = 5 }, + {.oaxis = 44, .raxis = 227}, {.oaxis = 45, .raxis = 90 }, + {.oaxis = 46, .raxis = 312}, {.oaxis = 46, .raxis = 175}, + {.oaxis = 47, .raxis = 37 }, {.oaxis = 48, .raxis = 260}, + {.oaxis = 48, .raxis = 122}, {.oaxis = 49, .raxis = 345}, + {.oaxis = 49, .raxis = 207}, {.oaxis = 50, .raxis = 70 }, + {.oaxis = 51, .raxis = 292}, {.oaxis = 51, .raxis = 155}, + {.oaxis = 52, .raxis = 17 }, {.oaxis = 53, .raxis = 240}, + {.oaxis = 53, .raxis = 102}, {.oaxis = 54, .raxis = 325}, + {.oaxis = 54, .raxis = 187}, {.oaxis = 55, .raxis = 50 }, + {.oaxis = 55, .raxis = 272}, {.oaxis = 56, .raxis = 135}, + {.oaxis = 57, .raxis = 357}, {.oaxis = 57, .raxis = 220}, + {.oaxis = 58, .raxis = 82 }, {.oaxis = 58, .raxis = 305}, + {.oaxis = 59, .raxis = 167}, {.oaxis = 59, .raxis = 30 }, + {.oaxis = 60, .raxis = 252} +}; +#else +PHY_ANT_ANGLE antSubnrrwPattern[NUM_ANT_SUBNRRW_PATTERN] = +{ + 0 +}; +PHY_ANT_ANGLE antNrrwPattern[NUM_ANT_NRRW_PATTERN] = +{ + 0 +}; +#endif +/*****************************************************************************/ +/** + * @brief + * + * @param antConfigPtr + * + * @return + * + ******************************************************************************/ +int32_t Phy_AntConfigInit(PHY_ANT_COINFO *antConfigPtr) +{ + ASSERT(antConfigPtr != NULL); + + antConfigPtr->ctrlWord = 0x00; + antConfigPtr->antMode = ATN_MODE_DEFAULT; + + // FIXME: Dummy default value. + // off axis angle setting + antConfigPtr->oaxis[0] = 0; + antConfigPtr->oaxis[1] = 0; + // round axis angle setting + antConfigPtr->raxis[0] = 0; + antConfigPtr->raxis[1] = 0; + // *********************** + + antConfigPtr->antFreq[0] = (uint8_t)(DEFAULT_CENTRTAL_FREQ); + antConfigPtr->antFreq[1] = (uint8_t)(DEFAULT_CENTRTAL_FREQ >> 8); + + // FIXME: Dummy default value. + // trSelect + antConfigPtr->trSlect = 0; + // Antenna attenuation setting + antConfigPtr->antAtt = 20; + // phase setting + antConfigPtr->phase = 0; + // *********************** + + antConfigPtr->rxtxMode = RXTXMODE_DEFAULT; + antConfigPtr->calibrMode = CALIBRMODE_NORMAL; + antConfigPtr->antReserved = 0x00; + + // FIXME: Dummy default value. + // RF mode control + antConfigPtr->rfCtrl = RF_CTRL_DEFAULT; + // RF frequency + antConfigPtr->rfFreq[0] = (uint8_t)(DEFAULT_CENTRTAL_FREQ); + antConfigPtr->rfFreq[1] = (uint8_t)(DEFAULT_CENTRTAL_FREQ >> 8); + // RF MGC control + antConfigPtr->rfTxMgc = 0; + // RF channel 1&2 calibration mgc + antConfigPtr->rf12CalMgc = 0; + // RF channel 2&3 calibration mgc + antConfigPtr->rf34CalMgc = 0; + // Receive channel 1-4 MGC + antConfigPtr->rcvMgc = 0; + antConfigPtr->rfReserved0 = 0x00; + antConfigPtr->rfReserved1 = 0x00; + // *********************** + return SUCCESS; +} + +int32_t Phy_SetBeamNo(PHY_INST *instPtr, int32_t beamNo) +{ + if (instPtr->beamWd.next == PHY_ANT_BEAM_8) + { + if (beamNo >= L1_NUM_ANT_NRRW_PATTERN) + { + return FAILURE; + } + else + { + instPtr->beamNo.next = beamNo; + instPtr->antConfigPtr.oaxis[1] = (uint8_t)(antNrrwPattern[beamNo].oaxis); + instPtr->antConfigPtr.oaxis[0] = (uint8_t)((antNrrwPattern[beamNo].oaxis) >> 8); + instPtr->antConfigPtr.raxis[1] = (uint8_t)(antNrrwPattern[beamNo].raxis); + instPtr->antConfigPtr.raxis[0] = (uint8_t)((antNrrwPattern[beamNo].raxis) >> 8); + return SUCCESS; + } + } + else if (instPtr->beamWd.next == PHY_ANT_BEAM_25) + { + if (beamNo >= L1_NUM_ANT_SUBNRRW_PATTERN) + { + return FAILURE; + } + else + { + instPtr->beamNo.next = beamNo; + instPtr->antConfigPtr.oaxis[1] = (uint8_t)(antSubnrrwPattern[beamNo].oaxis); + instPtr->antConfigPtr.oaxis[0] = (uint8_t)((antSubnrrwPattern[beamNo].oaxis) >> 8); + instPtr->antConfigPtr.raxis[1] = (uint8_t)(antSubnrrwPattern[beamNo].raxis); + instPtr->antConfigPtr.raxis[0] = (uint8_t)((antSubnrrwPattern[beamNo].raxis) >> 8); + return SUCCESS; + } + } + else + { + // Beam number assign not support. + // Assign default angle (0,0) + instPtr->beamNo.next = 0; + instPtr->antConfigPtr.oaxis[1] = 0; + instPtr->antConfigPtr.oaxis[0] = 0; + instPtr->antConfigPtr.raxis[1] = 0; + instPtr->antConfigPtr.raxis[0] = 0; + DBG_WARNING("Using default beam number...\n"); + return SUCCESS; + } +} + +int32_t Phy_SetBeamWidth(PHY_INST *instPtr, PHY_ANT_BEAM_WIDTH beamWidth) +{ + uint8_t beamConfig = instPtr->antConfigPtr.antMode & (~ANT_MODE_BEAM_MASK); + switch (beamWidth) + { + case PHY_ANT_BEAM_120: + beamConfig |= ANT_MODE_WIDE_BEAM_3; + break; + case PHY_ANT_BEAM_60: + beamConfig |= ANT_MODE_WIDE_BEAM_2; + break; + case PHY_ANT_BEAM_25: + beamConfig |= ANT_MODE_WIDE_BEAM_1; + break; + case PHY_ANT_BEAM_8: + beamConfig |= ANT_MODE_NARROR_BEAM; + break; + default: + DBG_ERROR("Beam width code: 0x%08X is illegal.\n\r", beamWidth); + return EPARAM; + break; + } + instPtr->antConfigPtr.antMode = beamConfig; + instPtr->beamWd.next = beamWidth; + return SUCCESS; +} + +// Common version radius double input +int32_t Phy_SetBeamAngle(PHY_INST *phyInstPtr, double offAx, double rndAx) +{ + uint16_t offAxDeg = 0; + uint16_t rndAxDeg = 0; + offAxDeg = (offAx >= 0) ? (((int32_t)(offAx * 180 / ANT_PI)) % 360) : (((int32_t)(offAx * 180 / ANT_PI)) % 360 + 360); + rndAxDeg = (rndAx >= 0) ? (((int32_t)(rndAx * 180 / ANT_PI)) % 360) : (((int32_t)(rndAx * 180 / ANT_PI)) % 360 + 360); + if (offAxDeg > 60) + { + DBG_ERROR("Angle out of range, off axis angle: %u (should be 0~60), round axis angle: %u (should be 0~360).\n", + offAxDeg, rndAxDeg); + return EPARAM; + } + offAxDeg = offAxDeg * 10; + rndAxDeg = rndAxDeg * 10; + phyInstPtr->antConfigPtr.oaxis[1] = (uint8_t)offAxDeg; + phyInstPtr->antConfigPtr.oaxis[0] = (uint8_t)(offAxDeg >> 8); + phyInstPtr->antConfigPtr.raxis[1] = (uint8_t)rndAxDeg; + phyInstPtr->antConfigPtr.raxis[0] = (uint8_t)(rndAxDeg >> 8); + return SUCCESS; +} diff --git a/df_datalink_sp/src/networking/phy_layer/phy_layer.c b/df_datalink_sp/src/networking/phy_layer/phy_layer.c new file mode 100644 index 0000000..7c71e31 --- /dev/null +++ b/df_datalink_sp/src/networking/phy_layer/phy_layer.c @@ -0,0 +1,921 @@ +/*****************************************************************************/ +/** + * Description: Implementation of physical control functions + * + * Date: 2021-11-16 00:08 + * LastEditTime: 2023-04-23 17:48 + * Revisions: Rev 0.2 + * History: + * [2021-11-16]: Initial version. + * [2022-06-18]: New branch for glink control purpose: + * -Add poll mode, physical layer will start Tx/Rx procedure + * at specific time stamp. + * -Add 61/37 beam switch + * -Code simplification. + * [2023-04-24]: Porting for DUIFEI. + * + * Copyright(c) 2021 Beijing Institute of Technology. + * Lab of Communication and Networking + * + ******************************************************************************/ + +/***************************** Include Files *********************************/ +#include +#include +#include "xbram.h" +#include "xadcps.h" +#include "phy_layer.h" +#include "util.h" +#include "error.h" +#include "../config/app_config.h" + +/************************** Constant Definitions *****************************/ +#define TOR_BUFF_MAX_SIZE 1024 // 8192bits +#define TMWORD_FRAC_MAX 500000 +#define ANTCONFIG_MAX_LEN (8192 / 2) +#define PAYLOAD_MAX_LEN (4096 / 2) + +#define INIT_BEAM_NO 0 +#define INIT_ANT_WD PHY_ANT_BEAM_120 +#define INIT_ANT_NO 0 + +#define L1_FRAME_NONE_LEN UINT32_MAX // byte +#define L1_FRAME_2KBPS_20MS_LEN 0 // byte +#define L1_FRAME_2KBPS_100MS_LEN (240 / 8) // byte +#define L1_FRAME_10KBPS_10MS_LEN 0 // byte +#define L1_FRAME_10KBPS_20MS_LEN (240 / 8) // byte +#define L1_FRAME_40KBPS_20MS_LEN (2160 / 8) // byte +#define L1_FRAME_40KBPS_10MS_LEN (720 / 8) // byte +#define L1_FRAME_200KBPS_5MS_LEN (2048 / 8) // byte +#define L1_FRAME_1M2BPS_5MS_LEN (8184 / 8) // byte + +#define L1_FRAME_NONE_COMP UINT32_MAX // *10ns +#define L1_FRAME_2KBPS_20MS_COMP 1622400 // *10ns +#define L1_FRAME_2KBPS_100MS_COMP 1622400 // *10ns +#define L1_FRAME_10KBPS_10MS_COMP 747366 // *10ns +#define L1_FRAME_10KBPS_20MS_COMP 747366 // *10ns +#define L1_FRAME_40KBPS_20MS_COMP 97066 // *10ns +#define L1_FRAME_40KBPS_10MS_COMP 97066 // *10ns +#define L1_FRAME_200KBPS_5MS_COMP 17067 // *10ns +#define L1_FRAME_1M2BPS_5MS_COMP 17067 // *10ns + +/***************** Macros (Inline Functions) Definitions *********************/ +/************************** Function Prototypes ******************************/ +static void Phy_RcdShift(PHY_RCD *rcd, int32_t netxVal); +static int32_t SetSendData(PHY_INST *instPtr, L1_FRAME_TYPE frameType, uint8_t *buff); + +/**************************** Type Definitions *******************************/ + +/************************** Variable Definitions *****************************/ + +/*****************************************************************************/ +/** + * @brief Get received data (base on PS Record), store it to data buffer. + * + * @param instPtr + * rcvBuffPtr + * + * @return SUCCESS + * FAILURE last frame type cannot be recognized. + * + ******************************************************************************/ +int32_t Phy_RetrieveRecvData(PHY_INST *instPtr, uint8_t *buff) +{ + ASSERT(instPtr != NULL); + uint32_t frameLen, recvBramAddr; + frameLen = Phy_GetFrameLen(instPtr->frameType.last); + if (frameLen == L1_FRAME_NONE_LEN) + { + return FAILURE; + } + else + { + // Ping-pong flow. + recvBramAddr = instPtr->rxDataPtr + ((PhyRead(instPtr, RECV_DATA_SATE) & RECV_DATA_OFFSET_MASK) >> RECV_DATA_OFFSET_SHIFT); + memcpy(buff, (uint8_t *)recvBramAddr, frameLen); + } + return SUCCESS; +} + +/*****************************************************************************/ +/** + * @brief Setup data will be sent in next slot. + * + * @param instPtr A pointer to physical layer control instance. + * + * @return FAILURE Error occurred. + * SUCCESS Setting data successful. + * + ******************************************************************************/ +static int32_t SetSendData(PHY_INST *instPtr, L1_FRAME_TYPE frameType, uint8_t *buff) +{ + ASSERT(instPtr != NULL); + uint32_t frameLen, sendCmd; + frameLen = Phy_GetFrameLen(frameType); + + if (frameLen == L1_FRAME_NONE_LEN) + { + return FAILURE; + } + else + { + // Implement a ping-pong flow, offset always is 0 or half of buffer depth. + instPtr->sendOffset = (instPtr->sendOffset == PAYLOAD_MAX_LEN) ? 0 : PAYLOAD_MAX_LEN; + memcpy((uint8_t *)(instPtr->txDataPtr + instPtr->sendOffset), buff, frameLen); + // Trigger Physical layer to start fetching data. + sendCmd = frameLen & SEND_DATA_CMD_LEN_MASK; + sendCmd |= (instPtr->sendOffset << SEND_DATA_CMD_OFFSET_SHIFT) & SEND_DATA_CMD_OFFSET_MASK; + PhyWrite(instPtr, SEND_DATA_CMD, sendCmd); + } + return SUCCESS; +} + +/*****************************************************************************/ +/** + * @brief Check whether a frame was detected. (Do not check if the frame was + * deoced.) + * + * @param instPtr + * + * @return true + * false + * + ******************************************************************************/ +inline bool Phy_IsFrameDetected(PHY_INST *instPtr) +{ + ASSERT(instPtr != NULL); + if (instPtr->TOR.last == PHY_TOR_RX && instPtr->isAcq && instPtr->isFrameSync) + { + return true; + } + else + { + return false; + } +} + +/*****************************************************************************/ +/** + * @brief Check whether a frame was received. (Do not check if the frame was + * crashed.) + * + * @param instPtr + * + * @return true + * false + * + ******************************************************************************/ +inline bool Phy_IsFrameReceived(PHY_INST *instPtr) +{ + ASSERT(instPtr != NULL); + if (instPtr->TOR.last == PHY_TOR_RX && instPtr->isAcq && instPtr->isFrameSync && instPtr->isDecode) + { + return true; + } + else + { + return false; + } +} + +/*****************************************************************************/ +/** + * @brief Check whether a frame was valid. (if the frame was crashed, it will + * be regarded as not valid. + * + * @param instPtr + * + * @return true + * false + * + ******************************************************************************/ +inline bool Phy_IsFrameValid(PHY_INST *instPtr) +{ + ASSERT(instPtr != NULL); + if (instPtr->TOR.last == PHY_TOR_RX && instPtr->isAcq && instPtr->isFrameSync && instPtr->isDecode && instPtr->isValid) + { + return true; + } + else + { + return false; + } +} + +/*****************************************************************************/ +/** + * @brief Get frame type of the frame in receive data buffer (Base on PS Record). + * + * @param instPtr A pointer to physical layer control instance. + * + * @return Layer2 frame type. Refer "frame_def.h" + * + ******************************************************************************/ +inline L1_FRAME_TYPE Phy_GetLastDetectedFrameType(PHY_INST *instPtr) +{ + ASSERT(instPtr != NULL); + if (Phy_IsFrameDetected(instPtr) == false) + { + return L1_NONE_FRAME; + } + else + { + return instPtr->frameType.last; + } +} + +/*****************************************************************************/ +/** + * @brief Get frame type of the frame in receive data buffer (Base on PS Record). + * + * @param instPtr A pointer to physical layer control instance. + * + * @return Layer2 frame type. Refer "frame_def.h" + * + ******************************************************************************/ +inline L1_FRAME_TYPE Phy_GetLastReceivedFrameType(PHY_INST *instPtr) +{ + ASSERT(instPtr != NULL); + if (Phy_IsFrameReceived(instPtr) == false) + { + return L1_NONE_FRAME; + } + else + { + return instPtr->frameType.last; + } +} + +/*****************************************************************************/ +/** + * @brief Get frame type of the frame was sent in last slot. + * + * @param instPtr A pointer to physical layer control instance. + * + * @return Layer2 frame type. Refer "frame_def.h" + * + ******************************************************************************/ +inline L1_FRAME_TYPE Phy_GetLastSentFrameType(PHY_INST *instPtr) +{ + ASSERT(instPtr != NULL); + if (instPtr->TOR.last != PHY_TOR_TX) + { + return L1_NONE_FRAME; + } + else + { + return instPtr->frameType.last; + } +} + +/*****************************************************************************/ +/** + * @brief Shift l1 status record.(newval->next->curr->last) + * + * @param instPtr A pointer to physical layer control instance. + * + * @return NONE. + * + ******************************************************************************/ +static void Phy_RcdShift(PHY_RCD *rcd, int32_t netxVal) +{ + ASSERT(rcd != NULL); + rcd->last = rcd->curr; + rcd->curr = rcd->next; + rcd->next = netxVal; +} + +/*****************************************************************************/ +/** + * @brief Get corresponding frame length in byte of L1 frame. + * + * @param frameType + * + * @return Corresponding frame length + * L1_FRAME_NONE_LEN if the frame type code cannot be recognized. + * + ******************************************************************************/ +uint32_t Phy_GetFrameLen(L1_FRAME_TYPE frameType) +{ + switch (frameType) + { + case L1_2KBPS_20MS_FRAME: + // FIXME: for DUIFEI net setup + return L1_FRAME_2KBPS_100MS_LEN; + // return L1_FRAME_2KBPS_20MS_LEN; + case L1_2KBPS_100MS_FRAME: + return L1_FRAME_2KBPS_100MS_LEN; + case L1_10KBPS_10MS_FRAME: + return L1_FRAME_10KBPS_10MS_LEN; + case L1_10KBPS_20MS_FRAME: + return L1_FRAME_10KBPS_20MS_LEN; + case L1_40KBPS_20MS_FRAME: + return L1_FRAME_40KBPS_20MS_LEN; + case L1_40KBPS_10MS_FRAME: + return L1_FRAME_40KBPS_10MS_LEN; + case L1_200KBPS_5MS_FRAME: + return L1_FRAME_200KBPS_5MS_LEN; + case L1_1M2BPS_5MS_FRAME: + return L1_FRAME_1M2BPS_5MS_LEN; + default: + return L1_FRAME_NONE_LEN; + } +} + +/*****************************************************************************/ +/** + * @brief Update Physical Layer reception status. + * + * @param instPtr + * + * @return + * + ******************************************************************************/ +void Phy_UpdateState(PHY_INST *instPtr) +{ + ASSERT(instPtr != NULL); + + Phy_RcdShift(&(instPtr->TOR), PHY_TOR_SUSPEND); + Phy_RcdShift(&(instPtr->frameType), L1_NONE_FRAME); + Phy_RcdShift(&(instPtr->antNo), INIT_ANT_NO); + Phy_RcdShift(&(instPtr->beamNo), INIT_BEAM_NO); + Phy_RcdShift(&(instPtr->beamWd), INIT_ANT_WD); + /* Update Frame Sate. */ + uint32_t txrxSate = PhyRead(instPtr, TXRX_STATE); + instPtr->isAcq = ((txrxSate & TXRX_STATE_ACQ_MASK) == TXRX_STATE_ACQ_SUCCESS) ? true : false; + instPtr->isFrameSync = ((txrxSate & TXRX_STATE_FSYNC_MASK) == TXRX_STATE_FSYNC_SUCCESS) ? true : false; + instPtr->isDecode = ((txrxSate & TXRX_STATE_DECODE_MASK) == TXRX_STATE_DECODE_SUCCESS) ? true : false; + + if (Phy_IsFrameReceived(instPtr)) + { + DBG_INFO("Physical layer finished reception procedure, retrieving received data...\n"); + instPtr->isValid = true; + } + else + { + instPtr->isValid = false; + } + return; +} + +/*****************************************************************************/ +/** + * @brief Initialize Physical Layer instance, allocate memory for buffers, + * apply a self test. + * + * @param instPtr + * phyConfig + * + * @return + * + ******************************************************************************/ +int32_t Phy_InstInit(PHY_INST **instPtr, PHY_CONFIG *phyConfig) +{ + ASSERT(instPtr != NULL); + ASSERT(phyConfig != NULL); + int32_t Status = SUCCESS; + *instPtr = (PHY_INST *)malloc(sizeof(PHY_INST)); + if ((*instPtr) == NULL) + { + return ENOMEM; + } + + memcpy(&((*instPtr)->phyCofig), phyConfig, sizeof(PHY_CONFIG)); + (*instPtr)->isPhyEn = false; + (*instPtr)->isAcq = false; + (*instPtr)->isFrameSync = false; + (*instPtr)->isDecode = false; + (*instPtr)->isValid = false; + (*instPtr)->isPresetHop = true; + (*instPtr)->antConfigOffset = 0; + (*instPtr)->sendOffset = 0; + + memset(&((*instPtr))->TOR, PHY_TOR_SUSPEND, sizeof(PHY_RCD)); + memset(&((*instPtr)->frameType), L1_NONE_FRAME, sizeof(PHY_RCD)); + memset(&((*instPtr)->antNo), (int32_t)INIT_BEAM_NO, sizeof(PHY_RCD)); + memset(&((*instPtr)->beamNo), (int32_t)INIT_ANT_NO, sizeof(PHY_RCD)); + memset(&((*instPtr)->beamWd), (int32_t)INIT_ANT_WD, sizeof(PHY_RCD)); + memset(&((*instPtr)->hwSate), 0x00, sizeof(HWSTATE)); + + Status = Phy_AntConfigInit(&((*instPtr)->antConfigPtr)); + if (Status != SUCCESS) + { + goto init_error; + } + + XBram_Config *bramConfigPtr; + XBram antConfigBram; + XBram txDataBram; + XBram rxDataBram; + bramConfigPtr = XBram_LookupConfig(phyConfig->antBramId); + if (bramConfigPtr == NULL) + { + Status = EDCONF; + goto init_error; + } + Status = XBram_CfgInitialize(&antConfigBram, bramConfigPtr, + bramConfigPtr->CtrlBaseAddress); + if (Status != SUCCESS) + { + goto init_error; + } + /* + * Execute the BRAM driver selftest. + */ + Status = XBram_SelfTest(&antConfigBram, 0); + if (Status != SUCCESS) + { + goto init_error; + } + + bramConfigPtr = XBram_LookupConfig(phyConfig->txBramId); + if (bramConfigPtr == NULL) + { + Status = EDCONF; + goto init_error; + } + Status = XBram_CfgInitialize(&txDataBram, bramConfigPtr, + bramConfigPtr->CtrlBaseAddress); + if (Status != SUCCESS) + { + goto init_error; + } + /* + * Execute the BRAM driver selftest. + */ + Status = XBram_SelfTest(&txDataBram, 0); + if (Status != SUCCESS) + { + goto init_error; + } + + bramConfigPtr = XBram_LookupConfig(phyConfig->rxBramId); + if (bramConfigPtr == NULL) + { + Status = EDCONF; + goto init_error; + } + Status = XBram_CfgInitialize(&rxDataBram, bramConfigPtr, + bramConfigPtr->CtrlBaseAddress); + if (Status != SUCCESS) + { + goto init_error; + } + /* + * Execute the BRAM driver selftest. + */ + Status = XBram_SelfTest(&rxDataBram, 0); + if (Status != SUCCESS) + { + goto init_error; + } + + (*instPtr)->txDataPtr = txDataBram.Config.MemBaseAddress; + (*instPtr)->rxDataPtr = rxDataBram.Config.MemBaseAddress; + (*instPtr)->antConfigDataPtr = antConfigBram.Config.MemBaseAddress; + + /* Initialize the XAdc driver. */ + XAdcPs_Config *xadcConfigPtr; + + xadcConfigPtr = XAdcPs_LookupConfig(phyConfig->hwXadcId); + if (xadcConfigPtr == NULL) + { + Status = EDCONF; + goto init_error; + } + XAdcPs_CfgInitialize(&((*instPtr)->hwXadc), xadcConfigPtr, xadcConfigPtr->BaseAddress); + + /* Self Test the XADC/ADC device */ + Status = XAdcPs_SelfTest(&((*instPtr)->hwXadc)); + if (Status != SUCCESS) + { + goto init_error; + } + + /* Disable the Channel Sequencer before configuring the Sequence registers. */ + XAdcPs_SetSequencerMode(&((*instPtr)->hwXadc), XADCPS_SEQ_MODE_SAFE); + + return SUCCESS; +init_error: + free(*instPtr); + return Status; +} + +/*****************************************************************************/ +/** + * @brief Start physical layer + * + * @param instPtr a pointer to physical instance + * + * @return NONE + * + ******************************************************************************/ +void Phy_Start(PHY_INST *instPtr) +{ + ASSERT(instPtr != NULL); + uint32_t phyMainCtrl = PhyRead(instPtr, PHY_MAIN_CTRL); + if ((phyMainCtrl & PHY_MAIN_CTRL_EN_MASK) == PHY_MAIN_CTRL_EN_EN) + { + DBG_WARNING("Physical layer was already enabled.\n"); + } + instPtr->isPhyEn = true; + // Enable CRC check automatically + PhyWrite(instPtr, PHY_MAIN_CTRL, (phyMainCtrl | PHY_MAIN_CTRL_EN_EN)); +} + +/*****************************************************************************/ +/** + * @brief Halt physical layer operation + * + * @param instPtr a pointer to physical instance + * + * @return NONE + * + ******************************************************************************/ +void Phy_Halt(PHY_INST *instPtr) +{ + ASSERT(instPtr != NULL); + uint32_t phyMainCtrl = PhyRead(instPtr, PHY_MAIN_CTRL); + if ((phyMainCtrl & PHY_MAIN_CTRL_EN_MASK) == PHY_MAIN_CTRL_EN_DSBL) + { + DBG_WARNING("Physical layer was allready halted.\n"); + } + instPtr->isPhyEn = false; + PhyWrite(instPtr, PHY_MAIN_CTRL, (phyMainCtrl & (~PHY_MAIN_CTRL_EN_MASK))); +} + +/*****************************************************************************/ +/** + * @brief Update Physical Layer mode. + * + * @param instPtr + * modeCod + * + * @return + * + ******************************************************************************/ +int32_t Phy_SetMode(PHY_INST *instPtr, PHY_MODE modeCod) +{ + ASSERT(instPtr != NULL); + uint32_t phyMainCtrl = PhyRead(instPtr, PHY_MAIN_CTRL) & ~PHY_MAIN_CTRL_MODE_MASK; + switch (modeCod) + { + case PHY_MODE_NONE: + phyMainCtrl |= PHY_MAIN_CTRL_MODE_NONE; + break; + case PHY_MODE_LISTEN: + phyMainCtrl |= PHY_MAIN_CTRL_MODE_LISTEN; + break; + case PHY_MODE_SCHEDULE: + phyMainCtrl |= PHY_MAIN_CTRL_MODE_SCHEDULE; + break; + case PHY_MODE_PULL: + phyMainCtrl |= PHY_MAIN_CTRL_MODE_PULL; + break; + default: + return FAILURE; + break; + } + PhyWrite(instPtr, PHY_MAIN_CTRL, phyMainCtrl | PHY_MAIN_CTRL_EN_EN); + return SUCCESS; +} + +/*****************************************************************************/ +/** + * @brief Setup next slot operation. + * + * @param instPtr + * txrxMode + * l2FrameType + * + * @return + * + ******************************************************************************/ +int32_t Phy_SetupNextSlot(PHY_INST *instPtr, PHY_TOR_TYPE txrxMode, + L1_FRAME_TYPE frameType, uint8_t *buff) +{ + ASSERT(instPtr != NULL); + int32_t Status = SUCCESS; + uint32_t phyModeCtrl, antConfigBramAddr, hopNum; + uint16_t *hopPattern; + // Implement a ping-pong flow, offset always is 0 or half of buffer depth. + instPtr->antConfigOffset = (instPtr->antConfigOffset == ANTCONFIG_MAX_LEN) ? 0 : ANTCONFIG_MAX_LEN; + antConfigBramAddr = instPtr->antConfigDataPtr + instPtr->antConfigOffset; + + instPtr->TOR.next = txrxMode; + instPtr->frameType.next = frameType; + + switch (txrxMode) + { + case PHY_TOR_SUSPEND: + phyModeCtrl = PHY_MODE_CTRL_TOR_SUSPEND; + break; + case PHY_TOR_RX: + phyModeCtrl = PHY_MODE_CTRL_TOR_RX; + break; + case PHY_TOR_TX: + phyModeCtrl = PHY_MODE_CTRL_TOR_TX; + break; + default: + return EPARAM; + } + if (instPtr->isPresetHop == false) + { + hopPattern = hopPattern_Config; + } + else + { + switch (frameType) + { + case L1_2KBPS_20MS_FRAME: + phyModeCtrl |= PHY_MODE_CTRL_FRAME_2KBPS_20MS; + hopNum = L1_FRAME_2KBPS_20MS_HOPS; + // FIXME: For DUIFEI net setup. + // hopPattern = (txrxMode == TOR_TX) ? hopPattern_2KBPS_20MS; + hopPattern = hopPattern_2KBPS_100MS; + break; + case L1_2KBPS_100MS_FRAME: + phyModeCtrl |= PHY_MODE_CTRL_FRAME_2KBPS_100MS; + hopNum = L1_FRAME_2KBPS_100MS_HOPS; + hopPattern = hopPattern_2KBPS_100MS; + break; + case L1_10KBPS_10MS_FRAME: + phyModeCtrl |= PHY_MODE_CTRL_FRAME_10KBPS_10MS; + hopNum = L1_FRAME_10KBPS_10MS_HOPS; + hopPattern = hopPattern_10KBPS_10MS; + break; + case L1_10KBPS_20MS_FRAME: + phyModeCtrl |= PHY_MODE_CTRL_FRAME_10KBPS_20MS; + hopNum = L1_FRAME_10KBPS_20MS_HOPS; + hopPattern = hopPattern_10KBPS_20MS; + break; + case L1_40KBPS_20MS_FRAME: + phyModeCtrl |= PHY_MODE_CTRL_FRAME_200KBPS_5MS; + hopNum = L1_FRAME_200KBPS_5MS_HOPS; + hopPattern = hopPattern_200KBPS_5MS; + break; + case L1_40KBPS_10MS_FRAME: + phyModeCtrl |= PHY_MODE_CTRL_FRAME_40KBPS_10MS; + hopNum = L1_FRAME_40KBPS_10MS_HOPS; + hopPattern = hopPattern_40KBPS_10MS; + break; + case L1_200KBPS_5MS_FRAME: + phyModeCtrl |= PHY_MODE_CTRL_FRAME_200KBPS_5MS; + hopNum = L1_FRAME_200KBPS_5MS_HOPS; + hopPattern = hopPattern_200KBPS_5MS; + break; + case L1_1M2BPS_5MS_FRAME: + phyModeCtrl |= PHY_MODE_CTRL_FRAME_1M2BPS_5MS; + hopNum = L1_FRAME_1M2BPS_5MS_HOPS; + hopPattern = hopPattern_1M2BPS_5MS; + break; + default: + return EPARAM; + break; + } + } + + PhyWrite(instPtr, PHY_MODE_CTRL, phyModeCtrl); + + // TODO: Set antenna stand by, when suspend. + const uint8_t *dataSrcPtr = (uint8_t *)(&(instPtr->antConfigPtr)); + for (int32_t i = 0; i < hopNum; i++) + { + instPtr->antConfigPtr.antFreq[1] = (uint8_t)(hopPattern[i] & 0x00FF); + instPtr->antConfigPtr.antFreq[0] = (uint8_t)((hopPattern[i] >> 8) & 0x00FF); + instPtr->antConfigPtr.rfFreq[1] = (uint8_t)(hopPattern[i] & 0x00FF); + instPtr->antConfigPtr.rfFreq[0] = (uint8_t)((hopPattern[i] >> 8) & 0x00FF); + memcpy((uint8_t *)(antConfigBramAddr + i * ANT_COINFO_LENGTH), + dataSrcPtr, sizeof(PHY_ANT_COINFO)); + } + uint32_t antCtrl = (instPtr->antConfigOffset & ANT_CONFIG_CMD_OFFSET_MASK) | ((hopNum << ANT_CONFIG_CMD_NUM_SHIFT) & ANT_CONFIG_CMD_NUM_MASK) | ((ANT_COINFO_LENGTH << ANT_CONFIG_CMD_LEN_SHIFT) & ANT_CONFIG_CMD_LEN_MASK); + PhyWrite(instPtr, ANT_CONFIG_CMD, antCtrl); + + // FIXME: For DUIFEI network setup. Should only set send data in send slots. + if (txrxMode == PHY_TOR_TX) + { + Status = SetSendData(instPtr, frameType, buff); + if (Status != SUCCESS) + { + return Status; + } + } + + // Trigger physical configuration. + PhyWrite(instPtr, SLOT_CONFIG_CMD, SLOT_CONFIG_CMD_VAULE); // Phy start fetching data. + return SUCCESS; +} + +/*****************************************************************************/ +/** + * @brief Get the corresponding frequency hopping pattern length of a + * specified L1 frame type. + * + * @param frameType a L1 frame type enumeration. + * + * @return SUCCESS + * FAILURE frame type cannot be recognized + * + ******************************************************************************/ +uint32_t Phy_GetHopLength(L1_FRAME_TYPE frameType) +{ + switch (frameType) + { + case L1_2KBPS_20MS_FRAME: + return L1_FRAME_2KBPS_20MS_HOPS; + case L1_2KBPS_100MS_FRAME: + return L1_FRAME_2KBPS_100MS_HOPS; + case L1_10KBPS_10MS_FRAME: + return L1_FRAME_10KBPS_10MS_HOPS; + case L1_10KBPS_20MS_FRAME: + return L1_FRAME_10KBPS_20MS_HOPS; + case L1_40KBPS_20MS_FRAME: + return L1_FRAME_40KBPS_20MS_HOPS; + case L1_40KBPS_10MS_FRAME: + return L1_FRAME_40KBPS_10MS_HOPS; + case L1_200KBPS_5MS_FRAME: + return L1_FRAME_200KBPS_5MS_HOPS; + case L1_1M2BPS_5MS_FRAME: + return L1_FRAME_1M2BPS_5MS_HOPS; + default: + return L1_FRAME_NONE_LEN; + } +} + +/*****************************************************************************/ +/** + * @brief Get the time from frame sync to slot end of different type. + * + * @param frameType + * + * @return 32bit unsigned integer (clock periods) + * + ******************************************************************************/ +uint32_t Phy_GetTimeComp(L1_FRAME_TYPE frameType) +{ + switch (frameType) + { + case L1_2KBPS_20MS_FRAME: + return L1_FRAME_2KBPS_20MS_COMP; + case L1_2KBPS_100MS_FRAME: + return L1_FRAME_2KBPS_100MS_COMP; + case L1_10KBPS_10MS_FRAME: + return L1_FRAME_10KBPS_10MS_COMP; + case L1_10KBPS_20MS_FRAME: + return L1_FRAME_10KBPS_20MS_COMP; + case L1_40KBPS_20MS_FRAME: + return L1_FRAME_40KBPS_20MS_COMP; + case L1_40KBPS_10MS_FRAME: + return L1_FRAME_40KBPS_10MS_COMP; + case L1_200KBPS_5MS_FRAME: + return L1_FRAME_200KBPS_5MS_COMP; + case L1_1M2BPS_5MS_FRAME: + return L1_FRAME_1M2BPS_5MS_COMP; + default: + return L1_FRAME_NONE_LEN; + } +} + +/*****************************************************************************/ +/** + * @brief Get latest frequency deviation estimation. + * + * @param instPtr + * + * @return 32bit signed integer (Hz) + * + ******************************************************************************/ +int32_t Phy_GetFreqEst(PHY_INST *instPtr) +{ + uint32_t temp; + int32_t acqCh, fsCh; + double freqEst; + temp = PhyRead(instPtr, COASE_FREQEST); + acqCh = temp & 0x000000FF; + acqCh = 80 - acqCh; + fsCh = (temp >> 8) & 0x000000FF; + fsCh = fsCh - 128; + freqEst = acqCh * (31.25e3 / 4) + fsCh * (31.25e3 / 256); + return ((int32_t)freqEst); +} + +/*****************************************************************************/ +/** + * @brief Setup a frequency hopping pattern. + * + * @param patternBuff a pointer to hopping pattern buffer + * @param patternLen a integer indicate the length of hopping pattern. + * + * @return SUCCESS + * FAILURE pattern length exceeds maximum length. + * + ******************************************************************************/ +int32_t Phy_SetHopPattern(void *patternBuff, uint32_t patternLen) +{ + ASSERT(patternBuff != NULL); + if (patternLen > L1_FRAME_MAX_HOPS) + { + return FAILURE; + } + memcpy(hopPattern_Config, patternBuff, patternLen * sizeof(uint16_t)); + return SUCCESS; +} + +/*****************************************************************************/ +/** + * @brief Setup a specific timer word register in physical controller. + * + * @param instPtr + * @param tmWord + * @param tmType + * + * @return SUCCESS + * FAILURE pattern length exceeds maximum length. + * + ******************************************************************************/ +int32_t Phy_SetTimeWord(PHY_INST *instPtr, uint64_t tmWord, PHY_TIME_WORD_TYPE tmType) +{ + ASSERT(instPtr != NULL); + switch (tmType) + { + case PHY_TIME_WORD_POLL: + PhyWrite(instPtr, POLLTIME_L, (uint32_t)tmWord); + PhyWrite(instPtr, POLLTIME_H, (uint32_t)(tmWord >> 32)); + break; + case PHY_TIME_WORD_LOCAL_ADJ: + PhyWrite(instPtr, LOCALTM_ADJ_L, (uint32_t)tmWord); + PhyWrite(instPtr, LOCALTM_ADJ_H, (uint32_t)(tmWord >> 32)); + break; + case PHY_TIME_WORD_STEP: + PhyWrite(instPtr, CNT_STEP_OPT, (uint32_t)tmWord); + break; + default: + return EPARAM; + } + return SUCCESS; +} + +/*****************************************************************************/ +/** + * @brief Setup a specific timer word register in physical controller. + * + * @param instPtr a pointer to hopping pattern buffer + * @param patternLen a integer indicate the length of hopping pattern. + * + * @return SUCCESS + * FAILURE pattern length exceeds maximum length. + * + ******************************************************************************/ +void Phy_UpdateHwSate(PHY_INST *instPtr) +{ + ASSERT(instPtr != NULL); + uint32_t rawData; + + // -- Update Chip voltage, unit mV + rawData = XAdcPs_GetAdcData(&(instPtr->hwXadc), XADCPS_CH_VCCPINT); + instPtr->hwSate.spVolt = (uint16_t)(XAdcPs_RawToVoltage(rawData) * 1000); + + // -- Update Chip temperature, unit 0.01 deg + rawData = XAdcPs_GetAdcData(&(instPtr->hwXadc), XADCPS_CH_TEMP); + instPtr->hwSate.spTemp = (uint16_t)(XAdcPs_RawToTemperature(rawData) * 100); + + // FIXME: Chip status determine. + instPtr->hwSate.chipSt = 0; + + /*** Voltage and Status ***/ + rawData = PhyRead(instPtr, ANT_STATUS); + // -- Update Antenna Status Code: 0xAA - normal, 0x55 - error + instPtr->hwSate.antSt = ((rawData & ANT_STATUS_CODE_MASK) == 0) ? 0xAA : 0x55; + // -- Update Antenna Voltage Status: 1 - normal, 0 - error + // [0] - ANT voltage status + // [2] - RF voltage status + // [4] - NIL voltage status + instPtr->hwSate.antVolt = (rawData & ANT_STATUS_ANT_VOLT_MASK) ? 0x01 : 0x00; + instPtr->hwSate.antVolt |= (rawData & ANT_STATUS_RF_VOLT_MASK) ? 0x04 : 0x00; + instPtr->hwSate.antVolt |= (rawData & ANT_STATUS_NIL_VOLT_MASK) ? 0x10 : 0x00; + + /*** Temperature and Lock Status ***/ + rawData = PhyRead(instPtr, RF_STATUS); + //-- Update Antenna Temperature (signed 8bit integer, 1 centigrade per LSB) + instPtr->hwSate.antTemp = (uint8_t)(rawData & RF_STATUS_TEMP_MASK); + // -- Update Antenna PLL Lock Status: 1 - normal, 0 - error + // [0] - BASEBAND lock status + // [2] - PLLA lock status + // [4] - PLLB lock status + instPtr->hwSate.antPll = (rawData & RF_STATUS_BDLOCK_MASK) ? 0x01 : 0x00; + instPtr->hwSate.antPll |= (rawData & RF_STATUS_PLLA_MASK) ? 0x04 : 0x00; + instPtr->hwSate.antPll |= (rawData & RF_STATUS_PLLB_MASK) ? 0x10 : 0x00; + + /*** MGCs ***/ + rawData = PhyRead(instPtr, RF_MGC); + // -- Update Antenna MGC (0~15 dB) + // [3:0] - Channel 1 MGC + // [7:4] - Channel 2 MGC + // [11:8] - Channel 3 MGC + // [15:12] - Channel 4 MGC + instPtr->hwSate.antMgc = (rawData & RF_MGC_CH1_MASK); + instPtr->hwSate.antMgc |= (rawData & RF_MGC_CH2_MASK) >> 4; + instPtr->hwSate.antMgc |= (rawData & RF_MGC_CH3_MASK) >> 8; + instPtr->hwSate.antMgc |= (rawData & RF_MGC_CH4_MASK) >> 12; + SysMonitor_UpdateHardwareStatus(&(instPtr->hwSate)); +} diff --git a/df_datalink_sp/src/networking/phy_layer/phy_layer.h b/df_datalink_sp/src/networking/phy_layer/phy_layer.h new file mode 100644 index 0000000..4536ab7 --- /dev/null +++ b/df_datalink_sp/src/networking/phy_layer/phy_layer.h @@ -0,0 +1,249 @@ +/*****************************************************************************/ +/** + * Description: Physical layer control definitions and function prototypes. + * + * Date: 2021-12-04 16:32 + * LastEditTime: 2023-04-24 17:41 + * Revisions: Rev 0.1 + * History: + * [2021-12-08]: Initial version. + * [2022-06-18]: New branch for glink control purpose: + * -Add poll mode, physical layer will start Tx/Rx procedure + * at specific time stamp. + * -Add 61/37 beam switch + * -Code simplification. + * [2023-04-24]: Porting for DUIFEI. + * + * Copyright(c) 2021 Beijing Institute of Technology. + * Lab of Communication and Networking + * + ******************************************************************************/ + +#ifndef PHY_CTRL_H_ +#define PHY_CTRL_H_ + +/***************************** Include Files *********************************/ +#include +#include "common.h" +#include "xbram.h" +#include "xadcps.h" +#include "phy_reg.h" +#include "../../system_monitor.h" +/************************** Constant Definitions *****************************/ +#define L1_FRAME_NONE_HOPS UINT32_MAX +#define L1_FRAME_MAX_HOPS 81 +#define L1_FRAME_2KBPS_20MS_HOPS 1 +#define L1_FRAME_2KBPS_100MS_HOPS 81 +#define L1_FRAME_10KBPS_10MS_HOPS 1 +#define L1_FRAME_10KBPS_20MS_HOPS 11 +#define L1_FRAME_40KBPS_20MS_HOPS 19 +#define L1_FRAME_40KBPS_10MS_HOPS 9 +#define L1_FRAME_200KBPS_5MS_HOPS 20 +#define L1_FRAME_1M2BPS_5MS_HOPS 20 + +#define L1_NUM_ANT_SUBNRRW_PATTERN 37 +#define L1_NUM_ANT_NRRW_PATTERN 61 + +#define ANT_COINFO_LENGTH 32 // bytes +/***************** Macros (Inline Functions) Definitions *********************/ +/**************************** Type Definitions *******************************/ +typedef enum +{ + L1_NONE_FRAME = 0, + L1_2KBPS_20MS_FRAME = 1, + L1_2KBPS_100MS_FRAME = 2, + L1_10KBPS_10MS_FRAME = 3, + L1_10KBPS_20MS_FRAME = 4, + L1_40KBPS_20MS_FRAME = 5, + L1_40KBPS_10MS_FRAME = 6, + L1_200KBPS_5MS_FRAME = 7, + L1_1M2BPS_5MS_FRAME = 8 +} L1_FRAME_TYPE; + +typedef struct +{ + /*** Ant Control ***/ + /* Antenna control frame head 0xAA */ + /* default 0, reserved for further use */ + uint8_t ctrlWord; + /* high 4 bits specified beam mode. + * low 4 bits specified power control */ + uint8_t antMode; + /* off-axis angle range is 0~60, + * 0.1 degree each LSB */ + uint8_t oaxis[2]; + /* round-axis angle range is 0~360, + * 0.1 degree each LSB */ + uint8_t raxis[2]; + /* 0~3500Mhz, step 1MHz */ + uint8_t antFreq[2]; + /* in single tr mode, 0~63 specified tr channel + * in single subarray mode, 0~3 specified the subarray + * Only in debug mode*/ + uint8_t trSlect; + /* Antenna attenuation 0~31, 0.5dB each LSB, Only in debug mode */ + uint8_t antAtt; + /* 0~63, 5.625 degree each LSB, Only in debug mode*/ + uint8_t phase; + /* Only for debug */ + /* default 0x00 */ + uint8_t rxtxMode; + /* 0x00 Normal, 0x01 single tr calibration */ + uint8_t calibrMode; + /* reserved for further use */ + uint8_t antReserved; + + /*** RF Control ***/ + /* [7:4]RF enable: 0-On, 1-Off(Default); [3:0]Work mode: 0(default) */ + uint8_t rfCtrl; + /* 0~3500Mhz, step 1MHz */ + uint8_t rfFreq[2]; + /* RF MGC control: 0~31, 1dB each LSB*/ + uint8_t rfTxMgc; + /* RF channel 1&2 calibration mgc: [7:4] Channle1 - max 15db, 1dB each LSB + * [3:0] Channle2 - max 15db, 1dB each LSB*/ + uint8_t rf12CalMgc; + /* RF channel 3&4 calibration mgc: [7:4] Channle3 - max 15db, 1dB each LSB + * [3:0] Channle4 - max 15db, 1dB each LSB*/ + uint8_t rf34CalMgc; + /* Receive channel 1-4 MGC: 0~31, 1dB each LSB */ + uint8_t rcvMgc; + /* Receive monitor, 0-normal, 1-switch to monitor port */ + uint8_t rfMonitor; + /* reserved for further use */ + uint8_t rfReserved0; + uint8_t rfReserved1; +} PHY_ANT_COINFO; + +typedef struct +{ + /* off-axis angle range is 0~60, + * 0.1 degree each LSB */ + uint16_t oaxis; + /* round-axis angle range is 0~360, + * 0.1 degree each LSB */ + uint16_t raxis; +} PHY_ANT_ANGLE; + +typedef enum +{ + PHY_TIME_WORD_NONE = 0, + PHY_TIME_WORD_POLL = 1, + PHY_TIME_WORD_LISTEN_TIMEOUT = 2, + PHY_TIME_WORD_LOCAL_ADJ = 3, + PHY_TIME_WORD_STEP = 4, +} PHY_TIME_WORD_TYPE; + +typedef enum +{ + PHY_ANT_BEAM_NONE = 0, + PHY_ANT_BEAM_120 = 1, + PHY_ANT_BEAM_60 = 2, + PHY_ANT_BEAM_25 = 3, + PHY_ANT_BEAM_8 = 4 +} PHY_ANT_BEAM_WIDTH; + +typedef enum +{ + PHY_TOR_SUSPEND = 0, + PHY_TOR_TX = 1, + PHY_TOR_RX = 2 +} PHY_TOR_TYPE; + +typedef enum +{ + PHY_MODE_NONE = 0, + PHY_MODE_LISTEN = 1, + PHY_MODE_SCHEDULE = 2, + PHY_MODE_PULL = 3 +} PHY_MODE; + +typedef struct +{ + uint32_t devId; + uint32_t txBramId; + uint32_t rxBramId; + uint32_t antBramId; + uint32_t hwXadcId; + uint32_t baseAddr; +} PHY_CONFIG; + +typedef struct +{ + int32_t last; + int32_t curr; + int32_t next; +} PHY_RCD; + +typedef struct +{ + PHY_CONFIG phyCofig; // Device address configs + bool isPhyEn; // if physical layer running + bool isAcq; // if last reception acquisition success + bool isFrameSync; // if last reception frame sync success + bool isDecode; // if last reception decode success + bool isValid; // if last reception frame data valid (crc check pass) + bool isPresetHop; // if using preset frequency hop + PHY_RCD antNo; // antenna number record + PHY_RCD beamNo; // beam number record + PHY_RCD beamWd; // beam width record + PHY_RCD TOR; // tx rx state record + PHY_RCD frameType; // frame type record + uint32_t antConfigOffset; // antenna configuration bram offset (to implement ping-pong data flow) + uint32_t sendOffset; // antenna configuration bram offset (to implement ping-pong data flow) + PHY_ANT_COINFO antConfigPtr; // antenna configuration pointer + uintptr_t txDataPtr; + uintptr_t rxDataPtr; + uintptr_t antConfigDataPtr; + XAdcPs hwXadc; + HWSTATE hwSate; +} PHY_INST; + +/************************** Variable Definitions *****************************/ +extern uint16_t hopPattern_Config[L1_FRAME_MAX_HOPS]; +extern uint16_t hopPattern_2KBPS_20MS[L1_FRAME_2KBPS_20MS_HOPS]; +extern uint16_t hopPattern_2KBPS_100MS[L1_FRAME_2KBPS_100MS_HOPS]; +extern uint16_t hopPattern_10KBPS_10MS[L1_FRAME_10KBPS_10MS_HOPS]; +extern uint16_t hopPattern_10KBPS_20MS[L1_FRAME_10KBPS_20MS_HOPS]; +extern uint16_t hopPattern_40KBPS_10MS[L1_FRAME_40KBPS_10MS_HOPS]; +extern uint16_t hopPattern_40KBPS_20MS[L1_FRAME_40KBPS_20MS_HOPS]; + +extern uint16_t hopPattern_200KBPS_5MS[L1_FRAME_200KBPS_5MS_HOPS]; +extern uint16_t hopPattern_1M2BPS_5MS[L1_FRAME_1M2BPS_5MS_HOPS]; + +extern PHY_ANT_ANGLE antSubnrrwPattern[L1_NUM_ANT_SUBNRRW_PATTERN]; +extern PHY_ANT_ANGLE antNrrwPattern[L1_NUM_ANT_NRRW_PATTERN]; + +/************************** Function Prototypes ******************************/ +int32_t Phy_InstInit(PHY_INST **instPtr, PHY_CONFIG *phyConfig); +void Phy_UpdateState(PHY_INST *instPtr); +void Phy_UpdateHwSate(PHY_INST *instPtr); + +void Phy_Start(PHY_INST *instPtr); +void Phy_Halt(PHY_INST *instPtr); +int32_t Phy_SetMode(PHY_INST *instPtr, PHY_MODE modeCod); + +int32_t Phy_SetupNextSlot(PHY_INST *instPtr, PHY_TOR_TYPE txrxMode, L1_FRAME_TYPE frameType, uint8_t *buff); +int32_t Phy_RetrieveRecvData(PHY_INST *instPtr, uint8_t *buff); + +bool Phy_IsFrameDetected(PHY_INST *instPtr); +bool Phy_IsFrameReceived(PHY_INST *instPtr); +bool Phy_IsFrameValid(PHY_INST *instPtr); +uint32_t Phy_GetFrameLen(L1_FRAME_TYPE frameType); + +L1_FRAME_TYPE Phy_GetLastDetectedFrameType(PHY_INST *instPtr); +L1_FRAME_TYPE Phy_GetLastReceivedFrameType(PHY_INST *instPtr); +L1_FRAME_TYPE Phy_GetLastSentFrameType(PHY_INST *instPtr); + +int32_t Phy_SetHopPattern(void *patternBuff, uint32_t patternLen); +uint32_t Phy_GetHopLength(L1_FRAME_TYPE frameType); +uint32_t Phy_GetTimeComp(L1_FRAME_TYPE frameType); +int32_t Phy_GetFreqEst(PHY_INST *instPtr); +int32_t Phy_SetTimeWord(PHY_INST *instPtr, uint64_t tmWord, PHY_TIME_WORD_TYPE tmType); + +int32_t Phy_AntConfigInit(PHY_ANT_COINFO *antCoinfoPtr); +int32_t Phy_SetBeamWidth(PHY_INST *instPtr, PHY_ANT_BEAM_WIDTH beamWidth); +int32_t Phy_SetBeamNo(PHY_INST *instPtr, int32_t beamNo); +int32_t Phy_SetBeamAngle(PHY_INST *phyInstPtr, double offAx, double rndAx); + +#endif /* PHY_CTRL_H_ */ diff --git a/df_datalink_sp/src/networking/phy_layer/phy_reg.h b/df_datalink_sp/src/networking/phy_layer/phy_reg.h new file mode 100644 index 0000000..c5c7a00 --- /dev/null +++ b/df_datalink_sp/src/networking/phy_layer/phy_reg.h @@ -0,0 +1,334 @@ +/*****************************************************************************/ +/** + * Description: Physical layer register definitions + * + * Author: Fan Hao + * Date: 2021-11-16 00:08 + * LastEditors: Fan Hao + * LastEditTime: 2023-04-24 17:32 + * Revisions: Rev 0.1 + * History: + * [2021-11-16]: Initial version. + * [2022-06-18]: New branch for glink control purpose: + * -Add poll modephysical layer will start Tx/Rx procedure + * at specific time stamp. + * [2023-04-24]: Porting for DUIFEI. + * + * Copyright(c) 2021 Beijing Institute of Technology. + * Lab of Communication and Networking + * + ******************************************************************************/ + +#ifndef PHY_CTRLREG_H_ +#define PHY_CTRLREG_H_ + +/***************************** Include Files *********************************/ +#include "util.h" + +/***************** Macros (Inline Functions) Definitions *********************/ + +// Read Physical Layer register (0x00000000~0x000000FF) +#define PhyRead(instPtr, addr) IO_In32(instPtr->phyCofig.baseAddr + addr) +// Write Physical Layer register (0x000000100~0x00000200) +#define PhyWrite(instPtr, addr, value) IO_Out32(instPtr->phyCofig.baseAddr + addr, value) + +/************************** Constant Definitions *****************************/ +/************************* Ps2Pl Regs PS Write Only ***************************/ +/** + * Register: PHY_MAIN_CTRL + */ +#define PHY_MAIN_CTRL 0X00000000U +#define PHY_MAIN_CTRL_EN_SHIFT 0 +#define PHY_MAIN_CTRL_EN_WIDTH 1 +#define PHY_MAIN_CTRL_EN_MASK 0x00000001U +#define PHY_MAIN_CTRL_MODE_SHIFT 8 +#define PHY_MAIN_CTRL_MODE_WIDTH 8 +#define PHY_MAIN_CTRL_MODE_MASK 0x0000FF00U + +#define PHY_MAIN_CTRL_EN_EN 0x00000001U +#define PHY_MAIN_CTRL_EN_DSBL 0x00000000U +#define PHY_MAIN_CTRL_MODE_NONE 0x00000000U +#define PHY_MAIN_CTRL_MODE_LISTEN 0x00000100U +#define PHY_MAIN_CTRL_MODE_SCHEDULE 0x00000200U +#define PHY_MAIN_CTRL_MODE_PULL 0x00000300U + +/** + * Register: TXRX_CTRL + */ +#define PHY_MODE_CTRL 0x00000004U +#define PHY_MODE_CTRL_TOR_SHIFT 0 +#define PHY_MODE_CTRL_TOR_WIDTH 2 +#define PHY_MODE_CTRL_TOR_MASK 0x00000003U +#define PHY_MODE_CTRL_FRAME_SHIFT 16 +#define PHY_MODE_CTRL_FRAME_WIDTH 8 +#define PHY_MODE_CTRL_FRAME_MASK 0x00FF0000U + +#define PHY_MODE_CTRL_TOR_SUSPEND 0x00000000U +#define PHY_MODE_CTRL_TOR_TX 0x00000001U +#define PHY_MODE_CTRL_TOR_RX 0x00000002U + +#define PHY_MODE_CTRL_FRAME_NONE 0x00000000U +#define PHY_MODE_CTRL_FRAME_2KBPS_20MS 0x00000100U +#define PHY_MODE_CTRL_FRAME_2KBPS_100MS 0x00000200U +#define PHY_MODE_CTRL_FRAME_10KBPS_10MS 0x00000300U // Initial Scan Frame +#define PHY_MODE_CTRL_FRAME_10KBPS_20MS 0x00000400U // Benchmark Frame +#define PHY_MODE_CTRL_FRAME_40KBPS_20MS 0x00000500U +#define PHY_MODE_CTRL_FRAME_40KBPS_10MS 0x00000600U +#define PHY_MODE_CTRL_FRAME_200KBPS_5MS 0x00000700U // 2-Way ACQ Frame, Management Frame, Service Frame +#define PHY_MODE_CTRL_FRAME_1M2BPS_5MS 0x00000800U // Bistatic Synthetic Aperture Radar Frame + +/** + * Register: POLLTIME_L + */ +#define POLLTIME_L 0x00000008U +#define POLLTIME_L_SHIFT 0 +#define POLLTIME_L_WIDTH 32 +#define POLLTIME_L_MASK 0xFFFFFFFFU + +/** + * Register: POLLTIME_H + */ +#define POLLTIME_H 0x0000000CU +#define POLLTIME_H_SHIFT 0 +#define POLLTIME_H_WIDTH 32 +#define POLLTIME_H_MASK 0xFFFFFFFFU + +/** + * Register: TM_ADJ_MODE + */ +#define TM_ADJ_MODE 0x00000010U +#define TM_ADJ_MODE_SHIFT 0 +#define TM_ADJ_MODE_WIDTH 8 +#define TM_ADJ_MODE_MASK 0x000000FFU +#define TM_ADJ_MODE_NONE 0x00000000U +#define TM_ADJ_MODE_ADD 0x00000001U +#define TM_ADJ_MODE_SET 0x00000002U + +#define TM_ADJ_MODE_LOCAL_SHIFT 8 +#define TM_ADJ_MODE_LOCAL_WIDTH 8 +#define TM_ADJ_MODE_LOCAL_MASK 0x0000FF00U +#define TM_ADJ_MODE_LOCAL_NONE 0x00000000U +#define TM_ADJ_MODE_LOCAL_ADD 0x00000100U +#define TM_ADJ_MODE_LOCAL_SET 0x00000200U + +/** + * Register: LOCALTM_ADJ_L + */ +#define LOCALTM_ADJ_L 0x00000014U +#define LOCALTM_ADJ_L_SHIFT 0 +#define LOCALTM_ADJ_L_WIDTH 32 +#define LOCALTM_ADJ_L_MASK 0xFFFFFFFFU + +/** + * Register: LOCALTM_ADJ_H + */ +#define LOCALTM_ADJ_H 0x00000018U +#define LOCALTM_ADJ_H_SHIFT 0 +#define LOCALTM_ADJ_H_WIDTH 32 +#define LOCALTM_ADJ_H_MASK 0xFFFFFFFFU + +/** + * Register: CNT_STEP_TOPT + */ +#define CNT_STEP_OPT 0x0000001CU +#define CNT_STEP_OPT_SHIFT 0 +#define CNT_STEP_OPT_WIDTH 32 +#define CNT_STEP_OPT_MASK 0xFFFFFFFFU + +/** + * Register: SEND_DATA_CMD + */ +#define SEND_DATA_CMD 0x00000020U +#define SEND_DATA_CMD_LEN_SHIFT 0 +#define SEND_DATA_CMD_LEN_WIDTH 16 +#define SEND_DATA_CMD_LEN_MASK 0x0000FFFFU +#define SEND_DATA_CMD_OFFSET_SHIFT 16 +#define SEND_DATA_CMD_OFFSET_WIDTH 16 +#define SEND_DATA_CMD_OFFSET_MASK 0xFFFF0000U + +/** + * Register: ANT_CONFIG_CMD + */ +#define ANT_CONFIG_CMD 0x00000024U +#define ANT_CONFIG_CMD_OFFSET_SHIFT 0 +#define ANT_CONFIG_CMD_OFFSET_WIDTH 16 +#define ANT_CONFIG_CMD_OFFSET_MASK 0x0000FFFFU +#define ANT_CONFIG_CMD_LEN_SHIFT 16 +#define ANT_CONFIG_CMD_LEN_WIDTH 8 +#define ANT_CONFIG_CMD_LEN_MASK 0x00FF0000U +#define ANT_CONFIG_CMD_NUM_SHIFT 24 +#define ANT_CONFIG_CMD_NUM_WIDTH 8 +#define ANT_CONFIG_CMD_NUM_MASK 0xFF000000U + +/** + * Register: SLOT_CONFIG_CMD + */ +#define SLOT_CONFIG_CMD 0x00000028U +#define SLOT_CONFIG_CMD_SHIFT 0 +#define SLOT_CONFIG_CMD_WIDTH 32 +#define SLOT_CONFIG_CMD_MASK 0xFFFFFFFFU +#define SLOT_CONFIG_CMD_VAULE 0x4846414E + +/************************* Ps2Pl Regs PS Read Only ***************************/ +/** + * Register: TXRX_STATE + */ +#define TXRX_STATE 0x00000100U +#define TXRX_STATE_ACQ_SHIFT 0 +#define TXRX_STATE_ACQ_WIDTH 8 +#define TXRX_STATE_ACQ_MASK 0x000000FFU +#define TXRX_STATE_ACQ_SUCCESS 0x00000001U +#define TXRX_STATE_ACQ_FAIL 0x00000002U + +#define TXRX_STATE_FSYNC_SHIFT 8 +#define TXRX_STATE_FSYNC_WIDTH 8 +#define TXRX_STATE_FSYNC_MASK 0x0000FF00U +#define TXRX_STATE_FSYNC_SUCCESS 0x00000100U +#define TXRX_STATE_FSYNC_FAIL 0x00000200U + +#define TXRX_STATE_DECODE_SHIFT 16 +#define TXRX_STATE_DECODE_WIDTH 8 +#define TXRX_STATE_DECODE_MASK 0x00FF0000U +#define TXRX_STATE_DECODE_SUCCESS 0x00010000U +#define TXRX_STATE_DECODE_FAIL 0x00020000U + +/** + * Register: RECV_SATE + */ +#define RECV_DATA_SATE 0x00000104U +#define RECV_DATA_LEN_SHIFT 0 +#define RECV_DATA_LEN_WIDTH 16 +#define RECV_DATA_LEN_MASK 0x0000FFFFU +#define RECV_DATA_OFFSET_SHIFT 16 +#define RECV_DATA_OFFSET_WIDTH 16 +#define RECV_DATA_OFFSET_MASK 0xFFFFF0000U + +/** + * Register: FSTIME_L + */ +#define FSTIME_L 0x00000108U +#define FSTIME_L_SHIFT 0 +#define FSTIME_L_WIDTH 32 +#define FSTIME_L_MASK 0xFFFFFFFFU + +/** + * Register: FSTIME_INT1 + */ +#define FSTIME_H 0x0000010CU +#define FSTIME_H_SHIFT 0 +#define FSTIME_H_WIDTH 32 +#define FSTIME_H_MASK 0xFFFFFFFFU + +/** + * Register: TM_TARGET_L + */ +#define TM_TARGET_L 0x00000110U +#define TM_TARGET_L_SHIFT 0 +#define TM_TARGET_L_WIDTH 32 +#define TM_TARGET_L_MASK 0xFFFFFFFFU + +/** + * Register: TM_TARGET_H + */ +#define TM_TARGET_H 0x00000114U +#define TM_TARGET_H_SHIFT 0 +#define TM_TARGET_H_WIDTH 32 +#define TM_TARGET_H_MASK 0xFFFFFFFFU + +/** + * Register: LOCALTM_L + */ +#define TM_LOCAL_L 0x00000118U +#define TM_LOCAL_L_SHIFT 0 +#define TM_LOCAL_L_WIDTH 32 +#define TM_LOCAL_L_MASK 0xFFFFFFFFU + +/** + * Register: LOCALTM_H + */ +#define TM_LOCAL_H 0x0000011CU +#define TM_LOCAL_H_SHIFT 0 +#define TM_LOCAL_H_WIDTH 32 +#define TM_LOCAL_H_MASK 0xFFFFFFFFU + +/** + * Register: COASEFREQEST + */ +#define COASE_FREQEST 0x00000120U +#define COASE_FREQEST_SHIFT 0 +#define COASE_FREQEST_WIDTH 32 +#define COASE_FREQEST_MASK 0xFFFFFFFFU + +/** + * Register: INTR_TYPE + */ +#define INTR_TYPE 0x00000124U + +/** + * Register: ANT_STATUS_0 + */ +#define ANT_STATUS 0x00000128U +#define ANT_STATUS_CODE_SHIFT 0 +#define ANT_STATUS_CODE_WIDTH 8 +#define ANT_STATUS_CODE_MASK 0x000000FFU +#define ANT_STATUS_NIL_VOLT_SHIFT 8 +#define ANT_STATUS_NIL_VOLT_WIDTH 8 +#define ANT_STATUS_NIL_VOLT_MASK 0x0000FF00U +#define ANT_STATUS_RF_VOLT_SHIFT 16 +#define ANT_STATUS_RF_VOLT_WIDTH 8 +#define ANT_STATUS_RF_VOLT_MASK 0x00FF0000U +#define ANT_STATUS_ANT_VOLT_SHIFT 24 +#define ANT_STATUS_ANT_VOLT_WIDTH 8 +#define ANT_STATUS_ANT_VOLT_MASK 0xFF000000U + +/** + * Register: ANT_FRAME_CNT + */ +#define ANT_FRAME_CNT 0x0000012CU +#define ANT_FRAME_CNT_SHIFT 0 +#define ANT_FRAME_CNT_WIDTH 32 +#define ANT_FRAME_CNT_MASK 0xFFFFFFFFU + +/** + * Register: RF_STATUS + */ +#define RF_STATUS 0x00000130U +#define RF_STATUS_TEMP_SHIFT 0 +#define RF_STATUS_TEMP_WIDTH 8 +#define RF_STATUS_TEMP_MASK 0x000000FFU +#define RF_STATUS_BDLOCK_SHIFT 8 +#define RF_STATUS_BDLOCK_WIDTH 8 +#define RF_STATUS_BDLOCK_MASK 0x0000FF00U +#define RF_STATUS_PLLA_SHIFT 16 +#define RF_STATUS_PLLA_WIDTH 8 +#define RF_STATUS_PLLA_MASK 0x00FF0000U +#define RF_STATUS_PLLB_SHIFT 24 +#define RF_STATUS_PLLB_WIDTH 8 +#define RF_STATUS_PLLB_MASK 0xFF000000U + +/** + * Register: RF_MGC + */ +#define RF_MGC 0x00000134U +#define RF_MGC_CH1_SHIFT 0 +#define RF_MGC_CH1_WIDTH 4 +#define RF_MGC_CH1_MASK 0x0000000FU +#define RF_MGC_CH2_SHIFT 8 +#define RF_MGC_CH2_WIDTH 4 +#define RF_MGC_CH2_MASK 0x00000F00U +#define RF_MGC_CH3_SHIFT 16 +#define RF_MGC_CH3_WIDTH 4 +#define RF_MGC_CH3_MASK 0x000F0000U +#define RF_MGC_CH4_SHIFT 24 +#define RF_MGC_CH4_WIDTH 4 +#define RF_MGC_CH4_MASK 0x0F000000U + +/** + * Register: RF_FRAME_CNT + */ +#define RF_FRAME_CNT 0x00000138U +#define RF_FRAME_CNT_SHIFT 0 +#define RF_FRAME_CNT_WIDTH 32 +#define RF_FRAME_CNT_MASK 0xFFFFFFFFU + +#endif /* PHY_CTRLREG_H_ */ diff --git a/df_datalink_sp/src/system_monitor.c b/df_datalink_sp/src/system_monitor.c new file mode 100644 index 0000000..eec9c04 --- /dev/null +++ b/df_datalink_sp/src/system_monitor.c @@ -0,0 +1,625 @@ +#include +#include +#include +#include "common.h" +#include "system_monitor.h" + +#define BUFF_A 0x00 +#define BUFF_B 0x01 +#define BUFF_NONE 0xFF + +#define SYSINFO_PACK_LEN 54 // bytes +#define PAYLOAD_PACK_LEN 46 // bytes +#define SLOTLOG_PACK_LEN 88 // bytes +#define PRTCLLOG_PACK_ELN 24 // bytes +#define HWSTATE_PACK_ELN 12 // bytes + +typedef struct +{ + int8_t latest; + int8_t rBusy; + int8_t wBusy; +} PINGPONG; + +typedef struct +{ + PINGPONG recvPLCtrl; + PAYLOAD recvPL[2]; + PINGPONG sendPLCtrl; + PAYLOAD sendPL[2]; + PINGPONG sysInfoCtrl; + SYSINFO sysInfo[2]; + PINGPONG sendLogCtrl; + SLOTLOG sendLog[2]; + PINGPONG recvLogCtrl; + SLOTLOG recvLog[2]; + PINGPONG protocolLogCtrl; + PRTCLLOG protocolLog[2]; + PINGPONG hwStateCtrl; + HWSTATE hwState[2]; +} SYSMONITOR; + +static SYSMONITOR *sysMonitorInst; + +uint8_t GetWritable(PINGPONG ctrllor); +uint8_t GetReadable(PINGPONG ctrllor); + +inline uint8_t GetWritable(PINGPONG ctrllor) +{ + ASSERT(ctrllor.wBusy != BUFF_NONE); + if (ctrllor.rBusy == BUFF_NONE) + return ((ctrllor.latest == BUFF_B) ? BUFF_A : BUFF_B); + else + return ((ctrllor.rBusy == BUFF_B) ? BUFF_A : BUFF_B); +} + +inline uint8_t GetReadable(PINGPONG ctrllor) +{ + if (ctrllor.wBusy == BUFF_NONE || ctrllor.wBusy != ctrllor.latest) + return ctrllor.latest; + else + return ((ctrllor.wBusy == BUFF_B) ? BUFF_A : BUFF_B); +} + +// System monitor initialise +int32_t SysMonitor_Init(void) +{ + sysMonitorInst = calloc(1, sizeof(SYSMONITOR)); + if (sysMonitorInst == NULL) + { + return ENOMEM; + } + memset(&(sysMonitorInst->recvPLCtrl), BUFF_NONE, sizeof(PINGPONG)); + memset(&(sysMonitorInst->sendPLCtrl), BUFF_NONE, sizeof(PINGPONG)); + memset(&(sysMonitorInst->sysInfoCtrl), BUFF_NONE, sizeof(PINGPONG)); + memset(&(sysMonitorInst->sendLogCtrl), BUFF_NONE, sizeof(PINGPONG)); + memset(&(sysMonitorInst->recvLogCtrl), BUFF_NONE, sizeof(PINGPONG)); + memset(&(sysMonitorInst->protocolLogCtrl), BUFF_NONE, sizeof(PINGPONG)); + memset(&(sysMonitorInst->hwStateCtrl), BUFF_NONE, sizeof(PINGPONG)); + return SUCCESS; +} + +// @System Info +void SysMonitor_UpdateSysinfo(SYSINFO *info) +{ + uint8_t buffIndx; + buffIndx = GetWritable(sysMonitorInst->sysInfoCtrl); + sysMonitorInst->sysInfoCtrl.wBusy = buffIndx; + memcpy(&(sysMonitorInst->sysInfo[buffIndx]), info, sizeof(SYSINFO)); + sysMonitorInst->sysInfoCtrl.latest = buffIndx; + sysMonitorInst->sysInfoCtrl.wBusy = BUFF_NONE; +} + +void SysMonitor_UpdateSysinfoRaw(uint8_t *buff) +{ + ASSERT(sysMonitorInst != NULL); + uint8_t buffIndx; + buffIndx = GetWritable(sysMonitorInst->sysInfoCtrl); + sysMonitorInst->sysInfoCtrl.wBusy = buffIndx; + // Decapsulate Systeminfo + SYSINFO *infoEntry = &(sysMonitorInst->sysInfo[buffIndx]); + memcpy(&(infoEntry->psBDS), buff, sizeof(infoEntry->psBDS)); + buff += sizeof(infoEntry->psBDS); + memcpy(&(infoEntry->pBDS), buff, sizeof(infoEntry->pBDS)); + buff += sizeof(infoEntry->pBDS); + memcpy(&(infoEntry->psGPS), buff, sizeof(infoEntry->psGPS)); + buff += sizeof(infoEntry->psGPS); + memcpy(&(infoEntry->pGPS), buff, sizeof(infoEntry->pGPS)); + buff += sizeof(infoEntry->pGPS); + memcpy(&(infoEntry->tmInd), buff, sizeof(infoEntry->tmInd)); + buff += sizeof(infoEntry->tmInd); + memcpy(&(infoEntry->tmFly), buff, sizeof(infoEntry->tmFly)); + buff += sizeof(infoEntry->tmFly); + memcpy(&(infoEntry->stFly), buff, sizeof(infoEntry->stFly)); + buff += sizeof(infoEntry->stFly); + memcpy(&(infoEntry->posX), buff, sizeof(infoEntry->posX)); + buff += sizeof(infoEntry->posX); + memcpy(&(infoEntry->posY), buff, sizeof(infoEntry->posY)); + buff += sizeof(infoEntry->posY); + memcpy(&(infoEntry->posZ), buff, sizeof(infoEntry->posZ)); + buff += sizeof(infoEntry->posZ); + memcpy(&(infoEntry->vX), buff, sizeof(infoEntry->vX)); + buff += sizeof(infoEntry->vX); + memcpy(&(infoEntry->vY), buff, sizeof(infoEntry->vY)); + buff += sizeof(infoEntry->vY); + memcpy(&(infoEntry->vZ), buff, sizeof(infoEntry->vZ)); + buff += sizeof(infoEntry->vZ); + memcpy(&(infoEntry->pitch), buff, sizeof(infoEntry->pitch)); + buff += sizeof(infoEntry->pitch); + memcpy(&(infoEntry->yaw), buff, sizeof(infoEntry->yaw)); + buff += sizeof(infoEntry->yaw); + memcpy(&(infoEntry->roll), buff, sizeof(infoEntry->roll)); + sysMonitorInst->sysInfoCtrl.latest = buffIndx; + sysMonitorInst->sysInfoCtrl.wBusy = BUFF_NONE; +} + +void SysMonitor_GetSysinfo(SYSINFO *info) +{ + ASSERT(sysMonitorInst != NULL); + uint8_t buffIndx, buffIndex_old; + buffIndex_old = sysMonitorInst->sysInfoCtrl.rBusy; + if (buffIndex_old != BUFF_NONE) + buffIndx = buffIndex_old; // Keep it busy + else + buffIndx = GetReadable(sysMonitorInst->sysInfoCtrl); + sysMonitorInst->sysInfoCtrl.rBusy = buffIndx; + memcpy(info, &(sysMonitorInst->sysInfo[buffIndx]), sizeof(SYSINFO)); + sysMonitorInst->sysInfoCtrl.rBusy = buffIndex_old; +} + +void SysMonitor_GetSysinfoRaw(uint8_t *buff) +{ + uint8_t buffIndx, buffIndex_old; + buffIndex_old = sysMonitorInst->sysInfoCtrl.rBusy; + if (buffIndex_old != BUFF_NONE) + buffIndx = buffIndex_old; // Keep it busy + else + buffIndx = GetReadable(sysMonitorInst->sysInfoCtrl); + sysMonitorInst->sysInfoCtrl.rBusy = buffIndx; + + // Encapsulate Systeminfo + SYSINFO *infoEntry = &(sysMonitorInst->sysInfo[buffIndx]); + memcpy(buff, &(infoEntry->psBDS), sizeof(infoEntry->psBDS)); + buff += sizeof(infoEntry->psBDS); + memcpy(buff, &(infoEntry->pBDS), sizeof(infoEntry->pBDS)); + buff += sizeof(infoEntry->pBDS); + memcpy(buff, &(infoEntry->psGPS), sizeof(infoEntry->psGPS)); + buff += sizeof(infoEntry->psGPS); + memcpy(buff, &(infoEntry->pGPS), sizeof(infoEntry->pGPS)); + buff += sizeof(infoEntry->pGPS); + memcpy(buff, &(infoEntry->tmInd), sizeof(infoEntry->tmInd)); + buff += sizeof(infoEntry->tmInd); + memcpy(buff, &(infoEntry->tmFly), sizeof(infoEntry->tmFly)); + buff += sizeof(infoEntry->tmFly); + memcpy(buff, &(infoEntry->stFly), sizeof(infoEntry->stFly)); + buff += sizeof(infoEntry->stFly); + memcpy(buff, &(infoEntry->posX), sizeof(infoEntry->posX)); + buff += sizeof(infoEntry->posX); + memcpy(buff, &(infoEntry->posY), sizeof(infoEntry->posY)); + buff += sizeof(infoEntry->posY); + memcpy(buff, &(infoEntry->posZ), sizeof(infoEntry->posZ)); + buff += sizeof(infoEntry->posZ); + memcpy(buff, &(infoEntry->vX), sizeof(infoEntry->vX)); + buff += sizeof(infoEntry->vX); + memcpy(buff, &(infoEntry->vY), sizeof(infoEntry->vY)); + buff += sizeof(infoEntry->vY); + memcpy(buff, &(infoEntry->vZ), sizeof(infoEntry->vZ)); + buff += sizeof(infoEntry->vZ); + memcpy(buff, &(infoEntry->pitch), sizeof(infoEntry->pitch)); + buff += sizeof(infoEntry->pitch); + memcpy(buff, &(infoEntry->yaw), sizeof(infoEntry->yaw)); + buff += sizeof(infoEntry->yaw); + memcpy(buff, &(infoEntry->roll), sizeof(infoEntry->roll)); + sysMonitorInst->sysInfoCtrl.rBusy = buffIndex_old; +} +// @Send Payload +/** + * Update send FLJ payload by raw data. + */ +void SysMonitor_UpdateSendPayloadFLJRaw(uint8_t *buff) +{ + ASSERT(sysMonitorInst != NULL); + uint8_t buffIndx; + buffIndx = GetWritable(sysMonitorInst->sendPLCtrl); + sysMonitorInst->sendPLCtrl.wBusy = buffIndx; + memcpy(sysMonitorInst->sendPL[buffIndx].data_flj, buff, sizeof(uint8_t) * PAYLOAD_FLJ); + sysMonitorInst->sendPLCtrl.latest = buffIndx; + sysMonitorInst->sendPLCtrl.wBusy = BUFF_NONE; +} + +/** + * Get send FLJ payload as raw data. + */ +void SysMonitor_GetSendPayloadFLJRaw(uint8_t *buff) +{ + ASSERT(sysMonitorInst != NULL); + uint8_t buffIndx, buffIndex_old; + buffIndex_old = sysMonitorInst->sendPLCtrl.rBusy; + if (buffIndex_old != BUFF_NONE) + buffIndx = buffIndex_old; // Keep it busy + else + buffIndx = GetReadable(sysMonitorInst->sendPLCtrl); + sysMonitorInst->sendPLCtrl.rBusy = buffIndx; + memcpy(buff, sysMonitorInst->sendPL[buffIndx].data_flj, sizeof(uint8_t) * PAYLOAD_FLJ); + sysMonitorInst->sendPLCtrl.rBusy = buffIndex_old; +} + +/** + * Update LJ send payload by raw data. + */ +void SysMonitor_UpdateSendPayloadLJRaw(uint8_t *buff) +{ + ASSERT(sysMonitorInst != NULL); + uint8_t buffIndx; + buffIndx = GetWritable(sysMonitorInst->sendPLCtrl); + sysMonitorInst->sendPLCtrl.wBusy = buffIndx; + memcpy(sysMonitorInst->sendPL[buffIndx].data_lj, buff, sizeof(uint8_t) * PAYLOAD_LJ); + sysMonitorInst->sendPLCtrl.latest = buffIndx; + sysMonitorInst->sendPLCtrl.wBusy = BUFF_NONE; +} + +/** + * Get send LJ payload as raw data. + */ +void SysMonitor_GetSendPayloadLJRaw(uint8_t *buff) +{ + ASSERT(sysMonitorInst != NULL); + uint8_t buffIndx, buffIndex_old; + buffIndex_old = sysMonitorInst->sendPLCtrl.rBusy; + if (buffIndex_old != BUFF_NONE) + buffIndx = buffIndex_old; // Keep it busy + else + buffIndx = GetReadable(sysMonitorInst->sendPLCtrl); + sysMonitorInst->sendPLCtrl.rBusy = buffIndx; + memcpy(buff, sysMonitorInst->sendPL[buffIndx].data_lj, sizeof(uint8_t) * PAYLOAD_LJ); + sysMonitorInst->sendPLCtrl.rBusy = buffIndex_old; +} + +// @Receive Payload +/** + * Update receive FLJ payload by raw data. + */ +void SysMonitor_UpdateRecvPayloadFLJRaw(uint8_t *buff) +{ + ASSERT(sysMonitorInst != NULL); + uint8_t buffIndx; + buffIndx = GetWritable(sysMonitorInst->recvPLCtrl); + sysMonitorInst->recvPLCtrl.wBusy = buffIndx; + memcpy(sysMonitorInst->recvPL[buffIndx].data_flj, buff, sizeof(uint8_t) * PAYLOAD_FLJ); + sysMonitorInst->recvPLCtrl.latest = buffIndx; + sysMonitorInst->recvPLCtrl.wBusy = BUFF_NONE; +} + +/** + * Get send FLJ payload as raw data. + */ +void SysMonitor_GetRecvPayloadFLJRaw(uint8_t *buff) +{ + ASSERT(sysMonitorInst != NULL); + uint8_t buffIndx, buffIndex_old; + buffIndex_old = sysMonitorInst->recvPLCtrl.rBusy; + if (buffIndex_old != BUFF_NONE) + buffIndx = buffIndex_old; // Keep it busy + else + buffIndx = GetReadable(sysMonitorInst->recvPLCtrl); + sysMonitorInst->recvPLCtrl.rBusy = buffIndx; + memcpy(buff, sysMonitorInst->recvPL[buffIndx].data_flj, sizeof(uint8_t) * PAYLOAD_FLJ); + sysMonitorInst->recvPLCtrl.rBusy = buffIndex_old; +} + +/** + * Update receive LJ payload by raw data. + */ +void SysMonitor_UpdateRecvPayloadLJRaw(uint8_t *buff) +{ + ASSERT(sysMonitorInst != NULL); + uint8_t buffIndx; + buffIndx = GetWritable(sysMonitorInst->recvPLCtrl); + sysMonitorInst->recvPLCtrl.wBusy = buffIndx; + memcpy(sysMonitorInst->recvPL[buffIndx].data_lj, buff, sizeof(uint8_t) * PAYLOAD_LJ); + sysMonitorInst->recvPLCtrl.latest = buffIndx; + sysMonitorInst->recvPLCtrl.wBusy = BUFF_NONE; +} + +/** + * Get send LJ payload as raw data. + */ +void SysMonitor_GetRecvPayloadLJRaw(uint8_t *buff) +{ + ASSERT(sysMonitorInst != NULL); + uint8_t buffIndx, buffIndex_old; + buffIndex_old = sysMonitorInst->recvPLCtrl.rBusy; + if (buffIndex_old != BUFF_NONE) + buffIndx = buffIndex_old; // Keep it busy + else + buffIndx = GetReadable(sysMonitorInst->recvPLCtrl); + sysMonitorInst->recvPLCtrl.rBusy = buffIndx; + memcpy(buff, sysMonitorInst->recvPL[buffIndx].data_lj, sizeof(uint8_t) * PAYLOAD_LJ); + sysMonitorInst->recvPLCtrl.rBusy = buffIndex_old; +} + +// @Send Slot log +/** + * Log send slot information + */ +void SysMonitor_UpdateSendSlotLog(SLOTLOG *log) +{ + ASSERT(sysMonitorInst != NULL); + uint8_t buffIndx; + buffIndx = GetWritable(sysMonitorInst->sendLogCtrl); + sysMonitorInst->sendLogCtrl.wBusy = buffIndx; + memcpy(&(sysMonitorInst->sendLog[buffIndx]), log, sizeof(SLOTLOG)); + sysMonitorInst->sendLogCtrl.latest = buffIndx; + sysMonitorInst->sendLogCtrl.wBusy = BUFF_NONE; +} + +/** + * Get the latest send slot log + */ +void SysMonitor_GetSendSlotLog(SLOTLOG *log) +{ + ASSERT(sysMonitorInst != NULL); + uint8_t buffIndx, buffIndex_old; + buffIndex_old = sysMonitorInst->sendLogCtrl.rBusy; + if (buffIndex_old != BUFF_NONE) + buffIndx = buffIndex_old; // Keep it busy + else + buffIndx = GetReadable(sysMonitorInst->sendLogCtrl); + sysMonitorInst->sendLogCtrl.rBusy = buffIndx; + memcpy(log, &(sysMonitorInst->sendLog[buffIndx]), sizeof(SLOTLOG)); + sysMonitorInst->sendLogCtrl.rBusy = buffIndex_old; +} + +/** + * Get the latest send slot log as raw data + */ +void SysMonitor_GetSendSlotLogRaw(uint8_t *buff) +{ + ASSERT(sysMonitorInst != NULL); + uint8_t buffIndx, buffIndex_old; + buffIndex_old = sysMonitorInst->sendLogCtrl.rBusy; + if (buffIndex_old != BUFF_NONE) + buffIndx = buffIndex_old; // Keep it busy + else + buffIndx = GetReadable(sysMonitorInst->sendLogCtrl); + sysMonitorInst->sendLogCtrl.rBusy = buffIndx; + + // Encapsulate log + SLOTLOG *logEntry = &(sysMonitorInst->sendLog[buffIndx]); + memcpy(buff, &(logEntry->tuNo), sizeof(logEntry->tuNo)); + buff += sizeof(logEntry->tuNo); + memcpy(buff, &(logEntry->slotNo), sizeof(logEntry->slotNo)); + buff += sizeof(logEntry->slotNo); + memcpy(buff, &(logEntry->frameType), sizeof(logEntry->frameType)); + buff += sizeof(logEntry->frameType); + memcpy(buff, &(logEntry->srcId), sizeof(logEntry->srcId)); + buff += sizeof(logEntry->srcId); + memcpy(buff, &(logEntry->dstId), sizeof(logEntry->dstId)); + buff += sizeof(logEntry->dstId); + memcpy(buff, &(logEntry->baseInfo), sizeof(logEntry->baseInfo)); + buff += sizeof(logEntry->baseInfo); + memcpy(buff, &(logEntry->payload), sizeof(logEntry->payload)); + buff += sizeof(logEntry->payload); + memcpy(buff, &(logEntry->tmStamp), sizeof(logEntry->tmStamp)); + buff += sizeof(logEntry->tmStamp); + memcpy(buff, &(logEntry->tmDevi), sizeof(logEntry->tmDevi)); + buff += sizeof(logEntry->tmDevi); + memcpy(buff, &(logEntry->freqDevi), sizeof(logEntry->freqDevi)); + sysMonitorInst->sendLogCtrl.rBusy = buffIndex_old; +} + +// @Receive Slot log +/** + * Log receive slot information + */ +void SysMonitor_UpdateRecvSlotLog(SLOTLOG *log) +{ + ASSERT(sysMonitorInst != NULL); + uint8_t buffIndx; + buffIndx = GetWritable(sysMonitorInst->recvLogCtrl); + sysMonitorInst->recvLogCtrl.wBusy = buffIndx; + memcpy(&(sysMonitorInst->recvLog[buffIndx]), log, sizeof(SLOTLOG)); + sysMonitorInst->recvLogCtrl.latest = buffIndx; + sysMonitorInst->recvLogCtrl.wBusy = BUFF_NONE; +} + +/** + * Get the latest receive slot information + */ +void SysMonitor_GetRecvSlotLog(SLOTLOG *log) +{ + ASSERT(sysMonitorInst != NULL); + uint8_t buffIndx, buffIndex_old; + buffIndex_old = sysMonitorInst->recvLogCtrl.rBusy; + if (buffIndex_old != BUFF_NONE) + buffIndx = buffIndex_old; // Keep it busy + else + buffIndx = GetReadable(sysMonitorInst->recvLogCtrl); + sysMonitorInst->recvLogCtrl.rBusy = buffIndx; + memcpy(log, &(sysMonitorInst->recvLog[buffIndx]), sizeof(SLOTLOG)); + sysMonitorInst->recvLogCtrl.rBusy = buffIndex_old; +} + +/** + * Get the latest receive slot information as raw data + */ +void SysMonitor_GetRecvSlotLogRaw(uint8_t *buff) +{ + ASSERT(sysMonitorInst != NULL); + uint8_t buffIndx, buffIndex_old; + buffIndex_old = sysMonitorInst->recvLogCtrl.rBusy; + if (buffIndex_old != BUFF_NONE) + buffIndx = buffIndex_old; // Keep it busy + else + buffIndx = GetReadable(sysMonitorInst->recvLogCtrl); + sysMonitorInst->recvLogCtrl.rBusy = buffIndx; + + // Encapsulate log + SLOTLOG *logEntry = &(sysMonitorInst->recvLog[buffIndx]); + memcpy(buff, &(logEntry->tuNo), sizeof(logEntry->tuNo)); + buff += sizeof(logEntry->tuNo); + memcpy(buff, &(logEntry->slotNo), sizeof(logEntry->slotNo)); + buff += sizeof(logEntry->slotNo); + memcpy(buff, &(logEntry->frameType), sizeof(logEntry->frameType)); + buff += sizeof(logEntry->frameType); + memcpy(buff, &(logEntry->srcId), sizeof(logEntry->srcId)); + buff += sizeof(logEntry->srcId); + memcpy(buff, &(logEntry->dstId), sizeof(logEntry->dstId)); + buff += sizeof(logEntry->dstId); + memcpy(buff, &(logEntry->baseInfo), sizeof(logEntry->baseInfo)); + buff += sizeof(logEntry->baseInfo); + memcpy(buff, &(logEntry->payload), sizeof(logEntry->payload)); + buff += sizeof(logEntry->payload); + memcpy(buff, &(logEntry->tmStamp), sizeof(logEntry->tmStamp)); + buff += sizeof(logEntry->tmStamp); + memcpy(buff, &(logEntry->tmDevi), sizeof(logEntry->tmDevi)); + buff += sizeof(logEntry->tmDevi); + memcpy(buff, &(logEntry->freqDevi), sizeof(logEntry->freqDevi)); + sysMonitorInst->recvLogCtrl.rBusy = buffIndex_old; +} + +// @Protocol log +/** + * Log protocol running status. + */ +void SysMonitor_UpdateProtocolLog(PRTCLLOG *log) +{ + ASSERT(sysMonitorInst != NULL); + uint8_t buffIndx; + buffIndx = GetWritable(sysMonitorInst->protocolLogCtrl); + sysMonitorInst->protocolLogCtrl.wBusy = buffIndx; + memcpy(&(sysMonitorInst->protocolLog[buffIndx]), log, sizeof(PRTCLLOG)); + sysMonitorInst->protocolLogCtrl.latest = buffIndx; + sysMonitorInst->protocolLogCtrl.wBusy = BUFF_NONE; +} + +/** + * Get the protocol running log. + */ +void SysMonitor_GetProtocolLog(PRTCLLOG *log) +{ + ASSERT(sysMonitorInst != NULL); + uint8_t buffIndx, buffIndex_old; + buffIndex_old = sysMonitorInst->protocolLogCtrl.rBusy; + if (buffIndex_old != BUFF_NONE) + buffIndx = buffIndex_old; // Keep it busy + else + buffIndx = GetReadable(sysMonitorInst->protocolLogCtrl); + sysMonitorInst->protocolLogCtrl.rBusy = buffIndx; + memcpy(log, &(sysMonitorInst->protocolLog[buffIndx]), sizeof(PRTCLLOG)); + sysMonitorInst->protocolLogCtrl.rBusy = buffIndex_old; +} + +/** + * Get the protocol running log as raw data. + */ +void SysMonitor_GetProtocolLogRaw(uint8_t *buff) +{ + ASSERT(sysMonitorInst != NULL); + uint8_t buffIndx, buffIndex_old; + buffIndex_old = sysMonitorInst->protocolLogCtrl.rBusy; + if (buffIndex_old != BUFF_NONE) + buffIndx = buffIndex_old; // Keep it busy + else + buffIndx = GetReadable(sysMonitorInst->protocolLogCtrl); + sysMonitorInst->protocolLogCtrl.rBusy = buffIndx; + + // Encapsulate log + PRTCLLOG *logEntry = &(sysMonitorInst->protocolLog[buffIndx]); + memcpy(buff, &(logEntry->tmSys), sizeof(logEntry->tmSys)); + buff += sizeof(logEntry->tmSys); + memcpy(buff, &(logEntry->phySt), sizeof(logEntry->phySt)); + buff += sizeof(logEntry->phySt); + memcpy(buff, &(logEntry->tmLocal), sizeof(logEntry->tmLocal)); + buff += sizeof(logEntry->tmLocal); + memcpy(buff, &(logEntry->beamNo), sizeof(logEntry->beamNo)); + buff += sizeof(logEntry->beamNo); + memcpy(buff, &(logEntry->beamWidth), sizeof(logEntry->beamWidth)); + buff += sizeof(logEntry->beamWidth); + memcpy(buff, &(logEntry->stage), sizeof(logEntry->stage)); + buff += sizeof(logEntry->stage); + memcpy(buff, &(logEntry->recvCnt), sizeof(logEntry->recvCnt)); + buff += sizeof(logEntry->recvCnt); + memcpy(buff, &(logEntry->recvFineCnt), sizeof(logEntry->recvFineCnt)); + buff += sizeof(logEntry->recvFineCnt); + memcpy(buff, &(logEntry->nodeCnt), sizeof(logEntry->nodeCnt)); + buff += sizeof(logEntry->nodeCnt); + memcpy(buff, &(logEntry->myId), sizeof(logEntry->myId)); + buff += sizeof(logEntry->myId); + memcpy(buff, &(logEntry->dstId), sizeof(logEntry->dstId)); + sysMonitorInst->protocolLogCtrl.rBusy = buffIndex_old; +} + +// @Hardware state +/** + * Log hardware running status. + */ +void SysMonitor_UpdateHardwareStatus(HWSTATE *state) +{ + ASSERT(sysMonitorInst != NULL); + uint8_t buffIndx; + buffIndx = GetWritable(sysMonitorInst->hwStateCtrl); + sysMonitorInst->hwStateCtrl.wBusy = buffIndx; + memcpy(&(sysMonitorInst->hwState[buffIndx]), state, sizeof(HWSTATE)); + sysMonitorInst->hwStateCtrl.latest = buffIndx; + sysMonitorInst->hwStateCtrl.wBusy = BUFF_NONE; +} + +/** + * Get the latest hardware running status. + */ +void SysMonitor_GetHardwareStatus(HWSTATE *state) +{ + ASSERT(sysMonitorInst != NULL); + uint8_t buffIndx, buffIndex_old; + buffIndex_old = sysMonitorInst->hwStateCtrl.rBusy; + if (buffIndex_old != BUFF_NONE) + buffIndx = buffIndex_old; // Keep it busy + else + buffIndx = GetReadable(sysMonitorInst->hwStateCtrl); + sysMonitorInst->hwStateCtrl.rBusy = buffIndx; + memcpy(state, &(sysMonitorInst->hwState[buffIndx]), sizeof(HWSTATE)); + sysMonitorInst->hwStateCtrl.rBusy = buffIndex_old; +} + +/** + * Get the latest hardware running status as raw data. + */ +void SysMonitor_GetHardwareStatusRaw(uint8_t *buff) +{ + ASSERT(sysMonitorInst != NULL); + uint8_t buffIndx, buffIndex_old; + buffIndex_old = sysMonitorInst->hwStateCtrl.rBusy; + if (buffIndex_old != BUFF_NONE) + buffIndx = buffIndex_old; // Keep it busy + else + buffIndx = GetReadable(sysMonitorInst->hwStateCtrl); + sysMonitorInst->hwStateCtrl.rBusy = buffIndx; + + // Encapsulate state + HWSTATE *stateEntry = &(sysMonitorInst->hwState[buffIndx]); + memcpy(buff, &(stateEntry->spVolt), sizeof(stateEntry->spVolt)); + buff += sizeof(stateEntry->spVolt); + memcpy(buff, &(stateEntry->spTemp), sizeof(stateEntry->spTemp)); + buff += sizeof(stateEntry->spTemp); + memcpy(buff, &(stateEntry->chipSt), sizeof(stateEntry->chipSt)); + buff += sizeof(stateEntry->chipSt); + memcpy(buff, &(stateEntry->antVolt), sizeof(stateEntry->antVolt)); + buff += sizeof(stateEntry->antVolt); + memcpy(buff, &(stateEntry->antTemp), sizeof(stateEntry->antTemp)); + buff += sizeof(stateEntry->antTemp); + memcpy(buff, &(stateEntry->antPll), sizeof(stateEntry->antPll)); + buff += sizeof(stateEntry->antPll); + memcpy(buff, &(stateEntry->antMgc), sizeof(stateEntry->antMgc)); + buff += sizeof(stateEntry->antMgc); + memcpy(buff, &(stateEntry->antSt), sizeof(stateEntry->antSt)); + sysMonitorInst->hwStateCtrl.rBusy = buffIndex_old; +} + +// @System log +/** + * Get the latest system running log. + */ +void SysMonitor_GetSyslog(SYSLOG *log) +{ + ASSERT(sysMonitorInst != NULL); + SysMonitor_GetSendSlotLog(&(log->sendLog)); + SysMonitor_GetRecvSlotLog(&(log->recvLog)); + SysMonitor_GetProtocolLog(&(log->protocolLog)); + SysMonitor_GetHardwareStatus(&(log->hwSate)); +} + +/** + * Get the latest system running log as raw data. + */ +void SysMonitor_GetSyslogRaw(uint8_t *buff) +{ + ASSERT(sysMonitorInst != NULL); + SysMonitor_GetSendSlotLogRaw(buff); + buff += SLOTLOG_PACK_LEN; + SysMonitor_GetRecvSlotLogRaw(buff); + buff += SLOTLOG_PACK_LEN; + SysMonitor_GetProtocolLogRaw(buff); + buff += PRTCLLOG_PACK_ELN; + SysMonitor_GetHardwareStatusRaw(buff); +} diff --git a/df_datalink_sp/src/system_monitor.h b/df_datalink_sp/src/system_monitor.h new file mode 100644 index 0000000..c4b97ba --- /dev/null +++ b/df_datalink_sp/src/system_monitor.h @@ -0,0 +1,160 @@ +#ifndef __SYSTEM_MONITOR_H_ +#define __SYSTEM_MONITOR_H_ + +#include +#include + +#define PAYLOAD_FLJ 78 +#define PAYLOAD_LJ 168 + +typedef struct +{ + // FIXME: To Complete +} SYSCONFIG; + +typedef struct +{ + // -- unit: ms, 0~604799999 + uint32_t psBDS; + // -- unit: week, 0~0~8191 + uint16_t pBDS; + // -- unit: ms, 0~604799999 + uint32_t psGPS; + // -- unit: week, 0~0~8191 + uint16_t pGPS; + // Time validation indicator + // -- [0] GPS + // -- [1] reserve. + // -- [2] UTC + // -- [3] BDS + uint8_t tmInd; + // Time of flying + // uint: s + float tmFly; + // Status of flying + // [7:6] departure status 11 - departed/00 - not departed + // [5:4] ready status 11 - ready/00 - not ready + // [3:2] attitude status 11 - attitude ok/00 - attitude not ok + // [1:0] attitude adjust status 11 - adjusted/00 - not adjusted + uint8_t stFly; + // Position in launch coordinate system + float posX; + float posY; + float posZ; + // Speed in launch coordinate system + float vX; + float vY; + float vZ; + // Attitude in launch inertia coordinate system + float pitch; + float yaw; + float roll; +} SYSINFO; + +typedef struct +{ + uint8_t data_lj[PAYLOAD_LJ]; + uint8_t data_flj[PAYLOAD_FLJ]; +} PAYLOAD; + +typedef struct +{ + // Network log + uint32_t tuNo; + uint8_t slotNo; + uint8_t frameType; + uint8_t srcId; + uint8_t dstId; + uint8_t baseInfo[18]; + // Payload + uint8_t payload[46]; + // Time sync info + uint64_t tmStamp; + uint32_t tmDevi; + uint32_t freqDevi; +} SLOTLOG; + +typedef struct +{ + // Protocol log + // -- System time + uint32_t tmSys; + // -- Physical layer status + uint8_t phySt; + // -- Link layer status + uint32_t tmLocal; + uint16_t beamNo; + uint8_t beamWidth; + // -- Network layer status + uint8_t stage; + uint32_t recvCnt; + uint32_t recvFineCnt; + uint8_t nodeCnt; + uint8_t myId; + uint8_t dstId; +} PRTCLLOG; + +typedef struct +{ + // Hardware log + // -- Signal processor status + uint16_t spVolt; + uint16_t spTemp; + uint16_t chipSt; + // -- Antenna status + uint8_t antVolt; + uint8_t antTemp; + uint8_t antPll; + uint16_t antMgc; + uint8_t antSt; +} HWSTATE; + +typedef struct +{ + // Send slot log + SLOTLOG sendLog; + + // Receive slot log + SLOTLOG recvLog; + + // Protocol log + PRTCLLOG protocolLog; + + // Hardware status + HWSTATE hwSate; +} SYSLOG; + +int32_t SysMonitor_Init(void); + +void SysMonitor_UpdateSysinfo(SYSINFO *info); +void SysMonitor_UpdateSysinfoRaw(uint8_t *buff); +void SysMonitor_GetSysinfo(SYSINFO *info); +void SysMonitor_GetSysinfoRaw(uint8_t *buff); + +void SysMonitor_UpdateSendPayloadFLJRaw(uint8_t *buff); +void SysMonitor_UpdateRecvPayloadFLJRaw(uint8_t *buff); +void SysMonitor_UpdateSendPayloadLJRaw(uint8_t *buff); +void SysMonitor_UpdateRecvPayloadLJRaw(uint8_t *buff); +void SysMonitor_GetSendPayloadFLJRaw(uint8_t *buff); +void SysMonitor_GetRecvPayloadFLJRaw(uint8_t *buff); +void SysMonitor_GetSendPayloadLJRaw(uint8_t *buff); +void SysMonitor_GetRecvPayloadLJRaw(uint8_t *buff); + +void SysMonitor_UpdateSendSlotLog(SLOTLOG *log); +void SysMonitor_UpdateRecvSlotLog(SLOTLOG *log); +void SysMonitor_UpdateProtocolLog(PRTCLLOG *log); +void SysMonitor_GetSendSlotLog(SLOTLOG *log); +void SysMonitor_GetRecvSlotLog(SLOTLOG *log); +void SysMonitor_GetProtocolLog(PRTCLLOG *log); +void SysMonitor_GetSendSlotLogRaw(uint8_t *buff); +void SysMonitor_GetRecvSlotLogRaw(uint8_t *buff); +void SysMonitor_GetProtocolLogRaw(uint8_t *buff); + +void SysMonitor_UpdateHardwareStatus(HWSTATE *state); +void SysMonitor_GetHardwareStatus(HWSTATE *state); +void SysMonitor_GetHardwareStatusRaw(uint8_t *buff); + +void SysMonitor_GetSyslog(SYSLOG *log); +void SysMonitor_GetSyslogRaw(uint8_t *buff); + +#endif //__SYSTEM_MONITOR_H_ diff --git a/df_datalink_sp/src/systembus/systembus.c b/df_datalink_sp/src/systembus/systembus.c new file mode 100644 index 0000000..0868e07 --- /dev/null +++ b/df_datalink_sp/src/systembus/systembus.c @@ -0,0 +1,579 @@ +/*****************************************************************************/ +/** + * Description: System bus protocol implementation file. + * + * Date: 2023-05-06 10:13 + * Last Edit Time: [2023-05-06 21:45] + * + * Revisions: Rev 0.0 + * History: + * [2023-05-06]: Initial version. + * [2023-09-13]: Update to 485 protocol-20220816 + * + * Copyright(c) 2021 Beijing Institute of Technology. + * Lab of Communication and Network + * + ******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include +#include +#include +#include +#include "systembus_uart.h" +#include "systembus.h" +#include "util.h" +#include "common.h" +#include "error.h" +#include "circ_queue.h" + +#include "../system_monitor.h" + +// Common Field +// -- Command word +#define WD_CMD 0x00 + +// -- Production type +#define WD_PRD 0x01 +#define PRD_DL_K 0xDD +#define PRD_DL_S 0xDE +#define PRD_ALL 0xFF + +// Self-Test +#define CMD_SELF_TEST 0xE1 +// -- Request +// -- -- -- +// -- Response +// -- -- Self-Test Result +#define ST_RSP_LEN 16 +#define WD_ST_RET 0x02 +#define ST_RET_OK 0xAA +#define ST_RET_ERROR 0x55 +// -- -- Signal processor voltage +#define WD_SP_VOLT_L 0x03 +#define WD_SP_VOLT_H 0x04 +// -- -- Signal processor temperature +#define WD_SP_TEMP_L 0x05 +#define WD_SP_TEMP_H 0x06 +// -- -- Signal processor chip status +#define WD_SP_CS_L 0x07 +#define WD_SP_CS_H 0x08 +// -- -- Signal processor antenna voltage +#define WD_AS_VOLT 0x09 +// -- -- Signal processor antenna temperature +#define WD_AS_TEMP 0x0A +// -- -- Signal processor antenna PLL lock status +#define WD_AS_PLL 0x0B +// -- -- Signal processor antenna MGC +#define WD_AS_MGC_L 0x0C +#define WD_AS_MGC_H 0x0D +// -- -- Signal processor antenna status +#define WD_AS_ST 0x0E. +// -- -- Dummy must be 0x00 +#define WD_ST_DUMMY 0x0F + +// Data Send Test Command +#define CMD_DATA_TEST_A 0xE2 +// -- Request +#define DATA_TEST_REQ_A_LEN 80 +// -- -- 78 byte payload +// -- Response +#define DATA_TEST_RSP_A_LEN 80 +// -- -- 78 byte payload + +// Data Send Test Command +#define CMD_DATA_TEST_B 0xF2 +// -- Request +#define DATA_TEST_REQ_B_LEN 152 +// -- -- 150 byte payload +// -- Response +#define DATA_TEST_RSP_B_LEN 152 +// -- -- 150 byte payload + +// Config load +#define CMD_CONFIG 0xE3 +// -- Request +#define WD_EN_CMD 0x02 +#define EN_CMD_ON 0x66 + +#define WD_MODE_CMD 0x03 +#define MODE_CMD_HEAD 0x11 +#define MODE_CMD_MEMBER 0x11 +// -- Response +// -- -- none response + +// System info update +#define CMD_SYS_INFO 0x33 +#define SYS_INFO_OFFSET 2 +// -- Request +// -- -- 54 byte system info +// -- Response +// -- -- none response + +// Data Send Test Command +#define CMD_FLJ_SEND 0xE4 +#define FLJ_DATA_OFFSET 2 +// -- Request +// -- -- 78 byte payload +// -- Response +// -- -- none response + +// Data Send Test Command +#define CMD_LJ_SEND 0xF4 +#define LJ_DATA_OFFSET 2 +// -- Request +// -- -- 156 byte payload +// -- Response +// -- -- none response + +// FLJ Poll +#define CMD_FLJ_POLL 0xE5 +// -- Request +#define WD_FLJ_POLL 0x02 +#define FLJ_POLL_CODE 0x77 +// -- Response +#define FLJ_POLL_RESP_LEN 78 +// -- -- received 78 byte payload + +// LJ Poll +#define CMD_LJ_POLL 0xF5 +// -- Request +#define WD_LJ_POLL 0x02 +#define LJ_POLL_CODE 0x77 +// -- Response +#define LJ_POLL_RESP_LEN 168 +// -- -- received 156 byte payload + +// Remote Test FLJ +#define CMD_FLJ_RM_TEST 0xE6 +// -- Request +#define WD_FLJ_RM_TEST 0x02 +#define FLJ_RM_TEST_CODE 0x99 +// -- Response +#define FLJ_RM_TEST_RESP_LEN 158 + +// Remote Test LJ +#define CMD_LJ_RM_TEST 0xF6 +// -- Request +#define WD_LJ_RM_TEST 0x02 +#define LJ_RM_TEST_CODE 0x99 +// -- Response +#define LJ_RM_TEST_RESP_LEN 158 + + +// My Production Type +#define MY_PRD_ID PRD_DL_K + +inline bool SystemBus_IsReqPendding(SYSBUS *instPtr) +{ + ASSERT(instPtr != NULL); + return (!isCircQueueEmpty(instPtr->rxQueue)); +} + +inline bool SystemBus_IsRsqPendding(SYSBUS *instPtr) +{ + ASSERT(instPtr != NULL); + return (!isCircQueueEmpty(instPtr->txQueue)); +} + +inline bool SystemBus_IsTxBusy(SYSBUS *instPtr) +{ + ASSERT(instPtr != NULL); + return (!instPtr->isTxDone); +} +inline bool SystemBus_IsRxBusy(SYSBUS *instPtr) +{ + ASSERT(instPtr != NULL); + return SysbusUart_IsRxBusy(instPtr->uartInst); +} + +/*****************************************************************************/ +/** + * @brief Initialize System Bus instance. + * + * @param InstPtr A double pointer to System Bus instance. + * @param config A pointer to System Bus configurations. + * + * @return None. + * + ******************************************************************************/ +int32_t SystemBus_Init(SYSBUS **instPtr, SYSBUS_CONFIG *config) +{ + ASSERT(instPtr != NULL); + ASSERT(config != NULL); + SYSBUS_UART_CONFIG uartConfig; + int32_t Status; + (*instPtr) = malloc(sizeof(SYSBUS)); + if ((*instPtr) == NULL) + { + return FAILURE; + } + (*instPtr)->rxQueue = NULL; + (*instPtr)->txQueue = NULL; + (*instPtr)->uartInst = NULL; + memcpy(&((*instPtr)->config), config, sizeof(SYSBUS_CONFIG)); + uartConfig.baseAddr = config->baseAddr; + Status = SysbusUart_Init(&((*instPtr)->uartInst), &uartConfig); + if (Status != SUCCESS) + { + Status = ENOMEM; + goto sysbus_init_error; + } + if (CircQueueCreate(&((*instPtr)->txQueue), (*instPtr)->config.txQueueMax) == false) + { + Status = ENOMEM; + goto sysbus_init_error; + } + if (CircQueueCreate(&((*instPtr)->rxQueue), (*instPtr)->config.rxQueueMax) == false) + { + Status = ENOMEM; + goto sysbus_init_error; + } + (*instPtr)->isRxDone = false; // nothing received. + (*instPtr)->isTxDone = true; // nothing to be sent. + return SUCCESS; + +sysbus_init_error: + free((*instPtr)->uartInst); + free((*instPtr)->txQueue); + free((*instPtr)->rxQueue); + free(*instPtr); + return Status; +} + +/*****************************************************************************/ +/** + * @brief A handler function. This handler evaluate the message from system + * bus receive queue, and make appropriate response. + * + * @param instPtr A pointer to System Bus instance. + * + * @return None + * + ******************************************************************************/ +int32_t SystemBus_HandleCmd(SYSBUS *instPtr) +{ + ASSERT(instPtr != NULL); + int32_t Status; + SYSBUS_UART_FRAME *sysbusReq, *sysbusRsp; + uint8_t *data; + if (CircQueuePop(instPtr->rxQueue, (void **)(&sysbusReq)) == false) + { + DBG_WARNING("SystemBus::Nothing to be handled.\n"); + return EIGNORE; + } + data = sysbusReq->data; + if (data[WD_PRD] != MY_PRD_ID && data[WD_PRD] != PRD_ALL) + { + DBG_WARNING("SystemBus::Production code mismatch!\n"); + return EIGNORE; + } + switch (data[WD_CMD]) + { + case CMD_SELF_TEST: + { + sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME)); + if (sysbusRsp == NULL) { + DBG_ERROR("Failed to allocate memory for SELF TEST Response!\n"); + Status = ENOMEM; + break; + } + sysbusRsp->len = ST_RSP_LEN; + memset(sysbusRsp->data, 0x00, ST_RSP_LEN); + sysbusRsp->data[WD_CMD] = CMD_SELF_TEST; + sysbusRsp->data[WD_PRD] = MY_PRD_ID; + + // FIXME: run self-test and insert result + sysbusRsp->data[WD_ST_RET] = ST_RET_OK; + if (CircQueuePush(instPtr->txQueue, (void *)sysbusRsp) == false) + { + free(sysbusRsp); + DBG_ERROR("SystemBus::TX Queue overflowed!\n"); + Status = EQUEUE; + break; + } + Status = SUCCESS; + break; + } + case CMD_DATA_TEST_A: + { + sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME)); + if (sysbusRsp == NULL) { + DBG_ERROR("Failed to allocate memory for DATA TEST A Response!\n"); + Status = ENOMEM; + break; + } + sysbusRsp->len = DATA_TEST_RSP_A_LEN; + memcpy(sysbusRsp->data, sysbusReq->data, DATA_TEST_RSP_A_LEN); + if (CircQueuePush(instPtr->txQueue, (void *)sysbusRsp) == false) + { + free(sysbusRsp); + DBG_ERROR("SystemBus::TX Queue overflowed!\n"); + Status = EQUEUE; + break; + } + Status = SUCCESS; + break; + } + case CMD_DATA_TEST_B: + { + sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME)); + if (sysbusRsp == NULL) { + DBG_ERROR("Failed to allocate memory for DATA TEST B Response!\n"); + Status = ENOMEM; + break; + } + sysbusRsp->len = DATA_TEST_RSP_B_LEN; + memcpy(sysbusRsp->data, sysbusReq->data, DATA_TEST_RSP_B_LEN); + if (CircQueuePush(instPtr->txQueue, (void *)sysbusRsp) == false) + { + free(sysbusRsp); + DBG_ERROR("SystemBus::TX Queue overflowed!\n"); + Status = EQUEUE; + break; + } + Status = SUCCESS; + break; + } + case CMD_CONFIG: + { + // FIXME: apply configurations + // Power + Mode + // -- No response + _nop_(); // for debug + Status = SUCCESS; + break; + } + case CMD_SYS_INFO: + { + SysMonitor_UpdateSysinfoRaw(data + SYS_INFO_OFFSET); + Status = SUCCESS; + break; + } + // TODO + case CMD_FLJ_SEND: + { + SysMonitor_UpdateSendPayloadFLJRaw(data + FLJ_DATA_OFFSET); // omit control info + break; + } + case CMD_LJ_SEND: + { + SysMonitor_UpdateSendPayloadLJRaw(data + LJ_DATA_OFFSET); // omit control info + break; + } + case CMD_FLJ_POLL: + { + if (data[WD_FLJ_POLL] != FLJ_POLL_CODE) + { + DBG_ERROR("SystemBus::Invalid roll call code!\n"); + Status = EIGNORE; + break; + } + sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME)); + if (sysbusRsp == NULL) { + DBG_ERROR("Failed to allocate memory for FLJ POLL Response!\n"); + Status = ENOMEM; + break; + } + sysbusRsp->len = FLJ_POLL_RESP_LEN; + sysbusRsp->data[WD_CMD] = WD_FLJ_POLL; + sysbusRsp->data[WD_PRD] = MY_PRD_ID; + SysMonitor_GetRecvPayloadFLJRaw(sysbusRsp->data + FLJ_DATA_OFFSET); // omit control info + if (CircQueuePush(instPtr->txQueue, (void *)sysbusRsp) == false) + { + free(sysbusRsp); + DBG_WARNING("SystemBus::TX Queue overflowed!\n"); + Status = EQUEUE; + break; + } + Status = SUCCESS; + break; + } + case CMD_LJ_POLL: + { + if (data[WD_LJ_POLL] != LJ_POLL_CODE) + { + DBG_WARNING("SystemBus::Invalid roll call code!\n"); + Status = EIGNORE; + break; + } + sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME)); + if (sysbusRsp == NULL) { + DBG_ERROR("Failed to allocate memory for LJ POLL Response!\n"); + Status = ENOMEM; + break; + } + sysbusRsp->len = LJ_POLL_RESP_LEN; + sysbusRsp->data[WD_CMD] = WD_LJ_POLL; + sysbusRsp->data[WD_PRD] = MY_PRD_ID; + SysMonitor_GetRecvPayloadLJRaw(sysbusRsp->data + 2); // omit control info + if (CircQueuePush(instPtr->txQueue, (void *)sysbusRsp) == false) + { + free(sysbusRsp); + DBG_WARNING("SystemBus::TX Queue overflowed!\n"); + Status = EQUEUE; + break; + } + Status = SUCCESS; + break; + } + case CMD_FLJ_RM_TEST: + { + if (data[WD_FLJ_RM_TEST] != FLJ_RM_TEST_CODE) + { + DBG_WARNING("SystemBus::Invalid remote test code!\n"); + Status = EIGNORE; + break; + } + sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME)); + if (sysbusRsp == NULL) { + DBG_ERROR("Failed to allocate memory for FLJ REMOTE TEST Response!\n"); + Status = ENOMEM; + break; + } + sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME)); + sysbusRsp->len = FLJ_RM_TEST_RESP_LEN; + memset(sysbusRsp->data, 0x00, FLJ_RM_TEST_RESP_LEN); + sysbusRsp->data[WD_CMD] = CMD_FLJ_RM_TEST; + sysbusRsp->data[WD_PRD] = MY_PRD_ID; + + if (CircQueuePush(instPtr->txQueue, (void *)sysbusRsp) == false){ + free(sysbusRsp); + DBG_WARNING("SystemBus::TX Queue overflowed!\n"); + Status = EQUEUE; + break; + } + Status = SUCCESS; + break; + } + case CMD_LJ_RM_TEST: + { + if (data[WD_LJ_RM_TEST] != LJ_RM_TEST_CODE) + { + DBG_WARNING("SystemBus::Invalid remote test code!\n"); + Status = EIGNORE; + break; + } + sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME)); + if (sysbusRsp == NULL) { + DBG_ERROR("Failed to allocate memory for LJ REMOTE TEST Response!\n"); + Status = ENOMEM; + break; + } + sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME)); + sysbusRsp->len = LJ_RM_TEST_RESP_LEN; + memset(sysbusRsp->data, 0x00, LJ_RM_TEST_RESP_LEN); + sysbusRsp->data[WD_CMD] = CMD_LJ_RM_TEST; + sysbusRsp->data[WD_PRD] = MY_PRD_ID; + + if (CircQueuePush(instPtr->txQueue, (void *)sysbusRsp) == false){ + free(sysbusRsp); + DBG_WARNING("SystemBus::TX Queue overflowed!\n"); + Status = EQUEUE; + break; + } + Status = SUCCESS; + break; + } + default: + { + DBG_ERROR("SystemBus::Unknown command code!\n"); + break; + } + } + free(sysbusReq); + return Status; +} + +int32_t SystemBus_FLJ_PeriodUpdate(SYSBUS *instPtr) +{ + // TODO + return SUCCESS; +} + +int32_t SystemBus_LJ_PeriodUpdate(SYSBUS *instPtr) +{ + // TODO + return SUCCESS; +} + +/*****************************************************************************/ +/** + * @brief This function send a repose frame from system bus tx queue. + * + * @param instPtr A pointer to System Bus instance. + * + * @return None + * + ******************************************************************************/ +int32_t SystemBus_MakeResp(SYSBUS *instPtr) +{ + ASSERT(instPtr != NULL); + int32_t Status; + SYSBUS_UART_FRAME *sysbusRsp; + if (CircQueuePop(instPtr->txQueue, (void **)(&sysbusRsp)) == false) + { + DBG_WARNING("SystemBus::Nothing to be sent.\n"); + return EIGNORE; + } + instPtr->isTxDone = false; // A transmission procedure is started. + Status = SysbusUart_Send(instPtr->uartInst, sysbusRsp); + free(sysbusRsp); + return Status; +} + +/*****************************************************************************/ +/** + * @brief This function handles the systembus tx irq events. + * + * @param instPtr A pointer to System Bus instance. + * + * @return None + * + ******************************************************************************/ +int32_t SystemBus_TxIntrHandler(SYSBUS *instPtr) +{ + ASSERT(instPtr != NULL); + // nothing special... + instPtr->isTxDone = true; // A transmission procedure finished. + return SUCCESS; +} + +/*****************************************************************************/ +/** + * @brief This function handles the systembus rx irq events. + * + * @param instPtr A pointer to System Bus instance. + * + * @return None + * + ******************************************************************************/ +int32_t SystemBus_RxIntrHandler(SYSBUS *instPtr) +{ + ASSERT(instPtr != NULL); + int32_t Status; + SYSBUS_UART_FRAME *sysbusReq; + instPtr->isRxDone = true; // whether reception successes or not, receiving procedure ended. + sysbusReq = malloc(sizeof(SYSBUS_UART_FRAME)); + if (sysbusReq == NULL) + { + return ENOMEM; + } + Status = SysbusUart_Recv(instPtr->uartInst, sysbusReq); + if (Status != SUCCESS) + { + goto recv_error; + } + if (CircQueuePush(instPtr->rxQueue, (void *)sysbusReq) == false) + { + DBG_ERROR("SystemBus::RX Queue overflowed!\n"); + Status = EQUEUE; + goto recv_error; + } + instPtr->isRxDone = false; // another reception is undergoing. + return SUCCESS; +recv_error: + free(sysbusReq); + return Status; +} diff --git a/df_datalink_sp/src/systembus/systembus.h b/df_datalink_sp/src/systembus/systembus.h new file mode 100644 index 0000000..a901fce --- /dev/null +++ b/df_datalink_sp/src/systembus/systembus.h @@ -0,0 +1,65 @@ +/*****************************************************************************/ +/** + * Description: System bus protocol head file. + * + * Date: 2023-05-06 10:12 + * Last Edit Time: [2023-05-06 10:13] + * + * Revisions: Rev 0.0 + * History: + * [2023-05-06]: Initial version. + * + * Copyright(c) 2021 Beijing Institute of Technology. + * + ******************************************************************************/ + +#ifndef __SYSTEMBUS_H_ +#define __SYSTEMBUS_H_ + +/***************************** Include Files *********************************/ +#include "systembus_uart.h" // SystemBus UART driver +#include "circ_queue.h" +#include +#include + +/************************** Constant Definitions *****************************/ +/************************** Data Type Definitions ****************************/ +// Definition of SystemBus instance. +typedef struct +{ + uintptr_t baseAddr; + uint32_t txQueueMax; + uint32_t rxQueueMax; +} SYSBUS_CONFIG; + +typedef struct +{ + SYSBUS_CONFIG config; + SYSBUS_UART *uartInst; + CIRC_QUEUE *txQueue; + CIRC_QUEUE *rxQueue; + bool isRxDone; + bool isTxDone; +} SYSBUS; + +/************************** Function Prototypes ******************************/ + +int32_t SystemBus_Init(SYSBUS **instPtr, SYSBUS_CONFIG *config); + +int32_t SystemBus_HandleCmd(SYSBUS *instPtr); + +int32_t SystemBus_FLJ_PeriodUpdate(SYSBUS *instPtr); +int32_t SystemBus_LJ_PeriodUpdate(SYSBUS *instPtr); + +int32_t SystemBus_MakeResp(SYSBUS *instPtr); + +int32_t SystemBus_TxIntrHandler(SYSBUS *instPtr); +int32_t SystemBus_RxIntrHandler(SYSBUS *instPtr); + +bool SystemBus_IsReqPendding(SYSBUS *instPtr); +bool SystemBus_IsRsqPendding(SYSBUS *instPtr); + +bool SystemBus_IsTxBusy(SYSBUS *instPtr); +bool SystemBus_IsRxBusy(SYSBUS *instPtr); + +#endif //__SYSTEMBUS_H_ diff --git a/df_datalink_sp/src/systembus/systembus_uart.c b/df_datalink_sp/src/systembus/systembus_uart.c new file mode 100644 index 0000000..45e3446 --- /dev/null +++ b/df_datalink_sp/src/systembus/systembus_uart.c @@ -0,0 +1,248 @@ +/*****************************************************************************/ +/** + * Description: System bus uart driver implementation file. + * + * Date: 2023-05-06 10:59 + * LastEditTime: 2023-05-06 21:56 + * Revisions: Rev 0.0 + * History: + * [2023-05-06]: Initial version. + * + * Copyright(c) 2022 Beijing Institute of Technology. + * + ******************************************************************************/ + +/***************************** Include Files *******************************/ +#include +#include +#include +#include +#include "systembus_uart.h" +#include "common.h" + +// Control and status register +#define MODULE_VERSION 0 +#define UART_STATUS 4 +#define UART_SEND_CMD 8 +#define UART_RECV_CNT 12 + +// Status code +#define UART_STATUS_TX_BUSY 0x00010000 +#define UART_STATUS_RX_BUSY 0x01000000 +// Data buffer register +#define UART_TXBUFF_LOW 1024 +#define UART_TXBUFF_MAX 1024 +#define UART_RXBUFF_LOW 2048 +#define UART_RXBUFF_MAX 1024 + +// Frame Data offsets +#define FRAME_HEAD_LOW 0x5A +#define FRAME_HEAD_HIGH 0x54 +#define FRAME_TAIL_LOW 0x5A +#define FRAME_TAIL_HIGH 0xFE + +#define FRAME_HEAD_LEN 2 +#define FRAME_TAIL_LEN 2 +#define FRAME_DUMMY_LEN 1 // Dummy +#define FRAME_CHECK_LEN 1 // CheckSum +#define FRAME_INFO_LEN 3 // CheckSum, Dummy and DataLen +#define FRAME_OVERHEAD_LEN 7 // CheckSum, Dummy and DataLen +/*************************** Function Definitions ****************************/ + +/*****************************************************************************/ +/** + * @brief Instance initial + * + * @param instPtr A pointer to frame uart instance structure. + * @param config Base address of frame uart, refer to "xparameters.h" + * + * @return None. + * + ******************************************************************************/ +int SysbusUart_Init(SYSBUS_UART **instPtr, SYSBUS_UART_CONFIG *config) +{ + ASSERT(instPtr != NULL); + ASSERT(config != NULL); + (*instPtr) = malloc(sizeof(SYSBUS_UART)); + if ((*instPtr) == NULL) + { + return FAILURE; + } + (*instPtr)->config.baseAddr = config->baseAddr; + return SUCCESS; +} + +/*****************************************************************************/ +/** + * @brief Send a system bus frame. + * + * @param instPtr A pointer to SYSBUS_UART instance structure. + * @param buff A pointer to send data buffer + * @param dLen A integer indicate the send data buffer length in byte. + * + * @return + * + ******************************************************************************/ +int SysbusUart_Send(SYSBUS_UART *instPtr, SYSBUS_UART_FRAME *frame) +{ + ASSERT(instPtr != NULL); + ASSERT(frame != NULL); + uint8_t dLen, checkSum; + uint8_t sendLen; + uint8_t *sendBuff; + if (frame->len > UART_TXBUFF_MAX || frame->len == 0) + { + return FAILURE; + } + sendBuff = malloc(sizeof(uint8_t) * UART_TXBUFF_MAX); + if (sendBuff == NULL) + { + return FAILURE; + } + sendBuff[0] = FRAME_HEAD_LOW; + sendBuff[1] = FRAME_HEAD_HIGH; + dLen = 0; + checkSum = 0; + for (int i = 0; i < frame->len - 1; i++) + { + if (frame->data[i] == FRAME_TAIL_LOW && frame->data[i + 1] == FRAME_TAIL_HIGH) + { + sendBuff[FRAME_HEAD_LEN + dLen] = 0x00; + dLen++; + } + sendBuff[FRAME_HEAD_LEN + dLen] = frame->data[i]; + checkSum += sendBuff[FRAME_HEAD_LEN + dLen]; + dLen++; + } + // Last Byte + sendBuff[FRAME_HEAD_LEN + dLen] = frame->data[frame->len - 1]; + checkSum += sendBuff[FRAME_HEAD_LEN + dLen]; + dLen++; + // Dummy Byte + sendBuff[FRAME_HEAD_LEN + dLen] = 0x00; + // Check Sum + sendBuff[FRAME_HEAD_LEN + dLen + 1] = checkSum; + // Data Len + sendBuff[FRAME_HEAD_LEN + dLen + 2] = dLen; + // Frame Tail + sendBuff[FRAME_HEAD_LEN + dLen + 3] = FRAME_TAIL_LOW; + sendBuff[FRAME_HEAD_LEN + dLen + 4] = FRAME_TAIL_HIGH; + sendLen = dLen + FRAME_OVERHEAD_LEN; + if (sendLen > UART_TXBUFF_MAX) + { + free(sendBuff); + return FAILURE; + } + memcpy((void *)(instPtr->config.baseAddr + UART_TXBUFF_LOW), sendBuff, (sendLen + sizeof(uint32_t) - 1) / sizeof(uint32_t) * sizeof(uint32_t)); + free(sendBuff); + // Start Sending + SYSTEMBUS_UART_mWriteReg(instPtr->config.baseAddr, UART_SEND_CMD, sendLen); + return SUCCESS; +} + +/*****************************************************************************/ +/** + * @brief Get last system bus frame. + * + * @param instPtr A pointer to SYSBUS_UART instance structure. + * @param buff A pointer to receive data buffer. + * + * @return + * + ******************************************************************************/ +int SysbusUart_Recv(SYSBUS_UART *instPtr, SYSBUS_UART_FRAME *frame) +{ + ASSERT(instPtr != NULL); + ASSERT(frame != NULL); + + uint8_t dLen, dWLen, plLen, checkSum, checkSumCal; + uint8_t *plBuff, *dBuff; + dLen = SYSTEMBUS_UART_mReadReg(instPtr->config.baseAddr, UART_RECV_CNT); + if (dLen == 0 || dLen > UART_TXBUFF_MAX) + { + return EPARAM; + } + dWLen = (dLen + FRAME_HEAD_LEN + FRAME_INFO_LEN - 1) / 4 + 1; + + dBuff = malloc(sizeof(uint32_t) * dWLen); + if (dBuff == NULL) + { + return ENOMEM; + } + memcpy(dBuff, (void *)(instPtr->config.baseAddr + UART_RXBUFF_LOW), sizeof(uint32_t) * dWLen); + plBuff = dBuff + FRAME_HEAD_LEN; + checkSumCal = 0; + checkSum = plBuff[dLen + FRAME_DUMMY_LEN]; + plLen = 0; + for (int i = 0; i < dLen; i++) + { + if (plBuff[i + 1] == FRAME_TAIL_LOW && plBuff[i + 2] == FRAME_TAIL_HIGH) + { + continue; + } + checkSumCal += plBuff[i]; + frame->data[plLen] = plBuff[i]; + plLen++; + } + free(dBuff); + frame->len = plLen; + frame->checkSum = checkSumCal; + if (checkSumCal != checkSum) + { + frame->isValid = false; + return FAILURE; + } + frame->isValid = true; + return SUCCESS; +} + +/*****************************************************************************/ +/** + * @brief Get rx channel status. + * + * @param instPtr A pointer to SYSBUS_UART instance structure. + * + * @return true - SYSBUS_UART rx channel is busy. + * false - SYSBUS_UART rx channel is idle. + * + ******************************************************************************/ +bool SysbusUart_IsRxBusy(SYSBUS_UART *instPtr) +{ + ASSERT(instPtr != NULL); + uint32_t Status; + Status = SYSTEMBUS_UART_mReadReg(instPtr->config.baseAddr, UART_STATUS); + + if (Status & UART_STATUS_RX_BUSY) + { + return true; + } + else + { + return false; + } +} + +/*****************************************************************************/ +/** + * @brief Get tx channel status. + * + * @param instPtr A pointer to SYSBUS_UART instance structure. + * + * @return true - SYSBUS_UART tx channel is busy. + * false - SYSBUS_UART tx channel is idle. + * + ******************************************************************************/ +bool SysbusUart_IsTxBusy(SYSBUS_UART *instPtr) +{ + ASSERT(instPtr != NULL); + uint32_t Status; + Status = SYSTEMBUS_UART_mReadReg(instPtr->config.baseAddr, UART_STATUS); + if (Status & UART_STATUS_TX_BUSY) + { + return true; + } + else + { + return false; + } +} diff --git a/df_datalink_sp/src/systembus/systembus_uart.h b/df_datalink_sp/src/systembus/systembus_uart.h new file mode 100644 index 0000000..38aea96 --- /dev/null +++ b/df_datalink_sp/src/systembus/systembus_uart.h @@ -0,0 +1,99 @@ +/*****************************************************************************/ +/** + * Description: System bus uart driver implementation file. + * + * Date: 2023-05-06 10:59 + * LastEditTime: 2023-05-06 21:48 + * Revisions: Rev 0.0 + * History: + * [2023-05-06]: Initial version. + * + * Copyright(c) 2022 Beijing Institute of Technology. + * + ******************************************************************************/ + +#ifndef SYSTEMBUS_UART_H +#define SYSTEMBUS_UART_H + +/****************** Include Files ********************/ +#include +#include +#include "util.h" +/**************************** Type Definitions *****************************/ +/** + * + * Write a value to a SYSTEMBUS_UART register. A 32 bit write is performed. + * If the component is implemented in a smaller width, only the least + * significant data is written. + * + * @param baseAddr is the base address of the SYSTEMBUS_UARTdevice. + * @param offset is the register offset from the base to write to. + * @param data is the data written to the register. + * + * @return None. + * + * @note + * C-style signature: + * void SYSTEMBUS_UART_mWriteReg(uint32_t BaseAddress, unsigned RegOffset, uint32_t Data) + * + */ +#define SYSTEMBUS_UART_mWriteReg(baseAddr, offset, data) \ + IO_Out32((baseAddr) + (offset), (uint32_t)(data)) + +/** + * + * Read a value from a SYSTEMBUS_UART register. A 32 bit read is performed. + * If the component is implemented in a smaller width, only the least + * significant data is read from the register. The most significant data + * will be read as 0. + * + * @param baseAddr is the base address of the SYSTEMBUS_UART device. + * @param offset is the register offset from the base to write to. + * + * @return Data is the data from the register. + * + * @note + * C-style signature: + * uint32_t SYSTEMBUS_UART_mReadReg(uint32_t BaseAddress, unsigned RegOffset) + * + */ +#define SYSTEMBUS_UART_mReadReg(baseAddr, offset) \ + IO_In32((baseAddr) + (offset)) + +/************************** Data Type Definitions ****************************/ +typedef struct +{ + uintptr_t baseAddr; +} SYSBUS_UART_CONFIG; + +typedef struct +{ + SYSBUS_UART_CONFIG config; +} SYSBUS_UART; + +typedef struct +{ + uint8_t len; + uint8_t checkSum; + uint8_t isValid; + uint8_t dummy; + uint8_t data[256]; +} SYSBUS_UART_FRAME; + +/************************** Function Prototypes ******************************/ +// Instance initial +int SysbusUart_Init(SYSBUS_UART **instPtr, SYSBUS_UART_CONFIG *config); + +// Send a system bus frame. +int SysbusUart_Send(SYSBUS_UART *instPtr, SYSBUS_UART_FRAME *frame); + +// Get last system bus frame. +int SysbusUart_Recv(SYSBUS_UART *instPtr, SYSBUS_UART_FRAME *frame); + +// Get system bus rx channel status. +bool SysbusUart_IsRxBusy(SYSBUS_UART *instPtr); + +// Get system bus tx channel status. +bool SysbusUart_IsTxBusy(SYSBUS_UART *instPtr); + +#endif // SYSTEMBUS_UART_H diff --git a/df_datalink_sp/src/util/circ_queue.c b/df_datalink_sp/src/util/circ_queue.c new file mode 100644 index 0000000..fc6364f --- /dev/null +++ b/df_datalink_sp/src/util/circ_queue.c @@ -0,0 +1,141 @@ +/*****************************************************************************/ +/** + * Description: A simple circular FIFO bounded queue + * + * Author: Fan Hao + * Date: 2023-02-23 10:29 + * LastEditors: Fan Hao + * LastEditTime: 2023-02-23 13:18 + * Revisions: Rev 0.0 + * History: + * [2023-02-23]: Initial Version. + * + * Copyright(c) 2023 Beijing Institute of Technology. + * Lab of Communication and Networking + * NOTE: Forked from https://github.com/chrismerck/rpa_queue.git + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ + +#include "circ_queue.h" +#include "common.h" +#include +#include +#include + +inline bool isCircQueueFull(CIRC_QUEUE *queue) +{ + ASSERT(queue != NULL); + return ((queue)->nelts == (queue)->bounds); +} + +inline bool isCircQueueEmpty(CIRC_QUEUE *queue) +{ + ASSERT(queue != NULL); + return ((queue)->nelts == 0); +} + +void CircQueueFree(CIRC_QUEUE *queue) +{ + ASSERT(queue != NULL); + if (queue->data) + free(queue->data); + free(queue); +} + +/** + * Initialize the CIRC_QUEUE. + */ +bool CircQueueCreate(CIRC_QUEUE **q, uint32_t queueCapacity) +{ + ASSERT(q != NULL); + CIRC_QUEUE *queue; + queue = malloc(sizeof(CIRC_QUEUE)); + if (!queue) + { + return false; + } + *q = queue; + memset(queue, 0, sizeof(CIRC_QUEUE)); + + /* Set all the data in the queue to NULL */ + queue->data = malloc(queueCapacity * sizeof(void *)); + if (queue->data == NULL) + { + goto error; + } + queue->bounds = queueCapacity; + queue->nelts = 0; + queue->in = 0; + queue->out = 0; + return true; +error: + free(queue); + return false; +} + +/** + * Push new data onto the queue. + */ +bool CircQueuePush(CIRC_QUEUE *queue, void *data) +{ + ASSERT(queue != NULL); + + if (isCircQueueFull(queue)) + { + return false; + } + + queue->data[queue->in] = data; + queue->in++; + if (queue->in >= queue->bounds) + { + queue->in -= queue->bounds; + } + queue->nelts++; + + return true; +} + +/** + * Return current number of element in queue. + */ +inline uint32_t CircQueueSize(CIRC_QUEUE *queue) +{ + return queue->nelts; +} + +/** + * Retrieves the next item from the queue. + */ +bool CircQueuePop(CIRC_QUEUE *queue, void **data) +{ + ASSERT(queue != NULL); + + if (isCircQueueEmpty(queue)) + { + return false; + } + + *data = queue->data[queue->out]; + queue->nelts--; + + queue->out++; + if (queue->out >= queue->bounds) + { + queue->out -= queue->bounds; + } + return true; +} diff --git a/df_datalink_sp/src/util/common.c b/df_datalink_sp/src/util/common.c new file mode 100644 index 0000000..c2959fa --- /dev/null +++ b/df_datalink_sp/src/util/common.c @@ -0,0 +1,46 @@ +/*****************************************************************************/ +/** + * Description: Common functions + * + * Date: 2021-11-16 00:08 + * LastEditors: Fan Hao + * LastEditTime: 2022-07-16 17:13 + * Revisions: Rev 0.1 + * History: + * [2022-07-16]: New branch for Dijian. + * [2021-11-16]: Initial version. + * + * Copyright(c) 2021 Beijing Institute of Technology. + * Lab of Communication and Networking + * + ******************************************************************************/ + +/***************************** Include Files *********************************/ +#include "common.h" +#include "error.h" +#include "util.h" + +/************************** Constant Definitions *****************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/**************************** Type Definitions *******************************/ + +/************************** Variable Definitions *****************************/ + +/*****************************************************************************/ +/** + * @brief Throw an assert. + * + * @param file indicate the filename of the assertion + * @param line indicate which line the assertion occurs + * + * @return NONE. + * + ******************************************************************************/ +void AppAssert(const char *file, int line) +{ + DBG_PRINT("in %s #%4d [assert] .\n", file, line); + while (1) + ; +} diff --git a/df_datalink_sp/src/util/crc.c b/df_datalink_sp/src/util/crc.c new file mode 100644 index 0000000..d460215 --- /dev/null +++ b/df_datalink_sp/src/util/crc.c @@ -0,0 +1,439 @@ +/*****************************************************************************/ +/** + * Description: CRC implementation file + * + * Author: Hao Fan + * Date: 2021-11-16 00:50 + * LastEditors: Hao Fan + * LastEditTime: 2022-07-17 20:53 + * Revisions: Rev 0.0 + * History: + * [2022-07-17]: Add CRC16_0x8005 CRC8_0x31. + * [2022-01-06]: Initial verion (Basic CRC-16). + * + * Copyright(c) 2021 Beijing Institute of Technology. + * Lab of Communication and Networking + * + ******************************************************************************/ + +#include "util.h" +#include "error.h" + +#ifdef __CRC_LSB +// CRC-16-CCITT G(X)=X16+X12+X5+1 +// Reversed +static const uint16_t crc16_1021_lsb_lut[256] = +{ + 0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF, + 0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7, + 0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E, + 0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876, + 0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD, + 0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5, + 0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C, + 0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974, + 0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB, + 0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3, + 0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A, + 0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72, + 0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9, + 0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1, + 0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738, + 0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70, + 0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7, + 0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF, + 0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036, + 0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E, + 0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5, + 0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD, + 0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134, + 0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C, + 0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3, + 0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB, + 0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232, + 0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A, + 0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1, + 0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9, + 0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330, + 0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78 +}; + +// CRC-16-MAXIM G(X)=X16+X15+X2+1 +const uint16_t crc16_8005_lsb_lut[256] = +{ + 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, + 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, + 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, + 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, + 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, + 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, + 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, + 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, + 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, + 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, + 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, + 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, + 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, + 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, + 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, + 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, + 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, + 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, + 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, + 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, + 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, + 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, + 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, + 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, + 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, + 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, + 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, + 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, + 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, + 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, + 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, + 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040 +}; + +// CRC-8-MAXIM G(X)=X8+X5+X4+1 +const uint8_t crc8_31_lsb_lut[256] = +{ + 0x00, 0x5E, 0xBC, 0xE2, 0x61, 0x3F, 0xDD, 0x83, + 0xC2, 0x9C, 0x7E, 0x20, 0xA3, 0xFD, 0x1F, 0x41, + 0x9D, 0xC3, 0x21, 0x7F, 0xFC, 0xA2, 0x40, 0x1E, + 0x5F, 0x01, 0xE3, 0xBD, 0x3E, 0x60, 0x82, 0xDC, + 0x23, 0x7D, 0x9F, 0xC1, 0x42, 0x1C, 0xFE, 0xA0, + 0xE1, 0xBF, 0x5D, 0x03, 0x80, 0xDE, 0x3C, 0x62, + 0xBE, 0xE0, 0x02, 0x5C, 0xDF, 0x81, 0x63, 0x3D, + 0x7C, 0x22, 0xC0, 0x9E, 0x1D, 0x43, 0xA1, 0xFF, + 0x46, 0x18, 0xFA, 0xA4, 0x27, 0x79, 0x9B, 0xC5, + 0x84, 0xDA, 0x38, 0x66, 0xE5, 0xBB, 0x59, 0x07, + 0xDB, 0x85, 0x67, 0x39, 0xBA, 0xE4, 0x06, 0x58, + 0x19, 0x47, 0xA5, 0xFB, 0x78, 0x26, 0xC4, 0x9A, + 0x65, 0x3B, 0xD9, 0x87, 0x04, 0x5A, 0xB8, 0xE6, + 0xA7, 0xF9, 0x1B, 0x45, 0xC6, 0x98, 0x7A, 0x24, + 0xF8, 0xA6, 0x44, 0x1A, 0x99, 0xC7, 0x25, 0x7B, + 0x3A, 0x64, 0x86, 0xD8, 0x5B, 0x05, 0xE7, 0xB9, + 0x8C, 0xD2, 0x30, 0x6E, 0xED, 0xB3, 0x51, 0x0F, + 0x4E, 0x10, 0xF2, 0xAC, 0x2F, 0x71, 0x93, 0xCD, + 0x11, 0x4F, 0xAD, 0xF3, 0x70, 0x2E, 0xCC, 0x92, + 0xD3, 0x8D, 0x6F, 0x31, 0xB2, 0xEC, 0x0E, 0x50, + 0xAF, 0xF1, 0x13, 0x4D, 0xCE, 0x90, 0x72, 0x2C, + 0x6D, 0x33, 0xD1, 0x8F, 0x0C, 0x52, 0xB0, 0xEE, + 0x32, 0x6C, 0x8E, 0xD0, 0x53, 0x0D, 0xEF, 0xB1, + 0xF0, 0xAE, 0x4C, 0x12, 0x91, 0xCF, 0x2D, 0x73, + 0xCA, 0x94, 0x76, 0x28, 0xAB, 0xF5, 0x17, 0x49, + 0x08, 0x56, 0xB4, 0xEA, 0x69, 0x37, 0xD5, 0x8B, + 0x57, 0x09, 0xEB, 0xB5, 0x36, 0x68, 0x8A, 0xD4, + 0x95, 0xCB, 0x29, 0x77, 0xF4, 0xAA, 0x48, 0x16, + 0xE9, 0xB7, 0x55, 0x0B, 0x88, 0xD6, 0x34, 0x6A, + 0x2B, 0x75, 0x97, 0xC9, 0x4A, 0x14, 0xF6, 0xA8, + 0x74, 0x2A, 0xC8, 0x96, 0x15, 0x4B, 0xA9, 0xF7, + 0xB6, 0xE8, 0x0A, 0x54, 0xD7, 0x89, 0x6B, 0x35 +}; +#else +// CRC-16-CCITT G(X)=X16+X12+X5+1 +static const uint16_t crc16_1021_msb_lut[256] = +{ + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, + 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, + 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, + 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, + 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485, + 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D, + 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4, + 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, + 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, + 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, + 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, + 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, + 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, + 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, + 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70, + 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78, + 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F, + 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067, + 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, + 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, + 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, + 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, + 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C, + 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634, + 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, + 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3, + 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, + 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, + 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, + 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, + 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, + 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0 +}; + +// CRC-16-MAXIM G(X)=X16+X15+X2+1 +const uint16_t crc16_8005_msb_lut[256] = +{ + 0x0000, 0x8005, 0x800F, 0x000A, 0x801B, 0x001E, 0x0014, 0x8011, + 0x8033, 0x0036, 0x003C, 0x8039, 0x0028, 0x802D, 0x8027, 0x0022, + 0x8063, 0x0066, 0x006C, 0x8069, 0x0078, 0x807D, 0x8077, 0x0072, + 0x0050, 0x8055, 0x805F, 0x005A, 0x804B, 0x004E, 0x0044, 0x8041, + 0x80C3, 0x00C6, 0x00CC, 0x80C9, 0x00D8, 0x80DD, 0x80D7, 0x00D2, + 0x00F0, 0x80F5, 0x80FF, 0x00FA, 0x80EB, 0x00EE, 0x00E4, 0x80E1, + 0x00A0, 0x80A5, 0x80AF, 0x00AA, 0x80BB, 0x00BE, 0x00B4, 0x80B1, + 0x8093, 0x0096, 0x009C, 0x8099, 0x0088, 0x808D, 0x8087, 0x0082, + 0x8183, 0x0186, 0x018C, 0x8189, 0x0198, 0x819D, 0x8197, 0x0192, + 0x01B0, 0x81B5, 0x81BF, 0x01BA, 0x81AB, 0x01AE, 0x01A4, 0x81A1, + 0x01E0, 0x81E5, 0x81EF, 0x01EA, 0x81FB, 0x01FE, 0x01F4, 0x81F1, + 0x81D3, 0x01D6, 0x01DC, 0x81D9, 0x01C8, 0x81CD, 0x81C7, 0x01C2, + 0x0140, 0x8145, 0x814F, 0x014A, 0x815B, 0x015E, 0x0154, 0x8151, + 0x8173, 0x0176, 0x017C, 0x8179, 0x0168, 0x816D, 0x8167, 0x0162, + 0x8123, 0x0126, 0x012C, 0x8129, 0x0138, 0x813D, 0x8137, 0x0132, + 0x0110, 0x8115, 0x811F, 0x011A, 0x810B, 0x010E, 0x0104, 0x8101, + 0x8303, 0x0306, 0x030C, 0x8309, 0x0318, 0x831D, 0x8317, 0x0312, + 0x0330, 0x8335, 0x833F, 0x033A, 0x832B, 0x032E, 0x0324, 0x8321, + 0x0360, 0x8365, 0x836F, 0x036A, 0x837B, 0x037E, 0x0374, 0x8371, + 0x8353, 0x0356, 0x035C, 0x8359, 0x0348, 0x834D, 0x8347, 0x0342, + 0x03C0, 0x83C5, 0x83CF, 0x03CA, 0x83DB, 0x03DE, 0x03D4, 0x83D1, + 0x83F3, 0x03F6, 0x03FC, 0x83F9, 0x03E8, 0x83ED, 0x83E7, 0x03E2, + 0x83A3, 0x03A6, 0x03AC, 0x83A9, 0x03B8, 0x83BD, 0x83B7, 0x03B2, + 0x0390, 0x8395, 0x839F, 0x039A, 0x838B, 0x038E, 0x0384, 0x8381, + 0x0280, 0x8285, 0x828F, 0x028A, 0x829B, 0x029E, 0x0294, 0x8291, + 0x82B3, 0x02B6, 0x02BC, 0x82B9, 0x02A8, 0x82AD, 0x82A7, 0x02A2, + 0x82E3, 0x02E6, 0x02EC, 0x82E9, 0x02F8, 0x82FD, 0x82F7, 0x02F2, + 0x02D0, 0x82D5, 0x82DF, 0x02DA, 0x82CB, 0x02CE, 0x02C4, 0x82C1, + 0x8243, 0x0246, 0x024C, 0x8249, 0x0258, 0x825D, 0x8257, 0x0252, + 0x0270, 0x8275, 0x827F, 0x027A, 0x826B, 0x026E, 0x0264, 0x8261, + 0x0220, 0x8225, 0x822F, 0x022A, 0x823B, 0x023E, 0x0234, 0x8231, + 0x8213, 0x0216, 0x021C, 0x8219, 0x0208, 0x820D, 0x8207, 0x0202 +}; + +// CRC-8-MAXIM G(X)=X8+X5+X4+1 +const uint8_t crc8_31_msb_lut[256] = +{ + 0x00, 0x31, 0x62, 0x53, 0xC4, 0xF5, 0xA6, 0x97, + 0xB9, 0x88, 0xDB, 0xEA, 0x7D, 0x4C, 0x1F, 0x2E, + 0x43, 0x72, 0x21, 0x10, 0x87, 0xB6, 0xE5, 0xD4, + 0xFA, 0xCB, 0x98, 0xA9, 0x3E, 0x0F, 0x5C, 0x6D, + 0x86, 0xB7, 0xE4, 0xD5, 0x42, 0x73, 0x20, 0x11, + 0x3F, 0x0E, 0x5D, 0x6C, 0xFB, 0xCA, 0x99, 0xA8, + 0xC5, 0xF4, 0xA7, 0x96, 0x01, 0x30, 0x63, 0x52, + 0x7C, 0x4D, 0x1E, 0x2F, 0xB8, 0x89, 0xDA, 0xEB, + 0x3D, 0x0C, 0x5F, 0x6E, 0xF9, 0xC8, 0x9B, 0xAA, + 0x84, 0xB5, 0xE6, 0xD7, 0x40, 0x71, 0x22, 0x13, + 0x7E, 0x4F, 0x1C, 0x2D, 0xBA, 0x8B, 0xD8, 0xE9, + 0xC7, 0xF6, 0xA5, 0x94, 0x03, 0x32, 0x61, 0x50, + 0xBB, 0x8A, 0xD9, 0xE8, 0x7F, 0x4E, 0x1D, 0x2C, + 0x02, 0x33, 0x60, 0x51, 0xC6, 0xF7, 0xA4, 0x95, + 0xF8, 0xC9, 0x9A, 0xAB, 0x3C, 0x0D, 0x5E, 0x6F, + 0x41, 0x70, 0x23, 0x12, 0x85, 0xB4, 0xE7, 0xD6, + 0x7A, 0x4B, 0x18, 0x29, 0xBE, 0x8F, 0xDC, 0xED, + 0xC3, 0xF2, 0xA1, 0x90, 0x07, 0x36, 0x65, 0x54, + 0x39, 0x08, 0x5B, 0x6A, 0xFD, 0xCC, 0x9F, 0xAE, + 0x80, 0xB1, 0xE2, 0xD3, 0x44, 0x75, 0x26, 0x17, + 0xFC, 0xCD, 0x9E, 0xAF, 0x38, 0x09, 0x5A, 0x6B, + 0x45, 0x74, 0x27, 0x16, 0x81, 0xB0, 0xE3, 0xD2, + 0xBF, 0x8E, 0xDD, 0xEC, 0x7B, 0x4A, 0x19, 0x28, + 0x06, 0x37, 0x64, 0x55, 0xC2, 0xF3, 0xA0, 0x91, + 0x47, 0x76, 0x25, 0x14, 0x83, 0xB2, 0xE1, 0xD0, + 0xFE, 0xCF, 0x9C, 0xAD, 0x3A, 0x0B, 0x58, 0x69, + 0x04, 0x35, 0x66, 0x57, 0xC0, 0xF1, 0xA2, 0x93, + 0xBD, 0x8C, 0xDF, 0xEE, 0x79, 0x48, 0x1B, 0x2A, + 0xC1, 0xF0, 0xA3, 0x92, 0x05, 0x34, 0x67, 0x56, + 0x78, 0x49, 0x1A, 0x2B, 0xBC, 0x8D, 0xDE, 0xEF, + 0x82, 0xB3, 0xE0, 0xD1, 0x46, 0x77, 0x24, 0x15, + 0x3B, 0x0A, 0x59, 0x68, 0xFF, 0xCE, 0x9D, 0xAC +}; +#endif + +/* CRC lookup table algorithm +#define CRC_BIT_NUM 8u/16u/32u/64u +#define BITS_IN_BYTE 8u +uint8_t dataBuff[ARRAY_SIZE] = { 0x32, 0x33, …}; +uint8_t/uint16_t/uint32_t crc_val = 0x0; +// LSB +for(int i = 0; i < sizeof(dataBuff); i++) +{ + crc_val = (crc_val >> BITS_IN_BYTE) ^ crc_lsb_lut[(uint8)(crc_val^dataBuff[i])]; +} +// MSB +for(int i = 0; i < sizeof(dataBuff); i++) +{ + crc_val = (crc_val << BITS_IN_BYTE) ^ crc_msb_lut[(uint8)((crc_val>>8)^dataBuff[i])]; +} +*/ + +/*****************************************************************************/ +/** + * @brief CRC8 generator + * + * @param buffPtr data buffer pointer. + * @param dataLen data length + * @param poly polynomials of crc + * @param crcVal a pointer to store generated crc value + * + * @return SUCCESS + * FAILURE + * + ******************************************************************************/ +int crc8_gen(uint8_t *buffPtr, uint32_t dataLen, uint16_t poly, uint8_t *crcVal) +{ + uint8_t crc = CRC8_INIT; + const uint8_t *crc_lut = NULL; + + switch (poly) + { +#ifdef __CRC_LSB + case 0x31: + crc_lut = crc8_31_lsb_lut; + break; + default: + return FAILURE; +#else + case 0x31: + crc_lut = crc8_31_msb_lut; + break; + default: + return FAILURE; +#endif + } + + for (int i = 0; i < dataLen; i++) + { + crc = crc_lut[(uint8_t)(crc ^ buffPtr[i])]; + } + *crcVal = crc; + return SUCCESS; +} + +/*****************************************************************************/ +/** + * @brief CRC16 generator + * + * @param buffPtr data buffer pointer. + * @param dataLen data length + * @param poly polynomials of crc + * @param crcVal a pointer to store generated crc value + * + * @return SUCCESS + * FAILURE + * + ******************************************************************************/ +int crc16_gen(uint8_t *buffPtr, uint32_t dataLen, uint16_t poly, uint16_t *crcVal) +{ + uint16_t crc = CRC16_INIT; + const uint16_t *crc_lut = NULL; + switch (poly) + { +#ifdef __CRC_LSB + case 0x8005: + crc_lut = crc16_8005_lsb_lut; + break; + case 0x1021: + crc_lut = crc16_1021_lsb_lut; + break; + default: + return FAILURE; +#else + case 0x8005: + crc_lut = crc16_8005_msb_lut; + break; + case 0x1021: + crc_lut = crc16_1021_msb_lut; + break; + default: + return FAILURE; +#endif + } + for (int i = 0; i < dataLen; i++) + { +#ifdef __CRC_LSB + crc = (crc >> 8) ^ crc_lut[(uint8_t)(crc ^ buffPtr[i])]; +#else + crc = (crc << 8) ^ crc_lut[(uint8_t)((crc >> 8) ^ buffPtr[i])]; +#endif + } + *crcVal = crc; + return SUCCESS; +} + +/*****************************************************************************/ +/** + * @brief CRC8 compare cheker + * + * @param buffPtr data buffer pointer. + * @param dataLen data length + * @param crcOffset byte offset of crc stored position. + * @param poly polynomials of crc + * + * @return true + * false + * + ******************************************************************************/ +bool crc8_check(uint8_t *buffPtr, uint32_t dataLen, uint32_t crcOffset, uint16_t poly) +{ + int Status = SUCCESS; + uint8_t crc_comp; + uint8_t crc; + if (dataLen == 0) + { + return false; + } + crc_comp = (uint8_t)(*(buffPtr + crcOffset)); + Status = crc8_gen(buffPtr, dataLen, poly, &crc); + if (Status == SUCCESS) + { + if (crc == crc_comp) + { + return true; + } + else + { + return false; + } + } + else + { + return false; + } +} + +/*****************************************************************************/ +/** + * @brief CRC16 compare cheker + * + * @param buffPtr data buffer pointer. + * @param dataLen data length + * @param crcOffset byte offset of crc stored position. + * @param poly polynomials of crc + * + * @return true + * fasle + * + ******************************************************************************/ +bool crc16_check(uint8_t *buffPtr, uint32_t dataLen, uint32_t crcOffset, uint16_t poly) +{ + int Status = SUCCESS; + uint16_t crc_comp; + uint16_t crc; + if (dataLen == 0) + { + return false; + } + crc_comp = (uint16_t)(*(buffPtr + crcOffset)); + crc_comp |= (uint16_t)((*(buffPtr + crcOffset + 1)) << 8); + Status = crc16_gen(buffPtr, dataLen, poly, &crc); + if (Status == SUCCESS) + { + if (crc == crc_comp) + { + return true; + } + else + { + return false; + } + } + else + { + return false; + } +} diff --git a/df_datalink_sp/src/util/list.c b/df_datalink_sp/src/util/list.c new file mode 100644 index 0000000..21ea676 --- /dev/null +++ b/df_datalink_sp/src/util/list.c @@ -0,0 +1,887 @@ +/******************************************************************************* +//** + * @file list.c + * @brief List library implementation + * @author Mihail Chindris (mihail.chindris@analog.com) +******************************************************************************** + * Copyright 2020(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include "list.h" +#include "error.h" +#include + +/******************************************************************************/ +/*************************** Types Declarations *******************************/ +/******************************************************************************/ + +/** + * @struct list_elem + * @brief Format of each element of the list + */ +struct list_elem +{ + /** User data */ + void *data; + /** Reference to previous element */ + struct list_elem *prev; + /** Reference to next element */ + struct list_elem *next; +}; + +/** + * @struct list_iterator + * @brief Structure used to iterate through the list + */ +struct iterator +{ + /** List reference */ + struct _list_desc *list; + /** Current element reference */ + struct list_elem *elem; +}; + +/** + * @struct _list_desc + * @brief List descriptor + */ +struct _list_desc +{ + /** Reference to first element in the list */ + struct list_elem *first; + /** Reference to last element in the list*/ + struct list_elem *last; + /** Number of elements in the list */ + uint32_t nb_elements; + /** Function used to compare elements */ + f_cmp comparator; + /** Number of current active iterators */ + uint32_t nb_iterators; + /** Internal list iterator */ + struct iterator l_it; +}; + +/** @brief Default function used to compare element in the list ( \ref f_cmp) */ +static int32_t default_comparator(void *data1, void *data2) +{ + return (int32_t)((int32_t *)data1 - (int32_t *)data2); +} + +/** + * @brief Creates a new list elements an configure its value + * @param data - To set list_elem.data + * @param prev - To set list_elem.prev + * @param next - To set list_elem.next + * @return Address of the new element or NULL if allocation fails. + */ +static inline struct list_elem *create_element(void *data, + struct list_elem *prev, + struct list_elem *next) +{ + struct list_elem *elem; + + elem = (struct list_elem *)calloc(1, sizeof(*elem)); + if (!elem) + return NULL; + elem->data = data; + elem->prev = prev; + elem->next = next; + + return (elem); +} + +/** + * @brief Updates the necesary link on the list elements to add or remove one + * @param prev - Low element + * @param elem - Middle element + * @param next - High element + */ +static inline void update_links(struct list_elem *prev, struct list_elem *elem, + struct list_elem *next) +{ + if (prev) + prev->next = elem ? elem : next; + if (elem) + { + elem->prev = prev; + elem->next = next; + } + if (next) + next->prev = elem ? elem : prev; +} + +/** + * @brief Update according to modification the list descriptor + * @param list - List reference + * @param new_first - New first element + * @param new_last - New last element + */ +static inline void update_desc(struct _list_desc *list, + struct list_elem *new_first, + struct list_elem *new_last) +{ + if (new_first == list->first) + { + list->last = new_last; + if (new_first == NULL || new_last == NULL) + list->first = new_last; + } + else + { /* if (new_last == list->last) */ + list->first = new_first; + if (new_last == NULL || new_first == NULL) + list->last = new_first; + } +} + +/** + * @brief Set the adapter functions acording to the adapter type + * @param ad - Reference of the adapter + * @param type - Type of the adapter + */ +static inline void set_adapter(struct list_desc *ad, enum adapter_type type) +{ + switch (type) + { + case LIST_PRIORITY_LIST: + ad->push = list_add_find; + ad->pop = list_get_first; + ad->top_next = list_read_first; + ad->back = list_read_last; + ad->swap = list_edit_first; + break; + case LIST_QUEUE: + ad->push = list_add_last; + ad->pop = list_get_first; + ad->top_next = list_read_first; + ad->back = list_read_last; + ad->swap = list_edit_first; + break; + case LIST_DEFAULT: + case LIST_STACK: + default: + ad->push = list_add_last; + ad->pop = list_get_last; + ad->top_next = list_read_last; + ad->back = list_read_first; + ad->swap = list_edit_last; + break; + } +} + +/** + * @brief Create a new empty list + * @param list_desc - Where to store the reference of the new created list + * @param type - Type of adapter to use. + * @param comparator - Used to compare item when using an ordered list or when + * using the \em find functions. + * @return + * - \ref SUCCESS : On success + * - \ref FAILURE : Otherwise + */ +int32_t list_init(struct list_desc **list_desc, enum adapter_type type, + f_cmp comparator) +{ + struct list_desc *l_desc; + struct _list_desc *list; + + if (!list_desc) + return FAILURE; + l_desc = (struct list_desc *)calloc(1, sizeof(*l_desc)); + if (!l_desc) + return FAILURE; + list = (struct _list_desc *)calloc(1, sizeof(*list)); + if (!list) + { + free(l_desc); + return FAILURE; + } + + *list_desc = l_desc; + l_desc->priv_desc = list; + list->comparator = comparator ? comparator : default_comparator; + + /* Configure wrapper */ + set_adapter(l_desc, type); + list->l_it.list = list; + + return SUCCESS; +} + +/** + * @brief Remove the created list. + * + * All its elements will be cleared and the data inside each will be lost. If + * not all iterators have been removed, the list will not be removed. + * @param list_desc - Reference to the list + * @return + * - \ref SUCCESS : On success + * - \ref FAILURE : Otherwise + */ +int32_t list_remove(struct list_desc *list_desc) +{ + void *data; + struct _list_desc *list; + + if (!list_desc) + return FAILURE; + + list = list_desc->priv_desc; + if (list->nb_iterators != 0) + return FAILURE; + + /* Remove all the elements */ + while (SUCCESS == list_get_first(list_desc, &data)) + ; + free(list_desc->priv_desc); + free(list_desc); + + return SUCCESS; +} + +/** + * @brief Get the number of elements inside the list + * @param list_desc - List reference + * @param out_size - Where to store the number of elements + * @return + * - \ref SUCCESS : On success + * - \ref FAILURE : Otherwise + */ +int32_t list_get_size(struct list_desc *list_desc, uint32_t *out_size) +{ + struct _list_desc *list; + + if (!list_desc || !out_size) + return FAILURE; + + list = list_desc->priv_desc; + *out_size = list->nb_elements; + + return SUCCESS; +} + +/** @brief Add element at the begining of the list. Refer to \ref f_add */ +int32_t list_add_first(struct list_desc *list_desc, void *data) +{ + struct list_elem *prev; + struct list_elem *next; + struct list_elem *elem; + struct _list_desc *list; + + if (!list_desc) + return FAILURE; + + list = list_desc->priv_desc; + + prev = NULL; + next = list->first; + elem = create_element(data, prev, next); + if (!elem) + return FAILURE; + + update_links(prev, elem, next); + + update_desc(list, elem, list->last); + + list->nb_elements++; + + return SUCCESS; +} + +/** @brief Add element at the end of the list. Refer to \ref f_add */ +int32_t list_add_last(struct list_desc *list_desc, void *data) +{ + struct list_elem *prev; + struct list_elem *next; + struct list_elem *elem; + struct _list_desc *list; + + if (!list_desc) + return FAILURE; + list = list_desc->priv_desc; + + prev = list->last; + next = NULL; + elem = create_element(data, prev, next); + if (!elem) + return FAILURE; + + update_links(prev, elem, next); + + update_desc(list, list->first, elem); + + list->nb_elements++; + + return SUCCESS; +} + +/** @brief Add element at the specified idx. Refer to \ref f_add */ +int32_t list_add_idx(struct list_desc *list_desc, void *data, uint32_t idx) +{ + struct _list_desc *list; + + if (!list_desc) + return FAILURE; + list = list_desc->priv_desc; + + /* If there are no elements the creation of an iterator will fail */ + if (list->nb_elements == 0 || idx == 0) + return list_add_first(list_desc, data); + if (list->nb_elements == idx) + return list_add_last(list_desc, data); + + list->l_it.elem = list->first; + if (SUCCESS != iterator_move(&(list->l_it), idx)) + return FAILURE; + + return iterator_insert(&(list->l_it), data, 0); +} + +/** @brief Add element in ascending order. Refer to \ref f_add */ +int32_t list_add_find(struct list_desc *list_desc, void *data) +{ + struct list_elem *elem; + struct _list_desc *list; + + if (!list_desc) + return FAILURE; + list = list_desc->priv_desc; + + /* Based on place iterator */ + elem = list->first; + while (elem) + { + if (0 < list->comparator(elem->data, data)) + break; + elem = elem->next; + } + if (elem == NULL) + { + list->l_it.elem = list->last; + return iterator_insert(&(list->l_it), data, 1); + } + else + { + list->l_it.elem = elem; + return iterator_insert(&(list->l_it), data, 0); + } +} + +/** @brief Edit the first element of the list. Refer to \ref f_edit */ +int32_t list_edit_first(struct list_desc *list_desc, void *new_data) +{ + struct _list_desc *list; + + if (!list_desc) + return FAILURE; + + list = list_desc->priv_desc; + list->first->data = new_data; + + return SUCCESS; +} + +/** @brief Edit the last element of the list. Refer to \ref f_edit */ +int32_t list_edit_last(struct list_desc *list_desc, void *new_data) +{ + struct _list_desc *list; + + if (!list_desc) + return FAILURE; + + list = list_desc->priv_desc; + list->last->data = new_data; + + return SUCCESS; +} + +/** @brief Edit the element at the specified idx. Refer to \ref f_edit */ +int32_t list_edit_idx(struct list_desc *list_desc, void *new_data, uint32_t idx) +{ + struct _list_desc *list; + + if (!list_desc) + return FAILURE; + list = list_desc->priv_desc; + + list->l_it.elem = list->first; + if (SUCCESS != iterator_move(&(list->l_it), idx)) + return FAILURE; + + return iterator_edit(&(list->l_it), new_data); +} + +/** @brief Edit the element which match with cmp_data. Refer to \ref f_edit */ +int32_t list_edit_find(struct list_desc *list_desc, void *new_data, + void *cmp_data) +{ + struct _list_desc *list; + + if (!list_desc) + return FAILURE; + list = list_desc->priv_desc; + + list->l_it.elem = list->first; + if (SUCCESS != iterator_find(&(list->l_it), cmp_data)) + return FAILURE; + + return iterator_edit(&(list->l_it), new_data); +} + +/** @brief Read the first element of the list. Refer to \ref f_read */ +int32_t list_read_first(struct list_desc *list_desc, void **data) +{ + struct _list_desc *list; + + if (!list_desc || !data) + return FAILURE; + + *data = NULL; + list = list_desc->priv_desc; + if (!list->first) + return FAILURE; + + *data = list->first->data; + + return SUCCESS; +} + +/** @brief Read the last element of the list. Refer to \ref f_read */ +int32_t list_read_last(struct list_desc *list_desc, void **data) +{ + struct _list_desc *list; + + if (!list_desc || !data) + return FAILURE; + + *data = NULL; + list = list_desc->priv_desc; + if (!list->last) + return FAILURE; + + *data = list->last->data; + + return SUCCESS; +} + +/** @brief Read the element at the specified idx. Refer to \ref f_read */ +int32_t list_read_idx(struct list_desc *list_desc, void **data, uint32_t idx) +{ + struct _list_desc *list; + + if (!list_desc || !data) + return FAILURE; + + *data = NULL; + list = list_desc->priv_desc; + if (!list) + return FAILURE; + + if (idx >= list->nb_elements) + return FAILURE; + + list->l_it.elem = list->first; + if (SUCCESS != iterator_move(&(list->l_it), idx)) + return FAILURE; + + return iterator_read(&(list->l_it), data); +} + +/** @brief Read the element which match with cmp_data. Refer to \ref f_read */ +int32_t list_read_find(struct list_desc *list_desc, void **data, + void *cmp_data) +{ + struct _list_desc *list; + + if (!list_desc || !data) + return FAILURE; + + *data = NULL; + list = list_desc->priv_desc; + if (!list) + return FAILURE; + + list = list_desc->priv_desc; + list->l_it.elem = list->first; + if (SUCCESS != iterator_find(&(list->l_it), cmp_data)) + return FAILURE; + + return iterator_read(&(list->l_it), data); +} + +/** @brief Read and delete the first element of the list. Refer to \ref f_get */ +int32_t list_get_first(struct list_desc *list_desc, void **data) +{ + struct list_elem *prev; + struct list_elem *next; + struct list_elem *elem; + struct _list_desc *list; + + if (!list_desc || !data) + return FAILURE; + + *data = NULL; + list = list_desc->priv_desc; + if (!list->nb_elements) + return FAILURE; + + elem = list->first; + prev = elem->prev; + next = elem->next; + + update_links(prev, NULL, next); + update_desc(list, next, list->last); + list->nb_elements--; + + *data = elem->data; + free(elem); + + return SUCCESS; +} + +/** @brief Read and delete the last element of the list. Refer to \ref f_get */ +int32_t list_get_last(struct list_desc *list_desc, void **data) +{ + struct list_elem *prev; + struct list_elem *next; + struct list_elem *elem; + struct _list_desc *list; + + if (!list_desc || !data) + return FAILURE; + + *data = NULL; + list = list_desc->priv_desc; + if (!list->nb_elements) + return FAILURE; + + elem = list->last; + prev = elem->prev; + next = elem->next; + + update_links(prev, NULL, next); + update_desc(list, list->first, prev); + list->nb_elements--; + + *data = elem->data; + free(elem); + + return SUCCESS; +} + +/** @brief Read and delete the element at idx. Refer to \ref f_get */ +int32_t list_get_idx(struct list_desc *list_desc, void **data, uint32_t idx) +{ + struct _list_desc *list; + + if (!list_desc || !data) + return FAILURE; + + *data = NULL; + list = list_desc->priv_desc; + list->l_it.elem = list->first; + if (SUCCESS != iterator_move(&(list->l_it), idx)) + return FAILURE; + + return iterator_get(&(list->l_it), data); +} + +/** + * @brief Read and delete the element which match with cmp_data. + * Refer to \ref f_get + */ +int32_t list_get_find(struct list_desc *list_desc, void **data, void *cmp_data) +{ + struct _list_desc *list; + + if (!list_desc || !data) + return FAILURE; + + *data = NULL; + list = list_desc->priv_desc; + list->l_it.elem = list->first; + if (SUCCESS != iterator_find(&(list->l_it), cmp_data)) + return FAILURE; + + return iterator_get(&(list->l_it), data); +} + +/** + * @brief Create a new iterator + * @param iter - Where to store the reference for the new iterator + * @param list_desc - Reference of the list the iterator will be used for + * @param start - If it is true the iterator will be positioned at the first + * element of the list, else it will be positioned at the last. + * @return + * - \ref SUCCESS : On success + * - \ref FAILURE : Otherwise + */ +int32_t iterator_init(struct iterator **iter, struct list_desc *list_desc, + bool start) +{ + struct iterator *it; + + if (!list_desc) + return FAILURE; + + it = (struct iterator *)calloc(1, sizeof(*it)); + if (!it) + return FAILURE; + it->list = list_desc->priv_desc; + it->list->nb_iterators++; + it->elem = start ? it->list->first : it->list->last; + *iter = it; + + return SUCCESS; +} + +/** + * @brief Remove the created iterator + * @param iter - Reference of the iterator + * @return + * - \ref SUCCESS : On success + * - \ref FAILURE : Otherwise + */ +int32_t iterator_remove(struct iterator *iter) +{ + struct iterator *it = iter; + + if (!it) + return FAILURE; + + it->list->nb_iterators--; + free(it); + + return SUCCESS; +} + +/** + * @brief Move the position of the iteration through the list. + * + * If the required position is outside the list, the call will fail and the + * iterator will keep its position. + * @param iter - Reference of the iterator + * @param steps - Number of positions to be move. If positive, it will be moved + * forward, otherwise backwords. + * @return + * - \ref SUCCESS : On success + * - \ref FAILURE : Otherwise + */ +int32_t iterator_move(struct iterator *iter, int32_t steps) +{ + struct iterator *it = iter; + struct list_elem *elem; + int32_t dir = (steps < 0) ? -1 : 1; + + if (!it) + return FAILURE; + + steps = abs(steps); + elem = it->elem; + while (steps > 0 && elem) + { + elem = dir > 0 ? elem->next : elem->prev; + steps--; + } + if (!elem) + return FAILURE; + + it->elem = elem; + + return SUCCESS; +} + +/** + * @brief Move the position of the iterator at the specified index of the list. + * + * @param iter - Reference of the iterator + * @param idx - Position in the list. If negative start counting backwords + * @return + * - \ref SUCCESS : On success + * - \ref FAILURE : Otherwise + */ +int32_t iterator_move_to_idx(struct iterator *iter, int32_t idx) +{ + struct list_elem *elem; + int32_t dir = (idx < 0) ? -1 : 1; + + if (!iter) + return FAILURE; + + idx = abs(idx); + elem = dir > 0 ? iter->list->first : iter->list->last; + while (idx > 0 && elem) + { + elem = dir > 0 ? elem->next : elem->prev; + idx--; + } + if (!elem) + return FAILURE; + + iter->elem = elem; + + return SUCCESS; +} + +/** + * @brief Place the iterator where cmp_data if found. + * @param iter - Reference to the iterator + * @param cmp_data - Data to be found + * @return + * - \ref SUCCESS : On success + * - \ref FAILURE : Otherwise + */ +int32_t iterator_find(struct iterator *iter, void *cmp_data) +{ + struct iterator *it = iter; + struct list_elem *elem; + + if (!it) + return FAILURE; + + elem = it->list->first; + while (elem) + { + if (0 == it->list->comparator(elem->data, cmp_data)) + { + it->elem = elem; + return SUCCESS; + } + elem = elem->next; + } + + return FAILURE; +} + +/** + * @brief Replace the data at the current position. Refer to \ref f_edit + */ +int32_t iterator_edit(struct iterator *iter, void *new_data) +{ + struct iterator *it = iter; + + if (!it) + return FAILURE; + + it->elem->data = new_data; + + return SUCCESS; +} + +/** + * @brief Read and remove the data at the current position. Refer to \ref f_get. + * + * If the current item is the last one, the iterator will be moved to the + * previous one. + */ +int32_t iterator_get(struct iterator *iter, void **data) +{ + struct iterator *it = iter; + struct list_elem *next; + + if (!it || !it->elem || !data) + return FAILURE; + + update_links(it->elem->prev, NULL, it->elem->next); + if (it->elem == it->list->first) + update_desc(it->list, it->elem->next, it->list->last); + else if (it->elem == it->list->last) + update_desc(it->list, it->list->first, it->elem->prev); + it->list->nb_elements--; + + *data = it->elem->data; + if (it->elem == it->list->last) + next = it->elem->prev; + else + next = it->elem->next; + free(it->elem); + it->elem = next; + + return SUCCESS; +} + +/** + * @brief Read the data at the current position. Refer to \ref f_read + */ +int32_t iterator_read(struct iterator *iter, void **data) +{ + struct iterator *it = iter; + + if (!it || !it->elem || !data) + return FAILURE; + + *data = it->elem->data; + + return SUCCESS; +} + +/** + * @brief Insert an item in the list. Refer to \ref f_add + * @param iter + * @param data + * @param after - If true, the item will be inserted after the current position. + * Otherwise it will be inserted before. + */ +int32_t iterator_insert(struct iterator *iter, void *data, bool after) +{ + struct iterator *it = iter; + struct list_elem *elem; + struct list_desc list_desc; + + if (!it) + return FAILURE; + + list_desc.priv_desc = iter->list; + if (after && it->elem == it->list->last) + return list_add_last(&list_desc, data); + if (!after && it->elem == it->list->first) + return list_add_first(&list_desc, data); + + if (after) + elem = create_element(data, it->elem, it->elem->next); + else + elem = create_element(data, it->elem->prev, it->elem); + if (!elem) + return FAILURE; + + update_links(elem->prev, elem, elem->next); + + it->list->nb_elements++; + + return SUCCESS; +} diff --git a/df_datalink_sp/src/util/tables.txt b/df_datalink_sp/src/util/tables.txt new file mode 100644 index 0000000..b3bff8c --- /dev/null +++ b/df_datalink_sp/src/util/tables.txt @@ -0,0 +1,231 @@ +Generating CRC table for crc8-31-lsb + +0x00, 0x5E, 0xBC, 0xE2, 0x61, 0x3F, 0xDD, 0x83, +0xC2, 0x9C, 0x7E, 0x20, 0xA3, 0xFD, 0x1F, 0x41, +0x9D, 0xC3, 0x21, 0x7F, 0xFC, 0xA2, 0x40, 0x1E, +0x5F, 0x01, 0xE3, 0xBD, 0x3E, 0x60, 0x82, 0xDC, +0x23, 0x7D, 0x9F, 0xC1, 0x42, 0x1C, 0xFE, 0xA0, +0xE1, 0xBF, 0x5D, 0x03, 0x80, 0xDE, 0x3C, 0x62, +0xBE, 0xE0, 0x02, 0x5C, 0xDF, 0x81, 0x63, 0x3D, +0x7C, 0x22, 0xC0, 0x9E, 0x1D, 0x43, 0xA1, 0xFF, +0x46, 0x18, 0xFA, 0xA4, 0x27, 0x79, 0x9B, 0xC5, +0x84, 0xDA, 0x38, 0x66, 0xE5, 0xBB, 0x59, 0x07, +0xDB, 0x85, 0x67, 0x39, 0xBA, 0xE4, 0x06, 0x58, +0x19, 0x47, 0xA5, 0xFB, 0x78, 0x26, 0xC4, 0x9A, +0x65, 0x3B, 0xD9, 0x87, 0x04, 0x5A, 0xB8, 0xE6, +0xA7, 0xF9, 0x1B, 0x45, 0xC6, 0x98, 0x7A, 0x24, +0xF8, 0xA6, 0x44, 0x1A, 0x99, 0xC7, 0x25, 0x7B, +0x3A, 0x64, 0x86, 0xD8, 0x5B, 0x05, 0xE7, 0xB9, +0x8C, 0xD2, 0x30, 0x6E, 0xED, 0xB3, 0x51, 0x0F, +0x4E, 0x10, 0xF2, 0xAC, 0x2F, 0x71, 0x93, 0xCD, +0x11, 0x4F, 0xAD, 0xF3, 0x70, 0x2E, 0xCC, 0x92, +0xD3, 0x8D, 0x6F, 0x31, 0xB2, 0xEC, 0x0E, 0x50, +0xAF, 0xF1, 0x13, 0x4D, 0xCE, 0x90, 0x72, 0x2C, +0x6D, 0x33, 0xD1, 0x8F, 0x0C, 0x52, 0xB0, 0xEE, +0x32, 0x6C, 0x8E, 0xD0, 0x53, 0x0D, 0xEF, 0xB1, +0xF0, 0xAE, 0x4C, 0x12, 0x91, 0xCF, 0x2D, 0x73, +0xCA, 0x94, 0x76, 0x28, 0xAB, 0xF5, 0x17, 0x49, +0x08, 0x56, 0xB4, 0xEA, 0x69, 0x37, 0xD5, 0x8B, +0x57, 0x09, 0xEB, 0xB5, 0x36, 0x68, 0x8A, 0xD4, +0x95, 0xCB, 0x29, 0x77, 0xF4, 0xAA, 0x48, 0x16, +0xE9, 0xB7, 0x55, 0x0B, 0x88, 0xD6, 0x34, 0x6A, +0x2B, 0x75, 0x97, 0xC9, 0x4A, 0x14, 0xF6, 0xA8, +0x74, 0x2A, 0xC8, 0x96, 0x15, 0x4B, 0xA9, 0xF7, +0xB6, 0xE8, 0x0A, 0x54, 0xD7, 0x89, 0x6B, 0x35, + + +Generating CRC table for crc8-31-msb + +0x00, 0x31, 0x62, 0x53, 0xC4, 0xF5, 0xA6, 0x97, +0xB9, 0x88, 0xDB, 0xEA, 0x7D, 0x4C, 0x1F, 0x2E, +0x43, 0x72, 0x21, 0x10, 0x87, 0xB6, 0xE5, 0xD4, +0xFA, 0xCB, 0x98, 0xA9, 0x3E, 0x0F, 0x5C, 0x6D, +0x86, 0xB7, 0xE4, 0xD5, 0x42, 0x73, 0x20, 0x11, +0x3F, 0x0E, 0x5D, 0x6C, 0xFB, 0xCA, 0x99, 0xA8, +0xC5, 0xF4, 0xA7, 0x96, 0x01, 0x30, 0x63, 0x52, +0x7C, 0x4D, 0x1E, 0x2F, 0xB8, 0x89, 0xDA, 0xEB, +0x3D, 0x0C, 0x5F, 0x6E, 0xF9, 0xC8, 0x9B, 0xAA, +0x84, 0xB5, 0xE6, 0xD7, 0x40, 0x71, 0x22, 0x13, +0x7E, 0x4F, 0x1C, 0x2D, 0xBA, 0x8B, 0xD8, 0xE9, +0xC7, 0xF6, 0xA5, 0x94, 0x03, 0x32, 0x61, 0x50, +0xBB, 0x8A, 0xD9, 0xE8, 0x7F, 0x4E, 0x1D, 0x2C, +0x02, 0x33, 0x60, 0x51, 0xC6, 0xF7, 0xA4, 0x95, +0xF8, 0xC9, 0x9A, 0xAB, 0x3C, 0x0D, 0x5E, 0x6F, +0x41, 0x70, 0x23, 0x12, 0x85, 0xB4, 0xE7, 0xD6, +0x7A, 0x4B, 0x18, 0x29, 0xBE, 0x8F, 0xDC, 0xED, +0xC3, 0xF2, 0xA1, 0x90, 0x07, 0x36, 0x65, 0x54, +0x39, 0x08, 0x5B, 0x6A, 0xFD, 0xCC, 0x9F, 0xAE, +0x80, 0xB1, 0xE2, 0xD3, 0x44, 0x75, 0x26, 0x17, +0xFC, 0xCD, 0x9E, 0xAF, 0x38, 0x09, 0x5A, 0x6B, +0x45, 0x74, 0x27, 0x16, 0x81, 0xB0, 0xE3, 0xD2, +0xBF, 0x8E, 0xDD, 0xEC, 0x7B, 0x4A, 0x19, 0x28, +0x06, 0x37, 0x64, 0x55, 0xC2, 0xF3, 0xA0, 0x91, +0x47, 0x76, 0x25, 0x14, 0x83, 0xB2, 0xE1, 0xD0, +0xFE, 0xCF, 0x9C, 0xAD, 0x3A, 0x0B, 0x58, 0x69, +0x04, 0x35, 0x66, 0x57, 0xC0, 0xF1, 0xA2, 0x93, +0xBD, 0x8C, 0xDF, 0xEE, 0x79, 0x48, 0x1B, 0x2A, +0xC1, 0xF0, 0xA3, 0x92, 0x05, 0x34, 0x67, 0x56, +0x78, 0x49, 0x1A, 0x2B, 0xBC, 0x8D, 0xDE, 0xEF, +0x82, 0xB3, 0xE0, 0xD1, 0x46, 0x77, 0x24, 0x15, +0x3B, 0x0A, 0x59, 0x68, 0xFF, 0xCE, 0x9D, 0xAC, + + +Generating CRC table for crc16-8005-lsb + +0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, +0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, +0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, +0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, +0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, +0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, +0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, +0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, +0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, +0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, +0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, +0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, +0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, +0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, +0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, +0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, +0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, +0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, +0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, +0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, +0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, +0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, +0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, +0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, +0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, +0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, +0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, +0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, +0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, +0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, +0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, +0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040, + + +Generating CRC table for crc16-8005-msb + +0x0000, 0x8005, 0x800F, 0x000A, 0x801B, 0x001E, 0x0014, 0x8011, +0x8033, 0x0036, 0x003C, 0x8039, 0x0028, 0x802D, 0x8027, 0x0022, +0x8063, 0x0066, 0x006C, 0x8069, 0x0078, 0x807D, 0x8077, 0x0072, +0x0050, 0x8055, 0x805F, 0x005A, 0x804B, 0x004E, 0x0044, 0x8041, +0x80C3, 0x00C6, 0x00CC, 0x80C9, 0x00D8, 0x80DD, 0x80D7, 0x00D2, +0x00F0, 0x80F5, 0x80FF, 0x00FA, 0x80EB, 0x00EE, 0x00E4, 0x80E1, +0x00A0, 0x80A5, 0x80AF, 0x00AA, 0x80BB, 0x00BE, 0x00B4, 0x80B1, +0x8093, 0x0096, 0x009C, 0x8099, 0x0088, 0x808D, 0x8087, 0x0082, +0x8183, 0x0186, 0x018C, 0x8189, 0x0198, 0x819D, 0x8197, 0x0192, +0x01B0, 0x81B5, 0x81BF, 0x01BA, 0x81AB, 0x01AE, 0x01A4, 0x81A1, +0x01E0, 0x81E5, 0x81EF, 0x01EA, 0x81FB, 0x01FE, 0x01F4, 0x81F1, +0x81D3, 0x01D6, 0x01DC, 0x81D9, 0x01C8, 0x81CD, 0x81C7, 0x01C2, +0x0140, 0x8145, 0x814F, 0x014A, 0x815B, 0x015E, 0x0154, 0x8151, +0x8173, 0x0176, 0x017C, 0x8179, 0x0168, 0x816D, 0x8167, 0x0162, +0x8123, 0x0126, 0x012C, 0x8129, 0x0138, 0x813D, 0x8137, 0x0132, +0x0110, 0x8115, 0x811F, 0x011A, 0x810B, 0x010E, 0x0104, 0x8101, +0x8303, 0x0306, 0x030C, 0x8309, 0x0318, 0x831D, 0x8317, 0x0312, +0x0330, 0x8335, 0x833F, 0x033A, 0x832B, 0x032E, 0x0324, 0x8321, +0x0360, 0x8365, 0x836F, 0x036A, 0x837B, 0x037E, 0x0374, 0x8371, +0x8353, 0x0356, 0x035C, 0x8359, 0x0348, 0x834D, 0x8347, 0x0342, +0x03C0, 0x83C5, 0x83CF, 0x03CA, 0x83DB, 0x03DE, 0x03D4, 0x83D1, +0x83F3, 0x03F6, 0x03FC, 0x83F9, 0x03E8, 0x83ED, 0x83E7, 0x03E2, +0x83A3, 0x03A6, 0x03AC, 0x83A9, 0x03B8, 0x83BD, 0x83B7, 0x03B2, +0x0390, 0x8395, 0x839F, 0x039A, 0x838B, 0x038E, 0x0384, 0x8381, +0x0280, 0x8285, 0x828F, 0x028A, 0x829B, 0x029E, 0x0294, 0x8291, +0x82B3, 0x02B6, 0x02BC, 0x82B9, 0x02A8, 0x82AD, 0x82A7, 0x02A2, +0x82E3, 0x02E6, 0x02EC, 0x82E9, 0x02F8, 0x82FD, 0x82F7, 0x02F2, +0x02D0, 0x82D5, 0x82DF, 0x02DA, 0x82CB, 0x02CE, 0x02C4, 0x82C1, +0x8243, 0x0246, 0x024C, 0x8249, 0x0258, 0x825D, 0x8257, 0x0252, +0x0270, 0x8275, 0x827F, 0x027A, 0x826B, 0x026E, 0x0264, 0x8261, +0x0220, 0x8225, 0x822F, 0x022A, 0x823B, 0x023E, 0x0234, 0x8231, +0x8213, 0x0216, 0x021C, 0x8219, 0x0208, 0x820D, 0x8207, 0x0202, + + +Generating CRC table for crc16-1021-lsb + +0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF, +0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7, +0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E, +0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876, +0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD, +0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5, +0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C, +0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974, +0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB, +0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3, +0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A, +0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72, +0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9, +0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1, +0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738, +0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70, +0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7, +0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF, +0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036, +0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E, +0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5, +0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD, +0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134, +0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C, +0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3, +0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB, +0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232, +0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A, +0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1, +0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9, +0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330, +0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78, + + +Generating CRC table for crc16-1021-msb + +0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, +0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, +0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, +0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, +0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485, +0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D, +0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4, +0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, +0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, +0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, +0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, +0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, +0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, +0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, +0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70, +0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78, +0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F, +0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067, +0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, +0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, +0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, +0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, +0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C, +0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634, +0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, +0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3, +0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, +0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, +0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, +0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, +0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, +0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0, + + + +#define CRC_BIT_NUM 8u/16u/32u/64u +#define BITS_IN_BYTE 8u +uint8_t dataBuff[ARRAY_SIZE] = { 0x32, 0x33, ...; +uint8_t/uint16_t/uint32_t crc_val = 0x0; +// LSB +for(int i = 0; i < sizeof(dataBuff); i++) +{ + crc_val = (crc_val >> BITS_IN_BYTE) ^ crc_lsb_lut[(uint8)(crc_val^dataBuff[i])]; +} +// MSB +for(int i = 0; i < sizeof(dataBuff); i++) +{ + crc_val = (crc_val << BITS_IN_BYTE) ^ crc_msb_lut[(uint8)((crc_val>>8)^dataBuff[i])]; +} \ No newline at end of file diff --git a/df_datalink_sp/src/util/util.c b/df_datalink_sp/src/util/util.c new file mode 100644 index 0000000..02fdb01 --- /dev/null +++ b/df_datalink_sp/src/util/util.c @@ -0,0 +1,368 @@ +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ +#include +#include +// #include +#include "util.h" +#include "error.h" + +/******************************************************************************/ +/************************** Functions Implementation **************************/ +/******************************************************************************/ +#ifdef __BITSWAP_TABLE +static uint8_t byte_flipLR[256] = +{ + 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, + 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, + 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, + 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, + 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, + 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4, + 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, + 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC, + 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, + 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2, + 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, + 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA, + 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, + 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6, + 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, + 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE, + 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, + 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1, + 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, + 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9, + 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, + 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5, + 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, + 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD, + 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, + 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3, + 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, + 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB, + 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, + 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, + 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, + 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF +}; +#endif + +inline void IO_Out32(uintptr_t addr, uint32_t value) +{ + volatile uint32_t *localAddr = (volatile uint32_t *)addr; + *localAddr = value; +} + +inline uint32_t IO_In32(uintptr_t addr) +{ + return *(volatile uint32_t *)addr; +} + +uint8_t byte_bit_swap(uint8_t byte) +{ +#ifdef __BITSWAP_TABLE + return byte_flipLR[byte]; +#else + return bit_swap_constant_8(byte); +#endif +} + +uint32_t word_bit_swap(uint32_t word) +{ +#ifdef __BITSWAP_TABLE + uint32_t rv_word = (byte_flipLR[word & 0xff] << 24) | + (byte_flipLR[(word >> 8) & 0xff] << 16) | + (byte_flipLR[(word >> 16) & 0xff] << 8) | + (byte_flipLR[(word >> 24) & 0xff]); + return rv_word; +#else + word = (((word & 0xaaaaaaaa) >> 1) | ((word & 0x55555555) << 1)); + word = (((word & 0xcccccccc) >> 2) | ((word & 0x33333333) << 2)); + word = (((word & 0xf0f0f0f0) >> 4) | ((word & 0x0f0f0f0f) << 4)); + word = (((word & 0xff00ff00) >> 8) | ((word & 0x00ff00ff) << 8)); + return ((word >> 16) | (word << 16)); +#endif +} + +uint32_t count_ones(uint32_t word) +{ +#ifdef __GNUC__ + return __builtin_popcount(word); +#else + uint32_t one_count = 0; + while (word) + { + if (word & 0x00000001) + one_count++; + word >>= 1; + } + return one_count; +#endif +} + +double fix2double(int32_t val, uint8_t frac_bits) +{ + return (((double)val) / (BIT(frac_bits))); +} + +/** + * Find first set bit in word. + */ +uint32_t find_first_set_bit(uint32_t word) +{ +#ifdef __GNUC__ + if (word != 0) + { + return __builtin_ctz(word); + } + else + { + return 32; + } +#else + uint32_t first_set_bit = 0; + + while (word) + { + if (word & 0x1) + return first_set_bit; + word >>= 1; + first_set_bit++; + } + + return 32; +#endif +} + +/** + * Find last set bit in word. + */ +uint32_t find_last_set_bit(uint32_t word) +{ +#ifdef __GNUC__ + if (word != 0) + { + return (31 - __builtin_clz(word)); + } + else + { + return 32; + } +#else + uint32_t bit = 0; + uint32_t last_set_bit = 32; + + while (word) + { + if (word & 0x1) + last_set_bit = bit; + word >>= 1; + bit++; + } + + return last_set_bit; +#endif +} + +/** + * Locate the closest element in an array. + */ +uint32_t find_closest(int32_t val, + const int32_t *array, + uint32_t size) +{ + int32_t diff = abs(array[0] - val); + uint32_t ret = 0; + uint32_t i; + + for (i = 1; i < size; i++) + { + if (abs(array[i] - val) < diff) + { + diff = abs(array[i] - val); + ret = i; + } + } + + return ret; +} + +/** + * Shift the value and apply the specified mask. + */ +uint32_t field_prep(uint32_t mask, uint32_t val) +{ + return (val << find_first_set_bit(mask)) & mask; +} + +/** + * Get a field specified by a mask from a word. + */ +uint32_t field_get(uint32_t mask, uint32_t word) +{ + return (word & mask) >> find_first_set_bit(mask); +} + +/** + * Log base 2 of the given number. + */ +int32_t log_base_2(uint32_t x) +{ + return find_last_set_bit(x); +} + +/** + * Find greatest common divisor of the given two numbers. + */ +uint32_t greatest_common_divisor(uint32_t a, + uint32_t b) +{ + uint32_t div; + uint32_t common_div = 1; + + if ((a == 0) || (b == 0)) + return max(a, b); + + for (div = 1; (div <= a) && (div <= b); div++) + if (!(a % div) && !(b % div)) + common_div = div; + + return common_div; +} + +/** + * Calculate best rational approximation for a given fraction. + */ +void rational_best_approximation(uint32_t given_numerator, + uint32_t given_denominator, + uint32_t max_numerator, + uint32_t max_denominator, + uint32_t *best_numerator, + uint32_t *best_denominator) +{ + uint32_t gcd; + + gcd = greatest_common_divisor(given_numerator, given_denominator); + + *best_numerator = given_numerator / gcd; + *best_denominator = given_denominator / gcd; + + if ((*best_numerator > max_numerator) || + (*best_denominator > max_denominator)) + { + *best_numerator = 0; + *best_denominator = 0; + } +} + +/** + * Calculate the number of set bits. + */ +uint32_t hweight8(uint32_t word) +{ + uint32_t count = 0; + + while (word) + { + if (word & 0x1) + count++; + word >>= 1; + } + + return count; +} + +/** + * Calculate the quotient and the remainder of an integer division. + */ +uint64_t do_div(uint64_t *n, + uint64_t base) +{ + uint64_t mod = 0; + + mod = *n % base; + *n = *n / base; + + return mod; +} + +/** + * Unsigned 64bit divide with 64bit divisor and remainder + */ +uint64_t div64_u64_rem(uint64_t dividend, uint64_t divisor, uint64_t *remainder) +{ + *remainder = dividend % divisor; + + return dividend / divisor; +} + +/** + * Unsigned 64bit divide with 32bit divisor with remainder + */ +uint64_t div_u64_rem(uint64_t dividend, uint32_t divisor, uint32_t *remainder) +{ + *remainder = do_div(÷nd, divisor); + + return dividend; +} + +/** + * Signed 64bit divide with 32bit divisor with remainder + */ +int64_t div_s64_rem(int64_t dividend, int32_t divisor, int32_t *remainder) +{ + *remainder = dividend % divisor; + return dividend / divisor; +} + +/** + * Unsigned 64bit divide with 32bit divisor + */ +uint64_t div_u64(uint64_t dividend, uint32_t divisor) +{ + uint32_t remainder; + + return div_u64_rem(dividend, divisor, &remainder); +} + +/** + * Signed 64bit divide with 32bit divisor + */ +int64_t div_s64(int64_t dividend, int32_t divisor) +{ + int32_t remainder; + return div_s64_rem(dividend, divisor, &remainder); +} + +/** + * Converts from string to int32_t + * @param *str + * @return int32_t + */ +int32_t str_to_int32(const char *str) +{ + char *end; + int32_t value = strtol(str, &end, 0); + + if (end == str) + return FAILURE; + else + return value; +} + +/** + * Converts from string to uint32_t + * @param *str + * @return uint32_t + */ +uint32_t srt_to_uint32(const char *str) +{ + char *end; + uint32_t value = strtoul(str, &end, 0); + + if (end == str) + return FAILURE; + else + return value; +} diff --git a/unit_test_framework.h b/unit_test_framework.h new file mode 100644 index 0000000..2653cb8 --- /dev/null +++ b/unit_test_framework.h @@ -0,0 +1,332 @@ +/* + * Copyright (c) 2012 David Siñuela Pastor, siu.4coders@gmail.com + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef UNIT_TEST_FRAMEWORK_H +#define UNIT_TEST_FRAMEWORK_H + +/////////////////////////////////////////////////////////////////////////////// + +// Set macro and log tools +// #define XILINX_PLATFORM +// #include "lw_printf.h" +#include "stdio.h" +#define test_printf printf + +////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + +#define ASSERT_EQUAL(first, second) \ + assert_true((first == second), __LINE__, \ + "ASSERT_EQUAL(" #first ", " #second ")"); + +#define ASSERT_NOT_EQUAL(first, second) \ + assert_false((first == second), __LINE__, \ + "ASSERT_NOT_EQUAL(" #first ", " #second ")"); + +#define ASSERT_TRUE(value) \ + assert_true((value), __LINE__, "ASSERT_TRUE(" #value ")"); + +#define ASSERT_FALSE(value) \ + assert_false((value), __LINE__, "ASSERT_FALSE(" #value ")"); + +#define ASSERT_ALMOST_EQUAL(first, second, precision) \ + assert_almost_equal((first), (second), (precision), __LINE__, \ + "ASSERT_ALMOST_EQUAL(" #first ", " #second ", " #precision ")"); + +#if defined(_WIN32) +#include +#if defined(_MSC_VER) && _MSC_VER < 1900 +#define snprintf _snprintf +#define __func__ __FUNCTION__ +#endif + +#elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__)) + +/* Change POSIX C SOURCE version for pure c99 compilers */ +#if !defined(_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 200112L +#undef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE 200112L +#endif + +#include /* POSIX flags */ +#include /* clock_gettime(), time() */ +#include /* gethrtime(), gettimeofday() */ +#include +#include +#include + +#if defined(__MACH__) && defined(__APPLE__) +#include +#include +#endif + +#if __GNUC__ >= 5 && !defined(__STDC_VERSION__) +#define __func__ __extension__ __FUNCTION__ +#endif + +#else // baremetal application +#include + +// Xilinx +#ifdef XILINX_PLATFORM +#include "xparameters.h" + +#if !defined(PLATFORM_MP) && !defined(PLATFORM_RISCV) +#include "xtime_l.h" + +#if defined(PLATFORM_ZYNQ) +#define TIMER_CLK_FREQ_HZ (XPAR_CPU_CORTEXA9_0_CPU_CLK_FREQ_HZ / 2) +#elif defined(PLATFORM_ZYNQMP) || defined(versal) + +#if defined(__aarch64__) +#define TIMER_CLK_FREQ_HZ XPAR_PSU_CORTEXA53_0_TIMESTAMP_CLK_FREQ +#elif defined(__arm__) +#define TIMER_CLK_FREQ_HZ (XPAR_PSU_CORTEXR5_0_CPU_CLK_FREQ_HZ / 2) +#else +#Warning "Unable to define timers for microblaze platform, timer is disabled" +#endif +#endif + +#else +#Warning "Unable to define timers for microblaze platform, timer is disabled" +#endif + +#endif + +#endif + +#include + +/* Maximum length of last message */ +#define TEST_MESSAGE_LEN 1024 +/* Accuracy with which floats are compared */ +#define TEST_EPSILON 1E-12 + + /* Misc. counters */ + static int unit_run = 0; + static int unit_assert = 0; + static int unit_fail = 0; + static int unit_status = 0; + + /* Timers */ + static double unit_real_timer = 0; + static double unit_proc_timer = 0; + + /* Last message */ + static char unit_last_message[TEST_MESSAGE_LEN]; + + /* Test setup and teardown function pointers */ + static void (*unit_setup)(void) = NULL; + static void (*unit_teardown)(void) = NULL; + +/* Definitions */ +#define TEST(method_name) static void method_name(void) +#define TEST_SUITE(suite_name) static void suite_name(void) + +#define __SAFE_BLOCK(block) \ + do \ + { \ + block \ + } while (0) + +/* Run test suite and unset setup and teardown functions */ +#define RUN_TEST_SUITE(suite_name) __SAFE_BLOCK( \ + suite_name(); \ + unit_setup = NULL; \ + unit_teardown = NULL;) + +/* Configure setup and teardown functions */ +#define TEST_SUITE_CONFIGURE(setup_fun, teardown_fun) __SAFE_BLOCK( \ + unit_setup = setup_fun; \ + unit_teardown = teardown_fun;) + +/* Test runner */ +#define RUN_TEST(test) __SAFE_BLOCK( \ + if (unit_real_timer == 0 && unit_proc_timer == 0) { \ + unit_real_timer = timer_real(); \ + unit_proc_timer = timer_cpu(); \ + } if (unit_setup) (*unit_setup)(); \ + unit_status = 0; \ + test(); \ + unit_run++; \ + if (unit_status) { \ + unit_fail++; \ + test_printf("%s\n\t--FAIL\n", #test); \ + test_printf("%s\n", unit_last_message); \ + } else { \ + test_printf("%s\n\t--PASS\n", #test); \ + }(void)fflush(stdout); \ + if (unit_teardown)(*unit_teardown)();) + +/* Report */ +#define TEST_REPORT() __SAFE_BLOCK( \ + double unit_end_real_timer; \ + double unit_end_proc_timer; \ + test_printf("\n\n%d tests, %d assertions, %d failures\n", unit_run, unit_assert, unit_fail); \ + unit_end_real_timer = timer_real(); \ + unit_end_proc_timer = timer_cpu(); \ + test_printf("\nFinished in %.8f seconds (real) %.8f seconds (proc)\n\n", \ + unit_end_real_timer - unit_real_timer, \ + unit_end_proc_timer - unit_proc_timer);) +#define TEST_EXIT_CODE unit_fail + + /* Assertions */ + void assert_true(bool value, int line_number, const char *assertion_text) + { + unit_assert++; + if (value) + { + return; + } + unit_status = 1; + test_printf("In %s, line %d:\n", assertion_text, line_number); + test_printf("Expected true, but was false.\n"); + } + + void assert_false(bool value, int line_number, const char *assertion_text) + { + unit_assert++; + if (!value) + { + return; + } + unit_status = 1; + test_printf("In %s, line %d:\n", assertion_text, line_number); + test_printf("Expected false, but was true.\n"); + } + + void assert_almost_equal(double first, double second, double precision, + int line_number, const char *assertion_text) + { + unit_assert++; + if (fabs(first - second) <= precision) + { + return; + } + unit_status = 1; + test_printf("In %s, line %d:\n", assertion_text, line_number); + test_printf("Values too far apart: %f and %f.\n", first, second); + } + + /** + * Returns the real time, in seconds, or -1.0 if an error occurred. + * + * Time is measured since an arbitrary and OS-dependent start time. + * The returned real time is only useful for computing an elapsed time + * between two calls to this function. + */ + static double timer_real(void) + { +#if defined(_WIN32) + /* Windows 2000 and later. ---------------------------------- */ + LARGE_INTEGER Time; + LARGE_INTEGER Frequency; + + QueryPerformanceFrequency(&Frequency); + QueryPerformanceCounter(&Time); + + Time.QuadPart *= 1e6; + Time.QuadPart /= Frequency.QuadPart; + + return (double)Time.QuadPart / 1e6; + +#elif (defined(__hpux) || defined(hpux)) || ((defined(__sun__) || defined(__sun) || defined(sun)) && (defined(__SVR4) || defined(__svr4__))) + /* HP-UX, Solaris. ------------------------------------------ */ + return (double)gethrtime() / 1e6; + +#elif defined(__MACH__) && defined(__APPLE__) + /* OSX. ----------------------------------------------------- */ + static double timeConvert = 0.0; + if (timeConvert == 0.0) + { + mach_timebase_info_data_t timeBase; + (void)mach_timebase_info(&timeBase); + timeConvert = (double)timeBase.numer / + (double)timeBase.denom / 1e6; + } + return (double)mach_absolute_time() * timeConvert; + +#elif defined(_POSIX_VERSION) + /* POSIX. --------------------------------------------------- */ + struct timeval tm; + /* AIX, BSD, Cygwin, HP-UX, Linux, OSX, POSIX, Solaris. ----- */ + gettimeofday(&tm, NULL); + return (double)tm.tv_sec + (double)tm.tv_usec / 1e6; +#else // bare metal platform + +#if defined(XILINX_PLATFORM) && defined(TIMER_CLK_FREQ_HZ) + // Xilinx platform + int64_t clocks; + XTime_GetTime(&clocks); + return ((double)clocks / (double)TIMER_CLK_FREQ_HZ); +#endif + +#endif + } + + /** + * Returns the amount of CPU time used by the current process, + * in seconds, or -1.0 if an error occurred. + */ + static double timer_cpu(void) + { +#if defined(_WIN32) + /* Windows -------------------------------------------------- */ + FILETIME createTime; + FILETIME exitTime; + FILETIME kernelTime; + FILETIME userTime; + + /* This approach has a resolution of 1/64 second. Unfortunately, Windows' API does not offer better */ + if (GetProcessTimes(GetCurrentProcess(), + &createTime, &exitTime, &kernelTime, &userTime) != 0) + { + ULARGE_INTEGER userSystemTime; + memcpy(&userSystemTime, &userTime, sizeof(ULARGE_INTEGER)); + return (double)userSystemTime.QuadPart / 1e6; + } + +#elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__)) + /* AIX, BSD, Cygwin, HP-UX, Linux, OSX, and Solaris --------- */ +#if defined(CLOCKS_PER_SEC) + clock_t cl = clock(); + if (cl != (clock_t)-1) + return (double)cl / (double)CLOCKS_PER_SEC; +#endif + +#else // bare metal platform + return timer_real(); +#endif + return -1.0; /* Failed. */ + } +#ifdef __cplusplus +} +#endif + +#endif /* UNIT_TEST_FRAMEWORK_H */