From 68678b39f6579d00754df06e914a97a2f1974afd Mon Sep 17 00:00:00 2001 From: Gatsby Van Date: Mon, 22 Jan 2024 19:09:45 +0800 Subject: [PATCH] add ground emulator code. --- df_datalink_ge/bsp/Makefile | 35 + .../include/_profile_timer_hw.h | 308 + .../bsp/ps7_cortexa9_0/include/bspconfig.h | 44 + .../bsp/ps7_cortexa9_0/include/frame_uart.h | 128 + .../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/xgpio.h | 211 + .../bsp/ps7_cortexa9_0/include/xgpio_i.h | 83 + .../bsp/ps7_cortexa9_0/include/xgpio_l.h | 189 + .../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 | 564 + .../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/xspips.h | 703 + .../bsp/ps7_cortexa9_0/include/xspips_hw.h | 309 + .../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 | 123 + .../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/frame_uart_v1_0/src/Makefile | 26 + .../libsrc/frame_uart_v1_0/src/frame_uart.c | 138 + .../libsrc/frame_uart_v1_0/src/frame_uart.h | 128 + .../libsrc/gpio_v4_4/src/Makefile | 40 + .../libsrc/gpio_v4_4/src/xgpio.c | 251 + .../libsrc/gpio_v4_4/src/xgpio.h | 211 + .../libsrc/gpio_v4_4/src/xgpio_extra.c | 160 + .../libsrc/gpio_v4_4/src/xgpio_g.c | 53 + .../libsrc/gpio_v4_4/src/xgpio_i.h | 83 + .../libsrc/gpio_v4_4/src/xgpio_intr.c | 290 + .../libsrc/gpio_v4_4/src/xgpio_l.h | 189 + .../libsrc/gpio_v4_4/src/xgpio_selftest.c | 106 + .../libsrc/gpio_v4_4/src/xgpio_sinit.c | 155 + .../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/spips_v3_2/src/Makefile | 40 + .../libsrc/spips_v3_2/src/xspips.c | 1154 + .../libsrc/spips_v3_2/src/xspips.h | 703 + .../libsrc/spips_v3_2/src/xspips_g.c | 52 + .../libsrc/spips_v3_2/src/xspips_hw.c | 143 + .../libsrc/spips_v3_2/src/xspips_hw.h | 309 + .../libsrc/spips_v3_2/src/xspips_options.c | 431 + .../libsrc/spips_v3_2/src/xspips_selftest.c | 163 + .../libsrc/spips_v3_2/src/xspips_sinit.c | 96 + .../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_ge/bsp/system.mss | 261 + df_datalink_ge/build/Xilinx.spec | 2 + df_datalink_ge/build/makefile | 80 + df_datalink_ge/build/objects.mk | 8 + df_datalink_ge/build/sources.mk | 32 + df_datalink_ge/build/src/config/subdir.mk | 24 + .../build/src/dev_profile/subdir.mk | 30 + .../build/src/drivers/api/subdir.mk | 30 + .../build/src/drivers/platform/subdir.mk | 30 + .../build/src/hardware/mykonos/subdir.mk | 39 + df_datalink_ge/build/src/hardware/subdir.mk | 36 + .../networking/link_layer/geometry/subdir.mk | 30 + .../build/src/networking/link_layer/subdir.mk | 45 + .../build/src/networking/phy_layer/subdir.mk | 27 + df_datalink_ge/build/src/subdir.mk | 30 + df_datalink_ge/build/src/systembus/subdir.mk | 27 + df_datalink_ge/build/src/time_ctrl/subdir.mk | 23 + df_datalink_ge/build/src/util/subdir.mk | 39 + df_datalink_ge/src/Xilinx.spec | 2 + df_datalink_ge/src/config/app_config.h | 98 + df_datalink_ge/src/config/platform.c | 110 + df_datalink_ge/src/config/platform.h | 41 + df_datalink_ge/src/config/platform_config.h | 7 + df_datalink_ge/src/dev_profile/dev_profile.h | 13 + .../src/dev_profile/global_timer_profile.c | 11 + df_datalink_ge/src/dev_profile/intc_profile.c | 13 + .../src/dev_profile/timer_profile.c | 17 + df_datalink_ge/src/drivers/api/irq.c | 229 + df_datalink_ge/src/drivers/api/timer.c | 211 + df_datalink_ge/src/drivers/api/trng.c | 111 + .../src/drivers/platform/xilinx_axi_io.c | 79 + .../src/drivers/platform/xilinx_irq.c | 433 + .../src/drivers/platform/xilinx_irq.h | 91 + .../src/drivers/platform/xilinx_timer.c | 456 + .../src/drivers/platform/xilinx_timer.h | 101 + df_datalink_ge/src/hardware/common.c | 275 + df_datalink_ge/src/hardware/common.h | 131 + df_datalink_ge/src/hardware/headless.c | 1138 + df_datalink_ge/src/hardware/headless.h | 348 + df_datalink_ge/src/hardware/myk_ad9528init.c | 189 + df_datalink_ge/src/hardware/myk_ad9528init.h | 20 + df_datalink_ge/src/hardware/myk_init.c | 558 + df_datalink_ge/src/hardware/myk_init.h | 24 + .../src/hardware/mykonos/Mykonos_M3.c | 8518 +++++++ .../src/hardware/mykonos/Mykonos_M3.h | 13 + df_datalink_ge/src/hardware/mykonos/ad9528.c | 740 + df_datalink_ge/src/hardware/mykonos/ad9528.h | 44 + df_datalink_ge/src/hardware/mykonos/mykonos.c | 18444 ++++++++++++++++ df_datalink_ge/src/hardware/mykonos/mykonos.h | 277 + .../src/hardware/mykonos/mykonosMmap.c | 136 + .../src/hardware/mykonos/mykonos_gpio.c | 5357 +++++ .../src/hardware/mykonos/mykonos_gpio.h | 172 + .../src/hardware/mykonos/mykonos_macros.h | 707 + .../src/hardware/mykonos/mykonos_user.c | 176 + .../src/hardware/mykonos/mykonos_user.h | 85 + .../src/hardware/mykonos/mykonos_version.h | 31 + .../src/hardware/mykonos/t_ad9528.h | 194 + .../src/hardware/mykonos/t_mykonos.h | 1710 ++ .../src/hardware/mykonos/t_mykonos_gpio.h | 375 + df_datalink_ge/src/hardware/parameters.h | 81 + .../src/hardware/platform_drivers.c | 497 + .../src/hardware/platform_drivers.h | 223 + df_datalink_ge/src/include/axi_io.h | 59 + df_datalink_ge/src/include/circ_queue.h | 111 + df_datalink_ge/src/include/clist.h | 118 + df_datalink_ge/src/include/common.h | 92 + df_datalink_ge/src/include/error.h | 47 + df_datalink_ge/src/include/global_timer.h | 95 + df_datalink_ge/src/include/gpio.h | 188 + df_datalink_ge/src/include/irq.h | 235 + df_datalink_ge/src/include/list.h | 327 + df_datalink_ge/src/include/timer.h | 159 + df_datalink_ge/src/include/trng.h | 115 + df_datalink_ge/src/include/util.h | 195 + df_datalink_ge/src/lscript.ld | 292 + df_datalink_ge/src/main.c | 505 + df_datalink_ge/src/networking | 1 + df_datalink_ge/src/system_monitor.c | 1 + df_datalink_ge/src/system_monitor.h | 1 + df_datalink_ge/src/systembus | 1 + df_datalink_ge/src/time_ctrl | 1 + df_datalink_ge/src/util | 1 + 367 files changed, 115148 insertions(+) create mode 100644 df_datalink_ge/bsp/Makefile create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/_profile_timer_hw.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/bspconfig.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/frame_uart.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/mblaze_nt_types.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/profile.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/sleep.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/smc.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/vectors.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xadcps.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xadcps_hw.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xbasic_types.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xbram.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xbram_hw.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xcoresightpsdcc.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xcpu_cortexa9.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xddrps.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xdebug.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xdevcfg.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xdevcfg_hw.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xdmaps.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xdmaps_hw.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xenv.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xenv_standalone.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xgpio.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xgpio_i.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xgpio_l.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xgpiops.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xgpiops_hw.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xil_assert.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xil_cache.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xil_cache_l.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xil_cache_vxworks.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xil_errata.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xil_exception.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xil_hal.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xil_io.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xil_macroback.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xil_mem.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xil_misc_psreset_api.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xil_mmu.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xil_printf.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xil_sleeptimer.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xil_testcache.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xil_testio.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xil_testmem.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xil_types.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xil_util.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xl2cc.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xl2cc_counter.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xparameters.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xparameters_ps.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xplatform_info.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xpm_counter.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xpseudo_asm.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xpseudo_asm_gcc.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xqspips.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xqspips_hw.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xreg_cortexa9.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xscugic.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xscugic_hw.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xscutimer.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xscutimer_hw.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xscuwdt.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xscuwdt_hw.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xspips.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xspips_hw.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xstatus.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xtime_l.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xuartps.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/include/xuartps_hw.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/Makefile create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram_g.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram_hw.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram_intr.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram_selftest.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram_sinit.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/coresightps_dcc_v1_5/src/Makefile create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/coresightps_dcc_v1_5/src/xcoresightpsdcc.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/coresightps_dcc_v1_5/src/xcoresightpsdcc.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/cpu_cortexa9_v2_7/src/Makefile create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/cpu_cortexa9_v2_7/src/xcpu_cortexa9.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/ddrps_v1_0/src/Makefile create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/ddrps_v1_0/src/xddrps.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/Makefile create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg_g.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg_hw.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg_hw.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg_intr.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg_selftest.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg_sinit.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/Makefile create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps_g.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps_hw.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps_hw.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps_selftest.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps_sinit.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/frame_uart_v1_0/src/Makefile create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/frame_uart_v1_0/src/frame_uart.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/frame_uart_v1_0/src/frame_uart.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpio_v4_4/src/Makefile create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpio_v4_4/src/xgpio.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpio_v4_4/src/xgpio.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpio_v4_4/src/xgpio_extra.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpio_v4_4/src/xgpio_g.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpio_v4_4/src/xgpio_i.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpio_v4_4/src/xgpio_intr.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpio_v4_4/src/xgpio_l.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpio_v4_4/src/xgpio_selftest.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpio_v4_4/src/xgpio_sinit.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/Makefile create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops_g.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops_hw.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops_hw.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops_intr.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops_selftest.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops_sinit.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/Makefile create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips_g.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips_hw.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips_hw.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips_options.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips_selftest.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips_sinit.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/Makefile create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic_g.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic_hw.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic_hw.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic_intr.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic_selftest.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic_sinit.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/Makefile create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/xscutimer.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/xscutimer.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/xscutimer_g.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/xscutimer_hw.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/xscutimer_selftest.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/xscutimer_sinit.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/Makefile create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/xscuwdt.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/xscuwdt.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/xscuwdt_g.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/xscuwdt_hw.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/xscuwdt_selftest.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/xscuwdt_sinit.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/spips_v3_2/src/Makefile create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/spips_v3_2/src/xspips.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/spips_v3_2/src/xspips.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/spips_v3_2/src/xspips_g.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/spips_v3_2/src/xspips_hw.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/spips_v3_2/src/xspips_hw.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/spips_v3_2/src/xspips_options.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/spips_v3_2/src/xspips_selftest.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/spips_v3_2/src/xspips_sinit.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/Makefile create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/_exit.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/_open.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/_sbrk.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/abort.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/asm_vectors.S create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/boot.S create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/bspconfig.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/changelog.txt create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/close.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/config.make create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/cpu_init.S create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/errno.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/fcntl.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/fstat.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/getpid.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/inbyte.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/isatty.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/kill.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/lseek.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/open.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/outbyte.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/print.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/Makefile create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/_profile_clean.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/_profile_init.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/_profile_timer_hw.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/_profile_timer_hw.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/dummy.S create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/mblaze_nt_types.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/profile.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/profile_cg.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/profile_config.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/profile_hist.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/profile_mcount_arm.S create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/profile_mcount_mb.S create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/profile_mcount_ppc.S create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/putnum.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/read.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/sbrk.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/sleep.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/sleep.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/smc.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/translation_table.S create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/unlink.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/usleep.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/vectors.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/vectors.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/write.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xbasic_types.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xdebug.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xenv.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xenv_standalone.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil-crt0.S create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_assert.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_assert.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_cache.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_cache.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_cache_l.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_cache_vxworks.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_errata.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_exception.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_exception.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_hal.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_io.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_io.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_macroback.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_mem.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_mem.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_misc_psreset_api.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_misc_psreset_api.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_mmu.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_mmu.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_printf.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_printf.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_sleepcommon.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_sleeptimer.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_sleeptimer.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_testcache.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_testcache.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_testio.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_testio.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_testmem.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_testmem.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_types.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_util.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_util.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xl2cc.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xl2cc_counter.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xl2cc_counter.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xparameters_ps.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xplatform_info.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xplatform_info.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xpm_counter.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xpm_counter.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xpseudo_asm.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xpseudo_asm_gcc.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xreg_cortexa9.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xstatus.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xtime_l.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xtime_l.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/Makefile create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_g.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_hw.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_hw.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_intr.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_options.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_selftest.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_sinit.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/Makefile create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/xadcps.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/xadcps.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/xadcps_g.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/xadcps_hw.h create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/xadcps_intr.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/xadcps_selftest.c create mode 100644 df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/xadcps_sinit.c create mode 100644 df_datalink_ge/bsp/system.mss create mode 100644 df_datalink_ge/build/Xilinx.spec create mode 100644 df_datalink_ge/build/makefile create mode 100644 df_datalink_ge/build/objects.mk create mode 100644 df_datalink_ge/build/sources.mk create mode 100644 df_datalink_ge/build/src/config/subdir.mk create mode 100644 df_datalink_ge/build/src/dev_profile/subdir.mk create mode 100644 df_datalink_ge/build/src/drivers/api/subdir.mk create mode 100644 df_datalink_ge/build/src/drivers/platform/subdir.mk create mode 100644 df_datalink_ge/build/src/hardware/mykonos/subdir.mk create mode 100644 df_datalink_ge/build/src/hardware/subdir.mk create mode 100644 df_datalink_ge/build/src/networking/link_layer/geometry/subdir.mk create mode 100644 df_datalink_ge/build/src/networking/link_layer/subdir.mk create mode 100644 df_datalink_ge/build/src/networking/phy_layer/subdir.mk create mode 100644 df_datalink_ge/build/src/subdir.mk create mode 100644 df_datalink_ge/build/src/systembus/subdir.mk create mode 100644 df_datalink_ge/build/src/time_ctrl/subdir.mk create mode 100644 df_datalink_ge/build/src/util/subdir.mk create mode 100644 df_datalink_ge/src/Xilinx.spec create mode 100644 df_datalink_ge/src/config/app_config.h create mode 100644 df_datalink_ge/src/config/platform.c create mode 100644 df_datalink_ge/src/config/platform.h create mode 100644 df_datalink_ge/src/config/platform_config.h create mode 100644 df_datalink_ge/src/dev_profile/dev_profile.h create mode 100644 df_datalink_ge/src/dev_profile/global_timer_profile.c create mode 100644 df_datalink_ge/src/dev_profile/intc_profile.c create mode 100644 df_datalink_ge/src/dev_profile/timer_profile.c create mode 100644 df_datalink_ge/src/drivers/api/irq.c create mode 100644 df_datalink_ge/src/drivers/api/timer.c create mode 100644 df_datalink_ge/src/drivers/api/trng.c create mode 100644 df_datalink_ge/src/drivers/platform/xilinx_axi_io.c create mode 100644 df_datalink_ge/src/drivers/platform/xilinx_irq.c create mode 100644 df_datalink_ge/src/drivers/platform/xilinx_irq.h create mode 100644 df_datalink_ge/src/drivers/platform/xilinx_timer.c create mode 100644 df_datalink_ge/src/drivers/platform/xilinx_timer.h create mode 100644 df_datalink_ge/src/hardware/common.c create mode 100644 df_datalink_ge/src/hardware/common.h create mode 100644 df_datalink_ge/src/hardware/headless.c create mode 100644 df_datalink_ge/src/hardware/headless.h create mode 100644 df_datalink_ge/src/hardware/myk_ad9528init.c create mode 100644 df_datalink_ge/src/hardware/myk_ad9528init.h create mode 100644 df_datalink_ge/src/hardware/myk_init.c create mode 100644 df_datalink_ge/src/hardware/myk_init.h create mode 100644 df_datalink_ge/src/hardware/mykonos/Mykonos_M3.c create mode 100644 df_datalink_ge/src/hardware/mykonos/Mykonos_M3.h create mode 100644 df_datalink_ge/src/hardware/mykonos/ad9528.c create mode 100644 df_datalink_ge/src/hardware/mykonos/ad9528.h create mode 100644 df_datalink_ge/src/hardware/mykonos/mykonos.c create mode 100644 df_datalink_ge/src/hardware/mykonos/mykonos.h create mode 100644 df_datalink_ge/src/hardware/mykonos/mykonosMmap.c create mode 100644 df_datalink_ge/src/hardware/mykonos/mykonos_gpio.c create mode 100644 df_datalink_ge/src/hardware/mykonos/mykonos_gpio.h create mode 100644 df_datalink_ge/src/hardware/mykonos/mykonos_macros.h create mode 100644 df_datalink_ge/src/hardware/mykonos/mykonos_user.c create mode 100644 df_datalink_ge/src/hardware/mykonos/mykonos_user.h create mode 100644 df_datalink_ge/src/hardware/mykonos/mykonos_version.h create mode 100644 df_datalink_ge/src/hardware/mykonos/t_ad9528.h create mode 100644 df_datalink_ge/src/hardware/mykonos/t_mykonos.h create mode 100644 df_datalink_ge/src/hardware/mykonos/t_mykonos_gpio.h create mode 100644 df_datalink_ge/src/hardware/parameters.h create mode 100644 df_datalink_ge/src/hardware/platform_drivers.c create mode 100644 df_datalink_ge/src/hardware/platform_drivers.h create mode 100644 df_datalink_ge/src/include/axi_io.h create mode 100644 df_datalink_ge/src/include/circ_queue.h create mode 100644 df_datalink_ge/src/include/clist.h create mode 100644 df_datalink_ge/src/include/common.h create mode 100644 df_datalink_ge/src/include/error.h create mode 100644 df_datalink_ge/src/include/global_timer.h create mode 100644 df_datalink_ge/src/include/gpio.h create mode 100644 df_datalink_ge/src/include/irq.h create mode 100644 df_datalink_ge/src/include/list.h create mode 100644 df_datalink_ge/src/include/timer.h create mode 100644 df_datalink_ge/src/include/trng.h create mode 100644 df_datalink_ge/src/include/util.h create mode 100644 df_datalink_ge/src/lscript.ld create mode 100644 df_datalink_ge/src/main.c create mode 120000 df_datalink_ge/src/networking create mode 120000 df_datalink_ge/src/system_monitor.c create mode 120000 df_datalink_ge/src/system_monitor.h create mode 120000 df_datalink_ge/src/systembus create mode 120000 df_datalink_ge/src/time_ctrl create mode 120000 df_datalink_ge/src/util diff --git a/df_datalink_ge/bsp/Makefile b/df_datalink_ge/bsp/Makefile new file mode 100644 index 0000000..1e68922 --- /dev/null +++ b/df_datalink_ge/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=arm-none-eabi-gcc" "ARCHIVER=arm-none-eabi-ar" "COMPILER_FLAGS= -O2 -c" "EXTRA_COMPILER_FLAGS=-mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -nostartfiles -g -Wall -Wextra" + +%/make.libs: include + @echo "Running Make libs in $(subst /make.libs,,$@)" + $(MAKE) -C $(subst /make.libs,,$@) -s libs "SHELL=$(SHELL)" "COMPILER=arm-none-eabi-gcc" "ARCHIVER=arm-none-eabi-ar" "COMPILER_FLAGS= -O2 -c" "EXTRA_COMPILER_FLAGS=-mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -nostartfiles -g -Wall -Wextra" + +%/make.clean: + $(MAKE) -C $(subst /make.clean,,$@) -s clean +clean: + rm -f ${PROCESSOR}/lib/libxil.a diff --git a/df_datalink_ge/bsp/ps7_cortexa9_0/include/_profile_timer_hw.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/_profile_timer_hw.h new file mode 100644 index 0000000..1647600 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/bspconfig.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/bspconfig.h new file mode 100644 index 0000000..5ffeff5 --- /dev/null +++ b/df_datalink_ge/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-2024 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_ge/bsp/ps7_cortexa9_0/include/frame_uart.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/frame_uart.h new file mode 100644 index 0000000..7c576cf --- /dev/null +++ b/df_datalink_ge/bsp/ps7_cortexa9_0/include/frame_uart.h @@ -0,0 +1,128 @@ +/*****************************************************************************/ +/** + * Description: A brief description of this file + * + * Author: Fan Hao + * Date: 2021-12-26 10:59 + * LastEditors: Fan Hao + * LastEditTime: 2022-01-16 21:48 + * Revisions: Rev 0.0 + * History: + * [2021-12-26]: Initial version. + * + * Copyright(c) 2022 Beijing Institute of Technology. + * Lab of Communication and Networking + * + ******************************************************************************/ + +#ifndef FRAME_UART_H +#define FRAME_UART_H + +/****************** Include Files ********************/ +#include +#include +#include + +#define FRAME_UART_PROTOCOL_OVERHEAD_LEN 4 + +#define FRAME_UART_BYTE_PER_REG 4 +// Control register +#define FRAME_UART_SEND_START_OFFSET 0 +#define FRAME_UART_STATUS_OFFSET 4 + +// Data buffer register +#define FRAME_UART_TXBUFF_OFFSET 1024 +#define FRAME_UART_TXBUFF_MAX 1024 +#define FRAME_UART_RXBUFF_OFFSET 2048 +#define FRAME_UART_RXBUFF_MAX 2048 +#define FRAME_UART_RECV_DLEN_OFFSET 0 + +// Status +#define FRAME_UART_RX_BUSY 0x00010000 +#define FRAME_UART_TX_BUSY 0x00000001 + +/**************************** Type Definitions *****************************/ +/** + * + * Write a value to a FRAME_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 BaseAddress is the base address of the FRAME_UARTdevice. + * @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 FRAME_UART_mWriteReg(u32 BaseAddress, unsigned RegOffset, u32 Data) + * + */ +#define FRAME_UART_mWriteReg(BaseAddress, RegOffset, Data) \ + Xil_Out32((BaseAddress) + (RegOffset), (u32)(Data)) + +/** + * + * Read a value from a FRAME_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 BaseAddress is the base address of the FRAME_UART device. + * @param RegOffset is the register offset from the base to write to. + * + * @return Data is the data from the register. + * + * @note + * C-style signature: + * u32 FRAME_UART_mReadReg(u32 BaseAddress, unsigned RegOffset) + * + */ +#define FRAME_UART_mReadReg(BaseAddress, RegOffset) \ + Xil_In32((BaseAddress) + (RegOffset)) + +/************************** Function Prototypes ****************************/ +/** + * + * Run a self-test on the driver/device. Note this may be a destructive test if + * resets of the device are performed. + * + * If the hardware system is not built correctly, this function may never + * return to the caller. + * + * @param baseaddr_p is the base address of the FRAME_UART instance to be worked on. + * + * @return + * + * - XST_SUCCESS if all self-test code passed + * - XST_FAILURE if any self-test code failed + * + * @note Caching must be turned off for this function to work. + * @note Self test may fail if data memory and device are not on the same bus. + * + */ + +/************************** Data Type Definitions ****************************/ +typedef struct { + u32 BaseAddr; + u32 TxOffset; + u32 RxOffset; +} FrameUart; + +/************************** Function Prototypes ******************************/ +// Instance initial +int FrameUart_Init(FrameUart* InstPtr, u32 BaseAddr); + +// Send a system bus frame. +int FrameUart_Send(FrameUart* InstPtr, u8* DataBuff, u32 DataLenByte); + +// Get last system bus frame. +int FrameUart_Recv(FrameUart* InstPtr, u8* DataBuff); + +// Get system bus rx channel status. +bool FrameUart_IsRxBusy(FrameUart* InstPtr); + +// Get system bus tx channel status. +bool FrameUart_IsTxBusy(FrameUart* InstPtr); +#endif // FRAME_UART_H diff --git a/df_datalink_ge/bsp/ps7_cortexa9_0/include/mblaze_nt_types.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/mblaze_nt_types.h new file mode 100644 index 0000000..807dda3 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/profile.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/profile.h new file mode 100644 index 0000000..63f503a --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/sleep.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/sleep.h new file mode 100644 index 0000000..f3a632b --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/smc.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/smc.h new file mode 100644 index 0000000..f7cc91c --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/vectors.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/vectors.h new file mode 100644 index 0000000..56bacbc --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xadcps.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xadcps.h new file mode 100644 index 0000000..900edf0 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xadcps_hw.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xadcps_hw.h new file mode 100644 index 0000000..dd51473 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xbram.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xbram.h new file mode 100644 index 0000000..246df6d --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xbram_hw.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xbram_hw.h new file mode 100644 index 0000000..55a2505 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xcoresightpsdcc.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xcoresightpsdcc.h new file mode 100644 index 0000000..79bde0b --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xcpu_cortexa9.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xcpu_cortexa9.h new file mode 100644 index 0000000..e4a5e28 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xddrps.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xddrps.h new file mode 100644 index 0000000..b4d1f56 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xdebug.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xdebug.h new file mode 100644 index 0000000..b09c02d --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xdevcfg.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xdevcfg.h new file mode 100644 index 0000000..6586370 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xdevcfg_hw.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xdevcfg_hw.h new file mode 100644 index 0000000..80b6678 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xdmaps.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xdmaps.h new file mode 100644 index 0000000..73e2b1e --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xdmaps_hw.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xdmaps_hw.h new file mode 100644 index 0000000..42dfe69 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xenv.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xenv.h new file mode 100644 index 0000000..9c7c4c3 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xenv_standalone.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xenv_standalone.h new file mode 100644 index 0000000..ef905af --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xgpio.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xgpio.h new file mode 100644 index 0000000..b498fe0 --- /dev/null +++ b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xgpio.h @@ -0,0 +1,211 @@ +/****************************************************************************** +* +* Copyright (C) 2002 - 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 xgpio.h +* @addtogroup gpio_v4_4 +* @{ +* @details +* +* This file contains the software API definition of the Xilinx General Purpose +* I/O (XGpio) device driver. +* +* The Xilinx GPIO controller is a soft IP core designed for Xilinx FPGAs and +* contains the following general features: +* - Support for up to 32 I/O discretes for each channel (64 bits total). +* - Each of the discretes can be configured for input or output. +* - Configurable support for dual channels and interrupt generation. +* +* 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 XGpio_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 one +* of the following ways: +* +* - XGpio_Initialize(InstancePtr, DeviceId) - The driver looks up its own +* configuration structure created by the tool-chain based on an ID provided +* by the tool-chain. +* +* - XGpio_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 GPIO 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
+* ----- ---- -------- -----------------------------------------------
+* 1.00a rmm  03/13/02 First release
+* 2.00a jhl  11/26/03 Added support for dual channels and interrupts
+* 2.01a jvb  12/14/05 I separated dependency on the static config table and
+*                     xparameters.h from the driver initialization by moving
+*                     _Initialize and _LookupConfig to _sinit.c. I also added
+*                     the new _CfgInitialize routine.
+* 2.11a mta  03/21/07 Updated to new coding style, added GetDataDirection
+* 2.12a sv   11/21/07 Updated driver to support access through DCR bus
+* 2.12a sv   06/05/08 Updated driver to fix the XGpio_InterruptDisable function
+*		      to properly update the Interrupt Enable register
+* 2.13a sdm  08/22/08 Removed support for static interrupt handlers from the MDD
+*		      file
+* 3.00a sv   11/21/09 Updated to use HAL Processor APIs.
+*		      Renamed the macros XGpio_mWriteReg to XGpio_WriteReg and
+*		      XGpio_mReadReg to XGpio_ReadReg. Removed the macros
+*		      XGpio_mSetDataDirection, XGpio_mGetDataReg and
+*		      XGpio_mSetDataReg. Users should use XGpio_WriteReg and
+*		      XGpio_ReadReg to achieve the same functionality.
+* 3.01a bss  04/18/13 Updated driver tcl to generate Canonical params in
+*		      xparameters.h. CR#698589
+* 4.0   adk  19/12/13 Updated as per the New Tcl API's
+* 4.1   lks  11/18/15 Updated to use cannonical xparameters in examples and
+*		      clean up of the comments, removed support for DCR bridge
+*		      and removed xgpio_intr_example for CR 900381
+* 4.2   sk   08/16/16 Used UINTPTR instead of u32 for Baseaddress as part of
+*                     adding 64 bit support. CR# 867425.
+*                     Changed the prototype of XGpio_CfgInitialize API.
+* 4.3   sk   09/29/16 Modified the example to make it work when LED_bits are
+*                     configured as an output. CR# 958644
+*       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.
+* 4.4   sne  04/25/19 Updated Makefile for IAR compier (CR-1029421).
+*
+* 
+*****************************************************************************/ + +#ifndef XGPIO_H /* prevent circular inclusions */ +#define XGPIO_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files ********************************/ + +#include "xil_types.h" +#include "xil_assert.h" +#include "xstatus.h" +#include "xgpio_l.h" + +/************************** Constant Definitions ****************************/ + +/**************************** Type Definitions ******************************/ + +/** + * This typedef contains configuration information for the device. + */ +typedef struct { + u16 DeviceId; /* Unique ID of device */ + UINTPTR BaseAddress; /* Device base address */ + int InterruptPresent; /* Are interrupts supported in h/w */ + int IsDual; /* Are 2 channels supported in h/w */ +} XGpio_Config; + +/** + * The XGpio driver instance data. The user is required to allocate a + * variable of this type for every GPIO device in the system. A pointer + * to a variable of this type is then passed to the driver API functions. + */ +typedef struct { + UINTPTR BaseAddress; /* Device base address */ + u32 IsReady; /* Device is initialized and ready */ + int InterruptPresent; /* Are interrupts supported in h/w */ + int IsDual; /* Are 2 channels supported in h/w */ +} XGpio; + +/***************** Macros (Inline Functions) Definitions ********************/ + + +/************************** Function Prototypes *****************************/ + +/* + * Initialization functions in xgpio_sinit.c + */ +int XGpio_Initialize(XGpio *InstancePtr, u16 DeviceId); +XGpio_Config *XGpio_LookupConfig(u16 DeviceId); + +/* + * API Basic functions implemented in xgpio.c + */ +int XGpio_CfgInitialize(XGpio *InstancePtr, XGpio_Config * Config, + UINTPTR EffectiveAddr); +void XGpio_SetDataDirection(XGpio *InstancePtr, unsigned Channel, + u32 DirectionMask); +u32 XGpio_GetDataDirection(XGpio *InstancePtr, unsigned Channel); +u32 XGpio_DiscreteRead(XGpio *InstancePtr, unsigned Channel); +void XGpio_DiscreteWrite(XGpio *InstancePtr, unsigned Channel, u32 Mask); + + +/* + * API Functions implemented in xgpio_extra.c + */ +void XGpio_DiscreteSet(XGpio *InstancePtr, unsigned Channel, u32 Mask); +void XGpio_DiscreteClear(XGpio *InstancePtr, unsigned Channel, u32 Mask); + +/* + * API Functions implemented in xgpio_selftest.c + */ +int XGpio_SelfTest(XGpio *InstancePtr); + +/* + * API Functions implemented in xgpio_intr.c + */ +void XGpio_InterruptGlobalEnable(XGpio *InstancePtr); +void XGpio_InterruptGlobalDisable(XGpio *InstancePtr); +void XGpio_InterruptEnable(XGpio *InstancePtr, u32 Mask); +void XGpio_InterruptDisable(XGpio *InstancePtr, u32 Mask); +void XGpio_InterruptClear(XGpio *InstancePtr, u32 Mask); +u32 XGpio_InterruptGetEnabled(XGpio *InstancePtr); +u32 XGpio_InterruptGetStatus(XGpio *InstancePtr); + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/df_datalink_ge/bsp/ps7_cortexa9_0/include/xgpio_i.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xgpio_i.h new file mode 100644 index 0000000..7938b0f --- /dev/null +++ b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xgpio_i.h @@ -0,0 +1,83 @@ +/****************************************************************************** +* +* Copyright (C) 2002 - 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 xgpio_i.h +* @addtogroup gpio_v4_3 +* @{ +* +* This header file contains internal identifiers, which are those shared +* between the files of the driver. It is intended for internal use only. +* +* NOTES: +* +* None. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a rmm  03/13/02 First release
+* 2.11a mta  03/21/07 Updated to new coding style
+* 
+******************************************************************************/ + +#ifndef XGPIO_I_H /* prevent circular inclusions */ +#define XGPIO_I_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +#include "xgpio.h" + +/************************** Constant Definitions ****************************/ + + +/**************************** Type Definitions *******************************/ + + +/***************** Macros (Inline Functions) Definitions *********************/ + + +/************************** Function Prototypes ******************************/ + + +/************************** Variable Definitions ****************************/ + +extern XGpio_Config XGpio_ConfigTable[]; + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/df_datalink_ge/bsp/ps7_cortexa9_0/include/xgpio_l.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xgpio_l.h new file mode 100644 index 0000000..be6d04a --- /dev/null +++ b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xgpio_l.h @@ -0,0 +1,189 @@ +/****************************************************************************** +* +* Copyright (C) 2002 - 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 xgpio_l.h +* @addtogroup gpio_v4_4 +* @{ +* +* 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. +* +* The macros that are available in this file use a multiply to calculate the +* addresses of registers. The user can control whether that multiply is done +* at run time or at compile time. A constant passed as the channel parameter +* will cause the multiply to be done at compile time. A variable passed as the +* channel parameter will cause it to occur at run time. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a jhl  04/24/02 First release of low level driver
+* 2.00a jhl  11/26/03 Added support for dual channels and interrupts. This
+*                     change required the functions to be changed such that
+*                     the interface is not compatible with previous versions.
+*                     See the examples in the example directory for macros
+*                     to help compile an application that was designed for
+*                     previous versions of the driver. The interrupt registers
+*                     are accessible using the ReadReg and WriteReg macros and
+*                     a channel parameter was added to the other macros.
+* 2.11a mta  03/21/07 Updated to new coding style
+* 2.12a sv   11/21/07 Updated driver to support access through DCR bus.
+* 3.00a sv   11/21/09 Renamed the macros XGpio_mWriteReg to XGpio_WriteReg
+*		      XGpio_mReadReg to XGpio_ReadReg.
+*		      Removed the macros XGpio_mSetDataDirection,
+*		      XGpio_mGetDataReg and XGpio_mSetDataReg. Users
+*		      should use XGpio_WriteReg/XGpio_ReadReg to achieve the
+*		      same functionality.
+* 4.1  lks   11/18/15 Removed support for DCR bridge
+* 
+* +******************************************************************************/ + +#ifndef XGPIO_L_H /* prevent circular inclusions */ +#define XGPIO_L_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 XGPIO_DATA_OFFSET 0x0 /**< Data register for 1st channel */ +#define XGPIO_TRI_OFFSET 0x4 /**< I/O direction reg for 1st channel */ +#define XGPIO_DATA2_OFFSET 0x8 /**< Data register for 2nd channel */ +#define XGPIO_TRI2_OFFSET 0xC /**< I/O direction reg for 2nd channel */ + +#define XGPIO_GIE_OFFSET 0x11C /**< Glogal interrupt enable register */ +#define XGPIO_ISR_OFFSET 0x120 /**< Interrupt status register */ +#define XGPIO_IER_OFFSET 0x128 /**< Interrupt enable register */ + +/* @} */ + +/* The following constant describes the offset of each channels data and + * tristate register from the base address. + */ +#define XGPIO_CHAN_OFFSET 8 + +/** @name Interrupt Status and Enable Register bitmaps and masks + * + * Bit definitions for the interrupt status register and interrupt enable + * registers. + * @{ + */ +#define XGPIO_IR_MASK 0x3 /**< Mask of all bits */ +#define XGPIO_IR_CH1_MASK 0x1 /**< Mask for the 1st channel */ +#define XGPIO_IR_CH2_MASK 0x2 /**< Mask for the 2nd channel */ +/*@}*/ + + +/** @name Global Interrupt Enable Register bitmaps and masks + * + * Bit definitions for the Global Interrupt Enable register + * @{ + */ +#define XGPIO_GIE_GINTR_ENABLE_MASK 0x80000000 +/*@}*/ + + + +/**************************** Type Definitions *******************************/ + + +/***************** Macros (Inline Functions) Definitions *********************/ + +#define XGpio_In32 Xil_In32 +#define XGpio_Out32 Xil_Out32 + + +/****************************************************************************/ +/** +* +* Write a value to a GPIO register. A 32 bit write is performed. If the +* GPIO core is implemented in a smaller width, only the least significant data +* is written. +* +* @param BaseAddress is the base address of the GPIO device. +* @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 XGpio_WriteReg(u32 BaseAddress, u32 RegOffset, u32 Data) +* +****************************************************************************/ +#define XGpio_WriteReg(BaseAddress, RegOffset, Data) \ + XGpio_Out32((BaseAddress) + (RegOffset), (u32)(Data)) + +/****************************************************************************/ +/** +* +* Read a value from a GPIO register. A 32 bit read is performed. If the +* GPIO core 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 BaseAddress is the base address of the GPIO device. +* @param RegOffset is the register offset from the base to read from. +* +* @return Data read from the register. +* +* @note C-style signature: +* u32 XGpio_ReadReg(u32 BaseAddress, u32 RegOffset) +* +****************************************************************************/ +#define XGpio_ReadReg(BaseAddress, RegOffset) \ + XGpio_In32((BaseAddress) + (RegOffset)) + +/************************** Function Prototypes ******************************/ + +/************************** Variable Definitions *****************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/df_datalink_ge/bsp/ps7_cortexa9_0/include/xgpiops.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xgpiops.h new file mode 100644 index 0000000..d0ff132 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xgpiops_hw.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xgpiops_hw.h new file mode 100644 index 0000000..599c7db --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xil_assert.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xil_assert.h new file mode 100644 index 0000000..917de31 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xil_cache.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xil_cache.h new file mode 100644 index 0000000..ce6fcf4 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xil_cache_l.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xil_cache_l.h new file mode 100644 index 0000000..b6ff809 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xil_cache_vxworks.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xil_cache_vxworks.h new file mode 100644 index 0000000..7e2a7d9 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xil_errata.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xil_errata.h new file mode 100644 index 0000000..c839b63 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xil_exception.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xil_exception.h new file mode 100644 index 0000000..807f310 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xil_hal.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xil_hal.h new file mode 100644 index 0000000..e8971c9 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xil_io.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xil_io.h new file mode 100644 index 0000000..00207cf --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xil_macroback.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xil_macroback.h new file mode 100644 index 0000000..b245c18 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xil_mem.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xil_mem.h new file mode 100644 index 0000000..9aae942 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xil_misc_psreset_api.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xil_misc_psreset_api.h new file mode 100644 index 0000000..3a26175 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xil_mmu.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xil_mmu.h new file mode 100644 index 0000000..3b63c0b --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xil_printf.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xil_printf.h new file mode 100644 index 0000000..a0177fc --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xil_sleeptimer.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xil_sleeptimer.h new file mode 100644 index 0000000..08f64ba --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xil_testcache.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xil_testcache.h new file mode 100644 index 0000000..8289ca9 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xil_testio.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xil_testio.h new file mode 100644 index 0000000..6f0fc1c --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xil_testmem.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xil_testmem.h new file mode 100644 index 0000000..ecce6b7 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xil_types.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xil_types.h new file mode 100644 index 0000000..625ff8c --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xil_util.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xil_util.h new file mode 100644 index 0000000..194c425 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xl2cc.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xl2cc.h new file mode 100644 index 0000000..22373c1 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xl2cc_counter.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xl2cc_counter.h new file mode 100644 index 0000000..b8d768f --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xparameters.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xparameters.h new file mode 100644 index 0000000..a0d32f0 --- /dev/null +++ b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xparameters.h @@ -0,0 +1,564 @@ +#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 TMC */ +#define XPAR_TMC_BASEADDR 0x43C40000 +#define XPAR_TMC_HIGHADDR 0x43C4FFFF + + +/* Definitions for interface PHYC */ +#define XPAR_PHYC_BASEADDR 0x43C60000 +#define XPAR_PHYC_HIGHADDR 0x43C60FFF + +#include "xparameters_ps.h" + +#define STDIN_BASEADDRESS 0xE0001000 +#define STDOUT_BASEADDRESS 0xE0001000 + +/******************************************************************/ + +/* 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 4U + +/* Definitions for peripheral MPC_BRAM_INTERFACE_MPC_BRAM_CTRL */ +#define XPAR_MPC_BRAM_INTERFACE_MPC_BRAM_CTRL_DEVICE_ID 0U +#define XPAR_MPC_BRAM_INTERFACE_MPC_BRAM_CTRL_DATA_WIDTH 32U +#define XPAR_MPC_BRAM_INTERFACE_MPC_BRAM_CTRL_ECC 0U +#define XPAR_MPC_BRAM_INTERFACE_MPC_BRAM_CTRL_FAULT_INJECT 0U +#define XPAR_MPC_BRAM_INTERFACE_MPC_BRAM_CTRL_CE_FAILING_REGISTERS 0U +#define XPAR_MPC_BRAM_INTERFACE_MPC_BRAM_CTRL_UE_FAILING_REGISTERS 0U +#define XPAR_MPC_BRAM_INTERFACE_MPC_BRAM_CTRL_ECC_STATUS_REGISTERS 0U +#define XPAR_MPC_BRAM_INTERFACE_MPC_BRAM_CTRL_CE_COUNTER_WIDTH 0U +#define XPAR_MPC_BRAM_INTERFACE_MPC_BRAM_CTRL_ECC_ONOFF_REGISTER 0U +#define XPAR_MPC_BRAM_INTERFACE_MPC_BRAM_CTRL_ECC_ONOFF_RESET_VALUE 0U +#define XPAR_MPC_BRAM_INTERFACE_MPC_BRAM_CTRL_WRITE_ACCESS 0U +#define XPAR_MPC_BRAM_INTERFACE_MPC_BRAM_CTRL_S_AXI_BASEADDR 0x44000000U +#define XPAR_MPC_BRAM_INTERFACE_MPC_BRAM_CTRL_S_AXI_HIGHADDR 0x44007FFFU +#define XPAR_MPC_BRAM_INTERFACE_MPC_BRAM_CTRL_S_AXI_CTRL_BASEADDR 0xFFFFFFFFU +#define XPAR_MPC_BRAM_INTERFACE_MPC_BRAM_CTRL_S_AXI_CTRL_HIGHADDR 0xFFFFFFFFU + + +/* Definitions for peripheral PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL */ +#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_DEVICE_ID 1U +#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_DATA_WIDTH 32U +#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_ECC 0U +#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_FAULT_INJECT 0U +#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_CE_FAILING_REGISTERS 0U +#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_UE_FAILING_REGISTERS 0U +#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_ECC_STATUS_REGISTERS 0U +#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_CE_COUNTER_WIDTH 0U +#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_ECC_ONOFF_REGISTER 0U +#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_ECC_ONOFF_RESET_VALUE 0U +#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_WRITE_ACCESS 0U +#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_S_AXI_BASEADDR 0x42000000U +#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_S_AXI_HIGHADDR 0x42001FFFU +#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_S_AXI_CTRL_BASEADDR 0xFFFFFFFFU +#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_S_AXI_CTRL_HIGHADDR 0xFFFFFFFFU + + +/* Definitions for peripheral PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL */ +#define XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_DEVICE_ID 2U +#define XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_DATA_WIDTH 32U +#define XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_ECC 0U +#define XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_FAULT_INJECT 0U +#define XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_CE_FAILING_REGISTERS 0U +#define XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_UE_FAILING_REGISTERS 0U +#define XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_ECC_STATUS_REGISTERS 0U +#define XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_CE_COUNTER_WIDTH 0U +#define XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_ECC_ONOFF_REGISTER 0U +#define XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_ECC_ONOFF_RESET_VALUE 0U +#define XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_WRITE_ACCESS 0U +#define XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_S_AXI_BASEADDR 0x46000000U +#define XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_S_AXI_HIGHADDR 0x46001FFFU +#define XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_S_AXI_CTRL_BASEADDR 0xFFFFFFFFU +#define XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_S_AXI_CTRL_HIGHADDR 0xFFFFFFFFU + + +/* Definitions for peripheral PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL */ +#define XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_DEVICE_ID 3U +#define XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_DATA_WIDTH 32U +#define XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_ECC 0U +#define XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_FAULT_INJECT 0U +#define XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_CE_FAILING_REGISTERS 0U +#define XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_UE_FAILING_REGISTERS 0U +#define XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_ECC_STATUS_REGISTERS 0U +#define XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_CE_COUNTER_WIDTH 0U +#define XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_ECC_ONOFF_REGISTER 0U +#define XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_ECC_ONOFF_RESET_VALUE 0U +#define XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_WRITE_ACCESS 0U +#define XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_S_AXI_BASEADDR 0x40000000U +#define XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_S_AXI_HIGHADDR 0x40001FFFU +#define XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_S_AXI_CTRL_BASEADDR 0xFFFFFFFFU +#define XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_S_AXI_CTRL_HIGHADDR 0xFFFFFFFFU + + +/******************************************************************/ + +/* Canonical definitions for peripheral MPC_BRAM_INTERFACE_MPC_BRAM_CTRL */ +#define XPAR_BRAM_0_DEVICE_ID XPAR_MPC_BRAM_INTERFACE_MPC_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 0x44007FFFU +#define XPAR_BRAM_0_CTRL_BASEADDR 0xFFFFFFFFU +#define XPAR_BRAM_0_CTRL_HIGHADDR 0xFFFFFFFEU + +/* Canonical definitions for peripheral PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL */ +#define XPAR_BRAM_1_DEVICE_ID XPAR_PHY_DATA_INTERFACE_ANT_INFO_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 0x42000000U +#define XPAR_BRAM_1_HIGHADDR 0x42001FFFU +#define XPAR_BRAM_1_CTRL_BASEADDR 0xFFFFFFFFU +#define XPAR_BRAM_1_CTRL_HIGHADDR 0xFFFFFFFEU + +/* Canonical definitions for peripheral PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL */ +#define XPAR_BRAM_2_DEVICE_ID XPAR_PHY_DATA_INTERFACE_RX_FRAME_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 0x46000000U +#define XPAR_BRAM_2_HIGHADDR 0x46001FFFU +#define XPAR_BRAM_2_CTRL_BASEADDR 0xFFFFFFFFU +#define XPAR_BRAM_2_CTRL_HIGHADDR 0xFFFFFFFEU + +/* Canonical definitions for peripheral PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL */ +#define XPAR_BRAM_3_DEVICE_ID XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_DEVICE_ID +#define XPAR_BRAM_3_DATA_WIDTH 32U +#define XPAR_BRAM_3_ECC 0U +#define XPAR_BRAM_3_FAULT_INJECT 0U +#define XPAR_BRAM_3_CE_FAILING_REGISTERS 0U +#define XPAR_BRAM_3_UE_FAILING_REGISTERS 0U +#define XPAR_BRAM_3_ECC_STATUS_REGISTERS 0U +#define XPAR_BRAM_3_CE_COUNTER_WIDTH 0U +#define XPAR_BRAM_3_ECC_ONOFF_REGISTER 0U +#define XPAR_BRAM_3_ECC_ONOFF_RESET_VALUE 0U +#define XPAR_BRAM_3_WRITE_ACCESS 0U +#define XPAR_BRAM_3_BASEADDR 0x40000000U +#define XPAR_BRAM_3_HIGHADDR 0x40001FFFU +#define XPAR_BRAM_3_CTRL_BASEADDR 0xFFFFFFFFU +#define XPAR_BRAM_3_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 JESD_JESD204_PHY */ +#define XPAR_JESD_JESD204_PHY_BASEADDR 0x43C00000 +#define XPAR_JESD_JESD204_PHY_HIGHADDR 0x43C0FFFF + + +/* Definitions for peripheral JESD_JESD204_RX */ +#define XPAR_JESD_JESD204_RX_BASEADDR 0x43C10000 +#define XPAR_JESD_JESD204_RX_HIGHADDR 0x43C1FFFF + + +/* Definitions for peripheral JESD_JESD204_TX */ +#define XPAR_JESD_JESD204_TX_BASEADDR 0x43C20000 +#define XPAR_JESD_JESD204_TX_HIGHADDR 0x43C2FFFF + + +/* 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 driver GPIO */ +#define XPAR_XGPIO_NUM_INSTANCES 1 + +/* Definitions for peripheral CONFIG_GPIO */ +#define XPAR_CONFIG_GPIO_BASEADDR 0x41200000 +#define XPAR_CONFIG_GPIO_HIGHADDR 0x4120FFFF +#define XPAR_CONFIG_GPIO_DEVICE_ID 0 +#define XPAR_CONFIG_GPIO_INTERRUPT_PRESENT 0 +#define XPAR_CONFIG_GPIO_IS_DUAL 1 + + +/******************************************************************/ + +/* Canonical definitions for peripheral CONFIG_GPIO */ +#define XPAR_GPIO_0_BASEADDR 0x41200000 +#define XPAR_GPIO_0_HIGHADDR 0x4120FFFF +#define XPAR_GPIO_0_DEVICE_ID XPAR_CONFIG_GPIO_DEVICE_ID +#define XPAR_GPIO_0_INTERRUPT_PRESENT 0 +#define XPAR_GPIO_0_IS_DUAL 1 + + +/******************************************************************/ + +/* 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_PHY_IRQ_INTR 61U +#define XPAR_FABRIC_FRAME_UART_0_RX_INTR_INTR 62U +#define XPAR_FABRIC_FRAME_UART_0_TX_INTR_INTR 63U +#define XPAR_FABRIC_MPC_IRQ_INTR 64U +#define XPAR_FABRIC_PHY_5MS_INTR 65U +#define XPAR_FABRIC_PHY_5MS_DELAY_2MS_INTR 66U + +/******************************************************************/ + +/* Canonical definitions for Fabric interrupts connected to ps7_scugic_0 */ +#define XPAR_FABRIC_FRAME_UART_0_RX_INTR_VEC_ID XPAR_FABRIC_FRAME_UART_0_RX_INTR_INTR +#define XPAR_FABRIC_FRAME_UART_0_TX_INTR_VEC_ID XPAR_FABRIC_FRAME_UART_0_TX_INTR_INTR + +/******************************************************************/ + +/* 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 SPIPS */ +#define XPAR_XSPIPS_NUM_INSTANCES 1 + +/* Definitions for peripheral PS7_SPI_0 */ +#define XPAR_PS7_SPI_0_DEVICE_ID 0 +#define XPAR_PS7_SPI_0_BASEADDR 0xE0006000 +#define XPAR_PS7_SPI_0_HIGHADDR 0xE0006FFF +#define XPAR_PS7_SPI_0_SPI_CLK_FREQ_HZ 166666672 + + +/******************************************************************/ + +/* Canonical definitions for peripheral PS7_SPI_0 */ +#define XPAR_XSPIPS_0_DEVICE_ID XPAR_PS7_SPI_0_DEVICE_ID +#define XPAR_XSPIPS_0_BASEADDR 0xE0006000 +#define XPAR_XSPIPS_0_HIGHADDR 0xE0006FFF +#define XPAR_XSPIPS_0_SPI_CLK_FREQ_HZ 166666672 + + +/******************************************************************/ + +/* Definitions for driver UARTPS */ +#define XPAR_XUARTPS_NUM_INSTANCES 1 + +/* Definitions for peripheral PS7_UART_1 */ +#define XPAR_PS7_UART_1_DEVICE_ID 0 +#define XPAR_PS7_UART_1_BASEADDR 0xE0001000 +#define XPAR_PS7_UART_1_HIGHADDR 0xE0001FFF +#define XPAR_PS7_UART_1_UART_CLK_FREQ_HZ 100000000 +#define XPAR_PS7_UART_1_HAS_MODEM 0 + + +/******************************************************************/ + +/* Canonical definitions for peripheral PS7_UART_1 */ +#define XPAR_XUARTPS_0_DEVICE_ID XPAR_PS7_UART_1_DEVICE_ID +#define XPAR_XUARTPS_0_BASEADDR 0xE0001000 +#define XPAR_XUARTPS_0_HIGHADDR 0xE0001FFF +#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_ge/bsp/ps7_cortexa9_0/include/xparameters_ps.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xparameters_ps.h new file mode 100644 index 0000000..2a6a0e0 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xplatform_info.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xplatform_info.h new file mode 100644 index 0000000..88851bb --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xpm_counter.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xpm_counter.h new file mode 100644 index 0000000..39db7d8 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xpseudo_asm.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xpseudo_asm.h new file mode 100644 index 0000000..c7123a0 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xpseudo_asm_gcc.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xpseudo_asm_gcc.h new file mode 100644 index 0000000..85b067d --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xqspips.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xqspips.h new file mode 100644 index 0000000..0255bc2 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xqspips_hw.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xqspips_hw.h new file mode 100644 index 0000000..88c232e --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xreg_cortexa9.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xreg_cortexa9.h new file mode 100644 index 0000000..ad93665 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xscugic.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xscugic.h new file mode 100644 index 0000000..5502a20 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xscugic_hw.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xscugic_hw.h new file mode 100644 index 0000000..60d111f --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xscutimer.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xscutimer.h new file mode 100644 index 0000000..5434684 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xscutimer_hw.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xscutimer_hw.h new file mode 100644 index 0000000..d577784 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xscuwdt.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xscuwdt.h new file mode 100644 index 0000000..551eaf5 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xscuwdt_hw.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xscuwdt_hw.h new file mode 100644 index 0000000..ad87a05 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xspips.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xspips.h new file mode 100644 index 0000000..1daee72 --- /dev/null +++ b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xspips.h @@ -0,0 +1,703 @@ +/****************************************************************************** +* +* 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 xspips.h +* @addtogroup spips_v3_2 +* @{ +* @details +* +* This file contains the implementation of the XSpiPs driver. It works for +* both the master and slave mode. User documentation for the driver functions +* is contained in this file in the form of comment blocks at the front of each +* function. +* +* An SPI device connects to an SPI bus through a 4-wire serial interface. +* The SPI 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. +* +* Initialization & Configuration +* +* The XSpiPs_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: +* - XSpiPs_LookupConfig(DeviceId) - Use the devide identifier to find the +* static configuration structure defined in xspips_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. +* - XSpiPs_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. +* +* Multiple Slaves +* +* Contention between multiple masters is detected by the hardware, in which +* case a mode fault occurs on the device. The device is disabled immediately +* by hardware, and the current word transfer is stopped. The Aborted word +* transfer due to the mode fault is resumed once the devie is enabled again. +* +* 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 deasserted when the TXFIFO becomes +* empty +* - Manual CS: Software must assert and deassert 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 deasserted. +* 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, +* XSpiPs_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 Full +* - Data Receive Register/FIFO Not Empty +* - Data Transmit Register/FIFO Full +* - Data Transmit Register/FIFO Overwater +* - Mode Fault Error +* - Data Receive Register/FIFO Overrun +* +* The Data Transmit Register/FIFO Overwater interrupt -- indicates that the +* SPI 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 SPI 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 SPI +* device received data and subsequently dropped the data because the data +* receive register and FIFO was full. The interrupt applies to both master +* and slave operation. 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. +* +* The Mode Fault Error interrupt -- indicates that while configured as a +* master, the device was selected as a slave by another master. This can be +* used by the application for arbitration in a multimaster environment or to +* indicate a problem with arbitration. When this interrupt occurs, the +* driver invokes the status callback with a status value of +* XST_SPI_MODE_FAULT. It is up to the application to resolve the conflict. +* When configured as a slave, Mode Fault Error interrupt indicates that a slave +* device was selected as a slave by a master, but the slave device was +* disabled. When configured as a master, Mode Fault Error interrupt indicates +* that another SPI device is acting as a master on the bus. +* +* +* Polled Operation +* +* Transfer in polled mode is supported through a separate interface function +* XSpiPs_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). This applies to both +* master and slave devices. +* +* Device Configuration +* +* The device can be configured in various ways during the FPGA implementation +* process. Configuration parameters are stored in the xspips_g.c file or +* passed in via XSpiPs_CfgInitialize(). A table is defined where each entry +* contains configuration information for an SPI 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. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date     Changes
+* ----- ------ -------- -----------------------------------------------
+* 1.00	drg/jz 01/25/10 First release
+* 1.00	sdm    10/25/11 Removed the Divide by 2 in the SPI Clock Prescaler
+*			options as this is not supported in the device.
+* 1.01	sg     03/07/12 Updated the code to always clear the relevant bits
+*			before writing to config register.
+*			Always clear the slave select bits before write and
+*			clear the bits to no slave at the end of transfer
+*			Modified the Polled transfer transmit/receive logic.
+*			Tx should wait on TXOW Interrupt and Rx on RXNEMTY.
+* 1.02	sg     05/31/12 Updated XSPIPS_FIFO_DEPTH to 128 from 32 to match HW
+*			for CR 658289
+* 1.03	sg     09/21/12 Added memory barrier dmb in polled transfer and
+*			interrupt handler to overcome the clock domain
+*			crossing issue in the controller. For CR #679252.
+* 1.04a	sg     01/30/13 Created XSPIPS_MANUAL_START_OPTION. Created macros
+*			XSpiPs_IsMaster, XSpiPs_IsManualStart and
+*			XSpiPs_IsManualChipSelect. Changed SPI
+*			Enable/Disable macro argument from BaseAddress to
+*			Instance Pointer. Added DelayNss argument to SetDelays
+*			and GetDelays API's. Added macros to set/get the
+*			RX Watermark value.Created macros XSpiPs_IsMaster,
+*			XSpiPs_IsManualStart and XSpiPs_IsManualChipSelect.
+*			Changed SPI 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.
+*			SetSlaveSelect API logic is modified to drive the bit
+*			position low based on the slave select value
+*			requested. GetSlaveSelect API will return the value
+*			based on bit position that is low.
+*			Created XSPIPS_CR_MODF_GEN_EN_MASK macro and added it
+*			to XSPIPS_CR_RESET_STATE. Created
+* 			XSPIPS_IXR_WR_TO_CLR_MASK for interrupts which need
+*			write-to-clear. Added shift and mask macros for d_nss
+*			parameter. Added Rx Watermark mask.
+* 1.05a hk 	   26/04/13 Added disable and enable in XSpiPs_SetOptions when
+*				CPOL/CPHA bits are set/reset. Fix for CR#707669.
+* 1.06a hk     08/22/13 Changed GetSlaveSelect function. CR# 727866.
+*                       Added masking ConfigReg before writing in SetSlaveSel
+*                       Added extended slave select support - CR#722569.
+*                       Added prototypes of reset API and related constant
+*                       definitions.
+*                       Added check for MODF in polled transfer function.
+* 3.0   vm    12/09/14	Modified driver source code for MISRA-C:2012 compliance.
+*			Support for Zynq Ultrascale Mp added.
+*       ms     03/17/17 Added readme.txt file in examples folder for doxygen
+*                       generation.
+*       ms     04/05/17 Modified Comment lines in functions of spips
+*                       examples to recognize it as documentation block
+*                       for doxygen generation and also modified filename tag
+*                       in eeprom interrupt, eeprom polled and flash polled
+*                       files to include them in doxygen examples.
+* 3.1	tjs    04/12/18 InputClockHz parameter copied in instance for use in
+* 						application. CR#998910
+* 3.2   aru    01/20/19 Fixes violations according to MISRAC-2012
+*                       in safety mode and done changes such as
+*                       Declared the pointer param as Pointer to const.
+* 3.2   nsk    03/26/19 Add support for versal - CR #1025583.
+* 
+* +******************************************************************************/ +#ifndef XSPIPS_H /* prevent circular inclusions */ +#define XSPIPS_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +#include "xstatus.h" +#include "xspips_hw.h" + +/************************** Constant Definitions *****************************/ + +/** @name Configuration options + * + * The following options are supported to enable/disable certain features of + * an SPI device. Each of the options is a bit mask, so more than one may be + * specified. + * + * The Master option configures the SPI device as a master. + * By default, the device is a slave. + * + * 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 SPI 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 Slave Select Decode Enable option selects how the SPI_SS_outN are + * controlled by the SPI Slave Select Decode bits. + * 0: Use this setting for the standard configuration of up to three slave + * select outputs. Only one of the three slave select outputs will be low. + * (Default) + * 1: Use this setting for the optional configuration of an additional decoder + * to support 8 slave select outputs. SPI_SS_outN reflects the value in the + * register. + * + * The SPI Force Slave Select option is used to enable manual control of + * the signals SPI_SS_outN. + * 0: The SPI_SS_outN signals are controlled by the SPI controller during + * transfers. (Default) + * 1: The SPI_SS_outN signal indicated by the Slave Select Control bit 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 + * SPI clock to be set to a faster speed. If the SPI clock is too fast, the + * processor cannot empty and refill the FIFOs before the TX FIFO is empty + * When the SPI 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 SPI 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 XSPIPS_MASTER_OPTION 0x00000001U /**< Master mode option */ +#define XSPIPS_CLK_ACTIVE_LOW_OPTION 0x00000002U /**< Active Low Clock option */ +#define XSPIPS_CLK_PHASE_1_OPTION 0x00000004U /**< Clock Phase one option */ +#define XSPIPS_DECODE_SSELECT_OPTION 0x00000008U /**< Select 16 slaves Option */ +#define XSPIPS_FORCE_SSELECT_OPTION 0x00000010U /**< Force Slave Select */ +#define XSPIPS_MANUAL_START_OPTION 0x00000020U /**< Manual Start mode option */ +/*@}*/ + + +/** @name SPI Clock Prescaler options + * The SPI 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/4 to pclk/256. + * + * @{ + */ + +#define XSPIPS_CLK_PRESCALE_4 0x01U /**< PCLK/4 Prescaler */ +#define XSPIPS_CLK_PRESCALE_8 0x02U /**< PCLK/8 Prescaler */ +#define XSPIPS_CLK_PRESCALE_16 0x03U /**< PCLK/16 Prescaler */ +#define XSPIPS_CLK_PRESCALE_32 0x04U /**< PCLK/32 Prescaler */ +#define XSPIPS_CLK_PRESCALE_64 0x05U /**< PCLK/64 Prescaler */ +#define XSPIPS_CLK_PRESCALE_128 0x06U /**< PCLK/128 Prescaler */ +#define XSPIPS_CLK_PRESCALE_256 0x07U /**< 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 XSPIPS_EVENT_MODE_FAULT 1U /**< Mode fault error */ +#define XSPIPS_EVENT_TRANSFER_DONE 2U /**< Transfer done */ +#define XSPIPS_EVENT_TRANSMIT_UNDERRUN 3U /**< TX FIFO empty */ +#define XSPIPS_EVENT_RECEIVE_OVERRUN 4U /**< Receive data loss because + RX FIFO full */ +/*@}*/ + + +/**************************** Type Definitions *******************************/ +/** + * The handler data type allows the user to define a callback function to + * handle the asynchronous processing for the SPI 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 XSpiPs_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 (*XSpiPs_StatusHandler) (const void *CallBackRef, u32 StatusEvent, + u32 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 */ +} XSpiPs_Config; + +/** + * The XSpiPs driver instance data. The user is required to allocate a + * variable of this type for every SPI device in the system. A pointer + * to a variable of this type is then passed to the driver API functions. + */ +typedef struct { + XSpiPs_Config Config; /**< Configuration structure */ + u32 IsReady; /**< Device is initialized and ready */ + + u8 *SendBufferPtr; /**< Buffer to send (state) */ + u8 *RecvBufferPtr; /**< Buffer to receive (state) */ + u32 RequestedBytes; /**< Number of bytes to transfer (state) */ + u32 RemainingBytes; /**< Number of bytes left to transfer(state) */ + u32 IsBusy; /**< A transfer is in progress (state) */ + u32 SlaveSelect; /**< The slave select value when + XSPIPS_FORCE_SSELECT_OPTION is set */ + + XSpiPs_StatusHandler StatusHandler; + void *StatusRef; /**< Callback reference for status handler */ + +} XSpiPs; + +/***************** Macros (Inline Functions) Definitions *********************/ +/****************************************************************************/ +/* +* +* Check in OptionsTable if Manual Start 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 XSpiPs_IsManualStart(XSpiPs *InstancePtr) +* +*****************************************************************************/ +#define XSpiPs_IsManualStart(InstancePtr) \ + (((XSpiPs_GetOptions(InstancePtr) & \ + XSPIPS_MANUAL_START_OPTION) != (u32)0U) ? 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 XSpiPs_IsManualChipSelect(XSpiPs *InstancePtr) +* +*****************************************************************************/ +#define XSpiPs_IsManualChipSelect(InstancePtr) \ + (((XSpiPs_GetOptions(InstancePtr) & \ + XSPIPS_FORCE_SSELECT_OPTION) != (u32)0U) ? TRUE : FALSE) + +/****************************************************************************/ +/* +* +* Check in OptionsTable if Decode Slave 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 XSpiPs_IsDecodeSSelect(XSpiPs *InstancePtr) +* +*****************************************************************************/ +#define XSpiPs_IsDecodeSSelect(InstancePtr) \ + (((XSpiPs_GetOptions(InstancePtr) & \ + XSPIPS_DECODE_SSELECT_OPTION) != (u32)0U) ? TRUE : FALSE) + +/****************************************************************************/ +/* +* +* Check in OptionsTable if Master 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 XSpiPs_IsMaster(XSpiPs *InstancePtr) +* +*****************************************************************************/ +#define XSpiPs_IsMaster(InstancePtr) \ + (((XSpiPs_GetOptions(InstancePtr) & \ + XSPIPS_MASTER_OPTION) != (u32)0U) ? TRUE : FALSE) + +/****************************************************************************/ +/** +* +* Set the contents of the slave idle count register. +* +* @param InstancePtr is a pointer to the XSpiPs instance. +* @param RegisterValue is the value to be writen, valid values are +* 0-255. +* +* @return None +* +* @note +* C-Style signature: +* void XSpiPs_SetSlaveIdle(XSpiPs *InstancePtr, u32 RegisterValue) +* +*****************************************************************************/ +#define XSpiPs_SetSlaveIdle(InstancePtr, RegisterValue) \ + XSpiPs_Out32(((InstancePtr)->Config.BaseAddress) + \ + XSPIPS_SICR_OFFSET, (RegisterValue)) + +/****************************************************************************/ +/** +* +* Get the contents of the slave idle count register. Use the XSPIPS_SICR_* +* constants defined in xspips_hw.h to interpret the bit-mask returned. +* +* @param InstancePtr is a pointer to the XSpiPs instance. +* +* @return 8-bit value representing the contents of the SIC register. +* +* @note C-Style signature: +* u32 XSpiPs_GetSlaveIdle(XSpiPs *InstancePtr) +* +*****************************************************************************/ +#define XSpiPs_GetSlaveIdle(InstancePtr) \ + XSpiPs_In32(((InstancePtr)->Config.BaseAddress) + \ + XSPIPS_SICR_OFFSET) + +/****************************************************************************/ +/** +* +* Set the contents of the transmit FIFO watermark register. +* +* @param InstancePtr is a pointer to the XSpiPs instance. +* @param RegisterValue is the value to be written, valid values +* are 1-128. +* +* @return None. +* +* @note +* C-Style signature: +* void XSpiPs_SetTXWatermark(XSpiPs *InstancePtr, u32 RegisterValue) +* +*****************************************************************************/ +#define XSpiPs_SetTXWatermark(InstancePtr, RegisterValue) \ + XSpiPs_Out32(((InstancePtr)->Config.BaseAddress) + \ + XSPIPS_TXWR_OFFSET, (RegisterValue)) + +/****************************************************************************/ +/** +* +* Get the contents of the transmit FIFO watermark register. +* Use the XSPIPS_TXWR_* constants defined xspips_hw.h to interpret +* the bit-mask returned. +* +* @param InstancePtr is a pointer to the XSpiPs instance. +* +* @return 8-bit value representing the contents of the TXWR register. +* +* @note C-Style signature: +* u32 XSpiPs_GetTXWatermark(u32 *InstancePtr) +* +*****************************************************************************/ +#define XSpiPs_GetTXWatermark(InstancePtr) \ + XSpiPs_In32(((InstancePtr)->Config.BaseAddress) + XSPIPS_TXWR_OFFSET) + +/****************************************************************************/ +/** +* +* Set the contents of the receive FIFO watermark register. +* +* @param InstancePtr is a pointer to the XSpiPs instance. +* @param RegisterValue is the value to be written, valid values +* are 1-128. +* +* @return None. +* +* @note +* C-Style signature: +* void XSpiPs_SetRXWatermark(XSpiPs *InstancePtr, u32 RegisterValue) +* +*****************************************************************************/ +#define XSpiPs_SetRXWatermark(InstancePtr, RegisterValue) \ + XSpiPs_Out32(((InstancePtr)->Config.BaseAddress) + \ + XSPIPS_RXWR_OFFSET, (RegisterValue)) + +/****************************************************************************/ +/** +* +* Get the contents of the receive FIFO watermark register. +* Use the XSPIPS_RXWR_* constants defined xspips_hw.h to interpret +* the bit-mask returned. +* +* @param InstancePtr is a pointer to the XSpiPs instance. +* +* @return A 8-bit value representing the contents of the RXWR register. +* +* @note C-Style signature: +* u32 XSpiPs_GetRXWatermark(u32 *InstancePtr) +* +*****************************************************************************/ +#define XSpiPs_GetRXWatermark(InstancePtr) \ + XSpiPs_In32(((InstancePtr)->Config.BaseAddress) + XSPIPS_RXWR_OFFSET) + +/****************************************************************************/ +/** +* +* Enable the device and uninhibit master transactions. +* +* @param InstancePtr is a pointer to the XSpiPs instance. +* +* @return None. +* +* @note C-Style signature: +* void XSpiPs_Enable(u32 *InstancePtr) +* +*****************************************************************************/ +#define XSpiPs_Enable(InstancePtr) \ + XSpiPs_Out32(((InstancePtr)->Config.BaseAddress) + XSPIPS_ER_OFFSET, \ + XSPIPS_ER_ENABLE_MASK) + +/****************************************************************************/ +/** +* +* Disable the device. +* +* @param InstancePtr is a pointer to the XSpiPs instance. +* +* @return None. +* +* @note C-Style signature: +* void XSpiPs_Disable(u32 *InstancePtr) +* +*****************************************************************************/ +#define XSpiPs_Disable(InstancePtr) \ + XSpiPs_Out32(((InstancePtr)->Config.BaseAddress) + XSPIPS_ER_OFFSET, 0U) + +/************************** Function Prototypes ******************************/ + +/* + * Initialization function, implemented in xspips_sinit.c + */ +XSpiPs_Config *XSpiPs_LookupConfig(u16 DeviceId); + +/* + * Functions implemented in xspips.c + */ +s32 XSpiPs_CfgInitialize(XSpiPs *InstancePtr, const XSpiPs_Config * ConfigPtr, + u32 EffectiveAddr); + +void XSpiPs_Reset(XSpiPs *InstancePtr); + +s32 XSpiPs_Transfer(XSpiPs *InstancePtr, u8 *SendBufPtr, u8 *RecvBufPtr, + u32 ByteCount); + +s32 XSpiPs_PolledTransfer(XSpiPs *InstancePtr, u8 *SendBufPtr, + u8 *RecvBufPtr, u32 ByteCount); + +void XSpiPs_SetStatusHandler(XSpiPs *InstancePtr, void *CallBackRef, + XSpiPs_StatusHandler FunctionPtr); +void XSpiPs_InterruptHandler(XSpiPs *InstancePtr); + +void XSpiPs_Abort(XSpiPs *InstancePtr); + +s32 XSpiPs_SetSlaveSelect(XSpiPs *InstancePtr, u8 SlaveSel); +u8 XSpiPs_GetSlaveSelect(const XSpiPs *InstancePtr); + +/* + * Functions for selftest, in xspips_selftest.c + */ +s32 XSpiPs_SelfTest(XSpiPs *InstancePtr); + +/* + * Functions for options, in xspips_options.c + */ +s32 XSpiPs_SetOptions(const XSpiPs *InstancePtr, u32 Options); +u32 XSpiPs_GetOptions(const XSpiPs *InstancePtr); + +s32 XSpiPs_SetClkPrescaler(const XSpiPs *InstancePtr, u8 Prescaler); +u8 XSpiPs_GetClkPrescaler(const XSpiPs *InstancePtr); + +s32 XSpiPs_SetDelays(const XSpiPs *InstancePtr, u8 DelayNss, u8 DelayBtwn, + u8 DelayAfter, u8 DelayInit); +void XSpiPs_GetDelays(const XSpiPs *InstancePtr, u8 *DelayNss, u8 *DelayBtwn, + u8 *DelayAfter, u8 *DelayInit); +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/df_datalink_ge/bsp/ps7_cortexa9_0/include/xspips_hw.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xspips_hw.h new file mode 100644 index 0000000..07b0687 --- /dev/null +++ b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xspips_hw.h @@ -0,0 +1,309 @@ +/****************************************************************************** +* +* 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 xspips_hw.h +* @addtogroup spips_v3_2 +* @{ +* +* 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 xspips.h. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date     Changes
+* ----- ------ -------- -----------------------------------------------
+* 1.00   drg/jz 01/25/10 First release
+* 1.02a  sg     05/31/12 Updated XSPIPS_FIFO_DEPTH to 128 from 32 to match HW
+*			 for CR 658289
+* 1.04a	 sg     01/30/13 Created XSPIPS_CR_MODF_GEN_EN_MASK macro and added it
+*			 to XSPIPS_CR_RESET_STATE. Created
+* 			 XSPIPS_IXR_WR_TO_CLR_MASK for interrupts which need
+*			 write-to-clear. Added shift and mask macros for d_nss
+*			 parameter. Added Rx Watermark mask.
+* 1.06a hk      08/22/13 Added prototypes of reset API and related constant
+*                        definitions.
+* 3.00  kvn     02/13/15 Modified code for MISRA-C:2012 compliance.
+*
+* 
+* +******************************************************************************/ + +#ifndef XSPIPS_HW_H /* prevent circular inclusions */ +#define XSPIPS_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 from the base address of an SPI device. + * @{ + */ +#define XSPIPS_CR_OFFSET 0x00U /**< Configuration */ +#define XSPIPS_SR_OFFSET 0x04U /**< Interrupt Status */ +#define XSPIPS_IER_OFFSET 0x08U /**< Interrupt Enable */ +#define XSPIPS_IDR_OFFSET 0x0CU /**< Interrupt Disable */ +#define XSPIPS_IMR_OFFSET 0x10U /**< Interrupt Enabled Mask */ +#define XSPIPS_ER_OFFSET 0x14U /**< Enable/Disable Register */ +#define XSPIPS_DR_OFFSET 0x18U /**< Delay Register */ +#define XSPIPS_TXD_OFFSET 0x1CU /**< Data Transmit Register */ +#define XSPIPS_RXD_OFFSET 0x20U /**< Data Receive Register */ +#define XSPIPS_SICR_OFFSET 0x24U /**< Slave Idle Count */ +#define XSPIPS_TXWR_OFFSET 0x28U /**< Transmit FIFO Watermark */ +#define XSPIPS_RXWR_OFFSET 0x2CU /**< Receive FIFO Watermark */ +/* @} */ + +/** @name Configuration Register + * + * This register contains various control bits that + * affects the operation of an SPI device. Read/Write. + * @{ + */ +#define XSPIPS_CR_MODF_GEN_EN_MASK 0x00020000U /**< Modefail Generation + Enable */ +#define XSPIPS_CR_MANSTRT_MASK 0x00010000U /**< Manual Transmission Start */ +#define XSPIPS_CR_MANSTRTEN_MASK 0x00008000U /**< Manual Transmission Start + Enable */ +#define XSPIPS_CR_SSFORCE_MASK 0x00004000U /**< Force Slave Select */ +#define XSPIPS_CR_SSCTRL_MASK 0x00003C00U /**< Slave Select Decode */ +#define XSPIPS_CR_SSCTRL_SHIFT 10U /**< Slave Select Decode shift */ +#define XSPIPS_CR_SSCTRL_MAXIMUM 0xFU /**< Slave Select maximum value */ +#define XSPIPS_CR_SSDECEN_MASK 0x00000200U /**< Slave Select Decode Enable */ + +#define XSPIPS_CR_PRESC_MASK 0x00000038U /**< Prescaler Setting */ +#define XSPIPS_CR_PRESC_SHIFT 3U /**< Prescaler shift */ +#define XSPIPS_CR_PRESC_MAXIMUM 0x07U /**< Prescaler maximum value */ + +#define XSPIPS_CR_CPHA_MASK 0x00000004U /**< Phase Configuration */ +#define XSPIPS_CR_CPOL_MASK 0x00000002U /**< Polarity Configuration */ + +#define XSPIPS_CR_MSTREN_MASK 0x00000001U /**< Master Mode Enable */ +#define XSPIPS_CR_RESET_STATE 0x00020000U /**< Mode Fail Generation Enable */ +/* @} */ + + +/** @name SPI Interrupt Registers + * + * SPI Status Register + * + * This register holds the interrupt status flags for an SPI 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. + * + * SPI Interrupt Enable Register + * + * This register is used to enable chosen interrupts for an SPI device. + * Writing a '1' to a bit in this register sets the corresponding bit in the + * SPI Interrupt Mask register. Write only. + * + * SPI Interrupt Disable Register + * + * This register is used to disable chosen interrupts for an SPI device. + * Writing a '1' to a bit in this register clears the corresponding bit in the + * SPI Interrupt Mask register. Write only. + * + * SPI Interrupt Mask Register + * + * This register shows the enabled/disabled interrupts of an SPI 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 XSPIPS_IXR_TXUF_MASK 0x00000040U /**< Tx FIFO Underflow */ +#define XSPIPS_IXR_RXFULL_MASK 0x00000020U /**< Rx FIFO Full */ +#define XSPIPS_IXR_RXNEMPTY_MASK 0x00000010U /**< Rx FIFO Not Empty */ +#define XSPIPS_IXR_TXFULL_MASK 0x00000008U /**< Tx FIFO Full */ +#define XSPIPS_IXR_TXOW_MASK 0x00000004U /**< Tx FIFO Overwater */ +#define XSPIPS_IXR_MODF_MASK 0x00000002U /**< Mode Fault */ +#define XSPIPS_IXR_RXOVR_MASK 0x00000001U /**< Rx FIFO Overrun */ +#define XSPIPS_IXR_DFLT_MASK 0x00000027U /**< Default interrupts + mask */ +#define XSPIPS_IXR_WR_TO_CLR_MASK 0x00000043U /**< Interrupts which + need write to clear */ +#define XSPIPS_ISR_RESET_STATE 0x04U /**< Default to tx/rx + * reg empty */ +#define XSPIPS_IXR_DISABLE_ALL_MASK 0x00000043U /**< Disable all + * interrupts */ +/* @} */ + + +/** @name Enable Register + * + * This register is used to enable or disable an SPI device. + * Read/Write + * @{ + */ +#define XSPIPS_ER_ENABLE_MASK 0x00000001U /**< SPI Enable Bit Mask */ +/* @} */ + + +/** @name Delay Register + * + * This register is used to program timing delays in + * slave mode. Read/Write + * @{ + */ +#define XSPIPS_DR_NSS_MASK 0xFF000000U /**< Delay for slave select + * de-assertion between + * word transfers mask */ +#define XSPIPS_DR_NSS_SHIFT 24U /**< Delay for slave select + * de-assertion between + * word transfers shift */ +#define XSPIPS_DR_BTWN_MASK 0x00FF0000U /**< Delay Between Transfers mask */ +#define XSPIPS_DR_BTWN_SHIFT 16U /**< Delay Between Transfers shift */ +#define XSPIPS_DR_AFTER_MASK 0x0000FF00U /**< Delay After Transfers mask */ +#define XSPIPS_DR_AFTER_SHIFT 8U /**< Delay After Transfers shift */ +#define XSPIPS_DR_INIT_MASK 0x000000FFU /**< Delay Initially mask */ +/* @} */ + + +/** @name Slave Idle Count Registers + * + * This register defines the number of pclk cycles the slave waits for a the + * SPI clock to become stable in quiescent state before it can detect the start + * of the next transfer in CPHA = 1 mode. + * Read/Write + * + * @{ + */ +#define XSPIPS_SICR_MASK 0x000000FFU /**< Slave Idle Count Mask */ +/* @} */ + + + +/** @name Transmit FIFO Watermark Register + * + * This register defines the watermark setting for the Transmit FIFO. The + * transmit FIFO is 128 bytes deep, so the register is 7 bits. Valid values + * are 1 to 128. + * + * @{ + */ +#define XSPIPS_TXWR_MASK 0x0000007FU /**< Transmit Watermark Mask */ +#define XSPIPS_TXWR_RESET_VALUE 0x00000001U /**< Transmit Watermark + * register reset value */ +/* @} */ + +/** @name Receive FIFO Watermark Register + * + * This register defines the watermark setting for the Receive FIFO. The + * receive FIFO is 128 bytes deep, so the register is 7 bits. Valid values + * are 1 to 128. + * + * @{ + */ +#define XSPIPS_RXWR_MASK 0x0000007FU /**< Receive Watermark Mask */ +#define XSPIPS_RXWR_RESET_VALUE 0x00000001U /**< Receive Watermark + * register reset value */ +/* @} */ + +/** @name FIFO Depth + * + * This macro provides the depth of transmit FIFO and receive FIFO. + * + * @{ + */ +#define XSPIPS_FIFO_DEPTH 128U /**< FIFO depth of Tx and Rx */ +/* @} */ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +#define XSpiPs_In32 Xil_In32 +#define XSpiPs_Out32 Xil_Out32 + +/****************************************************************************/ +/** +* 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 XSpiPs_ReadReg(u32 BaseAddress. int RegOffset) +* +******************************************************************************/ +#define XSpiPs_ReadReg(BaseAddress, RegOffset) \ + XSpiPs_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 XSpiPs_WriteReg(u32 BaseAddress, int RegOffset, +* u32 RegisterValue) +* +******************************************************************************/ +#define XSpiPs_WriteReg(BaseAddress, RegOffset, RegisterValue) \ + XSpiPs_Out32((BaseAddress) + (RegOffset), (RegisterValue)) + +/************************** Function Prototypes ******************************/ + +void XSpiPs_ResetHw(u32 BaseAddress); + +/************************** Variable Definitions *****************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/df_datalink_ge/bsp/ps7_cortexa9_0/include/xstatus.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xstatus.h new file mode 100644 index 0000000..1a212bf --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xtime_l.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xtime_l.h new file mode 100644 index 0000000..12004e1 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xuartps.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xuartps.h new file mode 100644 index 0000000..c6c2a0a --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/include/xuartps_hw.h b/df_datalink_ge/bsp/ps7_cortexa9_0/include/xuartps_hw.h new file mode 100644 index 0000000..8c46ecf --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/Makefile b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/Makefile new file mode 100644 index 0000000..dce15aa --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram.c new file mode 100644 index 0000000..0976b82 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram.h new file mode 100644 index 0000000..246df6d --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram_g.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram_g.c new file mode 100644 index 0000000..8d71ec5 --- /dev/null +++ b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram_g.c @@ -0,0 +1,123 @@ + +/******************************************************************* +* +* CAUTION: This file is automatically generated by HSI. +* Version: 2019.1.3 +* DO NOT EDIT. +* +* Copyright (C) 2010-2024 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_MPC_BRAM_INTERFACE_MPC_BRAM_CTRL_DEVICE_ID, + XPAR_MPC_BRAM_INTERFACE_MPC_BRAM_CTRL_DATA_WIDTH, + XPAR_MPC_BRAM_INTERFACE_MPC_BRAM_CTRL_ECC, + XPAR_MPC_BRAM_INTERFACE_MPC_BRAM_CTRL_FAULT_INJECT, + XPAR_MPC_BRAM_INTERFACE_MPC_BRAM_CTRL_CE_FAILING_REGISTERS, + 0, + XPAR_MPC_BRAM_INTERFACE_MPC_BRAM_CTRL_UE_FAILING_REGISTERS, + 0, + XPAR_MPC_BRAM_INTERFACE_MPC_BRAM_CTRL_ECC_STATUS_REGISTERS, + XPAR_MPC_BRAM_INTERFACE_MPC_BRAM_CTRL_CE_COUNTER_WIDTH, + XPAR_MPC_BRAM_INTERFACE_MPC_BRAM_CTRL_ECC_ONOFF_REGISTER, + XPAR_MPC_BRAM_INTERFACE_MPC_BRAM_CTRL_ECC_ONOFF_RESET_VALUE, + XPAR_MPC_BRAM_INTERFACE_MPC_BRAM_CTRL_WRITE_ACCESS, + XPAR_MPC_BRAM_INTERFACE_MPC_BRAM_CTRL_S_AXI_BASEADDR, + XPAR_MPC_BRAM_INTERFACE_MPC_BRAM_CTRL_S_AXI_HIGHADDR, + XPAR_MPC_BRAM_INTERFACE_MPC_BRAM_CTRL_S_AXI_CTRL_BASEADDR, + XPAR_MPC_BRAM_INTERFACE_MPC_BRAM_CTRL_S_AXI_CTRL_HIGHADDR + }, + { + XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_DEVICE_ID, + XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_DATA_WIDTH, + XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_ECC, + XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_FAULT_INJECT, + XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_CE_FAILING_REGISTERS, + 0, + XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_UE_FAILING_REGISTERS, + 0, + XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_ECC_STATUS_REGISTERS, + XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_CE_COUNTER_WIDTH, + XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_ECC_ONOFF_REGISTER, + XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_ECC_ONOFF_RESET_VALUE, + XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_WRITE_ACCESS, + XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_S_AXI_BASEADDR, + XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_S_AXI_HIGHADDR, + XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_S_AXI_CTRL_BASEADDR, + XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_S_AXI_CTRL_HIGHADDR + }, + { + XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_DEVICE_ID, + XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_DATA_WIDTH, + XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_ECC, + XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_FAULT_INJECT, + XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_CE_FAILING_REGISTERS, + 0, + XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_UE_FAILING_REGISTERS, + 0, + XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_ECC_STATUS_REGISTERS, + XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_CE_COUNTER_WIDTH, + XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_ECC_ONOFF_REGISTER, + XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_ECC_ONOFF_RESET_VALUE, + XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_WRITE_ACCESS, + XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_S_AXI_BASEADDR, + XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_S_AXI_HIGHADDR, + XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_S_AXI_CTRL_BASEADDR, + XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_S_AXI_CTRL_HIGHADDR + }, + { + XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_DEVICE_ID, + XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_DATA_WIDTH, + XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_ECC, + XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_FAULT_INJECT, + XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_CE_FAILING_REGISTERS, + 0, + XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_UE_FAILING_REGISTERS, + 0, + XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_ECC_STATUS_REGISTERS, + XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_CE_COUNTER_WIDTH, + XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_ECC_ONOFF_REGISTER, + XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_ECC_ONOFF_RESET_VALUE, + XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_WRITE_ACCESS, + XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_S_AXI_BASEADDR, + XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_S_AXI_HIGHADDR, + XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_S_AXI_CTRL_BASEADDR, + XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_S_AXI_CTRL_HIGHADDR + } +}; + + diff --git a/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram_hw.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram_hw.h new file mode 100644 index 0000000..55a2505 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram_intr.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram_intr.c new file mode 100644 index 0000000..50644aa --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram_selftest.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram_selftest.c new file mode 100644 index 0000000..e57e09c --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram_sinit.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/bram_v4_3/src/xbram_sinit.c new file mode 100644 index 0000000..adc560e --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/coresightps_dcc_v1_5/src/Makefile b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/coresightps_dcc_v1_5/src/Makefile new file mode 100644 index 0000000..007162d --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/coresightps_dcc_v1_5/src/xcoresightpsdcc.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/coresightps_dcc_v1_5/src/xcoresightpsdcc.c new file mode 100644 index 0000000..235eb8e --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/coresightps_dcc_v1_5/src/xcoresightpsdcc.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/coresightps_dcc_v1_5/src/xcoresightpsdcc.h new file mode 100644 index 0000000..79bde0b --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/cpu_cortexa9_v2_7/src/Makefile b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/cpu_cortexa9_v2_7/src/Makefile new file mode 100644 index 0000000..7ea505c --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/cpu_cortexa9_v2_7/src/xcpu_cortexa9.h b/df_datalink_ge/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_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/ddrps_v1_0/src/Makefile b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/ddrps_v1_0/src/Makefile new file mode 100644 index 0000000..7b191dd --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/ddrps_v1_0/src/xddrps.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/ddrps_v1_0/src/xddrps.h new file mode 100644 index 0000000..b4d1f56 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/Makefile b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/Makefile new file mode 100644 index 0000000..25ff740 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg.c new file mode 100644 index 0000000..74e1d59 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg.h new file mode 100644 index 0000000..6586370 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg_g.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg_g.c new file mode 100644 index 0000000..3f36d22 --- /dev/null +++ b/df_datalink_ge/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-2024 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_ge/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg_hw.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg_hw.c new file mode 100644 index 0000000..8a1379a --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg_hw.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg_hw.h new file mode 100644 index 0000000..80b6678 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg_intr.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg_intr.c new file mode 100644 index 0000000..f0e5044 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg_selftest.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg_selftest.c new file mode 100644 index 0000000..e8fc663 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg_sinit.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/devcfg_v3_5/src/xdevcfg_sinit.c new file mode 100644 index 0000000..838db3a --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/Makefile b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/Makefile new file mode 100644 index 0000000..d1240c5 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps.c new file mode 100644 index 0000000..b30a66f --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps.h new file mode 100644 index 0000000..73e2b1e --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps_g.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps_g.c new file mode 100644 index 0000000..8aade0c --- /dev/null +++ b/df_datalink_ge/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-2024 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_ge/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps_hw.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps_hw.c new file mode 100644 index 0000000..5fbe4ca --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps_hw.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps_hw.h new file mode 100644 index 0000000..42dfe69 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps_selftest.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps_selftest.c new file mode 100644 index 0000000..37e70f8 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps_sinit.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/dmaps_v2_4/src/xdmaps_sinit.c new file mode 100644 index 0000000..e0b6fae --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/frame_uart_v1_0/src/Makefile b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/frame_uart_v1_0/src/Makefile new file mode 100644 index 0000000..0bbff44 --- /dev/null +++ b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/frame_uart_v1_0/src/Makefile @@ -0,0 +1,26 @@ +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 + +libs: + echo "Compiling Frame_Uart..." + $(COMPILER) $(COMPILER_FLAGS) $(EXTRA_COMPILER_FLAGS) $(INCLUDES) $(LIBSOURCES) + $(ARCHIVER) -r ${RELEASEDIR}/${LIB} ${OUTS} + make clean + +include: + ${CP} $(INCLUDEFILES) $(INCLUDEDIR) + +clean: + rm -rf ${OUTS} diff --git a/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/frame_uart_v1_0/src/frame_uart.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/frame_uart_v1_0/src/frame_uart.c new file mode 100644 index 0000000..17f1674 --- /dev/null +++ b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/frame_uart_v1_0/src/frame_uart.c @@ -0,0 +1,138 @@ +/*****************************************************************************/ +/** + * Description: A brief description of this file + * + * Author: Fan Hao + * Date: 2021-12-26 10:59 + * LastEditors: Fan Hao + * LastEditTime: 2022-01-16 21:56 + * Revisions: Rev 0.0 + * History: + * [2022-01-16]: Initial version. + * + * Copyright(c) 2022 Beijing Institute of Technology. + * Lab of Communication and Networking + * + ******************************************************************************/ + +/***************************** Include Files *******************************/ +#include +#include +#include +#include +#include "frame_uart.h" + +/*************************** Function Definitions ****************************/ + +/*****************************************************************************/ +/** + * @brief Instance initial + * + * @param InstPtr A pointer to frame uart instance structure. + * @param BaseAddr Base address of frame uart, refer to "xparameters.h" + * + * @return None. + * + ******************************************************************************/ +int FrameUart_Init(FrameUart* InstPtr, u32 BaseAddr) { + Xil_AssertNonvoid(InstPtr != NULL); + InstPtr->BaseAddr = BaseAddr; + InstPtr->TxOffset = BaseAddr + FRAME_UART_TXBUFF_OFFSET; + InstPtr->RxOffset = BaseAddr + FRAME_UART_RXBUFF_OFFSET; + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** + * @brief Send a system bus frame. + * + * @param InstPtr A pointer to FrameUart instance structure. + * @param DataBuff A pointer to send data buffer + * @param DataLenByte A integer indicate the send data buffer length in byte. + * + * @return + * + ******************************************************************************/ +int FrameUart_Send(FrameUart* InstPtr, u8* DataBuff, u32 DataLenByte) { + Xil_AssertNonvoid(InstPtr != NULL); + Xil_AssertNonvoid(DataBuff != NULL); + if (DataLenByte > FRAME_UART_TXBUFF_MAX) { + return XST_FAILURE; + } + + memcpy((u8*) (InstPtr->TxOffset), (u8*) DataBuff, DataLenByte); +// Start Sending + Xil_Out32(InstPtr->BaseAddr + FRAME_UART_SEND_START_OFFSET, DataLenByte); + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** + * @brief Get last system bus frame. + * + * @param InstPtr A pointer to FrameUart instance structure. + * @param DataBuff A pointer to receive data buffer. + * + * @return + * + ******************************************************************************/ +int FrameUart_Recv(FrameUart* InstPtr, u8* DataBuff) { + Xil_AssertNonvoid(InstPtr != NULL); + Xil_AssertNonvoid(DataBuff != NULL); + + u32 Temp = 0; + u32 DataLenByte = 0; + Temp = Xil_In32(InstPtr->RxOffset) & 0xFFFF0000; + DataLenByte = (Temp >> 24) & 0x000000FF; + DataLenByte |= (Temp >> 8) & 0x0000FF00; + if (DataLenByte > FRAME_UART_RXBUFF_MAX - FRAME_UART_PROTOCOL_OVERHEAD_LEN + || DataLenByte == 0) { + return XST_FAILURE; + } + DataLenByte += FRAME_UART_PROTOCOL_OVERHEAD_LEN; + memcpy((u8*) (DataBuff), (u8*) (InstPtr->RxOffset), DataLenByte); + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** + * @brief Get rx channel status. + * + * @param InstPtr A pointer to FrameUart instance structure. + * + * @return true - FrameUart rx busy. + * false - FrameUart rx not busy. + * + ******************************************************************************/ +bool FrameUart_IsRxBusy(FrameUart* InstPtr) { + Xil_AssertNonvoid(InstPtr != NULL); + u32 Status = Xil_In32(InstPtr->BaseAddr + FRAME_UART_STATUS_OFFSET); + + if (Status & FRAME_UART_RX_BUSY) { + return true; + } + else { + return false; + } +} + +/*****************************************************************************/ +/** + * @brief Get tx channel status. + * + * @param InstPtr A pointer to FrameUart instance structure. + * + * @return true - FrameUart tx busy. + * false - FrameUart tx not busy. + * + ******************************************************************************/ +bool FrameUart_IsTxBusy(FrameUart* InstPtr) { + Xil_AssertNonvoid(InstPtr != NULL); + u32 Status = Xil_In32(InstPtr->BaseAddr + FRAME_UART_STATUS_OFFSET); + if (Status & FRAME_UART_TX_BUSY) { + return true; + } + else { + return false; + } +} diff --git a/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/frame_uart_v1_0/src/frame_uart.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/frame_uart_v1_0/src/frame_uart.h new file mode 100644 index 0000000..7c576cf --- /dev/null +++ b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/frame_uart_v1_0/src/frame_uart.h @@ -0,0 +1,128 @@ +/*****************************************************************************/ +/** + * Description: A brief description of this file + * + * Author: Fan Hao + * Date: 2021-12-26 10:59 + * LastEditors: Fan Hao + * LastEditTime: 2022-01-16 21:48 + * Revisions: Rev 0.0 + * History: + * [2021-12-26]: Initial version. + * + * Copyright(c) 2022 Beijing Institute of Technology. + * Lab of Communication and Networking + * + ******************************************************************************/ + +#ifndef FRAME_UART_H +#define FRAME_UART_H + +/****************** Include Files ********************/ +#include +#include +#include + +#define FRAME_UART_PROTOCOL_OVERHEAD_LEN 4 + +#define FRAME_UART_BYTE_PER_REG 4 +// Control register +#define FRAME_UART_SEND_START_OFFSET 0 +#define FRAME_UART_STATUS_OFFSET 4 + +// Data buffer register +#define FRAME_UART_TXBUFF_OFFSET 1024 +#define FRAME_UART_TXBUFF_MAX 1024 +#define FRAME_UART_RXBUFF_OFFSET 2048 +#define FRAME_UART_RXBUFF_MAX 2048 +#define FRAME_UART_RECV_DLEN_OFFSET 0 + +// Status +#define FRAME_UART_RX_BUSY 0x00010000 +#define FRAME_UART_TX_BUSY 0x00000001 + +/**************************** Type Definitions *****************************/ +/** + * + * Write a value to a FRAME_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 BaseAddress is the base address of the FRAME_UARTdevice. + * @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 FRAME_UART_mWriteReg(u32 BaseAddress, unsigned RegOffset, u32 Data) + * + */ +#define FRAME_UART_mWriteReg(BaseAddress, RegOffset, Data) \ + Xil_Out32((BaseAddress) + (RegOffset), (u32)(Data)) + +/** + * + * Read a value from a FRAME_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 BaseAddress is the base address of the FRAME_UART device. + * @param RegOffset is the register offset from the base to write to. + * + * @return Data is the data from the register. + * + * @note + * C-style signature: + * u32 FRAME_UART_mReadReg(u32 BaseAddress, unsigned RegOffset) + * + */ +#define FRAME_UART_mReadReg(BaseAddress, RegOffset) \ + Xil_In32((BaseAddress) + (RegOffset)) + +/************************** Function Prototypes ****************************/ +/** + * + * Run a self-test on the driver/device. Note this may be a destructive test if + * resets of the device are performed. + * + * If the hardware system is not built correctly, this function may never + * return to the caller. + * + * @param baseaddr_p is the base address of the FRAME_UART instance to be worked on. + * + * @return + * + * - XST_SUCCESS if all self-test code passed + * - XST_FAILURE if any self-test code failed + * + * @note Caching must be turned off for this function to work. + * @note Self test may fail if data memory and device are not on the same bus. + * + */ + +/************************** Data Type Definitions ****************************/ +typedef struct { + u32 BaseAddr; + u32 TxOffset; + u32 RxOffset; +} FrameUart; + +/************************** Function Prototypes ******************************/ +// Instance initial +int FrameUart_Init(FrameUart* InstPtr, u32 BaseAddr); + +// Send a system bus frame. +int FrameUart_Send(FrameUart* InstPtr, u8* DataBuff, u32 DataLenByte); + +// Get last system bus frame. +int FrameUart_Recv(FrameUart* InstPtr, u8* DataBuff); + +// Get system bus rx channel status. +bool FrameUart_IsRxBusy(FrameUart* InstPtr); + +// Get system bus tx channel status. +bool FrameUart_IsTxBusy(FrameUart* InstPtr); +#endif // FRAME_UART_H diff --git a/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpio_v4_4/src/Makefile b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpio_v4_4/src/Makefile new file mode 100644 index 0000000..a98e2a0 --- /dev/null +++ b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpio_v4_4/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 xgpio_libs clean + +%.o: %.c + ${COMPILER} $(CC_FLAGS) $(ECC_FLAGS) $(INCLUDES) -o $@ $< + +banner: + echo "Compiling gpio" + +xgpio_libs: ${OBJECTS} + $(ARCHIVER) -r ${RELEASEDIR}/${LIB} ${OBJECTS} + +.PHONY: include +include: xgpio_includes + +xgpio_includes: + ${CP} ${INCLUDEFILES} ${INCLUDEDIR} + +clean: + rm -rf ${OBJECTS} diff --git a/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpio_v4_4/src/xgpio.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpio_v4_4/src/xgpio.c new file mode 100644 index 0000000..a07e914 --- /dev/null +++ b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpio_v4_4/src/xgpio.c @@ -0,0 +1,251 @@ +/****************************************************************************** +* +* Copyright (C) 2002 - 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 xgpio.c +* @addtogroup gpio_v4_4 +* @{ +* +* The implementation of the XGpio driver's basic functionality. See xgpio.h +* for more information about the driver. +* +* @note +* +* None +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a rmm  02/04/02 First release
+* 2.00a jhl  12/16/02 Update for dual channel and interrupt support
+* 2.01a jvb  12/13/05 Changed Initialize() into CfgInitialize(), and made
+*                     CfgInitialize() take a pointer to a config structure
+*                     instead of a device id. Moved Initialize() into
+*                     xgpio_sinit.c, and had Initialize() call CfgInitialize()
+*                     after it retrieved the config structure using the device
+*                     id. Removed include of xparameters.h along with any
+*                     dependencies on xparameters.h and the _g.c config table.
+* 2.11a mta  03/21/07 Updated to new coding style, added GetDataDirection
+* 2.12a sv   11/21/07 Updated driver to support access through DCR bus
+* 3.00a sv   11/21/09 Updated to use HAL Processor APIs. Renamed the
+*		      macros to remove _m from the name.
+* 4.1   lks  11/18/15 Clean up of the comments in the code and
+*		      removed support for DCR bridge
+* 4.2   sk   08/16/16 Used UINTPTR instead of u32 for Baseaddress as part of
+*                     adding 64 bit support. CR# 867425.
+*                     Changed the prototype of XGpio_CfgInitialize API.
+* 
+* +*****************************************************************************/ + +/***************************** Include Files ********************************/ + +#include "xgpio.h" +#include "xstatus.h" + +/************************** Constant Definitions ****************************/ + +/**************************** Type Definitions ******************************/ + +/***************** Macros (Inline Functions) Definitions ********************/ + +/************************** Variable Definitions ****************************/ + + +/************************** Function Prototypes *****************************/ + + +/****************************************************************************/ +/** +* Initialize the XGpio 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 XGpio instance. The memory the +* pointer references must be pre-allocated by the caller. Further +* calls to manipulate the driver through the XGpio API must be +* made with this pointer. +* @param Config is a reference to a structure containing information +* about a specific GPIO 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 if the initialization is successfull. +* +* @note None. +* +*****************************************************************************/ +int XGpio_CfgInitialize(XGpio * InstancePtr, XGpio_Config * Config, + UINTPTR EffectiveAddr) +{ + /* Assert arguments */ + Xil_AssertNonvoid(InstancePtr != NULL); + + /* Set some default values. */ + InstancePtr->BaseAddress = EffectiveAddr; + + InstancePtr->InterruptPresent = Config->InterruptPresent; + InstancePtr->IsDual = Config->IsDual; + + /* + * Indicate the instance is now ready to use, initialized without error + */ + InstancePtr->IsReady = XIL_COMPONENT_IS_READY; + return (XST_SUCCESS); +} + + +/****************************************************************************/ +/** +* Set the input/output direction of all discrete signals for the specified +* GPIO channel. +* +* @param InstancePtr is a pointer to an XGpio instance to be worked on. +* @param Channel contains the channel of the GPIO (1 or 2) to operate on. +* @param DirectionMask is a bitmask specifying which discretes are input +* and which are output. Bits set to 0 are output and bits set to 1 +* are input. +* +* @return None. +* +* @note The hardware must be built for dual channels if this function +* is used with any channel other than 1. If it is not, this +* function will assert. +* +*****************************************************************************/ +void XGpio_SetDataDirection(XGpio *InstancePtr, unsigned Channel, + u32 DirectionMask) +{ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid((Channel == 1) || + ((Channel == 2) && (InstancePtr->IsDual == TRUE))); + + XGpio_WriteReg(InstancePtr->BaseAddress, + ((Channel - 1) * XGPIO_CHAN_OFFSET) + XGPIO_TRI_OFFSET, + DirectionMask); +} + +/****************************************************************************/ +/** +* Get the input/output direction of all discrete signals for the specified +* GPIO channel. +* +* @param InstancePtr is a pointer to an XGpio instance to be worked on. +* @param Channel contains the channel of the GPIO (1 or 2) to operate on. +* +* @return Bitmask specifying which discretes are input and +* which are output. Bits set to 0 are output and bits set to 1 are +* input. +* +* @note +* +* The hardware must be built for dual channels if this function is used +* with any channel other than 1. If it is not, this function will assert. +* +*****************************************************************************/ +u32 XGpio_GetDataDirection(XGpio *InstancePtr, unsigned Channel) +{ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid((Channel == 1) || + ((Channel == 2) && + (InstancePtr->IsDual == TRUE))); + + return XGpio_ReadReg(InstancePtr->BaseAddress, + ((Channel - 1) * XGPIO_CHAN_OFFSET) + XGPIO_TRI_OFFSET); +} + +/****************************************************************************/ +/** +* Read state of discretes for the specified GPIO channnel. +* +* @param InstancePtr is a pointer to an XGpio instance to be worked on. +* @param Channel contains the channel of the GPIO (1 or 2) to operate on. +* +* @return Current copy of the discretes register. +* +* @note The hardware must be built for dual channels if this function +* is used with any channel other than 1. If it is not, this +* function will assert. +* +*****************************************************************************/ +u32 XGpio_DiscreteRead(XGpio * InstancePtr, unsigned Channel) +{ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid((Channel == 1) || + ((Channel == 2) && (InstancePtr->IsDual == TRUE))); + + return XGpio_ReadReg(InstancePtr->BaseAddress, + ((Channel - 1) * XGPIO_CHAN_OFFSET) + + XGPIO_DATA_OFFSET); +} + +/****************************************************************************/ +/** +* Write to discretes register for the specified GPIO channel. +* +* @param InstancePtr is a pointer to an XGpio instance to be worked on. +* @param Channel contains the channel of the GPIO (1 or 2) to operate on. +* @param Data is the value to be written to the discretes register. +* +* @return None. +* +* @note The hardware must be built for dual channels if this function +* is used with any channel other than 1. If it is not, this +* function will assert. See also XGpio_DiscreteSet() and +* XGpio_DiscreteClear(). +* +*****************************************************************************/ +void XGpio_DiscreteWrite(XGpio * InstancePtr, unsigned Channel, u32 Data) +{ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid((Channel == 1) || + ((Channel == 2) && (InstancePtr->IsDual == TRUE))); + + XGpio_WriteReg(InstancePtr->BaseAddress, + ((Channel - 1) * XGPIO_CHAN_OFFSET) + XGPIO_DATA_OFFSET, + Data); +} +/** @} */ diff --git a/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpio_v4_4/src/xgpio.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpio_v4_4/src/xgpio.h new file mode 100644 index 0000000..b498fe0 --- /dev/null +++ b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpio_v4_4/src/xgpio.h @@ -0,0 +1,211 @@ +/****************************************************************************** +* +* Copyright (C) 2002 - 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 xgpio.h +* @addtogroup gpio_v4_4 +* @{ +* @details +* +* This file contains the software API definition of the Xilinx General Purpose +* I/O (XGpio) device driver. +* +* The Xilinx GPIO controller is a soft IP core designed for Xilinx FPGAs and +* contains the following general features: +* - Support for up to 32 I/O discretes for each channel (64 bits total). +* - Each of the discretes can be configured for input or output. +* - Configurable support for dual channels and interrupt generation. +* +* 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 XGpio_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 one +* of the following ways: +* +* - XGpio_Initialize(InstancePtr, DeviceId) - The driver looks up its own +* configuration structure created by the tool-chain based on an ID provided +* by the tool-chain. +* +* - XGpio_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 GPIO 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
+* ----- ---- -------- -----------------------------------------------
+* 1.00a rmm  03/13/02 First release
+* 2.00a jhl  11/26/03 Added support for dual channels and interrupts
+* 2.01a jvb  12/14/05 I separated dependency on the static config table and
+*                     xparameters.h from the driver initialization by moving
+*                     _Initialize and _LookupConfig to _sinit.c. I also added
+*                     the new _CfgInitialize routine.
+* 2.11a mta  03/21/07 Updated to new coding style, added GetDataDirection
+* 2.12a sv   11/21/07 Updated driver to support access through DCR bus
+* 2.12a sv   06/05/08 Updated driver to fix the XGpio_InterruptDisable function
+*		      to properly update the Interrupt Enable register
+* 2.13a sdm  08/22/08 Removed support for static interrupt handlers from the MDD
+*		      file
+* 3.00a sv   11/21/09 Updated to use HAL Processor APIs.
+*		      Renamed the macros XGpio_mWriteReg to XGpio_WriteReg and
+*		      XGpio_mReadReg to XGpio_ReadReg. Removed the macros
+*		      XGpio_mSetDataDirection, XGpio_mGetDataReg and
+*		      XGpio_mSetDataReg. Users should use XGpio_WriteReg and
+*		      XGpio_ReadReg to achieve the same functionality.
+* 3.01a bss  04/18/13 Updated driver tcl to generate Canonical params in
+*		      xparameters.h. CR#698589
+* 4.0   adk  19/12/13 Updated as per the New Tcl API's
+* 4.1   lks  11/18/15 Updated to use cannonical xparameters in examples and
+*		      clean up of the comments, removed support for DCR bridge
+*		      and removed xgpio_intr_example for CR 900381
+* 4.2   sk   08/16/16 Used UINTPTR instead of u32 for Baseaddress as part of
+*                     adding 64 bit support. CR# 867425.
+*                     Changed the prototype of XGpio_CfgInitialize API.
+* 4.3   sk   09/29/16 Modified the example to make it work when LED_bits are
+*                     configured as an output. CR# 958644
+*       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.
+* 4.4   sne  04/25/19 Updated Makefile for IAR compier (CR-1029421).
+*
+* 
+*****************************************************************************/ + +#ifndef XGPIO_H /* prevent circular inclusions */ +#define XGPIO_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files ********************************/ + +#include "xil_types.h" +#include "xil_assert.h" +#include "xstatus.h" +#include "xgpio_l.h" + +/************************** Constant Definitions ****************************/ + +/**************************** Type Definitions ******************************/ + +/** + * This typedef contains configuration information for the device. + */ +typedef struct { + u16 DeviceId; /* Unique ID of device */ + UINTPTR BaseAddress; /* Device base address */ + int InterruptPresent; /* Are interrupts supported in h/w */ + int IsDual; /* Are 2 channels supported in h/w */ +} XGpio_Config; + +/** + * The XGpio driver instance data. The user is required to allocate a + * variable of this type for every GPIO device in the system. A pointer + * to a variable of this type is then passed to the driver API functions. + */ +typedef struct { + UINTPTR BaseAddress; /* Device base address */ + u32 IsReady; /* Device is initialized and ready */ + int InterruptPresent; /* Are interrupts supported in h/w */ + int IsDual; /* Are 2 channels supported in h/w */ +} XGpio; + +/***************** Macros (Inline Functions) Definitions ********************/ + + +/************************** Function Prototypes *****************************/ + +/* + * Initialization functions in xgpio_sinit.c + */ +int XGpio_Initialize(XGpio *InstancePtr, u16 DeviceId); +XGpio_Config *XGpio_LookupConfig(u16 DeviceId); + +/* + * API Basic functions implemented in xgpio.c + */ +int XGpio_CfgInitialize(XGpio *InstancePtr, XGpio_Config * Config, + UINTPTR EffectiveAddr); +void XGpio_SetDataDirection(XGpio *InstancePtr, unsigned Channel, + u32 DirectionMask); +u32 XGpio_GetDataDirection(XGpio *InstancePtr, unsigned Channel); +u32 XGpio_DiscreteRead(XGpio *InstancePtr, unsigned Channel); +void XGpio_DiscreteWrite(XGpio *InstancePtr, unsigned Channel, u32 Mask); + + +/* + * API Functions implemented in xgpio_extra.c + */ +void XGpio_DiscreteSet(XGpio *InstancePtr, unsigned Channel, u32 Mask); +void XGpio_DiscreteClear(XGpio *InstancePtr, unsigned Channel, u32 Mask); + +/* + * API Functions implemented in xgpio_selftest.c + */ +int XGpio_SelfTest(XGpio *InstancePtr); + +/* + * API Functions implemented in xgpio_intr.c + */ +void XGpio_InterruptGlobalEnable(XGpio *InstancePtr); +void XGpio_InterruptGlobalDisable(XGpio *InstancePtr); +void XGpio_InterruptEnable(XGpio *InstancePtr, u32 Mask); +void XGpio_InterruptDisable(XGpio *InstancePtr, u32 Mask); +void XGpio_InterruptClear(XGpio *InstancePtr, u32 Mask); +u32 XGpio_InterruptGetEnabled(XGpio *InstancePtr); +u32 XGpio_InterruptGetStatus(XGpio *InstancePtr); + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpio_v4_4/src/xgpio_extra.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpio_v4_4/src/xgpio_extra.c new file mode 100644 index 0000000..af9a44b --- /dev/null +++ b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpio_v4_4/src/xgpio_extra.c @@ -0,0 +1,160 @@ +/****************************************************************************** +* +* Copyright (C) 2002 - 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 xgpio_extra.c +* @addtogroup gpio_v4_4 +* @{ +* +* The implementation of the XGpio driver's advanced discrete functions. +* See xgpio.h for more information about the driver. +* +* @note +* +* These APIs can only be used if the GPIO_IO ports in the IP are used for +* connecting to the external output ports. +* +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a rmm  02/04/02 First release
+* 2.00a jhl  12/16/02 Update for dual channel and interrupt support
+* 2.11a mta  03/21/07 Updated to new coding style
+* 3.00a sv   11/21/09 Updated to use HAL Processor APIs. Renamed the macros
+*		      XGpio_mWriteReg to XGpio_WriteReg, and XGpio_mReadReg
+*		      to XGpio_ReadReg.
+* 
+* +*****************************************************************************/ + +/***************************** Include Files ********************************/ + +#include "xgpio.h" +#include "xgpio_i.h" + +/************************** Constant Definitions ****************************/ + +/**************************** Type Definitions ******************************/ + +/***************** Macros (Inline Functions) Definitions ********************/ + +/************************** Variable Definitions ****************************/ + +/************************** Function Prototypes *****************************/ + + +/****************************************************************************/ +/** +* Set output discrete(s) to logic 1 for the specified GPIO channel. +* +* @param InstancePtr is a pointer to an XGpio instance to be worked on. +* @param Channel contains the channel of the GPIO (1 or 2) to operate on. +* @param Mask is the set of bits that will be set to 1 in the discrete +* data register. All other bits in the data register are +* unaffected. +* +* @return None. +* +* @note +* +* The hardware must be built for dual channels if this function is used +* with any channel other than 1. If it is not, this function will assert. +* +* This API can only be used if the GPIO_IO ports in the IP are used for +* connecting to the external output ports. +* +*****************************************************************************/ +void XGpio_DiscreteSet(XGpio * InstancePtr, unsigned Channel, u32 Mask) +{ + u32 Current; + unsigned DataOffset; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid((Channel == 1) || + ((Channel == 2) && (InstancePtr->IsDual == TRUE))); + + /* Calculate the offset to the data register of the GPIO */ + DataOffset = ((Channel - 1) * XGPIO_CHAN_OFFSET) + XGPIO_DATA_OFFSET; + + /* + * Read the contents of the data register, merge in Mask and write + * back results + */ + Current = XGpio_ReadReg(InstancePtr->BaseAddress, DataOffset); + Current |= Mask; + XGpio_WriteReg(InstancePtr->BaseAddress, DataOffset, Current); +} + + +/****************************************************************************/ +/** +* Set output discrete(s) to logic 0 for the specified GPIO channel. +* +* @param InstancePtr is a pointer to an XGpio instance to be worked on. +* @param Channel contains the channel of the GPIO (1 or 2) to operate on. +* @param Mask is the set of bits that will be set to 0 in the discrete +* data register. All other bits in the data register are +* unaffected. +* +* @return None. +* +* @note +* +* The hardware must be built for dual channels if this function is used +* with any channel other than 1. If it is not, this function will assert. +* +* This API can only be used if the GPIO_IO ports in the IP are used for +* connecting to the external output ports. +* +*****************************************************************************/ +void XGpio_DiscreteClear(XGpio * InstancePtr, unsigned Channel, u32 Mask) +{ + u32 Current; + unsigned DataOffset; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid((Channel == 1) || + ((Channel == 2) && (InstancePtr->IsDual == TRUE))); + + /* Calculate the offset to the data register of the GPIO */ + DataOffset = ((Channel - 1) * XGPIO_CHAN_OFFSET) + XGPIO_DATA_OFFSET; + + /* + * Read the contents of the data register, merge in Mask and write + * back results + */ + Current = XGpio_ReadReg(InstancePtr->BaseAddress, DataOffset); + Current &= ~Mask; + XGpio_WriteReg(InstancePtr->BaseAddress, DataOffset, Current); +} +/** @} */ diff --git a/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpio_v4_4/src/xgpio_g.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpio_v4_4/src/xgpio_g.c new file mode 100644 index 0000000..5b22540 --- /dev/null +++ b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpio_v4_4/src/xgpio_g.c @@ -0,0 +1,53 @@ + +/******************************************************************* +* +* CAUTION: This file is automatically generated by HSI. +* Version: 2019.1.3 +* DO NOT EDIT. +* +* Copyright (C) 2010-2024 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 "xgpio.h" + +/* +* The configuration table for devices +*/ + +XGpio_Config XGpio_ConfigTable[XPAR_XGPIO_NUM_INSTANCES] = +{ + { + XPAR_CONFIG_GPIO_DEVICE_ID, + XPAR_CONFIG_GPIO_BASEADDR, + XPAR_CONFIG_GPIO_INTERRUPT_PRESENT, + XPAR_CONFIG_GPIO_IS_DUAL + } +}; + + diff --git a/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpio_v4_4/src/xgpio_i.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpio_v4_4/src/xgpio_i.h new file mode 100644 index 0000000..7938b0f --- /dev/null +++ b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpio_v4_4/src/xgpio_i.h @@ -0,0 +1,83 @@ +/****************************************************************************** +* +* Copyright (C) 2002 - 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 xgpio_i.h +* @addtogroup gpio_v4_3 +* @{ +* +* This header file contains internal identifiers, which are those shared +* between the files of the driver. It is intended for internal use only. +* +* NOTES: +* +* None. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a rmm  03/13/02 First release
+* 2.11a mta  03/21/07 Updated to new coding style
+* 
+******************************************************************************/ + +#ifndef XGPIO_I_H /* prevent circular inclusions */ +#define XGPIO_I_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +#include "xgpio.h" + +/************************** Constant Definitions ****************************/ + + +/**************************** Type Definitions *******************************/ + + +/***************** Macros (Inline Functions) Definitions *********************/ + + +/************************** Function Prototypes ******************************/ + + +/************************** Variable Definitions ****************************/ + +extern XGpio_Config XGpio_ConfigTable[]; + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpio_v4_4/src/xgpio_intr.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpio_v4_4/src/xgpio_intr.c new file mode 100644 index 0000000..acbb084 --- /dev/null +++ b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpio_v4_4/src/xgpio_intr.c @@ -0,0 +1,290 @@ +/****************************************************************************** +* +* Copyright (C) 2002 - 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 xgpio_intr.c +* @addtogroup gpio_v4_4 +* @{ +* +* Implements GPIO interrupt processing functions for the XGpio driver. +* See xgpio.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
+* ----- ---- -------- -----------------------------------------------
+* 2.00a jhl  11/26/03 Initial release
+* 2.11a mta  03/21/07 Updated to new coding style
+* 2.12a sv   06/05/08 Updated driver to fix the XGpio_InterruptDisable function
+*		      to properly update the Interrupt Enable register
+* 3.00a sv   11/21/09 Updated to use HAL Processor APIs. Renamed the macros
+*		      XGpio_mWriteReg to XGpio_WriteReg, and XGpio_mReadReg
+*		      to XGpio_ReadReg.
+
+* 
+* +*****************************************************************************/ + +/***************************** Include Files ********************************/ +#include "xgpio.h" + + +/************************** Constant Definitions ****************************/ + +/**************************** Type Definitions ******************************/ + +/***************** Macros (Inline Functions) Definitions ********************/ + +/************************** Variable Definitions ****************************/ + +/************************** Function Prototypes *****************************/ + + +/****************************************************************************/ +/** +* Enable the interrupt output signal. Interrupts enabled through +* XGpio_InterruptEnable() will not be passed through until the global enable +* bit is set by this function. This function is designed to allow all +* interrupts (both channels) to be enabled easily for exiting a critical +* section. This function will assert if the hardware device has not been +* built with interrupt capabilities. +* +* @param InstancePtr is the GPIO instance to operate on. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XGpio_InterruptGlobalEnable(XGpio *InstancePtr) +{ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid(InstancePtr->InterruptPresent == TRUE); + + XGpio_WriteReg(InstancePtr->BaseAddress, XGPIO_GIE_OFFSET, + XGPIO_GIE_GINTR_ENABLE_MASK); +} + + +/****************************************************************************/ +/** +* Disable the interrupt output signal. Interrupts enabled through +* XGpio_InterruptEnable() will no longer be passed through until the global +* enable bit is set by XGpio_InterruptGlobalEnable(). This function is +* designed to allow all interrupts (both channels) to be disabled easily for +* entering a critical section. This function will assert if the hardware +* device has not been built with interrupt capabilities. +* +* @param InstancePtr is the GPIO instance to operate on. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XGpio_InterruptGlobalDisable(XGpio *InstancePtr) +{ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid(InstancePtr->InterruptPresent == TRUE); + + + XGpio_WriteReg(InstancePtr->BaseAddress, XGPIO_GIE_OFFSET, 0x0); + +} + + +/****************************************************************************/ +/** +* Enable interrupts. The global interrupt must also be enabled by calling +* XGpio_InterruptGlobalEnable() for interrupts to occur. This function will +* assert if the hardware device has not been built with interrupt capabilities. +* +* @param InstancePtr is the GPIO 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 XGPIO_IR* bits which +* are contained in xgpio_l.h. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XGpio_InterruptEnable(XGpio *InstancePtr, u32 Mask) +{ + u32 Register; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid(InstancePtr->InterruptPresent == TRUE); + + /* + * Read the interrupt enable register and only enable the specified + * interrupts without disabling or enabling any others. + */ + + Register = XGpio_ReadReg(InstancePtr->BaseAddress, XGPIO_IER_OFFSET); + XGpio_WriteReg(InstancePtr->BaseAddress, XGPIO_IER_OFFSET, + Register | Mask); + +} + + +/****************************************************************************/ +/** +* Disable interrupts. This function allows specific interrupts for each +* channel to be disabled. This function will assert if the hardware device +* has not been built with interrupt capabilities. +* +* @param InstancePtr is the GPIO 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 XGPIO_IR* bits which are +* contained in xgpio_l.h. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XGpio_InterruptDisable(XGpio *InstancePtr, u32 Mask) +{ + u32 Register; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid(InstancePtr->InterruptPresent == TRUE); + + /* + * Read the interrupt enable register and only disable the specified + * interrupts without enabling or disabling any others. + */ + Register = XGpio_ReadReg(InstancePtr->BaseAddress, XGPIO_IER_OFFSET); + XGpio_WriteReg(InstancePtr->BaseAddress, XGPIO_IER_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 GPIO 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 +* XGPIO_IR* bits which are contained in xgpio_l.h. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XGpio_InterruptClear(XGpio * InstancePtr, u32 Mask) +{ + u32 Register; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid(InstancePtr->InterruptPresent == TRUE); + + /* + * 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 = XGpio_ReadReg(InstancePtr->BaseAddress, XGPIO_ISR_OFFSET); + XGpio_WriteReg(InstancePtr->BaseAddress, XGPIO_ISR_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 GPIO instance to operate on. +* +* @return A mask of bits made from XGPIO_IR* bits which are contained in +* xgpio_l.h. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +u32 XGpio_InterruptGetEnabled(XGpio * InstancePtr) +{ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid(InstancePtr->InterruptPresent == TRUE); + + return XGpio_ReadReg(InstancePtr->BaseAddress, XGPIO_IER_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 GPIO instance to operate on. +* +* @return A pointer to a mask of bits made from XGPIO_IR* bits which are +* contained in xgpio_l.h. +* +* @note +* +* The interrupt status indicates the status of the device irregardless if +* the interrupts from the devices have been enabled or not through +* XGpio_InterruptEnable(). +* +*****************************************************************************/ +u32 XGpio_InterruptGetStatus(XGpio * InstancePtr) +{ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid(InstancePtr->InterruptPresent == TRUE); + + + return XGpio_ReadReg(InstancePtr->BaseAddress, XGPIO_ISR_OFFSET); +} +/** @} */ diff --git a/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpio_v4_4/src/xgpio_l.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpio_v4_4/src/xgpio_l.h new file mode 100644 index 0000000..be6d04a --- /dev/null +++ b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpio_v4_4/src/xgpio_l.h @@ -0,0 +1,189 @@ +/****************************************************************************** +* +* Copyright (C) 2002 - 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 xgpio_l.h +* @addtogroup gpio_v4_4 +* @{ +* +* 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. +* +* The macros that are available in this file use a multiply to calculate the +* addresses of registers. The user can control whether that multiply is done +* at run time or at compile time. A constant passed as the channel parameter +* will cause the multiply to be done at compile time. A variable passed as the +* channel parameter will cause it to occur at run time. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a jhl  04/24/02 First release of low level driver
+* 2.00a jhl  11/26/03 Added support for dual channels and interrupts. This
+*                     change required the functions to be changed such that
+*                     the interface is not compatible with previous versions.
+*                     See the examples in the example directory for macros
+*                     to help compile an application that was designed for
+*                     previous versions of the driver. The interrupt registers
+*                     are accessible using the ReadReg and WriteReg macros and
+*                     a channel parameter was added to the other macros.
+* 2.11a mta  03/21/07 Updated to new coding style
+* 2.12a sv   11/21/07 Updated driver to support access through DCR bus.
+* 3.00a sv   11/21/09 Renamed the macros XGpio_mWriteReg to XGpio_WriteReg
+*		      XGpio_mReadReg to XGpio_ReadReg.
+*		      Removed the macros XGpio_mSetDataDirection,
+*		      XGpio_mGetDataReg and XGpio_mSetDataReg. Users
+*		      should use XGpio_WriteReg/XGpio_ReadReg to achieve the
+*		      same functionality.
+* 4.1  lks   11/18/15 Removed support for DCR bridge
+* 
+* +******************************************************************************/ + +#ifndef XGPIO_L_H /* prevent circular inclusions */ +#define XGPIO_L_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 XGPIO_DATA_OFFSET 0x0 /**< Data register for 1st channel */ +#define XGPIO_TRI_OFFSET 0x4 /**< I/O direction reg for 1st channel */ +#define XGPIO_DATA2_OFFSET 0x8 /**< Data register for 2nd channel */ +#define XGPIO_TRI2_OFFSET 0xC /**< I/O direction reg for 2nd channel */ + +#define XGPIO_GIE_OFFSET 0x11C /**< Glogal interrupt enable register */ +#define XGPIO_ISR_OFFSET 0x120 /**< Interrupt status register */ +#define XGPIO_IER_OFFSET 0x128 /**< Interrupt enable register */ + +/* @} */ + +/* The following constant describes the offset of each channels data and + * tristate register from the base address. + */ +#define XGPIO_CHAN_OFFSET 8 + +/** @name Interrupt Status and Enable Register bitmaps and masks + * + * Bit definitions for the interrupt status register and interrupt enable + * registers. + * @{ + */ +#define XGPIO_IR_MASK 0x3 /**< Mask of all bits */ +#define XGPIO_IR_CH1_MASK 0x1 /**< Mask for the 1st channel */ +#define XGPIO_IR_CH2_MASK 0x2 /**< Mask for the 2nd channel */ +/*@}*/ + + +/** @name Global Interrupt Enable Register bitmaps and masks + * + * Bit definitions for the Global Interrupt Enable register + * @{ + */ +#define XGPIO_GIE_GINTR_ENABLE_MASK 0x80000000 +/*@}*/ + + + +/**************************** Type Definitions *******************************/ + + +/***************** Macros (Inline Functions) Definitions *********************/ + +#define XGpio_In32 Xil_In32 +#define XGpio_Out32 Xil_Out32 + + +/****************************************************************************/ +/** +* +* Write a value to a GPIO register. A 32 bit write is performed. If the +* GPIO core is implemented in a smaller width, only the least significant data +* is written. +* +* @param BaseAddress is the base address of the GPIO device. +* @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 XGpio_WriteReg(u32 BaseAddress, u32 RegOffset, u32 Data) +* +****************************************************************************/ +#define XGpio_WriteReg(BaseAddress, RegOffset, Data) \ + XGpio_Out32((BaseAddress) + (RegOffset), (u32)(Data)) + +/****************************************************************************/ +/** +* +* Read a value from a GPIO register. A 32 bit read is performed. If the +* GPIO core 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 BaseAddress is the base address of the GPIO device. +* @param RegOffset is the register offset from the base to read from. +* +* @return Data read from the register. +* +* @note C-style signature: +* u32 XGpio_ReadReg(u32 BaseAddress, u32 RegOffset) +* +****************************************************************************/ +#define XGpio_ReadReg(BaseAddress, RegOffset) \ + XGpio_In32((BaseAddress) + (RegOffset)) + +/************************** Function Prototypes ******************************/ + +/************************** Variable Definitions *****************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpio_v4_4/src/xgpio_selftest.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpio_v4_4/src/xgpio_selftest.c new file mode 100644 index 0000000..50d8d4f --- /dev/null +++ b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpio_v4_4/src/xgpio_selftest.c @@ -0,0 +1,106 @@ +/****************************************************************************** +* +* Copyright (C) 2002 - 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 xgpio_selftest.c +* @addtogroup gpio_v4_4 +* @{ +* +* The implementation of the XGpio driver's self test function. +* See xgpio.h for more information about the driver. +* +* @note +* +* None +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a rmm  02/04/02 First release
+* 2.00a jhl  01/13/04 Addition of dual channels and interrupts.
+* 2.11a mta  03/21/07 Updated to new coding style
+* 3.00a sv   11/21/09 Updated to use HAL Processor APIs.
+* 
+* +*****************************************************************************/ + +/***************************** Include Files ********************************/ +#include "xgpio.h" + +/************************** Constant Definitions ****************************/ + +/**************************** Type Definitions ******************************/ + +/***************** Macros (Inline Functions) Definitions ********************/ + +/************************** Variable Definitions ****************************/ + +/************************** Function Prototypes *****************************/ + + +/******************************************************************************/ +/** +* Run a self-test on the driver/device. This function does a minimal test +* in which the data register is read. It only does a read without any kind +* of test because the hardware has been parameterized such that it may be only +* an input such that the state of the inputs won't be known. +* +* All other hardware features of the device are not guaranteed to be in the +* hardware since they are parameterizable. +* +* +* @param InstancePtr is a pointer to the XGpio instance to be worked on. +* This parameter must have been previously initialized with +* XGpio_Initialize(). +* +* @return XST_SUCCESS always. If the GPIO device was 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 XGpio_SelfTest(XGpio * InstancePtr) +{ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read from the data register of channel 1 which is always guaranteed + * to be in the hardware device. Since the data may be configured as + * all inputs, there is not way to guarantee the value read so don't + * test it. + */ + (void) XGpio_DiscreteRead(InstancePtr, 1); + + return (XST_SUCCESS); +} +/** @} */ diff --git a/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpio_v4_4/src/xgpio_sinit.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpio_v4_4/src/xgpio_sinit.c new file mode 100644 index 0000000..0be44bd --- /dev/null +++ b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpio_v4_4/src/xgpio_sinit.c @@ -0,0 +1,155 @@ +/****************************************************************************** +* +* Copyright (C) 2003 - 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 xgpio_sinit.c +* @addtogroup gpio_v4_4 +* @{ +* +* The implementation of the XGpio 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.0   sha  07/15/15 Defined macro XPAR_XGPIO_NUM_INSTANCES if not
+*		      defined in xparameters.h
+* 
+* +*****************************************************************************/ + +/***************************** Include Files ********************************/ + +#include "xstatus.h" +#include "xparameters.h" +#include "xgpio_i.h" + +/************************** Constant Definitions ****************************/ + +#ifndef XPAR_XGPIO_NUM_INSTANCES +#define XPAR_XGPIO_NUM_INSTANCES 0 +#endif + +/**************************** Type Definitions ******************************/ + +/***************** Macros (Inline Functions) Definitions ********************/ + +/************************** Variable Definitions ****************************/ + + +/************************** 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 XGpio_Config which points to the +* device configuration if DeviceID is found. +* - NULL if DeviceID is not found. +* +* @note None. +* +******************************************************************************/ +XGpio_Config *XGpio_LookupConfig(u16 DeviceId) +{ + XGpio_Config *CfgPtr = NULL; + + int Index; + + for (Index = 0; Index < XPAR_XGPIO_NUM_INSTANCES; Index++) { + if (XGpio_ConfigTable[Index].DeviceId == DeviceId) { + CfgPtr = &XGpio_ConfigTable[Index]; + break; + } + } + + return CfgPtr; +} + + +/****************************************************************************/ +/** +* Initialize the XGpio instance provided by the caller based on the +* given DeviceID. +* +* Nothing is done except to initialize the InstancePtr. +* +* @param InstancePtr is a pointer to an XGpio instance. The memory the +* pointer references must be pre-allocated by the caller. Further +* calls to manipulate the instance/driver through the XGpio API +* must be made with this pointer. +* @param DeviceId is the unique id of the device controlled by this XGpio +* instance. Passing in a device id associates the generic XGpio +* instance to a specific device, as chosen by the caller or +* application developer. +* +* @return +* - XST_SUCCESS if the initialization was successfull. +* - XST_DEVICE_NOT_FOUND if the device configuration data was not +* found for a device with the supplied device ID. +* +* @note None. +* +*****************************************************************************/ +int XGpio_Initialize(XGpio * InstancePtr, u16 DeviceId) +{ + XGpio_Config *ConfigPtr; + + /* + * Assert arguments + */ + Xil_AssertNonvoid(InstancePtr != NULL); + + /* + * Lookup configuration data in the device configuration table. + * Use this configuration info down below when initializing this + * driver. + */ + ConfigPtr = XGpio_LookupConfig(DeviceId); + if (ConfigPtr == (XGpio_Config *) NULL) { + InstancePtr->IsReady = 0; + return (XST_DEVICE_NOT_FOUND); + } + + return XGpio_CfgInitialize(InstancePtr, ConfigPtr, + ConfigPtr->BaseAddress); +} +/** @} */ diff --git a/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/Makefile b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/Makefile new file mode 100644 index 0000000..8601ce4 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops.c new file mode 100644 index 0000000..39bcc94 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops.h new file mode 100644 index 0000000..d0ff132 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops_g.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops_g.c new file mode 100644 index 0000000..2fde48c --- /dev/null +++ b/df_datalink_ge/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-2024 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_ge/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops_hw.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops_hw.c new file mode 100644 index 0000000..4885c29 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops_hw.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops_hw.h new file mode 100644 index 0000000..599c7db --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops_intr.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops_intr.c new file mode 100644 index 0000000..0730c91 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops_selftest.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops_selftest.c new file mode 100644 index 0000000..322ca74 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops_sinit.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/gpiops_v3_5/src/xgpiops_sinit.c new file mode 100644 index 0000000..58ce55e --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/Makefile b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/Makefile new file mode 100644 index 0000000..3600928 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips.c new file mode 100644 index 0000000..e82cab6 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips.h new file mode 100644 index 0000000..0255bc2 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips_g.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips_g.c new file mode 100644 index 0000000..251e35d --- /dev/null +++ b/df_datalink_ge/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-2024 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_ge/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips_hw.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips_hw.c new file mode 100644 index 0000000..d5e0789 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips_hw.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips_hw.h new file mode 100644 index 0000000..88c232e --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips_options.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips_options.c new file mode 100644 index 0000000..14d0ca0 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips_selftest.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips_selftest.c new file mode 100644 index 0000000..c72e952 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips_sinit.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/qspips_v3_6/src/xqspips_sinit.c new file mode 100644 index 0000000..da2dc1e --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/Makefile b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/Makefile new file mode 100644 index 0000000..04867a4 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic.c new file mode 100644 index 0000000..8a73638 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic.h new file mode 100644 index 0000000..5502a20 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic_g.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic_g.c new file mode 100644 index 0000000..625b9d3 --- /dev/null +++ b/df_datalink_ge/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-2024 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_ge/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic_hw.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic_hw.c new file mode 100644 index 0000000..4193e80 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic_hw.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic_hw.h new file mode 100644 index 0000000..60d111f --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic_intr.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic_intr.c new file mode 100644 index 0000000..2157b4f --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic_selftest.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic_selftest.c new file mode 100644 index 0000000..052ef43 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic_sinit.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scugic_v4_0/src/xscugic_sinit.c new file mode 100644 index 0000000..3a3d710 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/Makefile b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/Makefile new file mode 100644 index 0000000..7c673d4 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/xscutimer.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/xscutimer.c new file mode 100644 index 0000000..d7f6348 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/xscutimer.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/xscutimer.h new file mode 100644 index 0000000..5434684 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/xscutimer_g.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/xscutimer_g.c new file mode 100644 index 0000000..a830fea --- /dev/null +++ b/df_datalink_ge/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-2024 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_ge/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/xscutimer_hw.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/xscutimer_hw.h new file mode 100644 index 0000000..d577784 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/xscutimer_selftest.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/xscutimer_selftest.c new file mode 100644 index 0000000..b3464b6 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/xscutimer_sinit.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scutimer_v2_1/src/xscutimer_sinit.c new file mode 100644 index 0000000..0c5f671 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/Makefile b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/Makefile new file mode 100644 index 0000000..493ad9a --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/xscuwdt.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/xscuwdt.c new file mode 100644 index 0000000..85f0507 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/xscuwdt.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/xscuwdt.h new file mode 100644 index 0000000..551eaf5 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/xscuwdt_g.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/xscuwdt_g.c new file mode 100644 index 0000000..8c741d0 --- /dev/null +++ b/df_datalink_ge/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-2024 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_ge/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/xscuwdt_hw.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/xscuwdt_hw.h new file mode 100644 index 0000000..ad87a05 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/xscuwdt_selftest.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/xscuwdt_selftest.c new file mode 100644 index 0000000..aa0cd39 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/xscuwdt_sinit.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/scuwdt_v2_1/src/xscuwdt_sinit.c new file mode 100644 index 0000000..e311a04 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/spips_v3_2/src/Makefile b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/spips_v3_2/src/Makefile new file mode 100644 index 0000000..10d24d7 --- /dev/null +++ b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/spips_v3_2/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 xspips_libs clean + +%.o: %.c + ${COMPILER} $(CC_FLAGS) $(ECC_FLAGS) $(INCLUDES) -o $@ $< + +banner: + echo "Compiling spips" + +xspips_libs: ${OBJECTS} + $(ARCHIVER) -r ${RELEASEDIR}/${LIB} ${OBJECTS} + +.PHONY: include +include: xspips_includes + +xspips_includes: + ${CP} ${INCLUDEFILES} ${INCLUDEDIR} + +clean: + rm -rf ${OBJECTS} diff --git a/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/spips_v3_2/src/xspips.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/spips_v3_2/src/xspips.c new file mode 100644 index 0000000..42bd5d1 --- /dev/null +++ b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/spips_v3_2/src/xspips.c @@ -0,0 +1,1154 @@ +/****************************************************************************** +* +* 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 xspips.c +* @addtogroup spips_v3_2 +* @{ +* +* Contains implements the interface functions of the XSpiPs driver. +* See xspips.h for a detailed description of the device and driver. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date     Changes
+* ----- ------ -------- -----------------------------------------------
+* 1.00  drg/jz 01/25/10 First release
+* 1.01	sg     03/07/12 Updated the code to always clear the relevant bits
+*			before writing to config register.
+*			Always clear the slave select bits before write and
+*			clear the bits to no slave at the end of transfer
+*			Modified the Polled transfer transmit/receive logic.
+*			Tx should wait on TXOW Interrupt and Rx on RXNEMTY.
+* 1.03	sg     09/21/12 Added memory barrier dmb in polled transfer and
+*			interrupt handler to overcome the clock domain
+*			crossing issue in the controller. For CR #679252.
+* 1.04a	sg     01/30/13 Changed SPI 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.
+*			SetSlaveSelect API logic is modified to drive the bit
+*			position low based on the slave select value
+*			requested. GetSlaveSelect API will return the value
+*			based on bit position that is low.
+* 1.06a hk     08/22/13 Changed GetSlaveSelect function. CR# 727866.
+*                       Added masking ConfigReg before writing in SetSlaveSel
+*                       Added extended slave select support - CR#722569.
+*                       Added check for MODF in polled transfer function.
+* 3.00  kvn    02/13/15 Modified code for MISRA-C:2012 compliance.
+* 3.02  raw    11/23/15 Updated XSpiPs_Abort() to read all RXFIFO entries.
+* 			This change is to tackle CR#910231.
+* 3.1	tjs    04/12/18 InputClockHz parameter copied in instance for use in
+* 						application. CR#998910
+* 3.1   tjs    11/23/18 Added a check for A72 and R5 processor to
+*                       avoid changes made for the workaround DT#842463.
+* 3.2	aru    01/20/19 Fixes violations according to MISRAC-2012
+*                       in safety mode and done changes such as
+*                       Declared the pointer param as Pointer to const,
+*			added goto statements.
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xspips.h" + +/************************** Constant Definitions *****************************/ + + +/**************************** Type Definitions *******************************/ + + +/***************** Macros (Inline Functions) Definitions *********************/ + +/****************************************************************************/ +/* +* +* Send one byte to the currently selected slave. A byte of data is written to +* transmit FIFO/register. +* +* @param BaseAddress is the base address of the device +* +* @return None. +* +* @note C-Style signature: +* void XSpiPs_SendByte(u32 BaseAddress, u8 Data) +* +*****************************************************************************/ +#define XSpiPs_SendByte(BaseAddress, Data) \ + XSpiPs_Out32((BaseAddress) + (u32)XSPIPS_TXD_OFFSET, (u32)(Data)) + +/****************************************************************************/ +/* +* +* Receive one byte from the device's receive FIFO/register. It is assumed +* that the byte is already available. +* +* @param BaseAddress is the base address of the device +* +* @return The byte retrieved from the receive FIFO/register. +* +* @note C-Style signature: +* u8 XSpiPs_RecvByte(u32 BaseAddress) +* +*****************************************************************************/ +#define XSpiPs_RecvByte(BaseAddress) \ + XSpiPs_In32((u32)((BaseAddress) + (u32)XSPIPS_RXD_OFFSET)) + +/************************** Function Prototypes ******************************/ + +static void StubStatusHandler(const void *CallBackRef, u32 StatusEvent, + u32 ByteCount); + +/************************** Variable Definitions *****************************/ + + +/*****************************************************************************/ +/** +* +* Initializes a specific XSpiPs instance such that the driver is ready to use. +* +* The state of the device after initialization is: +* - Device is disabled +* - Slave mode +* - Active high clock polarity +* - Clock phase 0 +* +* @param InstancePtr is a pointer to the XSpiPs instance. +* @param ConfigPtr is a reference to a structure containing information +* about a specific SPI 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 +* 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. +* +******************************************************************************/ +s32 XSpiPs_CfgInitialize(XSpiPs *InstancePtr, const XSpiPs_Config *ConfigPtr, + u32 EffectiveAddr) +{ + s32 Status; + 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) { + Status = (s32)XST_DEVICE_IS_STARTED; + } else { + + /* + * Set some default values. + */ + InstancePtr->IsBusy = FALSE; + + InstancePtr->Config.BaseAddress = EffectiveAddr; + InstancePtr->Config.InputClockHz = ConfigPtr->InputClockHz; + InstancePtr->StatusHandler = StubStatusHandler; + + InstancePtr->SendBufferPtr = NULL; + InstancePtr->RecvBufferPtr = NULL; + InstancePtr->RequestedBytes = 0U; + InstancePtr->RemainingBytes = 0U; + InstancePtr->IsReady = XIL_COMPONENT_IS_READY; + + /* + * Reset the SPI 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. + */ + XSpiPs_Reset(InstancePtr); + Status = (s32)XST_SUCCESS; + } + + return Status; +} + + +/*****************************************************************************/ +/** +* +* Resets the SPI device. Reset must only be called after the driver has been +* initialized. The configuration of the device after reset is the same as its +* configuration after initialization. Any data transfer that is in progress +* is aborted. +* +* The upper layer software is responsible for re-configuring (if necessary) +* and restarting the SPI device after the reset. +* +* @param InstancePtr is a pointer to the XSpiPs instance. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XSpiPs_Reset(XSpiPs *InstancePtr) +{ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Abort any transfer that is in progress + */ + XSpiPs_Abort(InstancePtr); + + /* + * Reset any values that are not reset by the hardware reset such that + * the software state matches the hardware device + */ + XSpiPs_WriteReg(InstancePtr->Config.BaseAddress, XSPIPS_CR_OFFSET, + XSPIPS_CR_RESET_STATE); + +} + +/*****************************************************************************/ +/** +* +* Transfers specified data on the SPI bus. If the SPI device is configured as +* a master, this function initiates bus communication and sends/receives the +* data to/from the selected SPI slave. If the SPI device is configured as a +* slave, this function prepares the buffers to be sent/received when selected +* by a master. For every byte sent, a byte is received. This function should +* be used to perform interrupt based transfers. +* +* 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: +*
+*   XSpiPs_Transfer(InstancePtr, SendBuf, RecvBuf, ByteCount)
+*	The caller wishes to send and receive, and provides two different
+*	buffers for send and receive.
+*
+*   XSpiPs_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.
+*
+*   XSpiPs_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.
+*
+*   XSpiPs_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. As a master, the SetSlaveSelect function must +* be called prior to this function. +* +* @param InstancePtr is a pointer to the XSpiPs instance. +* @param SendBufPtr is a pointer to a buffer of data for sending. +* 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 SPI bus at the same time. +* +******************************************************************************/ +s32 XSpiPs_Transfer(XSpiPs *InstancePtr, u8 *SendBufPtr, + u8 *RecvBufPtr, u32 ByteCount) +{ + u32 ConfigReg; + u8 TransCount = 0U; + s32 StatusTransfer; + + /* + * The RecvBufPtr argument can be null + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(SendBufPtr != NULL); + Xil_AssertNonvoid(ByteCount > 0U); + Xil_AssertNonvoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY); + + /* + * Check whether there is another transfer in progress. Not thread-safe. + */ + if (InstancePtr->IsBusy == TRUE) { + StatusTransfer = (s32)XST_DEVICE_BUSY; + } else { + + /* + * 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; + + /* + * If manual chip select mode, initialize the slave select value. + */ + if (XSpiPs_IsManualChipSelect(InstancePtr) != FALSE) { + ConfigReg = XSpiPs_ReadReg(InstancePtr->Config.BaseAddress, + XSPIPS_CR_OFFSET); + /* + * Set the slave select value. + */ + ConfigReg &= (u32)(~XSPIPS_CR_SSCTRL_MASK); + ConfigReg |= InstancePtr->SlaveSelect; + XSpiPs_WriteReg(InstancePtr->Config.BaseAddress, + XSPIPS_CR_OFFSET, ConfigReg); + } + + /* + * Enable the device. + */ + XSpiPs_Enable(InstancePtr); + + /* + * Clear all the interrrupts. + */ + XSpiPs_WriteReg(InstancePtr->Config.BaseAddress, XSPIPS_SR_OFFSET, + XSPIPS_IXR_WR_TO_CLR_MASK); + + /* + * Fill the TXFIFO with as many bytes as it will take (or as many as + * we have to send). + */ + while ((InstancePtr->RemainingBytes > 0U) && + (TransCount < XSPIPS_FIFO_DEPTH)) { + XSpiPs_SendByte(InstancePtr->Config.BaseAddress, + *InstancePtr->SendBufferPtr); + InstancePtr->SendBufferPtr += 1; + InstancePtr->RemainingBytes--; + TransCount++; + } + + /* + * Enable interrupts (connecting to the interrupt controller and + * enabling interrupts should have been done by the caller). + */ + XSpiPs_WriteReg(InstancePtr->Config.BaseAddress, + XSPIPS_IER_OFFSET, XSPIPS_IXR_DFLT_MASK); + + /* + * If master mode and manual start mode, issue manual start command + * to start the transfer. + */ + if ((XSpiPs_IsManualStart(InstancePtr) == TRUE) + && (XSpiPs_IsMaster(InstancePtr) == TRUE)) { + ConfigReg = XSpiPs_ReadReg(InstancePtr->Config.BaseAddress, + XSPIPS_CR_OFFSET); + ConfigReg |= XSPIPS_CR_MANSTRT_MASK; + XSpiPs_WriteReg(InstancePtr->Config.BaseAddress, + XSPIPS_CR_OFFSET, ConfigReg); + } + StatusTransfer = (s32)XST_SUCCESS; + } + return StatusTransfer; +} + +/*****************************************************************************/ +/** +* Transfers specified data on the SPI 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: +*
+*   XSpiPs_PolledTransfer(InstancePtr, SendBuf, RecvBuf, ByteCount)
+*	The caller wishes to send and receive, and provides two different
+*	buffers for send and receive.
+*
+*   XSpiPs_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.
+*
+*   XSpiPs_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.
+*
+*   XSpiPs_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 XSpiPs instance. +* @param SendBufPtr is a pointer to a buffer of data for sending. +* 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 SPI bus at the same time. +* +******************************************************************************/ +s32 XSpiPs_PolledTransfer(XSpiPs *InstancePtr, u8 *SendBufPtr, + u8 *RecvBufPtr, u32 ByteCount) +{ + u32 StatusReg; + u32 ConfigReg; + u32 TransCount; + u32 CheckTransfer; + s32 Status_Polled; + u8 TempData; + + /* + * The RecvBufPtr argument can be NULL. + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(SendBufPtr != NULL); + Xil_AssertNonvoid(ByteCount > 0U); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Check whether there is another transfer in progress. Not thread-safe. + */ + if (InstancePtr->IsBusy == TRUE) { + Status_Polled = (s32)XST_DEVICE_BUSY; + } else { + + /* + * 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; + + /* + * If manual chip select mode, initialize the slave select value. + */ + if (XSpiPs_IsManualChipSelect(InstancePtr) == TRUE) { + ConfigReg = XSpiPs_ReadReg(InstancePtr->Config.BaseAddress, + XSPIPS_CR_OFFSET); + /* + * Set the slave select value. + */ + ConfigReg &= (u32)(~XSPIPS_CR_SSCTRL_MASK); + ConfigReg |= InstancePtr->SlaveSelect; + XSpiPs_WriteReg(InstancePtr->Config.BaseAddress, + XSPIPS_CR_OFFSET, ConfigReg); + } + + /* + * Enable the device. + */ + XSpiPs_Enable(InstancePtr); + + while((InstancePtr->RemainingBytes > (u32)0U) || + (InstancePtr->RequestedBytes > (u32)0U)) { + TransCount = 0U; + /* + * Fill the TXFIFO with as many bytes as it will take (or as + * many as we have to send). + */ + while ((InstancePtr->RemainingBytes > (u32)0U) && + ((u32)TransCount < (u32)XSPIPS_FIFO_DEPTH)) { + XSpiPs_SendByte(InstancePtr->Config.BaseAddress, + *InstancePtr->SendBufferPtr); + InstancePtr->SendBufferPtr += 1; + InstancePtr->RemainingBytes--; + ++TransCount; + } + + /* + * If master mode and manual start mode, issue manual start + * command to start the transfer. + */ + if ((XSpiPs_IsManualStart(InstancePtr) == TRUE) + && (XSpiPs_IsMaster(InstancePtr) == TRUE)) { + ConfigReg = XSpiPs_ReadReg( + InstancePtr->Config.BaseAddress, + XSPIPS_CR_OFFSET); + ConfigReg |= XSPIPS_CR_MANSTRT_MASK; + XSpiPs_WriteReg(InstancePtr->Config.BaseAddress, + XSPIPS_CR_OFFSET, ConfigReg); + } + + /* + * Wait for the transfer to finish by polling Tx fifo status. + */ + CheckTransfer = (u32)0U; + while (CheckTransfer == 0U){ + StatusReg = XSpiPs_ReadReg( + InstancePtr->Config.BaseAddress, + XSPIPS_SR_OFFSET); + if ( (StatusReg & XSPIPS_IXR_MODF_MASK) != 0U) { + /* + * Clear the mode fail bit + */ + XSpiPs_WriteReg( + InstancePtr->Config.BaseAddress, + XSPIPS_SR_OFFSET, + XSPIPS_IXR_MODF_MASK); + Status_Polled = (s32)XST_SEND_ERROR; + goto END; + } + CheckTransfer = (StatusReg & + XSPIPS_IXR_TXOW_MASK); + } + + /* + * 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 (TransCount != (u32)0U) { + TempData = (u8)XSpiPs_RecvByte( + InstancePtr->Config.BaseAddress); + if (InstancePtr->RecvBufferPtr != NULL) { + *(InstancePtr->RecvBufferPtr) = TempData; + InstancePtr->RecvBufferPtr += 1; + } + InstancePtr->RequestedBytes--; + --TransCount; + } + } + + /* + * Clear the slave selects now, before terminating the transfer. + */ + if (XSpiPs_IsManualChipSelect(InstancePtr) == TRUE) { + ConfigReg = XSpiPs_ReadReg(InstancePtr->Config.BaseAddress, + XSPIPS_CR_OFFSET); + ConfigReg |= XSPIPS_CR_SSCTRL_MASK; + XSpiPs_WriteReg(InstancePtr->Config.BaseAddress, + XSPIPS_CR_OFFSET, ConfigReg); + } + + /* + * Clear the busy flag. + */ + InstancePtr->IsBusy = FALSE; + + /* + * Disable the device. + */ + XSpiPs_Disable(InstancePtr); + Status_Polled = (s32)XST_SUCCESS; + } + + END: + return Status_Polled; +} + +/*****************************************************************************/ +/** +* +* Selects or deselect the slave with which the master communicates. This setting +* affects the SPI_ss_outN signals. The behavior depends on the setting of the +* CR_SSDECEN bit. If CR_SSDECEN is 0, the SPI_ss_outN bits will be output with a +* single signal low. If CR_SSDECEN is 1, the SPI_ss_outN bits will reflect the +* value set. +* +* The user is not allowed to deselect the slave while a transfer is in progress. +* If no transfer is in progress, the user can select a new slave, which +* implicitly deselects the current slave. In order to explicitly deselect the +* current slave, a value of all 1's, 0x0F can be passed in as the argument to +* the function. +* +* @param InstancePtr is a pointer to the XSpiPs instance. +* @param SlaveSel is the slave number to be selected. +* Normally, 3 slaves can be selected with values 0-2. +* In case, 3-8 decode option is set, then upto 8 slaves +* can be selected. Only one slave can be selected at a time. +* +* @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 SPI is idle. The slave select +* has no affect when the device is configured as a slave. +* +******************************************************************************/ +s32 XSpiPs_SetSlaveSelect(XSpiPs *InstancePtr, u8 SlaveSel) +{ + u32 ConfigReg; + s32 Status_Slave; + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid(SlaveSel <= XSPIPS_CR_SSCTRL_MAXIMUM); + + /* + * Do not allow the slave select to change while a transfer is in + * progress. Not thread-safe. + */ + if (InstancePtr->IsBusy == TRUE) { + Status_Slave = (s32)XST_DEVICE_BUSY; + } else { + /* + * If decode slave select option is set, + * then set slave select value directly. + * Update the Instance structure member. + */ + if ( XSpiPs_IsDecodeSSelect( InstancePtr ) == TRUE) { + InstancePtr->SlaveSelect = ((u32)SlaveSel) << XSPIPS_CR_SSCTRL_SHIFT; + } + else { + /* + * Set the bit position to low using SlaveSel. Update the Instance + * structure member. + */ + InstancePtr->SlaveSelect = ((~(1U << SlaveSel)) & \ + XSPIPS_CR_SSCTRL_MAXIMUM) << XSPIPS_CR_SSCTRL_SHIFT; + } + + /* + * Read the config register, update the slave select value and write + * back to config register. + */ + ConfigReg = XSpiPs_ReadReg(InstancePtr->Config.BaseAddress, + XSPIPS_CR_OFFSET); + ConfigReg &= (u32)(~XSPIPS_CR_SSCTRL_MASK); + ConfigReg |= InstancePtr->SlaveSelect; + XSpiPs_WriteReg(InstancePtr->Config.BaseAddress, XSPIPS_CR_OFFSET, + ConfigReg); + Status_Slave = (s32)XST_SUCCESS; + } + return Status_Slave; +} + +/*****************************************************************************/ +/** +* +* Gets the current slave select setting for the SPI device. +* +* @param InstancePtr is a pointer to the XSpiPs instance. +* +* @return The slave number selected (starting from 0). +* +* @note None. +* +******************************************************************************/ +u8 XSpiPs_GetSlaveSelect(const XSpiPs *InstancePtr) +{ + u32 ConfigReg; + u32 SlaveSel; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + ConfigReg = InstancePtr->SlaveSelect; + ConfigReg &= XSPIPS_CR_SSCTRL_MASK; + ConfigReg >>= XSPIPS_CR_SSCTRL_SHIFT; + ConfigReg &= XSPIPS_CR_SSCTRL_MAXIMUM; + + /* + * If decode slave select option is set, then read value directly. + */ + if ( XSpiPs_IsDecodeSSelect( InstancePtr ) == TRUE) { + SlaveSel = ConfigReg; + } + else { + + /* + * Get the slave select value + */ + if(ConfigReg == 0x0FU) { + /* + * No slave selected + */ + SlaveSel = 0xFU; + }else { + /* + * Get selected slave number (0,1 or 2) + */ + SlaveSel = ((~ConfigReg) & XSPIPS_CR_SSCTRL_MAXIMUM)/2U; + } + } + return (u8)SlaveSel; +} + +/*****************************************************************************/ +/** +* +* 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_MODE_FAULT		A mode fault error occurred, meaning the device
+*				is selected as slave while being a master.
+*
+* 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 SPI device lost data. Data was received
+*				but the receive data register/FIFO was full.
+*
+* XST_SPI_SLAVE_MODE_FAULT	A slave SPI device was selected as a slave
+*				while it was disabled. This indicates the
+*				master is already transferring data (which is
+*				being dropped until the slave application
+*				issues a transfer).
+* 
+* @param InstancePtr is a pointer to the XSpiPs instance. +* @param CallBackRef is the upper layer callback reference passed back +* when the callback function is invoked. +* @param FunctionPtr 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 XSpiPs_SetStatusHandler(XSpiPs *InstancePtr, void *CallBackRef, + XSpiPs_StatusHandler FunctionPtr) +{ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(FunctionPtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + InstancePtr->StatusHandler = FunctionPtr; + 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(const void *CallBackRef, u32 StatusEvent, + u32 ByteCount) +{ + (const void) CallBackRef; + (void) StatusEvent; + (void) ByteCount; + + Xil_AssertVoidAlways(); +} + +/*****************************************************************************/ +/** +* +* The interrupt handler for SPI interrupts. This function must be connected +* by the user to an interrupt controller. +* +* The interrupts that are handled are: +* +* - Mode Fault Error. This interrupt is generated if this device is selected +* as a slave when it is configured as a master. The driver aborts any data +* transfer that is in progress by resetting FIFOs (if present) and resetting +* its buffer pointers. The upper layer software is informed of the error. +* +* - 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 SPI 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 +* SPI 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. +* +* - Slave Mode Fault Error. This interrupt is generated if a slave device is +* selected as a slave while it is disabled. 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 XSpiPs instance. +* +* @return None. +* +* @note +* +* The slave select register is being set to deselect the slave when a transfer +* is complete. This is being done regardless of whether it is a slave or a +* master since the hardware does not drive the slave select as a slave. +* +******************************************************************************/ +void XSpiPs_InterruptHandler(XSpiPs *InstancePtr) +{ + XSpiPs *SpiPtr = InstancePtr; + u32 IntrStatus; + u32 ConfigReg; + u32 BytesDone; /* Number of bytes done so far. */ + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(SpiPtr->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. + * Disable the TXOW interrupt because we transmit from within the ISR, + * which could potentially cause another TX_OW interrupt. + */ + IntrStatus = + XSpiPs_ReadReg(SpiPtr->Config.BaseAddress, XSPIPS_SR_OFFSET); + XSpiPs_WriteReg(SpiPtr->Config.BaseAddress, XSPIPS_SR_OFFSET, + (IntrStatus & XSPIPS_IXR_WR_TO_CLR_MASK)); + XSpiPs_WriteReg(SpiPtr->Config.BaseAddress, XSPIPS_IDR_OFFSET, + XSPIPS_IXR_TXOW_MASK); + + /* + * Check for mode fault error. We want to check for this error first, + * before checking for progress of a transfer, since this error needs + * to abort any operation in progress. + */ + if ((u32)XSPIPS_IXR_MODF_MASK == (u32)(IntrStatus & XSPIPS_IXR_MODF_MASK)) { + BytesDone = SpiPtr->RequestedBytes - SpiPtr->RemainingBytes; + + /* + * Abort any operation currently in progress. This includes + * clearing the mode fault condition by reading the status + * register. Note that the status register should be read after + * the abort, since reading the status register clears the mode + * fault condition and would cause the device to restart any + * transfer that may be in progress. + */ + XSpiPs_Abort(SpiPtr); + + SpiPtr->StatusHandler(SpiPtr->StatusRef, XST_SPI_MODE_FAULT, + BytesDone); + + goto END; /* Do not continue servicing other interrupts. */ + } + + + if ((IntrStatus & XSPIPS_IXR_TXOW_MASK) != 0U) { + u8 TempData; + u32 TransCount; + /* + * 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. 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). + * Initialize the TransCount based on the requested bytes. + * Loop on receive FIFO based on TransCount. + */ + TransCount = SpiPtr->RequestedBytes - SpiPtr->RemainingBytes; + + while (TransCount != 0U) { + TempData = (u8)XSpiPs_RecvByte(SpiPtr->Config.BaseAddress); + if (SpiPtr->RecvBufferPtr != NULL) { + *SpiPtr->RecvBufferPtr = TempData; + SpiPtr->RecvBufferPtr += 1; + } + SpiPtr->RequestedBytes--; + --TransCount; + } + + /* + * Fill the TXFIFO until data exists, otherwise fill upto + * FIFO depth. + */ + while ((SpiPtr->RemainingBytes > 0U) && + (TransCount < XSPIPS_FIFO_DEPTH)) { + XSpiPs_SendByte(SpiPtr->Config.BaseAddress, + *SpiPtr->SendBufferPtr); + SpiPtr->SendBufferPtr += 1; + SpiPtr->RemainingBytes--; + ++TransCount; + } + + if ((SpiPtr->RemainingBytes == 0U) && + (SpiPtr->RequestedBytes == 0U)) { + /* + * 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. + */ + XSpiPs_WriteReg(SpiPtr->Config.BaseAddress, + XSPIPS_IDR_OFFSET, XSPIPS_IXR_DFLT_MASK); + + /* + * Disable slave select lines as the transfer + * is complete. + */ + if (XSpiPs_IsManualChipSelect(InstancePtr) == TRUE) { + ConfigReg = XSpiPs_ReadReg( + SpiPtr->Config.BaseAddress, + XSPIPS_CR_OFFSET); + ConfigReg |= XSPIPS_CR_SSCTRL_MASK; + XSpiPs_WriteReg( + SpiPtr->Config.BaseAddress, + XSPIPS_CR_OFFSET, ConfigReg); + } + + /* + * Clear the busy flag. + */ + SpiPtr->IsBusy = FALSE; + + /* + * Disable the device. + */ + XSpiPs_Disable(SpiPtr); + + /* + * Inform the Transfer done to upper layers. + */ + SpiPtr->StatusHandler(SpiPtr->StatusRef, + XST_SPI_TRANSFER_DONE, + SpiPtr->RequestedBytes); + } else { + /* + * Enable the TXOW interrupt. + */ + XSpiPs_WriteReg(SpiPtr->Config.BaseAddress, + XSPIPS_IER_OFFSET, XSPIPS_IXR_TXOW_MASK); + /* + * Start the transfer by not inhibiting the transmitter + * any longer. + */ + if ((XSpiPs_IsManualStart(SpiPtr) == TRUE) + && (XSpiPs_IsMaster(SpiPtr) == TRUE)) { + ConfigReg = XSpiPs_ReadReg( + SpiPtr->Config.BaseAddress, + XSPIPS_CR_OFFSET); + ConfigReg |= XSPIPS_CR_MANSTRT_MASK; + XSpiPs_WriteReg( + SpiPtr->Config.BaseAddress, + XSPIPS_CR_OFFSET, ConfigReg); + } + } + } + + /* + * Check for overflow and underflow errors. + */ + if ((IntrStatus & XSPIPS_IXR_RXOVR_MASK) != 0U) { + BytesDone = SpiPtr->RequestedBytes - SpiPtr->RemainingBytes; + SpiPtr->IsBusy = FALSE; + + /* + * The Slave select lines are being manually controlled. + * Disable them because the transfer is complete. + */ + if (XSpiPs_IsManualChipSelect(SpiPtr) == TRUE) { + ConfigReg = XSpiPs_ReadReg( + SpiPtr->Config.BaseAddress, + XSPIPS_CR_OFFSET); + ConfigReg |= XSPIPS_CR_SSCTRL_MASK; + XSpiPs_WriteReg( + SpiPtr->Config.BaseAddress, + XSPIPS_CR_OFFSET, ConfigReg); + } + + SpiPtr->StatusHandler(SpiPtr->StatusRef, + XST_SPI_RECEIVE_OVERRUN, BytesDone); + } + + if ((IntrStatus & XSPIPS_IXR_TXUF_MASK) != 0U) { + BytesDone = SpiPtr->RequestedBytes - SpiPtr->RemainingBytes; + + SpiPtr->IsBusy = FALSE; + /* + * The Slave select lines are being manually controlled. + * Disable them because the transfer is complete. + */ + if (XSpiPs_IsManualChipSelect(SpiPtr) == TRUE) { + ConfigReg = XSpiPs_ReadReg( + SpiPtr->Config.BaseAddress, + XSPIPS_CR_OFFSET); + ConfigReg |= XSPIPS_CR_SSCTRL_MASK; + XSpiPs_WriteReg( + SpiPtr->Config.BaseAddress, + XSPIPS_CR_OFFSET, ConfigReg); + } + + SpiPtr->StatusHandler(SpiPtr->StatusRef, + XST_SPI_TRANSMIT_UNDERRUN, BytesDone); + } + + END: + return; + +} + +/*****************************************************************************/ +/** +* +* Aborts a transfer in progress by disabling the device and resetting the FIFOs +* if present. The byte counts are cleared, the busy flag is cleared, and mode +* fault is cleared. +* +* @param InstancePtr is a pointer to the XSpiPs 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 XSpiPs_Abort(XSpiPs *InstancePtr) +{ + + u8 Temp; + u32 Check; +#if !defined(versal) + u32 Count; +#endif + XSpiPs_Disable(InstancePtr); + + /* + * Clear the RX FIFO and drop any data. + */ + Check = (XSpiPs_ReadReg(InstancePtr->Config.BaseAddress, + XSPIPS_SR_OFFSET) & XSPIPS_IXR_RXNEMPTY_MASK); + while (Check != (u32)0U) { + Temp = (u8)XSpiPs_RecvByte(InstancePtr->Config.BaseAddress); + if(Temp != (u8)0U){ + } + Check = (XSpiPs_ReadReg(InstancePtr->Config.BaseAddress, + XSPIPS_SR_OFFSET) & XSPIPS_IXR_RXNEMPTY_MASK); + } + + /* + * Read all RX_FIFO entries + */ +#if !defined(versal) + for (Count = 0U; Count < XSPIPS_FIFO_DEPTH; Count++) { + (void)XSpiPs_ReadReg(InstancePtr->Config.BaseAddress, + XSPIPS_RXD_OFFSET); + } +#endif + /* + * Clear mode fault condition. + */ + XSpiPs_WriteReg(InstancePtr->Config.BaseAddress, + XSPIPS_SR_OFFSET, + XSPIPS_IXR_MODF_MASK); + + InstancePtr->RemainingBytes = 0U; + InstancePtr->RequestedBytes = 0U; + InstancePtr->IsBusy = FALSE; +} + +/** @} */ diff --git a/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/spips_v3_2/src/xspips.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/spips_v3_2/src/xspips.h new file mode 100644 index 0000000..1daee72 --- /dev/null +++ b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/spips_v3_2/src/xspips.h @@ -0,0 +1,703 @@ +/****************************************************************************** +* +* 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 xspips.h +* @addtogroup spips_v3_2 +* @{ +* @details +* +* This file contains the implementation of the XSpiPs driver. It works for +* both the master and slave mode. User documentation for the driver functions +* is contained in this file in the form of comment blocks at the front of each +* function. +* +* An SPI device connects to an SPI bus through a 4-wire serial interface. +* The SPI 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. +* +* Initialization & Configuration +* +* The XSpiPs_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: +* - XSpiPs_LookupConfig(DeviceId) - Use the devide identifier to find the +* static configuration structure defined in xspips_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. +* - XSpiPs_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. +* +* Multiple Slaves +* +* Contention between multiple masters is detected by the hardware, in which +* case a mode fault occurs on the device. The device is disabled immediately +* by hardware, and the current word transfer is stopped. The Aborted word +* transfer due to the mode fault is resumed once the devie is enabled again. +* +* 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 deasserted when the TXFIFO becomes +* empty +* - Manual CS: Software must assert and deassert 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 deasserted. +* 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, +* XSpiPs_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 Full +* - Data Receive Register/FIFO Not Empty +* - Data Transmit Register/FIFO Full +* - Data Transmit Register/FIFO Overwater +* - Mode Fault Error +* - Data Receive Register/FIFO Overrun +* +* The Data Transmit Register/FIFO Overwater interrupt -- indicates that the +* SPI 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 SPI 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 SPI +* device received data and subsequently dropped the data because the data +* receive register and FIFO was full. The interrupt applies to both master +* and slave operation. 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. +* +* The Mode Fault Error interrupt -- indicates that while configured as a +* master, the device was selected as a slave by another master. This can be +* used by the application for arbitration in a multimaster environment or to +* indicate a problem with arbitration. When this interrupt occurs, the +* driver invokes the status callback with a status value of +* XST_SPI_MODE_FAULT. It is up to the application to resolve the conflict. +* When configured as a slave, Mode Fault Error interrupt indicates that a slave +* device was selected as a slave by a master, but the slave device was +* disabled. When configured as a master, Mode Fault Error interrupt indicates +* that another SPI device is acting as a master on the bus. +* +* +* Polled Operation +* +* Transfer in polled mode is supported through a separate interface function +* XSpiPs_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). This applies to both +* master and slave devices. +* +* Device Configuration +* +* The device can be configured in various ways during the FPGA implementation +* process. Configuration parameters are stored in the xspips_g.c file or +* passed in via XSpiPs_CfgInitialize(). A table is defined where each entry +* contains configuration information for an SPI 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. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date     Changes
+* ----- ------ -------- -----------------------------------------------
+* 1.00	drg/jz 01/25/10 First release
+* 1.00	sdm    10/25/11 Removed the Divide by 2 in the SPI Clock Prescaler
+*			options as this is not supported in the device.
+* 1.01	sg     03/07/12 Updated the code to always clear the relevant bits
+*			before writing to config register.
+*			Always clear the slave select bits before write and
+*			clear the bits to no slave at the end of transfer
+*			Modified the Polled transfer transmit/receive logic.
+*			Tx should wait on TXOW Interrupt and Rx on RXNEMTY.
+* 1.02	sg     05/31/12 Updated XSPIPS_FIFO_DEPTH to 128 from 32 to match HW
+*			for CR 658289
+* 1.03	sg     09/21/12 Added memory barrier dmb in polled transfer and
+*			interrupt handler to overcome the clock domain
+*			crossing issue in the controller. For CR #679252.
+* 1.04a	sg     01/30/13 Created XSPIPS_MANUAL_START_OPTION. Created macros
+*			XSpiPs_IsMaster, XSpiPs_IsManualStart and
+*			XSpiPs_IsManualChipSelect. Changed SPI
+*			Enable/Disable macro argument from BaseAddress to
+*			Instance Pointer. Added DelayNss argument to SetDelays
+*			and GetDelays API's. Added macros to set/get the
+*			RX Watermark value.Created macros XSpiPs_IsMaster,
+*			XSpiPs_IsManualStart and XSpiPs_IsManualChipSelect.
+*			Changed SPI 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.
+*			SetSlaveSelect API logic is modified to drive the bit
+*			position low based on the slave select value
+*			requested. GetSlaveSelect API will return the value
+*			based on bit position that is low.
+*			Created XSPIPS_CR_MODF_GEN_EN_MASK macro and added it
+*			to XSPIPS_CR_RESET_STATE. Created
+* 			XSPIPS_IXR_WR_TO_CLR_MASK for interrupts which need
+*			write-to-clear. Added shift and mask macros for d_nss
+*			parameter. Added Rx Watermark mask.
+* 1.05a hk 	   26/04/13 Added disable and enable in XSpiPs_SetOptions when
+*				CPOL/CPHA bits are set/reset. Fix for CR#707669.
+* 1.06a hk     08/22/13 Changed GetSlaveSelect function. CR# 727866.
+*                       Added masking ConfigReg before writing in SetSlaveSel
+*                       Added extended slave select support - CR#722569.
+*                       Added prototypes of reset API and related constant
+*                       definitions.
+*                       Added check for MODF in polled transfer function.
+* 3.0   vm    12/09/14	Modified driver source code for MISRA-C:2012 compliance.
+*			Support for Zynq Ultrascale Mp added.
+*       ms     03/17/17 Added readme.txt file in examples folder for doxygen
+*                       generation.
+*       ms     04/05/17 Modified Comment lines in functions of spips
+*                       examples to recognize it as documentation block
+*                       for doxygen generation and also modified filename tag
+*                       in eeprom interrupt, eeprom polled and flash polled
+*                       files to include them in doxygen examples.
+* 3.1	tjs    04/12/18 InputClockHz parameter copied in instance for use in
+* 						application. CR#998910
+* 3.2   aru    01/20/19 Fixes violations according to MISRAC-2012
+*                       in safety mode and done changes such as
+*                       Declared the pointer param as Pointer to const.
+* 3.2   nsk    03/26/19 Add support for versal - CR #1025583.
+* 
+* +******************************************************************************/ +#ifndef XSPIPS_H /* prevent circular inclusions */ +#define XSPIPS_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +#include "xstatus.h" +#include "xspips_hw.h" + +/************************** Constant Definitions *****************************/ + +/** @name Configuration options + * + * The following options are supported to enable/disable certain features of + * an SPI device. Each of the options is a bit mask, so more than one may be + * specified. + * + * The Master option configures the SPI device as a master. + * By default, the device is a slave. + * + * 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 SPI 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 Slave Select Decode Enable option selects how the SPI_SS_outN are + * controlled by the SPI Slave Select Decode bits. + * 0: Use this setting for the standard configuration of up to three slave + * select outputs. Only one of the three slave select outputs will be low. + * (Default) + * 1: Use this setting for the optional configuration of an additional decoder + * to support 8 slave select outputs. SPI_SS_outN reflects the value in the + * register. + * + * The SPI Force Slave Select option is used to enable manual control of + * the signals SPI_SS_outN. + * 0: The SPI_SS_outN signals are controlled by the SPI controller during + * transfers. (Default) + * 1: The SPI_SS_outN signal indicated by the Slave Select Control bit 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 + * SPI clock to be set to a faster speed. If the SPI clock is too fast, the + * processor cannot empty and refill the FIFOs before the TX FIFO is empty + * When the SPI 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 SPI 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 XSPIPS_MASTER_OPTION 0x00000001U /**< Master mode option */ +#define XSPIPS_CLK_ACTIVE_LOW_OPTION 0x00000002U /**< Active Low Clock option */ +#define XSPIPS_CLK_PHASE_1_OPTION 0x00000004U /**< Clock Phase one option */ +#define XSPIPS_DECODE_SSELECT_OPTION 0x00000008U /**< Select 16 slaves Option */ +#define XSPIPS_FORCE_SSELECT_OPTION 0x00000010U /**< Force Slave Select */ +#define XSPIPS_MANUAL_START_OPTION 0x00000020U /**< Manual Start mode option */ +/*@}*/ + + +/** @name SPI Clock Prescaler options + * The SPI 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/4 to pclk/256. + * + * @{ + */ + +#define XSPIPS_CLK_PRESCALE_4 0x01U /**< PCLK/4 Prescaler */ +#define XSPIPS_CLK_PRESCALE_8 0x02U /**< PCLK/8 Prescaler */ +#define XSPIPS_CLK_PRESCALE_16 0x03U /**< PCLK/16 Prescaler */ +#define XSPIPS_CLK_PRESCALE_32 0x04U /**< PCLK/32 Prescaler */ +#define XSPIPS_CLK_PRESCALE_64 0x05U /**< PCLK/64 Prescaler */ +#define XSPIPS_CLK_PRESCALE_128 0x06U /**< PCLK/128 Prescaler */ +#define XSPIPS_CLK_PRESCALE_256 0x07U /**< 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 XSPIPS_EVENT_MODE_FAULT 1U /**< Mode fault error */ +#define XSPIPS_EVENT_TRANSFER_DONE 2U /**< Transfer done */ +#define XSPIPS_EVENT_TRANSMIT_UNDERRUN 3U /**< TX FIFO empty */ +#define XSPIPS_EVENT_RECEIVE_OVERRUN 4U /**< Receive data loss because + RX FIFO full */ +/*@}*/ + + +/**************************** Type Definitions *******************************/ +/** + * The handler data type allows the user to define a callback function to + * handle the asynchronous processing for the SPI 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 XSpiPs_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 (*XSpiPs_StatusHandler) (const void *CallBackRef, u32 StatusEvent, + u32 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 */ +} XSpiPs_Config; + +/** + * The XSpiPs driver instance data. The user is required to allocate a + * variable of this type for every SPI device in the system. A pointer + * to a variable of this type is then passed to the driver API functions. + */ +typedef struct { + XSpiPs_Config Config; /**< Configuration structure */ + u32 IsReady; /**< Device is initialized and ready */ + + u8 *SendBufferPtr; /**< Buffer to send (state) */ + u8 *RecvBufferPtr; /**< Buffer to receive (state) */ + u32 RequestedBytes; /**< Number of bytes to transfer (state) */ + u32 RemainingBytes; /**< Number of bytes left to transfer(state) */ + u32 IsBusy; /**< A transfer is in progress (state) */ + u32 SlaveSelect; /**< The slave select value when + XSPIPS_FORCE_SSELECT_OPTION is set */ + + XSpiPs_StatusHandler StatusHandler; + void *StatusRef; /**< Callback reference for status handler */ + +} XSpiPs; + +/***************** Macros (Inline Functions) Definitions *********************/ +/****************************************************************************/ +/* +* +* Check in OptionsTable if Manual Start 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 XSpiPs_IsManualStart(XSpiPs *InstancePtr) +* +*****************************************************************************/ +#define XSpiPs_IsManualStart(InstancePtr) \ + (((XSpiPs_GetOptions(InstancePtr) & \ + XSPIPS_MANUAL_START_OPTION) != (u32)0U) ? 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 XSpiPs_IsManualChipSelect(XSpiPs *InstancePtr) +* +*****************************************************************************/ +#define XSpiPs_IsManualChipSelect(InstancePtr) \ + (((XSpiPs_GetOptions(InstancePtr) & \ + XSPIPS_FORCE_SSELECT_OPTION) != (u32)0U) ? TRUE : FALSE) + +/****************************************************************************/ +/* +* +* Check in OptionsTable if Decode Slave 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 XSpiPs_IsDecodeSSelect(XSpiPs *InstancePtr) +* +*****************************************************************************/ +#define XSpiPs_IsDecodeSSelect(InstancePtr) \ + (((XSpiPs_GetOptions(InstancePtr) & \ + XSPIPS_DECODE_SSELECT_OPTION) != (u32)0U) ? TRUE : FALSE) + +/****************************************************************************/ +/* +* +* Check in OptionsTable if Master 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 XSpiPs_IsMaster(XSpiPs *InstancePtr) +* +*****************************************************************************/ +#define XSpiPs_IsMaster(InstancePtr) \ + (((XSpiPs_GetOptions(InstancePtr) & \ + XSPIPS_MASTER_OPTION) != (u32)0U) ? TRUE : FALSE) + +/****************************************************************************/ +/** +* +* Set the contents of the slave idle count register. +* +* @param InstancePtr is a pointer to the XSpiPs instance. +* @param RegisterValue is the value to be writen, valid values are +* 0-255. +* +* @return None +* +* @note +* C-Style signature: +* void XSpiPs_SetSlaveIdle(XSpiPs *InstancePtr, u32 RegisterValue) +* +*****************************************************************************/ +#define XSpiPs_SetSlaveIdle(InstancePtr, RegisterValue) \ + XSpiPs_Out32(((InstancePtr)->Config.BaseAddress) + \ + XSPIPS_SICR_OFFSET, (RegisterValue)) + +/****************************************************************************/ +/** +* +* Get the contents of the slave idle count register. Use the XSPIPS_SICR_* +* constants defined in xspips_hw.h to interpret the bit-mask returned. +* +* @param InstancePtr is a pointer to the XSpiPs instance. +* +* @return 8-bit value representing the contents of the SIC register. +* +* @note C-Style signature: +* u32 XSpiPs_GetSlaveIdle(XSpiPs *InstancePtr) +* +*****************************************************************************/ +#define XSpiPs_GetSlaveIdle(InstancePtr) \ + XSpiPs_In32(((InstancePtr)->Config.BaseAddress) + \ + XSPIPS_SICR_OFFSET) + +/****************************************************************************/ +/** +* +* Set the contents of the transmit FIFO watermark register. +* +* @param InstancePtr is a pointer to the XSpiPs instance. +* @param RegisterValue is the value to be written, valid values +* are 1-128. +* +* @return None. +* +* @note +* C-Style signature: +* void XSpiPs_SetTXWatermark(XSpiPs *InstancePtr, u32 RegisterValue) +* +*****************************************************************************/ +#define XSpiPs_SetTXWatermark(InstancePtr, RegisterValue) \ + XSpiPs_Out32(((InstancePtr)->Config.BaseAddress) + \ + XSPIPS_TXWR_OFFSET, (RegisterValue)) + +/****************************************************************************/ +/** +* +* Get the contents of the transmit FIFO watermark register. +* Use the XSPIPS_TXWR_* constants defined xspips_hw.h to interpret +* the bit-mask returned. +* +* @param InstancePtr is a pointer to the XSpiPs instance. +* +* @return 8-bit value representing the contents of the TXWR register. +* +* @note C-Style signature: +* u32 XSpiPs_GetTXWatermark(u32 *InstancePtr) +* +*****************************************************************************/ +#define XSpiPs_GetTXWatermark(InstancePtr) \ + XSpiPs_In32(((InstancePtr)->Config.BaseAddress) + XSPIPS_TXWR_OFFSET) + +/****************************************************************************/ +/** +* +* Set the contents of the receive FIFO watermark register. +* +* @param InstancePtr is a pointer to the XSpiPs instance. +* @param RegisterValue is the value to be written, valid values +* are 1-128. +* +* @return None. +* +* @note +* C-Style signature: +* void XSpiPs_SetRXWatermark(XSpiPs *InstancePtr, u32 RegisterValue) +* +*****************************************************************************/ +#define XSpiPs_SetRXWatermark(InstancePtr, RegisterValue) \ + XSpiPs_Out32(((InstancePtr)->Config.BaseAddress) + \ + XSPIPS_RXWR_OFFSET, (RegisterValue)) + +/****************************************************************************/ +/** +* +* Get the contents of the receive FIFO watermark register. +* Use the XSPIPS_RXWR_* constants defined xspips_hw.h to interpret +* the bit-mask returned. +* +* @param InstancePtr is a pointer to the XSpiPs instance. +* +* @return A 8-bit value representing the contents of the RXWR register. +* +* @note C-Style signature: +* u32 XSpiPs_GetRXWatermark(u32 *InstancePtr) +* +*****************************************************************************/ +#define XSpiPs_GetRXWatermark(InstancePtr) \ + XSpiPs_In32(((InstancePtr)->Config.BaseAddress) + XSPIPS_RXWR_OFFSET) + +/****************************************************************************/ +/** +* +* Enable the device and uninhibit master transactions. +* +* @param InstancePtr is a pointer to the XSpiPs instance. +* +* @return None. +* +* @note C-Style signature: +* void XSpiPs_Enable(u32 *InstancePtr) +* +*****************************************************************************/ +#define XSpiPs_Enable(InstancePtr) \ + XSpiPs_Out32(((InstancePtr)->Config.BaseAddress) + XSPIPS_ER_OFFSET, \ + XSPIPS_ER_ENABLE_MASK) + +/****************************************************************************/ +/** +* +* Disable the device. +* +* @param InstancePtr is a pointer to the XSpiPs instance. +* +* @return None. +* +* @note C-Style signature: +* void XSpiPs_Disable(u32 *InstancePtr) +* +*****************************************************************************/ +#define XSpiPs_Disable(InstancePtr) \ + XSpiPs_Out32(((InstancePtr)->Config.BaseAddress) + XSPIPS_ER_OFFSET, 0U) + +/************************** Function Prototypes ******************************/ + +/* + * Initialization function, implemented in xspips_sinit.c + */ +XSpiPs_Config *XSpiPs_LookupConfig(u16 DeviceId); + +/* + * Functions implemented in xspips.c + */ +s32 XSpiPs_CfgInitialize(XSpiPs *InstancePtr, const XSpiPs_Config * ConfigPtr, + u32 EffectiveAddr); + +void XSpiPs_Reset(XSpiPs *InstancePtr); + +s32 XSpiPs_Transfer(XSpiPs *InstancePtr, u8 *SendBufPtr, u8 *RecvBufPtr, + u32 ByteCount); + +s32 XSpiPs_PolledTransfer(XSpiPs *InstancePtr, u8 *SendBufPtr, + u8 *RecvBufPtr, u32 ByteCount); + +void XSpiPs_SetStatusHandler(XSpiPs *InstancePtr, void *CallBackRef, + XSpiPs_StatusHandler FunctionPtr); +void XSpiPs_InterruptHandler(XSpiPs *InstancePtr); + +void XSpiPs_Abort(XSpiPs *InstancePtr); + +s32 XSpiPs_SetSlaveSelect(XSpiPs *InstancePtr, u8 SlaveSel); +u8 XSpiPs_GetSlaveSelect(const XSpiPs *InstancePtr); + +/* + * Functions for selftest, in xspips_selftest.c + */ +s32 XSpiPs_SelfTest(XSpiPs *InstancePtr); + +/* + * Functions for options, in xspips_options.c + */ +s32 XSpiPs_SetOptions(const XSpiPs *InstancePtr, u32 Options); +u32 XSpiPs_GetOptions(const XSpiPs *InstancePtr); + +s32 XSpiPs_SetClkPrescaler(const XSpiPs *InstancePtr, u8 Prescaler); +u8 XSpiPs_GetClkPrescaler(const XSpiPs *InstancePtr); + +s32 XSpiPs_SetDelays(const XSpiPs *InstancePtr, u8 DelayNss, u8 DelayBtwn, + u8 DelayAfter, u8 DelayInit); +void XSpiPs_GetDelays(const XSpiPs *InstancePtr, u8 *DelayNss, u8 *DelayBtwn, + u8 *DelayAfter, u8 *DelayInit); +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/spips_v3_2/src/xspips_g.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/spips_v3_2/src/xspips_g.c new file mode 100644 index 0000000..304dc4a --- /dev/null +++ b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/spips_v3_2/src/xspips_g.c @@ -0,0 +1,52 @@ + +/******************************************************************* +* +* CAUTION: This file is automatically generated by HSI. +* Version: 2019.1.3 +* DO NOT EDIT. +* +* Copyright (C) 2010-2024 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 "xspips.h" + +/* +* The configuration table for devices +*/ + +XSpiPs_Config XSpiPs_ConfigTable[XPAR_XSPIPS_NUM_INSTANCES] = +{ + { + XPAR_PS7_SPI_0_DEVICE_ID, + XPAR_PS7_SPI_0_BASEADDR, + XPAR_PS7_SPI_0_SPI_CLK_FREQ_HZ + } +}; + + diff --git a/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/spips_v3_2/src/xspips_hw.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/spips_v3_2/src/xspips_hw.c new file mode 100644 index 0000000..ede1d7c --- /dev/null +++ b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/spips_v3_2/src/xspips_hw.c @@ -0,0 +1,143 @@ +/****************************************************************************** +* +* 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 xspips_hw.c +* @addtogroup spips_v3_2 +* @{ +* +* Contains the reset and post boot rom state initialization. +* Function prototypes in xspips_hw.h +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date     Changes
+* ----- ------ -------- -----------------------------------------------
+* 1.06a hk     08/22/13 First release.
+* 3.00  kvn    02/13/15 Modified code for MISRA-C:2012 compliance.
+* 3.02  raw    11/23/15 Updated XSpiPs_ResetHw() to read all RXFIFO
+* 			entries. This change is to tackle CR#910231.
+* 3.1   tjs    11/23/18 Added a check for A72 and R5 processor to
+*                       avoid changes made for the workaround DT#842463.
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xspips_hw.h" + +/************************** Constant Definitions *****************************/ + + +/**************************** Type Definitions *******************************/ + + +/***************** Macros (Inline Functions) Definitions *********************/ + + +/************************** Variable Definitions *****************************/ + + +/*****************************************************************************/ +/** +* +* Resets the spi module +* +* @param BaseAddress is the base address of the device. +* +* @return None +* +* @note None. +* +******************************************************************************/ +void XSpiPs_ResetHw(u32 BaseAddress) +{ + u32 Check; +#if !defined(versal) + u32 Count; +#endif + + /* + * Disable Interrupts + */ + XSpiPs_WriteReg(BaseAddress, XSPIPS_IDR_OFFSET, + XSPIPS_IXR_DISABLE_ALL_MASK); + + /* + * Disable device + */ + XSpiPs_WriteReg(BaseAddress, XSPIPS_ER_OFFSET, + 0U); + /* + * Write default value to RX and TX threshold registers + * RX threshold should be set to 1 here as the corresponding + * status bit is used to clear the FIFO next + */ + XSpiPs_WriteReg(BaseAddress, XSPIPS_TXWR_OFFSET, + (XSPIPS_TXWR_RESET_VALUE & XSPIPS_TXWR_MASK)); + XSpiPs_WriteReg(BaseAddress, XSPIPS_RXWR_OFFSET, + (XSPIPS_RXWR_RESET_VALUE & XSPIPS_RXWR_MASK)); + + /* + * Clear RXFIFO + */ + Check = (XSpiPs_ReadReg(BaseAddress,XSPIPS_SR_OFFSET) & + XSPIPS_IXR_RXNEMPTY_MASK); + while (Check != 0U) { + (void)XSpiPs_ReadReg(BaseAddress, XSPIPS_RXD_OFFSET); + Check = (XSpiPs_ReadReg(BaseAddress,XSPIPS_SR_OFFSET) & + XSPIPS_IXR_RXNEMPTY_MASK); + } + + /* + * Read all RXFIFO entries + */ +#if !defined(versal) + for (Count = 0U; Count < XSPIPS_FIFO_DEPTH; Count++) { + (void)XSpiPs_ReadReg(BaseAddress, XSPIPS_RXD_OFFSET); + } +#endif + /* + * Clear status register by writing 1 to the write to clear bits + */ + XSpiPs_WriteReg(BaseAddress, XSPIPS_SR_OFFSET, + XSPIPS_IXR_WR_TO_CLR_MASK); + + /* + * Write default value to configuration register + * De-select all slaves + */ + XSpiPs_WriteReg(BaseAddress, XSPIPS_CR_OFFSET, + XSPIPS_CR_RESET_STATE | + XSPIPS_CR_SSCTRL_MASK); + +} +/** @} */ diff --git a/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/spips_v3_2/src/xspips_hw.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/spips_v3_2/src/xspips_hw.h new file mode 100644 index 0000000..07b0687 --- /dev/null +++ b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/spips_v3_2/src/xspips_hw.h @@ -0,0 +1,309 @@ +/****************************************************************************** +* +* 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 xspips_hw.h +* @addtogroup spips_v3_2 +* @{ +* +* 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 xspips.h. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date     Changes
+* ----- ------ -------- -----------------------------------------------
+* 1.00   drg/jz 01/25/10 First release
+* 1.02a  sg     05/31/12 Updated XSPIPS_FIFO_DEPTH to 128 from 32 to match HW
+*			 for CR 658289
+* 1.04a	 sg     01/30/13 Created XSPIPS_CR_MODF_GEN_EN_MASK macro and added it
+*			 to XSPIPS_CR_RESET_STATE. Created
+* 			 XSPIPS_IXR_WR_TO_CLR_MASK for interrupts which need
+*			 write-to-clear. Added shift and mask macros for d_nss
+*			 parameter. Added Rx Watermark mask.
+* 1.06a hk      08/22/13 Added prototypes of reset API and related constant
+*                        definitions.
+* 3.00  kvn     02/13/15 Modified code for MISRA-C:2012 compliance.
+*
+* 
+* +******************************************************************************/ + +#ifndef XSPIPS_HW_H /* prevent circular inclusions */ +#define XSPIPS_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 from the base address of an SPI device. + * @{ + */ +#define XSPIPS_CR_OFFSET 0x00U /**< Configuration */ +#define XSPIPS_SR_OFFSET 0x04U /**< Interrupt Status */ +#define XSPIPS_IER_OFFSET 0x08U /**< Interrupt Enable */ +#define XSPIPS_IDR_OFFSET 0x0CU /**< Interrupt Disable */ +#define XSPIPS_IMR_OFFSET 0x10U /**< Interrupt Enabled Mask */ +#define XSPIPS_ER_OFFSET 0x14U /**< Enable/Disable Register */ +#define XSPIPS_DR_OFFSET 0x18U /**< Delay Register */ +#define XSPIPS_TXD_OFFSET 0x1CU /**< Data Transmit Register */ +#define XSPIPS_RXD_OFFSET 0x20U /**< Data Receive Register */ +#define XSPIPS_SICR_OFFSET 0x24U /**< Slave Idle Count */ +#define XSPIPS_TXWR_OFFSET 0x28U /**< Transmit FIFO Watermark */ +#define XSPIPS_RXWR_OFFSET 0x2CU /**< Receive FIFO Watermark */ +/* @} */ + +/** @name Configuration Register + * + * This register contains various control bits that + * affects the operation of an SPI device. Read/Write. + * @{ + */ +#define XSPIPS_CR_MODF_GEN_EN_MASK 0x00020000U /**< Modefail Generation + Enable */ +#define XSPIPS_CR_MANSTRT_MASK 0x00010000U /**< Manual Transmission Start */ +#define XSPIPS_CR_MANSTRTEN_MASK 0x00008000U /**< Manual Transmission Start + Enable */ +#define XSPIPS_CR_SSFORCE_MASK 0x00004000U /**< Force Slave Select */ +#define XSPIPS_CR_SSCTRL_MASK 0x00003C00U /**< Slave Select Decode */ +#define XSPIPS_CR_SSCTRL_SHIFT 10U /**< Slave Select Decode shift */ +#define XSPIPS_CR_SSCTRL_MAXIMUM 0xFU /**< Slave Select maximum value */ +#define XSPIPS_CR_SSDECEN_MASK 0x00000200U /**< Slave Select Decode Enable */ + +#define XSPIPS_CR_PRESC_MASK 0x00000038U /**< Prescaler Setting */ +#define XSPIPS_CR_PRESC_SHIFT 3U /**< Prescaler shift */ +#define XSPIPS_CR_PRESC_MAXIMUM 0x07U /**< Prescaler maximum value */ + +#define XSPIPS_CR_CPHA_MASK 0x00000004U /**< Phase Configuration */ +#define XSPIPS_CR_CPOL_MASK 0x00000002U /**< Polarity Configuration */ + +#define XSPIPS_CR_MSTREN_MASK 0x00000001U /**< Master Mode Enable */ +#define XSPIPS_CR_RESET_STATE 0x00020000U /**< Mode Fail Generation Enable */ +/* @} */ + + +/** @name SPI Interrupt Registers + * + * SPI Status Register + * + * This register holds the interrupt status flags for an SPI 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. + * + * SPI Interrupt Enable Register + * + * This register is used to enable chosen interrupts for an SPI device. + * Writing a '1' to a bit in this register sets the corresponding bit in the + * SPI Interrupt Mask register. Write only. + * + * SPI Interrupt Disable Register + * + * This register is used to disable chosen interrupts for an SPI device. + * Writing a '1' to a bit in this register clears the corresponding bit in the + * SPI Interrupt Mask register. Write only. + * + * SPI Interrupt Mask Register + * + * This register shows the enabled/disabled interrupts of an SPI 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 XSPIPS_IXR_TXUF_MASK 0x00000040U /**< Tx FIFO Underflow */ +#define XSPIPS_IXR_RXFULL_MASK 0x00000020U /**< Rx FIFO Full */ +#define XSPIPS_IXR_RXNEMPTY_MASK 0x00000010U /**< Rx FIFO Not Empty */ +#define XSPIPS_IXR_TXFULL_MASK 0x00000008U /**< Tx FIFO Full */ +#define XSPIPS_IXR_TXOW_MASK 0x00000004U /**< Tx FIFO Overwater */ +#define XSPIPS_IXR_MODF_MASK 0x00000002U /**< Mode Fault */ +#define XSPIPS_IXR_RXOVR_MASK 0x00000001U /**< Rx FIFO Overrun */ +#define XSPIPS_IXR_DFLT_MASK 0x00000027U /**< Default interrupts + mask */ +#define XSPIPS_IXR_WR_TO_CLR_MASK 0x00000043U /**< Interrupts which + need write to clear */ +#define XSPIPS_ISR_RESET_STATE 0x04U /**< Default to tx/rx + * reg empty */ +#define XSPIPS_IXR_DISABLE_ALL_MASK 0x00000043U /**< Disable all + * interrupts */ +/* @} */ + + +/** @name Enable Register + * + * This register is used to enable or disable an SPI device. + * Read/Write + * @{ + */ +#define XSPIPS_ER_ENABLE_MASK 0x00000001U /**< SPI Enable Bit Mask */ +/* @} */ + + +/** @name Delay Register + * + * This register is used to program timing delays in + * slave mode. Read/Write + * @{ + */ +#define XSPIPS_DR_NSS_MASK 0xFF000000U /**< Delay for slave select + * de-assertion between + * word transfers mask */ +#define XSPIPS_DR_NSS_SHIFT 24U /**< Delay for slave select + * de-assertion between + * word transfers shift */ +#define XSPIPS_DR_BTWN_MASK 0x00FF0000U /**< Delay Between Transfers mask */ +#define XSPIPS_DR_BTWN_SHIFT 16U /**< Delay Between Transfers shift */ +#define XSPIPS_DR_AFTER_MASK 0x0000FF00U /**< Delay After Transfers mask */ +#define XSPIPS_DR_AFTER_SHIFT 8U /**< Delay After Transfers shift */ +#define XSPIPS_DR_INIT_MASK 0x000000FFU /**< Delay Initially mask */ +/* @} */ + + +/** @name Slave Idle Count Registers + * + * This register defines the number of pclk cycles the slave waits for a the + * SPI clock to become stable in quiescent state before it can detect the start + * of the next transfer in CPHA = 1 mode. + * Read/Write + * + * @{ + */ +#define XSPIPS_SICR_MASK 0x000000FFU /**< Slave Idle Count Mask */ +/* @} */ + + + +/** @name Transmit FIFO Watermark Register + * + * This register defines the watermark setting for the Transmit FIFO. The + * transmit FIFO is 128 bytes deep, so the register is 7 bits. Valid values + * are 1 to 128. + * + * @{ + */ +#define XSPIPS_TXWR_MASK 0x0000007FU /**< Transmit Watermark Mask */ +#define XSPIPS_TXWR_RESET_VALUE 0x00000001U /**< Transmit Watermark + * register reset value */ +/* @} */ + +/** @name Receive FIFO Watermark Register + * + * This register defines the watermark setting for the Receive FIFO. The + * receive FIFO is 128 bytes deep, so the register is 7 bits. Valid values + * are 1 to 128. + * + * @{ + */ +#define XSPIPS_RXWR_MASK 0x0000007FU /**< Receive Watermark Mask */ +#define XSPIPS_RXWR_RESET_VALUE 0x00000001U /**< Receive Watermark + * register reset value */ +/* @} */ + +/** @name FIFO Depth + * + * This macro provides the depth of transmit FIFO and receive FIFO. + * + * @{ + */ +#define XSPIPS_FIFO_DEPTH 128U /**< FIFO depth of Tx and Rx */ +/* @} */ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +#define XSpiPs_In32 Xil_In32 +#define XSpiPs_Out32 Xil_Out32 + +/****************************************************************************/ +/** +* 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 XSpiPs_ReadReg(u32 BaseAddress. int RegOffset) +* +******************************************************************************/ +#define XSpiPs_ReadReg(BaseAddress, RegOffset) \ + XSpiPs_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 XSpiPs_WriteReg(u32 BaseAddress, int RegOffset, +* u32 RegisterValue) +* +******************************************************************************/ +#define XSpiPs_WriteReg(BaseAddress, RegOffset, RegisterValue) \ + XSpiPs_Out32((BaseAddress) + (RegOffset), (RegisterValue)) + +/************************** Function Prototypes ******************************/ + +void XSpiPs_ResetHw(u32 BaseAddress); + +/************************** Variable Definitions *****************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ diff --git a/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/spips_v3_2/src/xspips_options.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/spips_v3_2/src/xspips_options.c new file mode 100644 index 0000000..b5710aa --- /dev/null +++ b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/spips_v3_2/src/xspips_options.c @@ -0,0 +1,431 @@ +/****************************************************************************** +* +* 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 xspips_options.c +* @addtogroup spips_v3_2 +* @{ +* +* Contains functions for the configuration of the XSpiPs driver. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date     Changes
+* ----- ------ -------- -----------------------------------------------
+* 1.00  drg/jz 01/25/10 First release
+* 1.00	sdm    10/25/11 Removed the Divide by 2 in the SPI Clock Prescaler
+*			options as this is not supported in the device
+* 1.04a	sg     01/30/13 Added XSPIPS_MANUAL_START_OPTION. SetDelays and
+*			GetDelays API's include DelayNss parameter.
+* 1.05a hk 	   26/04/13 Added disable and enable in XSpiPs_SetOptions when
+*				CPOL/CPHA bits are set/reset. Fix for CR#707669.
+* 3.00  kvn    02/13/15 Modified code for MISRA-C:2012 compliance.
+* 3.2   aru    01/20/19 Fixes violations according to MISRAC-2012
+*                       in safety mode and done changes such as
+*                       Declared the pointer param as Pointer to const
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xspips.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[] = { + {XSPIPS_MASTER_OPTION, XSPIPS_CR_MSTREN_MASK}, + {XSPIPS_CLK_ACTIVE_LOW_OPTION, XSPIPS_CR_CPOL_MASK}, + {XSPIPS_CLK_PHASE_1_OPTION, XSPIPS_CR_CPHA_MASK}, + {XSPIPS_DECODE_SSELECT_OPTION, XSPIPS_CR_SSDECEN_MASK}, + {XSPIPS_FORCE_SSELECT_OPTION, XSPIPS_CR_SSFORCE_MASK}, + {XSPIPS_MANUAL_START_OPTION, XSPIPS_CR_MANSTRTEN_MASK} +}; + +#define XSPIPS_NUM_OPTIONS (sizeof(OptionsTable) / sizeof(OptionsMap)) + +/*****************************************************************************/ +/** +* +* This function sets the options for the SPI device driver. The options control +* how the device behaves relative to the SPI bus. The device must be idle +* rather than busy transferring data before setting these device options. +* +* @param InstancePtr is a pointer to the XSpiPs 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 XSPIPS_*_OPTIONS in the +* file xspips.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 XSpiPs_SetOptions(const XSpiPs *InstancePtr, u32 Options) +{ + u32 ConfigReg; + u32 Index; + u32 CurrentConfigReg; + s32 Status; + + 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 == TRUE) { + Status = (s32)XST_DEVICE_BUSY; + } else { + + ConfigReg = XSpiPs_ReadReg(InstancePtr->Config.BaseAddress, + XSPIPS_CR_OFFSET); + + CurrentConfigReg = ConfigReg; + + /* + * 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 = 0U; Index < XSPIPS_NUM_OPTIONS; Index++) { + if ((Options & OptionsTable[Index].Option) != (u32)0U) { + /* Turn it on */ + ConfigReg |= OptionsTable[Index].Mask; + } + else { + /* Turn it off */ + ConfigReg &= ~(OptionsTable[Index].Mask); + } + } + + + /* + * If CPOL-CPHA bits are toggled from previous state, + * disable before writing the configuration register and then enable. + */ + if( ((CurrentConfigReg & XSPIPS_CR_CPOL_MASK) != + (ConfigReg & XSPIPS_CR_CPOL_MASK)) || + ((CurrentConfigReg & XSPIPS_CR_CPHA_MASK) != + (ConfigReg & XSPIPS_CR_CPHA_MASK)) ) { + XSpiPs_Disable(InstancePtr); + } + + /* + * Now write the Config register. Leave it to the upper layers + * to restart the device. + */ + XSpiPs_WriteReg(InstancePtr->Config.BaseAddress, + XSPIPS_CR_OFFSET, ConfigReg); + + /* + * Enable + */ + if( ((CurrentConfigReg & XSPIPS_CR_CPOL_MASK) != + (ConfigReg & XSPIPS_CR_CPOL_MASK)) || + ((CurrentConfigReg & XSPIPS_CR_CPHA_MASK) != + (ConfigReg & XSPIPS_CR_CPHA_MASK)) ) { + XSpiPs_Enable(InstancePtr); + } + + Status = (s32)XST_SUCCESS; + } + return Status; +} + +/*****************************************************************************/ +/** +* +* This function gets the options for the SPI device. The options control how +* the device behaves relative to the SPI bus. +* +* @param InstancePtr is a pointer to the XSpiPs 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 XSPIPS_*_OPTIONS in file xspips.h. +* +* @note None. +* +******************************************************************************/ +u32 XSpiPs_GetOptions(const XSpiPs *InstancePtr) +{ + u32 OptionsFlag = 0U; + u32 ConfigReg; + u32 Index; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Get the current options + */ + ConfigReg = + XSpiPs_ReadReg(InstancePtr->Config.BaseAddress, + XSPIPS_CR_OFFSET); + + /* + * Loop through the options table to grab options + */ + for (Index = 0U; Index < XSPIPS_NUM_OPTIONS; Index++) { + if ((ConfigReg & OptionsTable[Index].Mask) != FALSE) { + OptionsFlag |= OptionsTable[Index].Option; + } + } + + return OptionsFlag; +} + +/*****************************************************************************/ +/** +* +* This function sets the clock prescaler for an SPI device. The device +* must be idle rather than busy transferring data before setting these device +* options. +* +* @param InstancePtr is a pointer to the XSpiPs instance. +* @param Prescaler is the value that determine how much the clock should +* be divided by. Use the XSPIPS_CLK_PRESCALE_* constants defined +* in xspips.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 XSpiPs_SetClkPrescaler(const XSpiPs *InstancePtr, u8 Prescaler) +{ + u32 ConfigReg; + s32 Status; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid((Prescaler > 0U) && (Prescaler <= XSPIPS_CR_PRESC_MAXIMUM)); + + /* + * Do not allow the prescaler to be changed while a transfer is in + * progress. Not thread-safe. + */ + if (InstancePtr->IsBusy == TRUE) { + Status = (s32)XST_DEVICE_BUSY; + } else { + + /* + * Read the Config register, mask out the interesting bits, and set + * them with the shifted value passed into the function. Write the + * results back to the Config register. + */ + ConfigReg = XSpiPs_ReadReg(InstancePtr->Config.BaseAddress, + XSPIPS_CR_OFFSET); + + ConfigReg &= (u32)(~XSPIPS_CR_PRESC_MASK); + ConfigReg |= (u32) ((u32)Prescaler & (u32)XSPIPS_CR_PRESC_MAXIMUM) << + XSPIPS_CR_PRESC_SHIFT; + + XSpiPs_WriteReg(InstancePtr->Config.BaseAddress, + XSPIPS_CR_OFFSET, + ConfigReg); + + Status = (s32)XST_SUCCESS; + } + return Status; +} + +/*****************************************************************************/ +/** +* +* This function gets the clock prescaler of an SPI device. +* +* @param InstancePtr is a pointer to the XSpiPs instance. +* +* @return The prescaler value. +* +* @note None. +* +* +******************************************************************************/ +u8 XSpiPs_GetClkPrescaler(const XSpiPs *InstancePtr) +{ + u32 ConfigReg; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + ConfigReg = XSpiPs_ReadReg(InstancePtr->Config.BaseAddress, + XSPIPS_CR_OFFSET); + + ConfigReg &= XSPIPS_CR_PRESC_MASK; + + return (u8)(ConfigReg >> XSPIPS_CR_PRESC_SHIFT); + +} + +/*****************************************************************************/ +/** +* +* This function sets the delay register for the SPI 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 XSpiPs instance. +* @param DelayNss is the delay for which the chip select outputs will +* be de-asserted between words when CPHA=0. +* @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: +* CPHA=0:DelayInit+DelayAfter+3 +* CPHA=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. +* +******************************************************************************/ +s32 XSpiPs_SetDelays(const XSpiPs *InstancePtr, u8 DelayNss, u8 DelayBtwn, + u8 DelayAfter, u8 DelayInit) +{ + u32 DelayRegister; + s32 Status; + + 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 == TRUE) { + Status = (s32)XST_DEVICE_BUSY; + } else { + + /* Shift, Mask and OR the values to build the register settings */ + DelayRegister = (u32) DelayNss << XSPIPS_DR_NSS_SHIFT; + DelayRegister |= (u32) DelayBtwn << XSPIPS_DR_BTWN_SHIFT; + DelayRegister |= (u32) DelayAfter << XSPIPS_DR_AFTER_SHIFT; + DelayRegister |= (u32) DelayInit; + + XSpiPs_WriteReg(InstancePtr->Config.BaseAddress, + XSPIPS_DR_OFFSET, DelayRegister); + + Status = (s32)XST_SUCCESS; + } + return Status; +} + +/*****************************************************************************/ +/** +* +* This function gets the delay settings for an SPI 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 XSpiPs instance. +* @param DelayNss is a pointer to the delay for which the chip select +* outputs will be de-asserted between words when CPHA=0. +* @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 XSpiPs_GetDelays(const XSpiPs *InstancePtr,u8 *DelayNss, u8 *DelayBtwn, + u8 *DelayAfter, u8 *DelayInit) +{ + u32 DelayRegister; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + DelayRegister = XSpiPs_ReadReg(InstancePtr->Config.BaseAddress, + XSPIPS_DR_OFFSET); + + *DelayInit = (u8)(DelayRegister & XSPIPS_DR_INIT_MASK); + + *DelayAfter = (u8)((DelayRegister & XSPIPS_DR_AFTER_MASK) >> + XSPIPS_DR_AFTER_SHIFT); + + *DelayBtwn = (u8)((DelayRegister & XSPIPS_DR_BTWN_MASK) >> + XSPIPS_DR_BTWN_SHIFT); + + *DelayNss = (u8)((DelayRegister & XSPIPS_DR_NSS_MASK) >> + XSPIPS_DR_NSS_SHIFT); + +} +/** @} */ diff --git a/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/spips_v3_2/src/xspips_selftest.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/spips_v3_2/src/xspips_selftest.c new file mode 100644 index 0000000..9b62a05 --- /dev/null +++ b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/spips_v3_2/src/xspips_selftest.c @@ -0,0 +1,163 @@ +/****************************************************************************** +* +* 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 xspips_selftest.c +* @addtogroup spips_v3_2 +* @{ +* +* This component contains the implementation of selftest functions for an SPI +* device. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date     Changes
+* ----- ------ -------- ----------------------------------------------
+* 1.00  drg/jz 01/25/10 First release
+* 1.04a	sg     01/30/13 SetDelays test includes DelayTestNss parameter.
+* 3.00  kvn    02/13/15 Modified code for MISRA-C:2012 compliance.
+* 3.2   aru    01/20/19 Fixes violations according to MISRAC-2012
+*                       in safety mode and done changes such as
+*                       Added goto statements.
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xspips.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 XSpiPs instance. +* +* @return +* - XST_SUCCESS if successful +* - XST_REGISTER_ERROR indicates a register did not read or write +* correctly. +* +* @note None. +* +******************************************************************************/ +s32 XSpiPs_SelfTest(XSpiPs *InstancePtr) +{ + s32 Status; + u32 Register; + u8 DelayTestNss; + u8 DelayTestBtwn; + u8 DelayTestAfter; + u8 DelayTestInit; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Reset the SPI device to leave it in a known good state + */ + XSpiPs_Reset(InstancePtr); + + /* + * All the SPI registers should be in their default state right now. + */ + Register = XSpiPs_ReadReg(InstancePtr->Config.BaseAddress, + XSPIPS_CR_OFFSET); + if (Register != XSPIPS_CR_RESET_STATE) { + Status = (s32)XST_REGISTER_ERROR; + goto END; + } + + Register = XSpiPs_ReadReg(InstancePtr->Config.BaseAddress, + XSPIPS_SR_OFFSET); + if (Register != XSPIPS_ISR_RESET_STATE) { + Status = (s32)XST_REGISTER_ERROR; + goto END;; + } + + DelayTestNss = 0x5AU; + DelayTestBtwn = 0xA5U; + DelayTestAfter = 0xAAU; + DelayTestInit = 0x55U; + + /* + * Write and read the delay register, just to be sure there is some + * hardware out there. + */ + Status = XSpiPs_SetDelays(InstancePtr, DelayTestNss, DelayTestBtwn, + DelayTestAfter, DelayTestInit); + if (Status != (s32)XST_SUCCESS) { + goto END; + } + + XSpiPs_GetDelays(InstancePtr, &DelayTestNss, &DelayTestBtwn, + &DelayTestAfter, &DelayTestInit); + if ((0x5AU != DelayTestNss) || (0xA5U != DelayTestBtwn) || + (0xAAU != DelayTestAfter) || (0x55U != DelayTestInit)) { + Status = (s32)XST_REGISTER_ERROR; + goto END; + } + + Status = XSpiPs_SetDelays(InstancePtr, 0U, 0U, 0U, 0U); + if (Status != (s32)XST_SUCCESS) { + goto END; + } + + /* + * Reset the SPI device to leave it in a known good state + */ + XSpiPs_Reset(InstancePtr); + + Status = (s32)XST_SUCCESS; + + END: + return Status; +} +/** @} */ diff --git a/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/spips_v3_2/src/xspips_sinit.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/spips_v3_2/src/xspips_sinit.c new file mode 100644 index 0000000..52c92f5 --- /dev/null +++ b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/spips_v3_2/src/xspips_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 xspips_sinit.c +* @addtogroup spips_v3_2 +* @{ +* +* The implementation of the XSpiPs driver's static initialization +* functionality. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date     Changes
+* ----- ------ -------- -----------------------------------------------
+* 1.00  drg/jz 01/25/10 First release
+* 3.00  kvn    02/13/15 Modified code for MISRA-C:2012 compliance.
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xstatus.h" +#include "xspips.h" +#include "xparameters.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/************************** Variable Definitions *****************************/ +extern XSpiPs_Config XSpiPs_ConfigTable[XPAR_XSPIPS_NUM_INSTANCES]; + +/*****************************************************************************/ +/** +* +* 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 xspips.h for the definition of XSpiPs_Config. +* +* @note None. +* +******************************************************************************/ +XSpiPs_Config *XSpiPs_LookupConfig(u16 DeviceId) +{ + XSpiPs_Config *CfgPtr = NULL; + u32 Index; + + for (Index = 0U; Index < (u32)XPAR_XSPIPS_NUM_INSTANCES; Index++) { + if (XSpiPs_ConfigTable[Index].DeviceId == DeviceId) { + CfgPtr = &XSpiPs_ConfigTable[Index]; + break; + } + } + return (XSpiPs_Config *)CfgPtr; +} +/** @} */ diff --git a/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/Makefile b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/Makefile new file mode 100644 index 0000000..2dfabd3 --- /dev/null +++ b/df_datalink_ge/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))) , arm-none-eabi-gcc) +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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/_exit.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/_exit.c new file mode 100644 index 0000000..87271ae --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/_open.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/_open.c new file mode 100644 index 0000000..4ef7441 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/_sbrk.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/_sbrk.c new file mode 100644 index 0000000..1c39e3a --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/abort.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/abort.c new file mode 100644 index 0000000..78d3839 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/asm_vectors.S b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/asm_vectors.S new file mode 100644 index 0000000..4fbfa2d --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/boot.S b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/boot.S new file mode 100644 index 0000000..c8ebfd1 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/bspconfig.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/bspconfig.h new file mode 100644 index 0000000..5ffeff5 --- /dev/null +++ b/df_datalink_ge/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-2024 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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/changelog.txt b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/changelog.txt new file mode 100644 index 0000000..cdefb9f --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/close.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/close.c new file mode 100644 index 0000000..64f7f49 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/config.make b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/config.make new file mode 100644 index 0000000..2668199 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/cpu_init.S b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/cpu_init.S new file mode 100644 index 0000000..5b597be --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/errno.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/errno.c new file mode 100644 index 0000000..3cdb751 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/fcntl.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/fcntl.c new file mode 100644 index 0000000..42c2bff --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/fstat.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/fstat.c new file mode 100644 index 0000000..92a3ebf --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/getpid.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/getpid.c new file mode 100644 index 0000000..36c8769 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/inbyte.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/inbyte.c new file mode 100644 index 0000000..0036459 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/isatty.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/isatty.c new file mode 100644 index 0000000..d1ef081 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/kill.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/kill.c new file mode 100644 index 0000000..22b66a2 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/lseek.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/lseek.c new file mode 100644 index 0000000..400d4cc --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/open.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/open.c new file mode 100644 index 0000000..4c46b67 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/outbyte.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/outbyte.c new file mode 100644 index 0000000..8b56036 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/print.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/print.c new file mode 100644 index 0000000..da7e768 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/Makefile b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/Makefile new file mode 100644 index 0000000..53a288e --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/_profile_clean.c b/df_datalink_ge/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_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/_profile_init.c b/df_datalink_ge/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_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/_profile_timer_hw.c b/df_datalink_ge/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_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/_profile_timer_hw.h b/df_datalink_ge/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_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/dummy.S b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/dummy.S new file mode 100644 index 0000000..f4ff406 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/mblaze_nt_types.h b/df_datalink_ge/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_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/profile.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/profile.h new file mode 100644 index 0000000..63f503a --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/profile_cg.c b/df_datalink_ge/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_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/profile_config.h b/df_datalink_ge/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_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/profile_hist.c b/df_datalink_ge/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_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/profile_mcount_arm.S b/df_datalink_ge/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_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/profile_mcount_mb.S b/df_datalink_ge/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_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/profile/profile_mcount_ppc.S b/df_datalink_ge/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_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/putnum.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/putnum.c new file mode 100644 index 0000000..aaf9ede --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/read.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/read.c new file mode 100644 index 0000000..9900842 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/sbrk.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/sbrk.c new file mode 100644 index 0000000..7f91b9c --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/sleep.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/sleep.c new file mode 100644 index 0000000..659c21b --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/sleep.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/sleep.h new file mode 100644 index 0000000..f3a632b --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/smc.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/smc.h new file mode 100644 index 0000000..f7cc91c --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/translation_table.S b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/translation_table.S new file mode 100644 index 0000000..418ded8 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/unlink.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/unlink.c new file mode 100644 index 0000000..abd0d87 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/usleep.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/usleep.c new file mode 100644 index 0000000..0965233 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/vectors.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/vectors.c new file mode 100644 index 0000000..2e23fc9 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/vectors.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/vectors.h new file mode 100644 index 0000000..56bacbc --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/write.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/write.c new file mode 100644 index 0000000..dc10ed7 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xbasic_types.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xbasic_types.h new file mode 100644 index 0000000..2d9b245 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xdebug.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xdebug.h new file mode 100644 index 0000000..b09c02d --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xenv.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xenv.h new file mode 100644 index 0000000..9c7c4c3 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xenv_standalone.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xenv_standalone.h new file mode 100644 index 0000000..ef905af --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil-crt0.S b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil-crt0.S new file mode 100644 index 0000000..8ea3a09 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_assert.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_assert.c new file mode 100644 index 0000000..f6ec066 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_assert.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_assert.h new file mode 100644 index 0000000..917de31 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_cache.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_cache.c new file mode 100644 index 0000000..536800f --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_cache.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_cache.h new file mode 100644 index 0000000..ce6fcf4 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_cache_l.h b/df_datalink_ge/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_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_cache_vxworks.h b/df_datalink_ge/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_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_errata.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_errata.h new file mode 100644 index 0000000..c839b63 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_exception.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_exception.c new file mode 100644 index 0000000..16facac --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_exception.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_exception.h new file mode 100644 index 0000000..807f310 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_hal.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_hal.h new file mode 100644 index 0000000..e8971c9 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_io.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_io.c new file mode 100644 index 0000000..6ed1559 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_io.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_io.h new file mode 100644 index 0000000..00207cf --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_macroback.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_macroback.h new file mode 100644 index 0000000..b245c18 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_mem.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_mem.c new file mode 100644 index 0000000..e089bb5 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_mem.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_mem.h new file mode 100644 index 0000000..9aae942 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_misc_psreset_api.c b/df_datalink_ge/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_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_misc_psreset_api.h b/df_datalink_ge/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_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_mmu.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_mmu.c new file mode 100644 index 0000000..ef5bbfe --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_mmu.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_mmu.h new file mode 100644 index 0000000..3b63c0b --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_printf.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_printf.c new file mode 100644 index 0000000..3113269 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_printf.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_printf.h new file mode 100644 index 0000000..a0177fc --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_sleepcommon.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_sleepcommon.c new file mode 100644 index 0000000..cb28204 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_sleeptimer.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_sleeptimer.c new file mode 100644 index 0000000..316efd5 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_sleeptimer.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_sleeptimer.h new file mode 100644 index 0000000..08f64ba --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_testcache.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_testcache.c new file mode 100644 index 0000000..6ea52a8 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_testcache.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_testcache.h new file mode 100644 index 0000000..8289ca9 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_testio.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_testio.c new file mode 100644 index 0000000..9a13a64 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_testio.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_testio.h new file mode 100644 index 0000000..6f0fc1c --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_testmem.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_testmem.c new file mode 100644 index 0000000..b7eb68b --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_testmem.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_testmem.h new file mode 100644 index 0000000..ecce6b7 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_types.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_types.h new file mode 100644 index 0000000..625ff8c --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_util.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_util.c new file mode 100644 index 0000000..d9282ca --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_util.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xil_util.h new file mode 100644 index 0000000..194c425 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xl2cc.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xl2cc.h new file mode 100644 index 0000000..22373c1 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xl2cc_counter.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xl2cc_counter.c new file mode 100644 index 0000000..465be05 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xl2cc_counter.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xl2cc_counter.h new file mode 100644 index 0000000..b8d768f --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xparameters_ps.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xparameters_ps.h new file mode 100644 index 0000000..2a6a0e0 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xplatform_info.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xplatform_info.c new file mode 100644 index 0000000..03b1742 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xplatform_info.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xplatform_info.h new file mode 100644 index 0000000..88851bb --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xpm_counter.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xpm_counter.c new file mode 100644 index 0000000..482671e --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xpm_counter.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xpm_counter.h new file mode 100644 index 0000000..39db7d8 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xpseudo_asm.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xpseudo_asm.h new file mode 100644 index 0000000..c7123a0 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xpseudo_asm_gcc.h b/df_datalink_ge/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_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xreg_cortexa9.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xreg_cortexa9.h new file mode 100644 index 0000000..ad93665 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xstatus.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xstatus.h new file mode 100644 index 0000000..1a212bf --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xtime_l.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xtime_l.c new file mode 100644 index 0000000..a687473 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xtime_l.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/standalone_v7_0/src/xtime_l.h new file mode 100644 index 0000000..12004e1 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/Makefile b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/Makefile new file mode 100644 index 0000000..88b1e62 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps.c new file mode 100644 index 0000000..944afa1 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps.h new file mode 100644 index 0000000..c6c2a0a --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_g.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_g.c new file mode 100644 index 0000000..2cb66a2 --- /dev/null +++ b/df_datalink_ge/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-2024 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_1_DEVICE_ID, + XPAR_PS7_UART_1_BASEADDR, + XPAR_PS7_UART_1_UART_CLK_FREQ_HZ, + XPAR_PS7_UART_1_HAS_MODEM + } +}; + + diff --git a/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_hw.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_hw.c new file mode 100644 index 0000000..11462ba --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_hw.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_hw.h new file mode 100644 index 0000000..8c46ecf --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_intr.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_intr.c new file mode 100644 index 0000000..88eed1e --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_options.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_options.c new file mode 100644 index 0000000..ee0db5f --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_selftest.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_selftest.c new file mode 100644 index 0000000..f26176a --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_sinit.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/uartps_v3_7/src/xuartps_sinit.c new file mode 100644 index 0000000..c3e809b --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/Makefile b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/Makefile new file mode 100644 index 0000000..837ca13 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/xadcps.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/xadcps.c new file mode 100644 index 0000000..5ec5a93 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/xadcps.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/xadcps.h new file mode 100644 index 0000000..900edf0 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/xadcps_g.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/xadcps_g.c new file mode 100644 index 0000000..11fdf17 --- /dev/null +++ b/df_datalink_ge/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-2024 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_ge/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/xadcps_hw.h b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/xadcps_hw.h new file mode 100644 index 0000000..dd51473 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/xadcps_selftest.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/xadcps_selftest.c new file mode 100644 index 0000000..2d2a7f2 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/xadcps_sinit.c b/df_datalink_ge/bsp/ps7_cortexa9_0/libsrc/xadcps_v2_3/src/xadcps_sinit.c new file mode 100644 index 0000000..5572976 --- /dev/null +++ b/df_datalink_ge/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_ge/bsp/system.mss b/df_datalink_ge/bsp/system.mss new file mode 100644 index 0000000..bc2857a --- /dev/null +++ b/df_datalink_ge/bsp/system.mss @@ -0,0 +1,261 @@ + + 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_1 + PARAMETER stdout = ps7_uart_1 +END + + +BEGIN PROCESSOR + PARAMETER DRIVER_NAME = cpu_cortexa9 + PARAMETER DRIVER_VER = 2.7 + PARAMETER HW_INSTANCE = ps7_cortexa9_0 +END + + +BEGIN DRIVER + PARAMETER DRIVER_NAME = frame_uart + PARAMETER DRIVER_VER = 1.0 + PARAMETER HW_INSTANCE = Frame_Uart_0 +END + +BEGIN DRIVER + PARAMETER DRIVER_NAME = gpio + PARAMETER DRIVER_VER = 4.4 + PARAMETER HW_INSTANCE = config_gpio +END + +BEGIN DRIVER + PARAMETER DRIVER_NAME = generic + PARAMETER DRIVER_VER = 2.0 + PARAMETER HW_INSTANCE = jesd_jesd204_phy +END + +BEGIN DRIVER + PARAMETER DRIVER_NAME = generic + PARAMETER DRIVER_VER = 2.0 + PARAMETER HW_INSTANCE = jesd_jesd204_rx +END + +BEGIN DRIVER + PARAMETER DRIVER_NAME = generic + PARAMETER DRIVER_VER = 2.0 + PARAMETER HW_INSTANCE = jesd_jesd204_tx +END + +BEGIN DRIVER + PARAMETER DRIVER_NAME = bram + PARAMETER DRIVER_VER = 4.3 + PARAMETER HW_INSTANCE = mpc_bram_interface_mpc_bram_ctrl +END + +BEGIN DRIVER + PARAMETER DRIVER_NAME = bram + PARAMETER DRIVER_VER = 4.3 + PARAMETER HW_INSTANCE = phy_data_interface_ant_info_bram_ctrl +END + +BEGIN DRIVER + PARAMETER DRIVER_NAME = bram + PARAMETER DRIVER_VER = 4.3 + PARAMETER HW_INSTANCE = phy_data_interface_rx_frame_bram_ctrl +END + +BEGIN DRIVER + PARAMETER DRIVER_NAME = bram + PARAMETER DRIVER_VER = 4.3 + PARAMETER HW_INSTANCE = phy_data_interface_tx_frame_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 = spips + PARAMETER DRIVER_VER = 3.2 + PARAMETER HW_INSTANCE = ps7_spi_0 +END + +BEGIN DRIVER + PARAMETER DRIVER_NAME = uartps + PARAMETER DRIVER_VER = 3.7 + PARAMETER HW_INSTANCE = ps7_uart_1 +END + +BEGIN DRIVER + PARAMETER DRIVER_NAME = xadcps + PARAMETER DRIVER_VER = 2.3 + PARAMETER HW_INSTANCE = ps7_xadc_0 +END + + diff --git a/df_datalink_ge/build/Xilinx.spec b/df_datalink_ge/build/Xilinx.spec new file mode 100644 index 0000000..8eea377 --- /dev/null +++ b/df_datalink_ge/build/Xilinx.spec @@ -0,0 +1,2 @@ +*startfile: +crti%O%s crtbegin%O%s diff --git a/df_datalink_ge/build/makefile b/df_datalink_ge/build/makefile new file mode 100644 index 0000000..1ff2505 --- /dev/null +++ b/df_datalink_ge/build/makefile @@ -0,0 +1,80 @@ +################################################################################ +# 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/time_ctrl/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/hardware/mykonos/subdir.mk +-include src/hardware/subdir.mk +-include src/drivers/platform/subdir.mk +-include src/drivers/api/subdir.mk +-include src/dev_profile/subdir.mk +-include src/config/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_ge.elf.size \ + + +# All Target +all: pre-build main-build + +# Main-build Target +main-build: df_datalink_ge.elf secondary-outputs + +# Tool invocations +df_datalink_ge.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_ge.elf" $(OBJS) $(USER_OBJS) $(LIBS) + @echo 'Finished building target: $@' + @echo ' ' + +df_datalink_ge.elf.size: df_datalink_ge.elf + @echo 'Invoking: ARM v7 Print Size' + arm-none-eabi-size df_datalink_ge.elf |tee "df_datalink_ge.elf.size" + @echo 'Finished building: $@' + @echo ' ' + +# Other Targets +clean: + -$(RM) $(EXECUTABLES)$(OBJS)$(S_UPPER_DEPS)$(C_DEPS)$(ELFSIZE) df_datalink_ge.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_ge/build/objects.mk b/df_datalink_ge/build/objects.mk new file mode 100644 index 0000000..24a8ef2 --- /dev/null +++ b/df_datalink_ge/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_ge/build/sources.mk b/df_datalink_ge/build/sources.mk new file mode 100644 index 0000000..b2fd6f1 --- /dev/null +++ b/df_datalink_ge/build/sources.mk @@ -0,0 +1,32 @@ +################################################################################ +# 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/config \ +src/dev_profile \ +src/drivers/api \ +src/drivers/platform \ +src/hardware \ +src/hardware/mykonos \ +src \ +src/networking/link_layer \ +src/networking/link_layer/geometry \ +src/networking/phy_layer \ +src/systembus \ +src/time_ctrl \ +src/util \ + diff --git a/df_datalink_ge/build/src/config/subdir.mk b/df_datalink_ge/build/src/config/subdir.mk new file mode 100644 index 0000000..ad07064 --- /dev/null +++ b/df_datalink_ge/build/src/config/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/config/platform.c + +OBJS += \ +./src/config/platform.o + +C_DEPS += \ +./src/config/platform.d + + +# Each subdirectory must supply rules for building sources it contributes +src/config/%.o: ../src/config/%.c + @echo 'Building file: $<' + @echo 'Invoking: ARM v7 gcc compiler' + $(CC) -Wall -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_ge/build/src/dev_profile/subdir.mk b/df_datalink_ge/build/src/dev_profile/subdir.mk new file mode 100644 index 0000000..9cdf218 --- /dev/null +++ b/df_datalink_ge/build/src/dev_profile/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/dev_profile/global_timer_profile.c \ +../src/dev_profile/intc_profile.c \ +../src/dev_profile/timer_profile.c + +OBJS += \ +./src/dev_profile/global_timer_profile.o \ +./src/dev_profile/intc_profile.o \ +./src/dev_profile/timer_profile.o + +C_DEPS += \ +./src/dev_profile/global_timer_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 -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_ge/build/src/drivers/api/subdir.mk b/df_datalink_ge/build/src/drivers/api/subdir.mk new file mode 100644 index 0000000..d428903 --- /dev/null +++ b/df_datalink_ge/build/src/drivers/api/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/drivers/api/irq.c \ +../src/drivers/api/timer.c \ +../src/drivers/api/trng.c + +OBJS += \ +./src/drivers/api/irq.o \ +./src/drivers/api/timer.o \ +./src/drivers/api/trng.o + +C_DEPS += \ +./src/drivers/api/irq.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 -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_ge/build/src/drivers/platform/subdir.mk b/df_datalink_ge/build/src/drivers/platform/subdir.mk new file mode 100644 index 0000000..4814ff4 --- /dev/null +++ b/df_datalink_ge/build/src/drivers/platform/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/drivers/platform/xilinx_axi_io.c \ +../src/drivers/platform/xilinx_irq.c \ +../src/drivers/platform/xilinx_timer.c + +OBJS += \ +./src/drivers/platform/xilinx_axi_io.o \ +./src/drivers/platform/xilinx_irq.o \ +./src/drivers/platform/xilinx_timer.o + +C_DEPS += \ +./src/drivers/platform/xilinx_axi_io.d \ +./src/drivers/platform/xilinx_irq.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 -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_ge/build/src/hardware/mykonos/subdir.mk b/df_datalink_ge/build/src/hardware/mykonos/subdir.mk new file mode 100644 index 0000000..c94c376 --- /dev/null +++ b/df_datalink_ge/build/src/hardware/mykonos/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/hardware/mykonos/Mykonos_M3.c \ +../src/hardware/mykonos/ad9528.c \ +../src/hardware/mykonos/mykonos.c \ +../src/hardware/mykonos/mykonosMmap.c \ +../src/hardware/mykonos/mykonos_gpio.c \ +../src/hardware/mykonos/mykonos_user.c + +OBJS += \ +./src/hardware/mykonos/Mykonos_M3.o \ +./src/hardware/mykonos/ad9528.o \ +./src/hardware/mykonos/mykonos.o \ +./src/hardware/mykonos/mykonosMmap.o \ +./src/hardware/mykonos/mykonos_gpio.o \ +./src/hardware/mykonos/mykonos_user.o + +C_DEPS += \ +./src/hardware/mykonos/Mykonos_M3.d \ +./src/hardware/mykonos/ad9528.d \ +./src/hardware/mykonos/mykonos.d \ +./src/hardware/mykonos/mykonosMmap.d \ +./src/hardware/mykonos/mykonos_gpio.d \ +./src/hardware/mykonos/mykonos_user.d + + +# Each subdirectory must supply rules for building sources it contributes +src/hardware/mykonos/%.o: ../src/hardware/mykonos/%.c + @echo 'Building file: $<' + @echo 'Invoking: ARM v7 gcc compiler' + $(CC) -Wall -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_ge/build/src/hardware/subdir.mk b/df_datalink_ge/build/src/hardware/subdir.mk new file mode 100644 index 0000000..729ddab --- /dev/null +++ b/df_datalink_ge/build/src/hardware/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/hardware/common.c \ +../src/hardware/headless.c \ +../src/hardware/myk_ad9528init.c \ +../src/hardware/myk_init.c \ +../src/hardware/platform_drivers.c + +OBJS += \ +./src/hardware/common.o \ +./src/hardware/headless.o \ +./src/hardware/myk_ad9528init.o \ +./src/hardware/myk_init.o \ +./src/hardware/platform_drivers.o + +C_DEPS += \ +./src/hardware/common.d \ +./src/hardware/headless.d \ +./src/hardware/myk_ad9528init.d \ +./src/hardware/myk_init.d \ +./src/hardware/platform_drivers.d + + +# Each subdirectory must supply rules for building sources it contributes +src/hardware/%.o: ../src/hardware/%.c + @echo 'Building file: $<' + @echo 'Invoking: ARM v7 gcc compiler' + $(CC) -Wall -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_ge/build/src/networking/link_layer/geometry/subdir.mk b/df_datalink_ge/build/src/networking/link_layer/geometry/subdir.mk new file mode 100644 index 0000000..bb27a61 --- /dev/null +++ b/df_datalink_ge/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 -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_ge/build/src/networking/link_layer/subdir.mk b/df_datalink_ge/build/src/networking/link_layer/subdir.mk new file mode 100644 index 0000000..28c09d9 --- /dev/null +++ b/df_datalink_ge/build/src/networking/link_layer/subdir.mk @@ -0,0 +1,45 @@ +################################################################################ +# 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/schdevent.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/schdevent.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/schdevent.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 -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_ge/build/src/networking/phy_layer/subdir.mk b/df_datalink_ge/build/src/networking/phy_layer/subdir.mk new file mode 100644 index 0000000..65d68d5 --- /dev/null +++ b/df_datalink_ge/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 -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_ge/build/src/subdir.mk b/df_datalink_ge/build/src/subdir.mk new file mode 100644 index 0000000..1583c87 --- /dev/null +++ b/df_datalink_ge/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 -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_ge/build/src/systembus/subdir.mk b/df_datalink_ge/build/src/systembus/subdir.mk new file mode 100644 index 0000000..fd7331d --- /dev/null +++ b/df_datalink_ge/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 -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_ge/build/src/time_ctrl/subdir.mk b/df_datalink_ge/build/src/time_ctrl/subdir.mk new file mode 100644 index 0000000..e3e2443 --- /dev/null +++ b/df_datalink_ge/build/src/time_ctrl/subdir.mk @@ -0,0 +1,23 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +# Add inputs and outputs from these tool invocations to the build variables +C_SRCS += \ +../src/time_ctrl/time_ctrl.c + +OBJS += \ +./src/time_ctrl/time_ctrl.o + +C_DEPS += \ +./src/time_ctrl/time_ctrl.d + + +# Each subdirectory must supply rules for building sources it contributes +src/time_ctrl/%.o: ../src/time_ctrl/%.c + @echo 'Building file: $<' + @echo 'Invoking: ARM v7 gcc compiler' + $(CC) -Wall -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_ge/build/src/util/subdir.mk b/df_datalink_ge/build/src/util/subdir.mk new file mode 100644 index 0000000..fc1b7b3 --- /dev/null +++ b/df_datalink_ge/build/src/util/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/util/circ_queue.c \ +../src/util/clist.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/clist.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/clist.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 -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_ge/src/Xilinx.spec b/df_datalink_ge/src/Xilinx.spec new file mode 100644 index 0000000..8eea377 --- /dev/null +++ b/df_datalink_ge/src/Xilinx.spec @@ -0,0 +1,2 @@ +*startfile: +crti%O%s crtbegin%O%s diff --git a/df_datalink_ge/src/config/app_config.h b/df_datalink_ge/src/config/app_config.h new file mode 100644 index 0000000..e7f9742 --- /dev/null +++ b/df_datalink_ge/src/config/app_config.h @@ -0,0 +1,98 @@ +/*****************************************************************************/ +/** + * 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 CONFIG_H_ +#define 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_PHYC_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_INFO_BRAM_CTRL_DEVICE_ID +// -- Buffers +#define PHY_TXBUFF_BRAM_DEVICE_ID XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_DEVICE_ID +#define PHY_RXBUFF_BRAM_DEVICE_ID XPAR_PHY_DATA_INTERFACE_RX_FRAME_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 +#define PERIODIC_5MS_INTR_ID XPAR_FABRIC_PHY_5MS_DELAY_2MS_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 + +// 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 diff --git a/df_datalink_ge/src/config/platform.c b/df_datalink_ge/src/config/platform.c new file mode 100644 index 0000000..364f8ce --- /dev/null +++ b/df_datalink_ge/src/config/platform.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. +* +* Use of the Software is limited solely to applications: +* (a) running on a Xilinx device, or +* (b) that interact with a Xilinx device through a bus or interconnect. +* +* 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 "xparameters.h" +#include "xil_cache.h" +#include "platform_config.h" + +/* + * Uncomment one of the following two lines, depending on the target, + * if ps7/psu init source files are added in the source directory for + * compiling example outside of SDK. + */ +/*#include "ps7_init.h"*/ +/*#include "psu_init.h"*/ + +#ifdef STDOUT_IS_16550 + #include "xuartns550_l.h" + + #define UART_BAUD 9600 +#endif + +void +enable_caches() +{ +#ifdef __PPC__ + Xil_ICacheEnableRegion(CACHEABLE_REGION_MASK); + Xil_DCacheEnableRegion(CACHEABLE_REGION_MASK); +#elif __MICROBLAZE__ +#ifdef XPAR_MICROBLAZE_USE_ICACHE + Xil_ICacheEnable(); +#endif +#ifdef XPAR_MICROBLAZE_USE_DCACHE + Xil_DCacheEnable(); +#endif +#endif +} + +void +disable_caches() +{ +#ifdef __MICROBLAZE__ +#ifdef XPAR_MICROBLAZE_USE_DCACHE + Xil_DCacheDisable(); +#endif +#ifdef XPAR_MICROBLAZE_USE_ICACHE + Xil_ICacheDisable(); +#endif +#endif +} + +void +init_uart() +{ +#ifdef STDOUT_IS_16550 + XUartNs550_SetBaud(STDOUT_BASEADDR, XPAR_XUARTNS550_CLOCK_HZ, UART_BAUD); + XUartNs550_SetLineControlReg(STDOUT_BASEADDR, XUN_LCR_8_DATA_BITS); +#endif + /* Bootrom/BSP configures PS7/PSU UART to 115200 bps */ +} + +void +init_platform() +{ + /* + * If you want to run this example outside of SDK, + * uncomment one of the following two lines and also #include "ps7_init.h" + * or #include "ps7_init.h" at the top, depending on the target. + * Make sure that the ps7/psu_init.c and ps7/psu_init.h files are included + * along with this example source files for compilation. + */ + /* ps7_init();*/ + /* psu_init();*/ + enable_caches(); + init_uart(); +} + +void +cleanup_platform() +{ + disable_caches(); +} diff --git a/df_datalink_ge/src/config/platform.h b/df_datalink_ge/src/config/platform.h new file mode 100644 index 0000000..e273e37 --- /dev/null +++ b/df_datalink_ge/src/config/platform.h @@ -0,0 +1,41 @@ +/****************************************************************************** +* +* Copyright (C) 2008 - 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. +* +* Use of the Software is limited solely to applications: +* (a) running on a Xilinx device, or +* (b) that interact with a Xilinx device through a bus or interconnect. +* +* 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 __PLATFORM_H_ +#define __PLATFORM_H_ + +#include "platform_config.h" + +void init_platform(); +void cleanup_platform(); + +#endif diff --git a/df_datalink_ge/src/config/platform_config.h b/df_datalink_ge/src/config/platform_config.h new file mode 100644 index 0000000..e2fd813 --- /dev/null +++ b/df_datalink_ge/src/config/platform_config.h @@ -0,0 +1,7 @@ +#ifndef __PLATFORM_CONFIG_H_ +#define __PLATFORM_CONFIG_H_ + +#define STDOUT_IS_PS7_UART +#define UART_DEVICE_ID 0 + +#endif diff --git a/df_datalink_ge/src/dev_profile/dev_profile.h b/df_datalink_ge/src/dev_profile/dev_profile.h new file mode 100644 index 0000000..fbe5d11 --- /dev/null +++ b/df_datalink_ge/src/dev_profile/dev_profile.h @@ -0,0 +1,13 @@ +#ifndef _DEV_PROFILE_H_ +#define _DEV_PROFILE_H_ + +#include "irq.h" +#include "error.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; + +#endif /* SRC_DEV_PROFILE_H_ */ diff --git a/df_datalink_ge/src/dev_profile/global_timer_profile.c b/df_datalink_ge/src/dev_profile/global_timer_profile.c new file mode 100644 index 0000000..78fab27 --- /dev/null +++ b/df_datalink_ge/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_ge/src/dev_profile/intc_profile.c b/df_datalink_ge/src/dev_profile/intc_profile.c new file mode 100644 index 0000000..47dc70a --- /dev/null +++ b/df_datalink_ge/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_ge/src/dev_profile/timer_profile.c b/df_datalink_ge/src/dev_profile/timer_profile.c new file mode 100644 index 0000000..53aac51 --- /dev/null +++ b/df_datalink_ge/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_ge/src/drivers/api/irq.c b/df_datalink_ge/src/drivers/api/irq.c new file mode 100644 index 0000000..9162366 --- /dev/null +++ b/df_datalink_ge/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_ge/src/drivers/api/timer.c b/df_datalink_ge/src/drivers/api/timer.c new file mode 100644 index 0000000..c9aae42 --- /dev/null +++ b/df_datalink_ge/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_ge/src/drivers/api/trng.c b/df_datalink_ge/src/drivers/api/trng.c new file mode 100644 index 0000000..1f3827a --- /dev/null +++ b/df_datalink_ge/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_ge/src/drivers/platform/xilinx_axi_io.c b/df_datalink_ge/src/drivers/platform/xilinx_axi_io.c new file mode 100644 index 0000000..5c33838 --- /dev/null +++ b/df_datalink_ge/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_ge/src/drivers/platform/xilinx_irq.c b/df_datalink_ge/src/drivers/platform/xilinx_irq.c new file mode 100644 index 0000000..8ecb1fa --- /dev/null +++ b/df_datalink_ge/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_ge/src/drivers/platform/xilinx_irq.h b/df_datalink_ge/src/drivers/platform/xilinx_irq.h new file mode 100644 index 0000000..386b233 --- /dev/null +++ b/df_datalink_ge/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_ge/src/drivers/platform/xilinx_timer.c b/df_datalink_ge/src/drivers/platform/xilinx_timer.c new file mode 100644 index 0000000..4b1fa85 --- /dev/null +++ b/df_datalink_ge/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_ge/src/drivers/platform/xilinx_timer.h b/df_datalink_ge/src/drivers/platform/xilinx_timer.h new file mode 100644 index 0000000..7f5ff87 --- /dev/null +++ b/df_datalink_ge/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_ge/src/hardware/common.c b/df_datalink_ge/src/hardware/common.c new file mode 100644 index 0000000..c4323b2 --- /dev/null +++ b/df_datalink_ge/src/hardware/common.c @@ -0,0 +1,275 @@ +/** + * \file common.c + * \brief Contains Mykonos API common wrapper functions for user hardware platform drivers + */ + +/** +* \page Disclaimer Legal Disclaimer +* Copyright 2015-2017 Analog Devices Inc. +* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file. +* +*/ + +#include +#include +#include +#include +#include +#include "common.h" +#include "platform_drivers.h" +#include "parameters.h" + +ADI_LOGLEVEL CMB_LOGLEVEL = ADIHAL_LOG_NONE; + +static uint32_t _desired_time_to_elapse_us = 0; +struct spi_desc *spi_ad_desc; +struct gpio_desc *gpio_ad9371_resetb; +struct gpio_desc *gpio_ad9528_resetb; +struct gpio_desc *gpio_ad9528_sysref_req; + +commonErr_t CMB_initPlatform(void) +{ + struct spi_init_param spi_param; + int32_t status = COMMONERR_OK; + + status |= gpio_get(&gpio_ad9371_resetb, AD9371_RESET_B); + status |= gpio_get(&gpio_ad9528_resetb, AD9528_RESET_B); + status |= gpio_get(&gpio_ad9528_sysref_req, AD9528_SYSREF_REQ); + + spi_param.id = 0; + spi_param.mode = SPI_MODE_0; + spi_param.chip_select = AD9371_CS; + spi_param.max_speed_hz = 25000000u; + + status |= spi_init(&spi_ad_desc, &spi_param); + + if (status != SUCCESS) { + return COMMONERR_FAILED; + } + + return COMMONERR_OK; +} + +commonErr_t CMB_closeHardware(void) +{ + return(COMMONERR_OK); +} + +commonErr_t CMB_setGPIO(uint32_t GPIO) +{ + return(COMMONERR_OK); +} + +commonErr_t CMB_hardReset(uint8_t spiChipSelectIndex) +{ + struct gpio_desc *reset_gpio; + + switch (spiChipSelectIndex) { + case AD9371_CS: + reset_gpio = gpio_ad9371_resetb; + break; + case AD9528_CS: + reset_gpio = gpio_ad9528_resetb; + break; + default: + return(COMMONERR_FAILED); + } + + gpio_direction_output(reset_gpio, 1); + CMB_wait_ms(1); + gpio_direction_output(reset_gpio, 0); + CMB_wait_ms(1); + gpio_direction_output(reset_gpio, 1); + CMB_wait_ms(1); + + return(COMMONERR_OK); +} + +commonErr_t CMB_setSPIOptions(spiSettings_t *spiSettings) +{ + return(COMMONERR_OK); +} + +commonErr_t CMB_setSPIChannel(uint16_t chipSelectIndex ) +{ + return(COMMONERR_OK); +} + +commonErr_t CMB_SPIWriteByte(spiSettings_t *spiSettings, uint16_t addr, + uint8_t data) +{ + uint8_t buf[3]; + + spi_ad_desc->chip_select = spiSettings->chipSelectIndex - 1; + + buf[0] = (uint8_t) ((addr >> 8) & 0x7f); + buf[1] = (uint8_t) (addr & 0xff); + buf[2] = (uint8_t) data; + + spi_write_and_read(spi_ad_desc, buf, 3); + + return(COMMONERR_OK); +} + +commonErr_t CMB_SPIWriteBytes(spiSettings_t *spiSettings, uint16_t *addr, + uint8_t *data, uint32_t count) +{ + uint32_t index; + + for (index = 0; index < count; index++) + if (CMB_SPIWriteByte(spiSettings, *(addr + index), + *(data + index)) != COMMONERR_OK) + return(COMMONERR_FAILED); + + return(COMMONERR_OK); +} + +commonErr_t CMB_SPIReadByte(spiSettings_t *spiSettings, uint16_t addr, + uint8_t *readdata) +{ + uint8_t buf[3]; + + spi_ad_desc->chip_select = spiSettings->chipSelectIndex - 1; + + buf[0] = (uint8_t) ((addr >> 8) | 0x80); + buf[1] = (uint8_t) (addr & 0xff); + buf[2] = (uint8_t) 0x00; + + spi_write_and_read(spi_ad_desc, buf, 3); + *readdata = buf[2]; + + return(COMMONERR_OK); +} + +commonErr_t CMB_SPIWriteField(spiSettings_t *spiSettings, uint16_t addr, + uint8_t field_val, uint8_t mask, uint8_t start_bit) +{ + uint8_t data; + + if (CMB_SPIReadByte(spiSettings, addr, &data) != COMMONERR_OK) + return(COMMONERR_FAILED); + + data = (data & ~mask) | ((field_val << start_bit) & mask); + + if (CMB_SPIWriteByte(spiSettings, addr, data) != COMMONERR_OK) + return(COMMONERR_FAILED); + + return(COMMONERR_OK); +} + +/* read a field in a single register space (not multibyte fields) */ +commonErr_t CMB_SPIReadField(spiSettings_t *spiSettings, uint16_t addr, + uint8_t *field_val, uint8_t mask, uint8_t start_bit) +{ + uint8_t data; + + if (CMB_SPIReadByte(spiSettings, addr, &data) != COMMONERR_OK) + return(COMMONERR_FAILED); + + data = (data & mask) >> start_bit; + *field_val = data; + + return(COMMONERR_OK); +} + + +commonErr_t CMB_writeToLog(ADI_LOGLEVEL level, uint8_t deviceIndex, + uint32_t errorCode, const char *comment) +{ + + if((CMB_LOGLEVEL & ADIHAL_LOG_ERROR) && (level == ADIHAL_LOG_ERROR)) { + printf("ERROR: %d: %s", (int)errorCode, comment); + } else if((CMB_LOGLEVEL & ADIHAL_LOG_WARNING) + && (level == ADIHAL_LOG_WARNING)) { + printf("WARNING: %d: %s",(int)errorCode, comment); + } else if((CMB_LOGLEVEL & ADIHAL_LOG_MESSAGE) + && (level == ADIHAL_LOG_MESSAGE)) { + printf("MESSAGE: %d: %s",(int)errorCode, comment); + } else if(CMB_LOGLEVEL == ADIHAL_LOG_NONE ) { + //printf("MESSAGE: %d: %s",(int)errorCode, comment); + } else { + printf("Undefined Log Level: 0x%X", level); + } + + return(COMMONERR_OK); +} + +/* if filename null, a default path will be used in logging.c */ +commonErr_t CMB_openLog(const char *filename) +{ + return(COMMONERR_OK); +} + +commonErr_t CMB_closeLog(void) +{ + return(COMMONERR_OK); +} + +commonErr_t CMB_flushLog(void) +{ + return(COMMONERR_OK); +} + +commonErr_t CMB_wait_ms(uint32_t time_ms) +{ + mdelay(time_ms); + + return(COMMONERR_OK); +} + +commonErr_t CMB_wait_us(uint32_t time_us) +{ + udelay(time_us); + + return(COMMONERR_OK); +} + +commonErr_t CMB_setTimeout_ms(uint32_t timeOut_ms) +{ +#ifdef _XPARAMETERS_PS_H_ + _desired_time_to_elapse_us = timeOut_ms * 1000; +#else + _desired_time_to_elapse_us = timeOut_ms * 50; // FIXME +#endif + + return(COMMONERR_OK); +} + +commonErr_t CMB_setTimeout_us(uint32_t timeOut_us) +{ + _desired_time_to_elapse_us = timeOut_us; + + return(COMMONERR_OK); +} + + +commonErr_t CMB_hasTimeoutExpired() +{ + udelay(1); + + _desired_time_to_elapse_us--; + if (_desired_time_to_elapse_us > 0) + return(COMMONERR_OK); + + return(COMMONERR_FAILED); +} + +commonErr_t CMB_regRead(uint32_t offset, uint32_t *data) +{ + return(COMMONERR_OK); +} + +commonErr_t CMB_regWrite(uint32_t offset, uint32_t data) +{ + return(COMMONERR_OK); +} + +commonErr_t CMB_memRead(uint32_t offset, uint32_t *data, uint32_t len) +{ + return(COMMONERR_OK); +} + +commonErr_t CMB_memWrite(uint32_t offset, uint32_t *data, uint32_t len) +{ + return(COMMONERR_OK); +} diff --git a/df_datalink_ge/src/hardware/common.h b/df_datalink_ge/src/hardware/common.h new file mode 100644 index 0000000..785217d --- /dev/null +++ b/df_datalink_ge/src/hardware/common.h @@ -0,0 +1,131 @@ +/** + * \file common.h + * \brief Contains type definitions and prototype declarations for common.c + */ + +/** +* \page Disclaimer Legal Disclaimer +* Copyright 2015-2017 Analog Devices Inc. +* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file. +* +*/ + +#ifndef _COMMON_H_ +#define _COMMON_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* build project settings include the path to the desired platform folder for correct includes */ +#include "stdint.h" + +#define THROW_ERROR() + +#define SPIARRAYSIZE 1024 + +/* assuming 3 byte SPI message - integer math enforces floor() */ +#define SPIARRAYTRIPSIZE ((SPIARRAYSIZE / 3) * 3) + +/*======================================== + * Enums and structures + *=======================================*/ +/* proposed to increase number of error return values to make unique for each return */ +typedef enum +{ + ADIERR_OK=0, + ADIERR_INV_PARM, + ADIERR_FAILED +} ADI_ERR; + +/*!< \brief COMMON layer error reporting enumerated types */ +typedef enum +{ + COMMONERR_OK=0, + COMMONERR_FAILED +} commonErr_t; + +/* bit 0 is MESSAGE, bit 1 is WARNING, bit 2 is ERROR */ +typedef enum +{ + ADIHAL_LOG_NONE = 0x0, + ADIHAL_LOG_MESSAGE = 0x1, + ADIHAL_LOG_WARNING = 0x2, + ADIHAL_LOG_ERROR = 0x4, + ADIHAL_LOG_SPI = 0x8, + ADIHAL_LOG_AXI_REG = 0x10, + ADIHAL_LOG_AXI_MEM = 0x20, + ADIHAL_LOG_ALL = 0x3F +} ADI_LOGLEVEL; + +/** + * \brief Data structure to hold SPI settings for all system device types + */ +typedef struct +{ + uint8_t chipSelectIndex; ///< valid 1~8 + uint8_t writeBitPolarity; ///< the level of the write bit of a SPI write instruction word, value is inverted for SPI read operation + uint8_t longInstructionWord; ///< 1 = 16bit instruction word, 0 = 8bit instruction word + uint8_t MSBFirst; ///< 1 = MSBFirst, 0 = LSBFirst + uint8_t CPHA; ///< clock phase, sets which clock edge the data updates (valid 0 or 1) + uint8_t CPOL; ///< clock polarity 0 = clock starts low, 1 = clock starts high + uint8_t enSpiStreaming; ///< Not implemented. SW feature to improve SPI throughput. + uint8_t autoIncAddrUp; ///< Not implemented. For SPI Streaming, set address increment direction. 1= next addr = addr+1, 0:addr = addr-1 + uint8_t fourWireMode; ///< 1: Use 4-wire SPI, 0: 3-wire SPI (SDIO pin is bidirectional). NOTE: ADI's FPGA platform always uses 4-wire mode. + uint32_t spiClkFreq_Hz; ///< SPI Clk frequency in Hz (default 25000000), platform will use next lowest frequency that it's baud rate generator can create */ + +} spiSettings_t; + +/* global variable so application layer can set the log level */ +extern ADI_LOGLEVEL CMB_LOGLEVEL; +extern struct spi_desc *spi_ad_desc; +extern struct gpio_desc *gpio_ad9371_resetb; +extern struct gpio_desc *gpio_ad9528_resetb; +extern struct gpio_desc *gpio_ad9528_sysref_req; + +/* initialize hardware platform */ +commonErr_t CMB_initPlatform(void); + +/* close hardware pointers */ +commonErr_t CMB_closeHardware(void); + +/* GPIO function */ +commonErr_t CMB_setGPIO(uint32_t GPIO); + +/* hardware reset function */ +commonErr_t CMB_hardReset(uint8_t spiChipSelectIndex); + +/* SPI read/write functions */ +commonErr_t CMB_setSPIOptions(spiSettings_t *spiSettings); /* allows the platform HAL to work with devices with various SPI settings */ +commonErr_t CMB_setSPIChannel(uint16_t chipSelectIndex ); /* value of 0 deasserts all chip selects */ +commonErr_t CMB_SPIWriteByte(spiSettings_t *spiSettings, uint16_t addr, uint8_t data); /* single SPI byte write function */ +commonErr_t CMB_SPIWriteBytes(spiSettings_t *spiSettings, uint16_t *addr, uint8_t *data, uint32_t count); +commonErr_t CMB_SPIReadByte (spiSettings_t *spiSettings, uint16_t addr, uint8_t *readdata); /* single SPI byte read function */ +commonErr_t CMB_SPIWriteField(spiSettings_t *spiSettings, uint16_t addr, uint8_t field_val, uint8_t mask, uint8_t start_bit); /* write a field in a single register */ +commonErr_t CMB_SPIReadField (spiSettings_t *spiSettings, uint16_t addr, uint8_t *field_val, uint8_t mask, uint8_t start_bit); /* read a field in a single register */ + +/* platform timer functions */ +commonErr_t CMB_wait_ms(uint32_t time_ms); +commonErr_t CMB_wait_us(uint32_t time_us); +commonErr_t CMB_setTimeout_ms(uint32_t timeOut_ms); +commonErr_t CMB_setTimeout_us(uint32_t timeOut_us); +commonErr_t CMB_hasTimeoutExpired(); + +/* platform logging functions */ +commonErr_t CMB_openLog(const char *filename); +commonErr_t CMB_closeLog(void); +commonErr_t CMB_writeToLog(ADI_LOGLEVEL level, uint8_t deviceIndex, uint32_t errorCode, const char *comment); +commonErr_t CMB_flushLog(void); + +/* platform FPGA AXI register read/write functions */ +commonErr_t CMB_regRead(uint32_t offset, uint32_t *data); +commonErr_t CMB_regWrite(uint32_t offset, uint32_t data); + +/* platform DDR3 memory read/write functions */ +commonErr_t CMB_memRead(uint32_t offset, uint32_t *data, uint32_t len); +commonErr_t CMB_memWrite(uint32_t offset, uint32_t *data, uint32_t len); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/df_datalink_ge/src/hardware/headless.c b/df_datalink_ge/src/hardware/headless.c new file mode 100644 index 0000000..c90c1d0 --- /dev/null +++ b/df_datalink_ge/src/hardware/headless.c @@ -0,0 +1,1138 @@ +/***************************************************************************//** + * @file ad9371/src/app/headless.c + * @brief Implementation of Main Function. +******************************************************************************** + * Copyright 2017(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 "headless.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Variable Definitions *****************************/ + +//XGpio GpioFreqCtrl; +//XGpio GpioGainCtrl; +//XGpio GpioAttnCtrl; +XScuGic Intc; + +/************************** Function Prototypes ******************************/ + +int HARDWARE_initialize() +{ + int Status; + + // use configuration + mykDevice.rx->rxPllLoFrequency_Hz = 2500000000u; + mykDevice.tx->txPllLoFrequency_Hz = 2500000000u; + mykDevice.tx->tx1Atten_mdB = 20000; + mykDevice.tx->tx2Atten_mdB = 20000; + + Status = HARDWARE_ad9371Config(); + + if (Status != ADIERR_OK){ + return ADIERR_FAILED; + } + +// /**********************************************************/ +// /************ AD9371 Dynamical Reconfiguration ************/ +// /**********************************************************/ +// Status = HW_ad9371DynamicCfgInit(); +// if (Status != ADIERR_OK){ +// printf("HW:: AD9371 dynamic configuration initialization failed!\n"); +// return ADIERR_FAILED; +// } +// +// printf("HW:: AD9371 ready to be reconfigured!\n"); +// +// // main loop +// while(1); + + // never reach + return ADIERR_OK; +} + +// this function is NOT safe +int HARDWARE_ad9371Config(void) +{ + int Status; + uint8_t reg508; + uint8_t framerStatus; + uint8_t obsFramerStatus; + uint8_t deframerStatus; + + /**********************************************************/ + /*********** Initialize Configuration Interface ***********/ + /**********************************************************/ + Status = CMB_initPlatform(); + if (Status != ADIERR_OK){ + return ADIERR_FAILED; + } + + Status = HW_adiCfgProfileInit(); + if (Status != ADIERR_OK){ + return ADIERR_FAILED; + } + + printf("HW:: Initialize configuration interface done!\n"); + + /**********************************************************/ + /****************** AD9528 Configuration ******************/ + /**********************************************************/ + Status = HW_9528Config(ad9528Init); + if (Status != ADIERR_OK){ + return ADIERR_FAILED; + } + + printf("HW:: AD9528 configuration done!\n"); + + Status = HW_9528GetLockStatus(ad9528Init, ®508); + if (Status != ADIERR_OK){ + return ADIERR_FAILED; + } + + printf("HW:: AD9528 REG508: 0x%02x\n",reg508); + + /**********************************************************/ + /****************** AD9371 Configuration ******************/ + /**********************************************************/ + Status = HW_9371Config(ad9528Init, &mykDevice); + if (Status != ADIERR_OK){ + return ADIERR_FAILED; + } + + Status = HW_9371CheckJesdStatus(&mykDevice, &framerStatus, + &obsFramerStatus, &deframerStatus); + if (Status != ADIERR_OK){ + return ADIERR_FAILED; + } + else { + // typical value: 0x3E + printf("HW:: RxFramerStatus = 0x%x\n", framerStatus); + // typical value: 0x3E + printf("HW:: OrxFramerStatus = 0x%x\n", obsFramerStatus); + // typical value: 0x28 + printf("HW:: DeframerStatus = 0x%x\n", deframerStatus); + } + + printf("HW:: All configuration done!\n"); + + return ADIERR_OK; +} + +// this function is NOT safe +//int HW_ad9371DynamicCfgInit(void) +//{ +// int Status; +// +// Status = HW_setupIntrSystem(INTC_DEVICE_ID, &Intc); +// if (Status != XST_SUCCESS) { +// printf("HW: HW_setupIntrSystem() failed!\n"); +// return XST_FAILURE; +// } +// +// Status = XGpio_Initialize(&GpioFreqCtrl, FREQ_CTRL_DEVICE_ID); +// Status |= XGpio_Initialize(&GpioGainCtrl, GAIN_CTRL_DEVICE_ID); +// Status |= XGpio_Initialize(&GpioAttnCtrl, ATTN_CTRL_DEVICE_ID); +// if (Status != XST_SUCCESS) { +// printf("HW: GPIO init failed!\n"); +// return XST_FAILURE; +// } +// +// /* Set the direction for all signals as inputs. */ +// XGpio_SetDataDirection(&GpioFreqCtrl, AXI_GPIO_BANK_1, 0xFFFFFFFF); +// XGpio_SetDataDirection(&GpioFreqCtrl, AXI_GPIO_BANK_2, 0xFFFFFFFF); +// +// XGpio_SetDataDirection(&GpioGainCtrl, AXI_GPIO_BANK_1, 0xFFFFFFFF); +// XGpio_SetDataDirection(&GpioGainCtrl, AXI_GPIO_BANK_2, 0xFFFFFFFF); +// +// XGpio_SetDataDirection(&GpioAttnCtrl, AXI_GPIO_BANK_1, 0xFFFFFFFF); +// XGpio_SetDataDirection(&GpioAttnCtrl, AXI_GPIO_BANK_2, 0xFFFFFFFF); +// +// Status = HW_connectIntr(&Intc, FREQ_CTRL_INTR_ID, +// (Xil_InterruptHandler)FreqIntrHandler, &GpioFreqCtrl, 0xA0, 0x3); +// Status |= HW_connectIntr(&Intc, GAIN_CTRL_INTR_ID, +// (Xil_InterruptHandler)GainIntrHandler, &GpioGainCtrl, 0xA0, 0x3); +// Status |= HW_connectIntr(&Intc, ATTN_CTRL_INTR_ID, +// (Xil_InterruptHandler)AttnIntrHandler, &GpioAttnCtrl, 0xA0, 0x3); +// +// XGpio_InterruptEnable(&GpioFreqCtrl, XGPIO_IR_MASK); +// XGpio_InterruptGlobalEnable(&GpioFreqCtrl); +// +// XGpio_InterruptEnable(&GpioGainCtrl, XGPIO_IR_MASK); +// XGpio_InterruptGlobalEnable(&GpioGainCtrl); +// +// XGpio_InterruptEnable(&GpioAttnCtrl, XGPIO_IR_MASK); +// XGpio_InterruptGlobalEnable(&GpioAttnCtrl); +// +// return XST_SUCCESS; +//} + +/*****************************************************************************/ +/* +* +* This function setups the interrupt system. +* +* @param DeviceId is the unique identifier for a GIC device. +* @param GicPtr is a pointer to the instance of the INTC. +* +* @return +* - XST_SUCCESS if successful, +* - XST_FAILURE.if not succesful +* +* @note None. +* +******************************************************************************/ +int HW_setupIntrSystem(u16 DeviceId, XScuGic * GicPtr) +{ + int Status; + XScuGic_Config *CfgPtr; + + /* + * Initialize the interrupt controller driver so that it is ready to + * use. + */ + CfgPtr = XScuGic_LookupConfig(DeviceId); + if (!CfgPtr) { + printf("No interrupt config found for %d\n", DeviceId); + return XST_FAILURE; + } + + Status = XScuGic_CfgInitialize(GicPtr, CfgPtr, CfgPtr->CpuBaseAddress); + if (Status != XST_SUCCESS) { + printf("No interrupt config found for %d\n", DeviceId); + return XST_FAILURE; + } + + Xil_ExceptionInit(); + Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, + (Xil_ExceptionHandler)XScuGic_InterruptHandler, + (void *)GicPtr); + Xil_ExceptionEnable(); + + return XST_SUCCESS; +} + + +int HW_connectIntr(XScuGic *GicPtr,u32 IntrId,Xil_InterruptHandler Handler, + void *CallBackRef, u8 Priority, u8 Trigger) +{ + int Status; + // Register interrupt handler + Status = XScuGic_Connect(GicPtr, IntrId, (Xil_InterruptHandler)Handler, + CallBackRef); + if(Status != XST_SUCCESS) + { + return XST_FAILURE; + } + XScuGic_SetPriorityTriggerType(GicPtr, IntrId, Priority, Trigger); + + XScuGic_Enable(GicPtr, IntrId); + + return XST_SUCCESS; +} + + +int HW_adiCfgProfileInit(void) +{ + if (!ad9528Init) { + printf("Cannot find ad9528 configuration profile with name 'ad9528Init'!"); + return ADIERR_FAILED; + } + + if (!&mykDevice) { + printf("Cannot find ad9371 configuration profile with name 'mykDevice'!"); + return ADIERR_FAILED; + } + + ad9528Init->spiSettings->chipSelectIndex = AD9528_CS; + mykDevice.spiSettings->chipSelectIndex = AD9371_CS; + + mykDevice.rx->framer->serializerLanesEnabled = 0x03; + mykDevice.rx->framer->serializerLaneCrossbar = 0xE4; + mykDevice.obsRx->framer->serializerLanesEnabled = 0x04; + mykDevice.tx->deframer->deserializerLanesEnabled = 0x03; + mykDevice.tx->deframer->deserializerLaneCrossbar = 0xE4; + + return ADIERR_OK; +} + + +int HW_9528Config(ad9528Device_t *clockAD9528_device) +{ + ADI_ERR error; + /**************************************************************************/ + /***** System Clocks Initialization Initialization Sequence *****/ + /**************************************************************************/ + + /* Perform a hard reset on the AD9528 DUT */ + error = AD9528_resetDevice(clockAD9528_device); + if (error != ADIERR_OK) { + printf("AD9528_resetDevice() failed\n"); + return ADIERR_FAILED; + } + + error = AD9528_initDeviceDataStruct(clockAD9528_device, + clockAD9528_device->pll1Settings->vcxo_Frequency_Hz, + clockAD9528_device->pll1Settings->refA_Frequency_Hz, + clockAD9528_device->outputSettings->outFrequency_Hz[1]); + if (error != ADIERR_OK) { + printf("AD9528_initDeviceDataStruct() failed\n"); + return ADIERR_FAILED; + } + + /* Initialize the AD9528 by writing all SPI registers */ + error = AD9528_initialize(clockAD9528_device); + if (error != ADIERR_OK) { + printf("WARNING: AD9528_initialize() issues.\n"); + } + + return ADIERR_OK; +} + + +int HW_9528GetLockStatus(ad9528Device_t *device, uint8_t *reg508) +{ + ADI_ERR error; + + error = CMB_SPIReadByte(device->spiSettings, AD9528_ADDR_STATUS_READBACK0, reg508); + if (error != ADIERR_OK) { + printf("HW_9528GetLockStatus failed.\n"); + return ADIERR_FAILED; + } + + return ADIERR_OK; +} + + +int HW_9371Config(ad9528Device_t *clockAD9528_device, mykonosDevice_t *mykDevice) +{ + ADI_ERR error; + mykonosErr_t mykError; + const char *errorString; + uint8_t pllLockStatus; + uint8_t mcsStatus; + uint8_t arm_major; + uint8_t arm_minor; + uint8_t arm_release; + uint32_t initCalMask = TX_BB_FILTER | ADC_TUNER | TIA_3DB_CORNER | DC_OFFSET | + TX_ATTENUATION_DELAY | RX_GAIN_DELAY | FLASH_CAL | + PATH_DELAY | TX_LO_LEAKAGE_INTERNAL | TX_QEC_INIT | + LOOPBACK_RX_LO_DELAY | LOOPBACK_RX_RX_QEC_INIT | + RX_LO_DELAY | RX_QEC_INIT ; + uint8_t errorFlag = 0; + uint8_t errorCode = 0; + uint32_t initCalsCompleted; + uint32_t trackingCalMask = TRACK_ORX1_QEC | TRACK_ORX2_QEC | TRACK_RX1_QEC | + TRACK_RX2_QEC | TRACK_TX1_QEC | TRACK_TX2_QEC; + + /* Allocating memory for the errorString */ + errorString = NULL; + + + + /*************************************************************************/ + /***** Mykonos Initialization Sequence *****/ + /*************************************************************************/ + + /* Perform a hard reset on the MYKONOS DUT (Toggle RESETB pin on device) */ + if ((mykError = MYKONOS_resetDevice(mykDevice)) != MYKONOS_ERR_OK) { + errorString = getMykonosErrorMessage(mykError); + goto error_11; + } + + if ((mykError = MYKONOS_initialize(mykDevice)) != MYKONOS_ERR_OK) { + errorString = getMykonosErrorMessage(mykError); + goto error_11; + } + + /*************************************************************************/ + /***** Mykonos CLKPLL Status Check *****/ + /*************************************************************************/ + + if ((mykError = MYKONOS_checkPllsLockStatus(mykDevice, + &pllLockStatus)) != MYKONOS_ERR_OK) { + errorString = getMykonosErrorMessage(mykError); + goto error_11; + } + + /*************************************************************************/ + /***** Mykonos Perform MultiChip Sync *****/ + /*************************************************************************/ + + if ((mykError = MYKONOS_enableMultichipSync(mykDevice, 1, + &mcsStatus)) != MYKONOS_ERR_OK) { + errorString = getMykonosErrorMessage(mykError); + goto error_11; + } + + /* Minimum 3 SYSREF pulses from Clock Device has to be produced for MulticChip Sync */ + + AD9528_requestSysref(clockAD9528_device, 1); + mdelay(1); + AD9528_requestSysref(clockAD9528_device, 1); + mdelay(1); + AD9528_requestSysref(clockAD9528_device, 1); + mdelay(1); + AD9528_requestSysref(clockAD9528_device, 1); + mdelay(1); + + /*************************************************************************/ + /***** Mykonos Verify MultiChip Sync *****/ + /*************************************************************************/ + + if ((mykError = MYKONOS_enableMultichipSync(mykDevice, 0, + &mcsStatus)) != MYKONOS_ERR_OK) { + errorString = getMykonosErrorMessage(mykError); + goto error_11; + } + + if ((mcsStatus & 0x0B) == 0x0B) + printf("MCS successful\n"); + else + printf("MCS failed\n"); + + /*************************************************************************/ + /***** Mykonos Load ARM file *****/ + /*************************************************************************/ + + if (pllLockStatus & 0x01) { + printf("CLKPLL locked\n"); + if ((mykError = MYKONOS_initArm(mykDevice)) != MYKONOS_ERR_OK) { + errorString = getMykonosErrorMessage(mykError); + goto error_11; + } + + if ((mykError = MYKONOS_loadArmFromBinary(mykDevice, + &firmware_Mykonos_M3_bin[0], firmware_Mykonos_M3_bin_len)) != MYKONOS_ERR_OK) { + errorString = getMykonosErrorMessage(mykError); + goto error_11; + } + } else { + printf("CLKPLL not locked (0x%x)\n", pllLockStatus); + error = ADIERR_FAILED; + goto error_2; + } + + /* Read back the version of the ARM binary loaded into the Mykonos ARM memory */ + if ((mykError = MYKONOS_getArmVersion(mykDevice, &arm_major, &arm_minor, + &arm_release, NULL)) == MYKONOS_ERR_OK) + printf("AD9371 ARM version %d.%d.%d\n", arm_major, arm_minor, arm_release); + + /*************************************************************************/ + /***** Mykonos Set RF PLL Frequencies *****/ + /*************************************************************************/ + + if ((mykError = MYKONOS_setRfPllFrequency(mykDevice, RX_PLL, + mykDevice->rx->rxPllLoFrequency_Hz)) != MYKONOS_ERR_OK) { + errorString = getMykonosErrorMessage(mykError); + goto error_11; + } + + if ((mykError = MYKONOS_setRfPllFrequency(mykDevice, TX_PLL, + mykDevice->tx->txPllLoFrequency_Hz)) != MYKONOS_ERR_OK) { + errorString = getMykonosErrorMessage(mykError); + goto error_11; + } + + if ((mykError = MYKONOS_setRfPllFrequency(mykDevice, SNIFFER_PLL, + mykDevice->obsRx->snifferPllLoFrequency_Hz)) != MYKONOS_ERR_OK) { + errorString = getMykonosErrorMessage(mykError); + goto error_11; + } + + /* Wait 200ms for PLLs to lock */ + mdelay(200); + + if ((mykError = MYKONOS_checkPllsLockStatus(mykDevice, + &pllLockStatus)) != MYKONOS_ERR_OK) { + errorString = getMykonosErrorMessage(mykError); + goto error_11; + } + + if ((pllLockStatus & 0x0F) == 0x0F) + printf("PLLs locked\n"); + else { + printf("PLLs not locked (0x%x)\n", pllLockStatus); + error = ADIERR_FAILED; + goto error_2; + } + +// /*************************************************************************/ +// /***** Mykonos Set GPIOs *****/ +// /*************************************************************************/ +// +// if ((mykGpioErr = MYKONOS_setRx1GainCtrlPin(mykDevice, 0, 0, 0, 0, +// 0)) != MYKONOS_ERR_GPIO_OK) { +// errorString = getGpioMykonosErrorMessage(mykGpioErr); +// goto error_11; +// } +// +// if ((mykGpioErr = MYKONOS_setRx2GainCtrlPin(mykDevice, 0, 0, 0, 0, +// 0)) != MYKONOS_ERR_GPIO_OK) { +// errorString = getGpioMykonosErrorMessage(mykGpioErr); +// goto error_11; +// } +// +// if ((mykGpioErr = MYKONOS_setTx1AttenCtrlPin(mykDevice, 0, 0, 0, 0, +// 0)) != MYKONOS_ERR_GPIO_OK) { +// errorString = getGpioMykonosErrorMessage(mykGpioErr); +// goto error_11; +// } +// +// if ((mykGpioErr = MYKONOS_setTx2AttenCtrlPin(mykDevice, 0, 0, 0, +// 0)) != MYKONOS_ERR_GPIO_OK) { +// errorString = getGpioMykonosErrorMessage(mykGpioErr); +// goto error_11; +// } +// +// if ((mykGpioErr = MYKONOS_setupGpio(mykDevice)) != MYKONOS_ERR_GPIO_OK) { +// errorString = getGpioMykonosErrorMessage(mykGpioErr); +// goto error_11; +// } +// +// /*************************************************************************/ +// /***** Mykonos Set manual gains values *****/ +// /*************************************************************************/ +// +// if ((mykError = MYKONOS_setRx1ManualGain(mykDevice, 255)) != MYKONOS_ERR_OK) { +// errorString = getMykonosErrorMessage(mykError); +// goto error_11; +// } +// +// if ((mykError = MYKONOS_setRx2ManualGain(mykDevice, 255)) != MYKONOS_ERR_OK) { +// errorString = getMykonosErrorMessage(mykError); +// goto error_11; +// } +// +// if ((mykError = MYKONOS_setObsRxManualGain(mykDevice, OBS_RX1_TXLO, +// 255)) != MYKONOS_ERR_OK) { +// errorString = getMykonosErrorMessage(mykError); +// goto error_11; +// } +// +// if ((mykError = MYKONOS_setObsRxManualGain(mykDevice, OBS_RX2_TXLO, +// 255)) != MYKONOS_ERR_OK) { +// errorString = getMykonosErrorMessage(mykError); +// goto error_11; +// } +// +// if ((mykError = MYKONOS_setObsRxManualGain(mykDevice, OBS_SNIFFER_A, +// 255)) != MYKONOS_ERR_OK) { +// errorString = getMykonosErrorMessage(mykError); +// goto error_11; +// } +// +// if ((mykError = MYKONOS_setObsRxManualGain(mykDevice, OBS_SNIFFER_B, +// 255)) != MYKONOS_ERR_OK) { +// errorString = getMykonosErrorMessage(mykError); +// goto error_11; +// } +// +// if ((mykError = MYKONOS_setObsRxManualGain(mykDevice, OBS_SNIFFER_C, +// 255)) != MYKONOS_ERR_OK) { +// errorString = getMykonosErrorMessage(mykError); +// goto error_11; +// } +// +// /*************************************************************************/ +// /***** Mykonos Initialize attenuations *****/ +// /*************************************************************************/ +// +// mykError = MYKONOS_setTx1Attenuation(mykDevice, 10000); +// if (mykError != MYKONOS_ERR_OK) { +// errorString = getMykonosErrorMessage(mykError); +// goto error_11; +// } +// +// mykError = MYKONOS_setTx2Attenuation(mykDevice, 10000); +// if (mykError != MYKONOS_ERR_OK) { +// errorString = getMykonosErrorMessage(mykError); +// goto error_11; +// } + + /*************************************************************************/ + /***** Mykonos ARM Initialization Calibrations *****/ + /*************************************************************************/ + + if ((mykError = MYKONOS_runInitCals(mykDevice, + (initCalMask & ~TX_LO_LEAKAGE_EXTERNAL))) != MYKONOS_ERR_OK) { + errorString = getMykonosErrorMessage(mykError); + goto error_11; + } + + if ((mykError = MYKONOS_waitInitCals(mykDevice, 60000, &errorFlag, + &errorCode)) != MYKONOS_ERR_OK) { + errorString = getMykonosErrorMessage(mykError); + goto error_11; + } + + if ((errorFlag != 0) || (errorCode != 0)) { + /*** < Info: abort init cals > ***/ + if ((mykError = MYKONOS_abortInitCals(mykDevice, + &initCalsCompleted)) != MYKONOS_ERR_OK) { + errorString = getMykonosErrorMessage(mykError); + goto error_11; + } + if (initCalsCompleted) + printf("Completed calibrations: %x\n", (unsigned int)initCalsCompleted); + } else + printf("Calibrations completed successfully\n"); + + /*************************************************************************/ + /***** Mykonos ARM Initialization External LOL Calibrations with PA *****/ + /*************************************************************************/ + + /* Please ensure PA is enabled operational at this time */ + if (initCalMask & TX_LO_LEAKAGE_EXTERNAL) { + if ((mykError = MYKONOS_runInitCals(mykDevice, + TX_LO_LEAKAGE_EXTERNAL)) != MYKONOS_ERR_OK) { + errorString = getMykonosErrorMessage(mykError); + goto error_11; + } + + if ((mykError = MYKONOS_waitInitCals(mykDevice, 60000, &errorFlag, + &errorCode)) != MYKONOS_ERR_OK) { + errorString = getMykonosErrorMessage(mykError); + goto error_11; + } + + if ((errorFlag != 0) || (errorCode != 0)) { + /*** < Info: abort init cals > ***/ + if ((mykError = MYKONOS_abortInitCals(mykDevice, + &initCalsCompleted)) != MYKONOS_ERR_OK) { + errorString = getMykonosErrorMessage(mykError); + goto error_11; + } + } else + printf("External LOL Calibrations completed successfully\n"); + } + + /*************************************************************************/ + /***** SYSTEM JESD bring up procedure *****/ + /*************************************************************************/ + + if ((mykError = MYKONOS_enableSysrefToRxFramer(mykDevice, + 1)) != MYKONOS_ERR_OK) { + errorString = getMykonosErrorMessage(mykError); + goto error_11; + } + /*** < Info: Mykonos is waiting for sysref in order to start + * transmitting CGS from the RxFramer> ***/ + + if ((mykError = MYKONOS_enableSysrefToObsRxFramer(mykDevice, + 1)) != MYKONOS_ERR_OK) { + errorString = getMykonosErrorMessage(mykError); + goto error_11; + } + /*** < Info: Mykonos is waiting for sysref in order to start + * transmitting CGS from the ObsRxFramer> ***/ + + if ((mykError = MYKONOS_enableSysrefToDeframer(mykDevice, + 0)) != MYKONOS_ERR_OK) { + errorString = getMykonosErrorMessage(mykError); + goto error_11; + } + + if ((mykError = MYKONOS_resetDeframer(mykDevice)) != MYKONOS_ERR_OK) { + errorString = getMykonosErrorMessage(mykError); + goto error_11; + } + + if ((mykError = MYKONOS_enableSysrefToDeframer(mykDevice, + 1)) != MYKONOS_ERR_OK) { + errorString = getMykonosErrorMessage(mykError); + goto error_11; + } + + /*************************************************************************/ + /***** Enable SYSREF to Mykonos and BBIC *****/ + /*************************************************************************/ + + /* Request a SYSREF from the AD9528 */ + AD9528_requestSysref(clockAD9528_device, 1); + mdelay(1); + + /*** < Info: Mykonos is actively transmitting CGS from the RxFramer> ***/ + + /*** < Info: Mykonos is actively transmitting CGS from the ObsRxFramer> ***/ + + /* Request two SYSREFs from the AD9528 */ + AD9528_requestSysref(clockAD9528_device, 1); + mdelay(1); + AD9528_requestSysref(clockAD9528_device, 1); + mdelay(5); + + /*************************************************************************/ + /***** Mykonos enable tracking calibrations *****/ + /*************************************************************************/ + + if ((mykError = MYKONOS_enableTrackingCals(mykDevice, + trackingCalMask)) != MYKONOS_ERR_OK) { + errorString = getMykonosErrorMessage(mykError); + goto error_11; + } + + /*** < Info: Allow Rx1/2 QEC tracking and Tx1/2 QEC tracking to run when in the radioOn state + * Tx calibrations will only run if radioOn and the obsRx path is set to OBS_INTERNAL_CALS > ***/ + + /*** < Info: Function to turn radio on, Enables transmitters and receivers + * that were setup during MYKONOS_initialize() > ***/ + if ((mykError = MYKONOS_radioOn(mykDevice)) != MYKONOS_ERR_OK) { + errorString = getMykonosErrorMessage(mykError); + goto error_11; + } + + /*** < Info: Allow TxQEC to run when User: is not actively using ORx receive path > ***/ + if ((mykError = MYKONOS_setObsRxPathSource(mykDevice, + OBS_RXOFF)) != MYKONOS_ERR_OK) { + errorString = getMykonosErrorMessage(mykError); + goto error_11; + } + if ((mykError = MYKONOS_setObsRxPathSource(mykDevice, + OBS_INTERNALCALS)) != MYKONOS_ERR_OK) { + errorString = getMykonosErrorMessage(mykError); + goto error_11; + } + + mdelay(1000); + + if ((mykError = MYKONOS_setObsRxPathSource(mykDevice, + OBS_RX1_SNIFFERLO)) != MYKONOS_ERR_OK) { + errorString = getMykonosErrorMessage(mykError); + goto error_11; + } + + Xil_DCacheInvalidateRange(DDR_MEM_BASEADDR + 0x800000, 16384 * 8); + + printf("Done\n"); + + return 0; + +error_11: + printf("%s", errorString); + +error_2: +// axi_clkgen_remove(rx_clkgen); + return FAILURE; +} + + +int HW_9371CheckJesdStatus(mykonosDevice_t *mykDevice, uint8_t *framerStatus, + uint8_t *obsFramerStatus, uint8_t *deframerStatus) +{ + mykonosErr_t mykError; + const char *errorString; + /* Allocating memory for the errorString */ + errorString = NULL; + + /*************************************************************************/ + /***** Check Mykonos Framer Status *****/ + /*************************************************************************/ + + if ((mykError = MYKONOS_readRxFramerStatus(mykDevice, + framerStatus)) != MYKONOS_ERR_OK) { + errorString = getMykonosErrorMessage(mykError); + return ADIERR_FAILED; + } + else { + // typical value: 0x3E + } + + if ((mykError = MYKONOS_readOrxFramerStatus(mykDevice, + obsFramerStatus)) != MYKONOS_ERR_OK) { + errorString = getMykonosErrorMessage(mykError); + return ADIERR_FAILED; + } else { + // typical value: 0x3E + } + + /*************************************************************************/ + /***** Check Mykonos Deframer Status *****/ + /*************************************************************************/ + + if ((mykError = MYKONOS_readDeframerStatus(mykDevice, + deframerStatus)) != MYKONOS_ERR_OK) { + errorString = getMykonosErrorMessage(mykError); + return ADIERR_FAILED; + } else { + // typical value: 0x28 + } + + return ADIERR_OK; +} + + +int HW_9371SmallFrequencyChange(mykonosDevice_t *mykDevice, uint64_t freq_Hz) +{ + mykonosErr_t mykError = MYKONOS_ERR_OK; + uint8_t pllLockStatus = 0; + /* + * Move the device into the radio off state. + */ + if((mykError = MYKONOS_radioOff(mykDevice)) != MYKONOS_ERR_OK) + { + printf("Turn radio off failed!\n\r"); + return ADIERR_FAILED; + } + + /* + * Program the new local oscillator (LO) frequency. Check if PLL is locked. + */ + if((mykError = MYKONOS_setRfPllFrequency(mykDevice, TX_PLL, + freq_Hz)) != MYKONOS_ERR_OK) + { + printf("Set TX PLL failed!\n\r"); + return ADIERR_FAILED; + } + mykError = MYKONOS_checkPllsLockStatus(mykDevice, &pllLockStatus); + if ((pllLockStatus & 0x07) != 0x07) + { + /*** < Info: Clock, Rx and Tx PLLs not locked > ***/ + printf("Not all PLLs locked, lock status: 0x%02x\n", pllLockStatus); + } + + /* + * Reset the external channel. + */ +// If((mykError = MYKONOS_resetExtTxLolChannel(mykDevice, TX1_TX2)) +// != MYKONOS_ERR_OK) ; //where TX1_TX2 is part of the enum mykonosTxChannels_t +// { +// printf("Reset external channel FAILED!"); +// } + + /* + * Move the device back into the radio on state. + */ + if ((mykError = MYKONOS_radioOn(mykDevice)) != MYKONOS_ERR_OK) + { + printf("Turn radio on failed!\n\r"); + return ADIERR_FAILED; + } + + /* + * Reenable tracking calibrations. + */ +// If((mykError = MYKONOS_MYKONOS_setObsRxPathSource(mykDevice, OBS_INTERNALCALS)) +// != MYKONOS_ERR_OK) ; //where TX1_TX2 is part of the enum mykonosTxChannels_t +// { +// printf("Reenable tracking calibrations FAILED!"); +// } + return ADIERR_OK; +} + + +int HW_9371LargeFrequencyChange(mykonosDevice_t *mykDevice, uint64_t freq_Hz) +{ + mykonosErr_t mykError = MYKONOS_ERR_OK; + uint8_t pllLockStatus = 0; + uint8_t errorFlag = 0; + uint8_t errorCode = 0; + uint32_t initCalsCompleted = 0; + uint16_t errorWord = 0; + uint16_t statusWord = 0; + uint8_t status = 0; + mykonosInitCalStatus_t initCalStatus = {0}; + + /* + * Move the device into the radio off state. + */ + if((mykError = MYKONOS_radioOff(mykDevice)) != MYKONOS_ERR_OK) + { + printf("Turn radio off failed!\n\r"); + return ADIERR_FAILED; + } + + /* + * Program the new local oscillator (LO) frequency. Check if PLL is locked. + */ + if((mykError = MYKONOS_setRfPllFrequency(mykDevice, TX_PLL, + freq_Hz)) != MYKONOS_ERR_OK) + { + printf("Set TX PLL failed!\n\r"); + return ADIERR_FAILED; + } + mykError = MYKONOS_checkPllsLockStatus(mykDevice, &pllLockStatus); + if ((pllLockStatus & 0x07) != 0x07) + { + /*** < Info: Clock, Rx and Tx PLLs not locked > ***/ + printf("Not all PLLs locked, lock status: 0x%02x\n", pllLockStatus); + } + + /* + * Rerun the initialization calibrations. + */ + uint32_t initCalMask = TX_QEC_INIT | LOOPBACK_RX_LO_DELAY | + LOOPBACK_RX_RX_QEC_INIT | RX_LO_DELAY | RX_QEC_INIT; + if ((mykError = MYKONOS_runInitCals(mykDevice, initCalMask)) + != MYKONOS_ERR_OK) + { + printf("Rerun the initialization calibrations FAILED!"); + return ADIERR_FAILED; + } + if ((mykError = MYKONOS_waitInitCals(mykDevice, 60000, &errorFlag, + &errorCode)) != MYKONOS_ERR_OK) + { + printf("Initialize calibration TIME OUT!"); + return ADIERR_FAILED; + } + if ((errorFlag != 0) || (errorCode != 0)) + { + printf("initial cals error!\n\r"); + + if((mykError = MYKONOS_getInitCalStatus(mykDevice, &initCalStatus)) + != MYKONOS_ERR_OK) + { + /*** < User log error return value to debug why init failed > ***/ + } + + //abort init calibrations + if((mykError = MYKONOS_abortInitCals(mykDevice, &initCalsCompleted)) + != MYKONOS_ERR_OK) + { + /*** < User log error return value to debug why init failed > ***/ + + } + if(initCalsCompleted) + { + /*** < which calls had completed, per the mask > ***/ + } + if((mykError = MYKONOS_readArmCmdStatus(mykDevice, &errorWord, + &statusWord)) != MYKONOS_ERR_OK) + { + /*** < User log error return value to debug why init failed > ***/ + } + if((mykError = MYKONOS_readArmCmdStatusByte(mykDevice, 2, &status)) + != MYKONOS_ERR_OK) + { + + } + if(status!=0) + { + /*** < Arm Mailbox Status Error errorWord > ***/ + /*** < Pending Flag per opcode statusWord, this follows the mask > ***/ + } + } + + /* + * Move the device back into the radio on state. + */ + if ((mykError = MYKONOS_radioOn(mykDevice)) != MYKONOS_ERR_OK) + { + printf("Turn radio on failed!\n\r"); + return ADIERR_FAILED; + } + + return ADIERR_OK; +} + + +//void FreqIntrHandler(void *CallbackRef) +//{ +// XGpio *GpioPtr = (XGpio *)CallbackRef; +// uint8_t IntrStatus; +// uint32_t NewFreqHz; +// IntrStatus = XGpio_InterruptGetStatus(GpioPtr); +// +// if (IntrStatus & XGPIO_IR_CH1_MASK) +// { +// /* Clear the Interrupt */ +// XGpio_InterruptClear(GpioPtr, XGPIO_IR_CH1_MASK); +// +// NewFreqHz = XGpio_DiscreteRead(GpioPtr, AXI_GPIO_BANK_1); +// if (NewFreqHz != mykDevice.tx->txPllLoFrequency_Hz) +// { +// if (NewFreqHz > 300000000 && NewFreqHz < 6000000000) +// { +// if (abs(NewFreqHz - mykDevice.tx->txPllLoFrequency_Hz) <= 100000000) +// { +// HW_9371SmallFrequencyChange(&mykDevice, NewFreqHz); +// } +// else +// { +// HW_9371LargeFrequencyChange(&mykDevice, NewFreqHz); +// } +// mykDevice.tx->txPllLoFrequency_Hz = NewFreqHz; +// printf("New Tx frequency set to %ld Hz!\n",NewFreqHz); +// } +// else +// { +// printf("The desired Tx Frequency is out of range(300 ~ 6000 MHz)!\n"); +// } +// } +// } +// +// if (IntrStatus & XGPIO_IR_CH2_MASK) +// { +// /* Clear the Interrupt */ +// XGpio_InterruptClear(GpioPtr, XGPIO_IR_CH2_MASK); +// +// NewFreqHz = XGpio_DiscreteRead(GpioPtr, AXI_GPIO_BANK_2); +// if (NewFreqHz != mykDevice.rx->rxPllLoFrequency_Hz) +// { +// if (NewFreqHz > 300000000 && NewFreqHz < 6000000000) +// { +// if (abs(NewFreqHz - mykDevice.rx->rxPllLoFrequency_Hz) <= 100000000) +// { +// HW_9371SmallFrequencyChange(&mykDevice, NewFreqHz); +// } +// else +// { +// HW_9371LargeFrequencyChange(&mykDevice, NewFreqHz); +// } +// mykDevice.rx->rxPllLoFrequency_Hz = NewFreqHz; +// printf("New Rx frequency set to %ld Hz!\n",NewFreqHz); +// } +// else +// { +// printf("The desired Rx Frequency is out of range(300 ~ 6000 MHz)!\n"); +// } +// } +// } +//} +// +// +//void GainIntrHandler(void *CallbackRef) +//{ +// XGpio *GpioPtr = (XGpio *)CallbackRef; +// uint8_t IntrStatus; +// uint32_t NewRxGain; +// IntrStatus = XGpio_InterruptGetStatus(GpioPtr); +// +// if (IntrStatus & XGPIO_IR_CH1_MASK) +// { +// /* Clear the Interrupt */ +// XGpio_InterruptClear(GpioPtr, XGPIO_IR_CH1_MASK); +// +// NewRxGain = XGpio_DiscreteRead(GpioPtr, AXI_GPIO_BANK_1); +// if (NewRxGain != mykDevice.rx->rxGainCtrl->rx1GainIndex) +// { +// if ((NewRxGain >= 195) && (NewRxGain <= 255)) +// { +// MYKONOS_setRx1ManualGain(&mykDevice, NewRxGain); +// mykDevice.rx->rxGainCtrl->rx1GainIndex = NewRxGain; +// char buf[BUFSIZ]; +// sprintf(buf, "%u", NewRxGain); +// printf("New Rx1 gain index set to %s!\n",buf); +// } +// else +// { +// printf("The desired Rx1 gain index is out of range(195 ~ 255), 0.5dB per stage!\n"); +// } +// } +// } +// +// if (IntrStatus & XGPIO_IR_CH2_MASK) +// { +// /* Clear the Interrupt */ +// XGpio_InterruptClear(GpioPtr, XGPIO_IR_CH2_MASK); +// +// NewRxGain = XGpio_DiscreteRead(GpioPtr, AXI_GPIO_BANK_2); +// if (NewRxGain != mykDevice.rx->rxGainCtrl->rx2GainIndex) +// { +// if ((NewRxGain >= 195) && (NewRxGain <= 255)) +// { +// MYKONOS_setRx2ManualGain(&mykDevice, NewRxGain); +// mykDevice.rx->rxGainCtrl->rx2GainIndex = NewRxGain; +// char buf[BUFSIZ]; +// sprintf(buf, "%u", NewRxGain); +// printf("New Rx2 gain index set to %s!\n",buf); +// } +// else +// { +// printf("The desired Rx2 gain index is out of range(195 ~ 255), 0.5dB per stage!\n"); +// } +// } +// } +//} +// +// +//void AttnIntrHandler(void *CallbackRef) +//{ +// XGpio *GpioPtr = (XGpio *)CallbackRef; +// uint8_t IntrStatus; +// uint32_t NewTxAttn; +// IntrStatus = XGpio_InterruptGetStatus(GpioPtr); +// +// if (IntrStatus & XGPIO_IR_CH1_MASK) +// { +// /* Clear the Interrupt */ +// XGpio_InterruptClear(GpioPtr, XGPIO_IR_CH1_MASK); +// +// NewTxAttn = XGpio_DiscreteRead(GpioPtr, AXI_GPIO_BANK_1); +// if (NewTxAttn != mykDevice.tx->tx1Atten_mdB) +// { +// if ((NewTxAttn >= 0) && (NewTxAttn <= 41950)) +// { +// MYKONOS_setTx1Attenuation(&mykDevice, NewTxAttn); +// mykDevice.tx->tx1Atten_mdB = NewTxAttn; +// char buf[BUFSIZ]; +// sprintf(buf, "%u", NewTxAttn); +// printf("New Tx1 attenuation set to %s dBm!\n",buf); +// } +// else +// { +// printf("The desired Tx1 attenuation is out of range(0 ~ 41950 dBm), 50 dBm step!\n"); +// } +// } +// } +// +// if (IntrStatus & XGPIO_IR_CH2_MASK) +// { +// /* Clear the Interrupt */ +// XGpio_InterruptClear(GpioPtr, XGPIO_IR_CH2_MASK); +// +// NewTxAttn = XGpio_DiscreteRead(GpioPtr, AXI_GPIO_BANK_2); +// if (NewTxAttn != mykDevice.tx->tx2Atten_mdB) +// { +// if ((NewTxAttn >= 0) && (NewTxAttn <= 41950)) +// { +// MYKONOS_setTx2Attenuation(&mykDevice, NewTxAttn); +// mykDevice.tx->tx2Atten_mdB = NewTxAttn; +// char buf[BUFSIZ]; +// sprintf(buf, "%u", NewTxAttn); +// printf("New Tx2 attenuation set to %s dBm!\n",buf); +// } +// else +// { +// printf("The desired Tx2 attenuation is out of range(0 ~ 41950 dBm), 50 dBm step!\n"); +// } +// } +// } +//} diff --git a/df_datalink_ge/src/hardware/headless.h b/df_datalink_ge/src/hardware/headless.h new file mode 100644 index 0000000..41efed4 --- /dev/null +++ b/df_datalink_ge/src/hardware/headless.h @@ -0,0 +1,348 @@ +/* + * headless.h + * + * Created on: 2021Äê6ÔÂ8ÈÕ + * Author: Josh + */ + +#ifndef SRC_HEADLESS_H_ +#define SRC_HEADLESS_H_ + +/***************************** Include Files ********************************/ +#include +#include +#include "xil_cache.h" +#include "xscugic.h" +//#include "xgpio.h" + +#include "common.h" +#include "./mykonos/ad9528.h" +#include "./mykonos/mykonos.h" +#include "./mykonos/Mykonos_M3.h" +#include "./mykonos/mykonos_gpio.h" +#include "myk_ad9528init.h" +#include "myk_init.h" + +#include "parameters.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Variable Definitions *****************************/ + +/************************** Function Prototypes ******************************/ + +/*****************************************************************************/ +/* +* +* This function setups ad9528 and ad9371 via spi. +* +* @param None. +* +* @return +* - ADIERR_FAILED if successful, +* - ADIERR_OK if not succesful +* +* @note None. +* +******************************************************************************/ +int HARDWARE_initialize(); + +int HARDWARE_ad9371Config(void); + +/*****************************************************************************/ +/* +* +* Setup up Axi Gpio, through which ad9371 can be reconfigured. Axi Gpio +* instance and interrupt system initialization are included. +* +* @param None. +* +* @return +* - ADIERR_FAILED if successful, +* - ADIERR_OK if not succesful +* +* @note None. +* +******************************************************************************/ +int HW_ad9371DynamicCfgInit(void); + +/*****************************************************************************/ +/* +* +* Setup up interrupt system, initialize exception handlers. +* +* @param DeviceId is the unique identifier for a device. +* @param GicPtr is a pointer to the XScuGic instance. +* +* @return +* - XST_SUCCESS if successful, +* - XST_FAILURE if not succesful +* +* @note None. +* +******************************************************************************/ +int HW_setupIntrSystem(u16 DeviceId, XScuGic * GicPtr); + +/*****************************************************************************/ +/* +* +* Make the connection between the Int_Id of the interrupt source and the +* associated handler. Set the interrupt priority and trigger type for the +* specified IRQ source.. +* +* @param GicPtr 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. +* @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 +* - XST_SUCCESS if successful, +* - XST_FAILURE if not succesful +* +* @note None. +* +******************************************************************************/ +int HW_connectIntr(XScuGic *GicPtr,u32 IntrId,Xil_InterruptHandler Handler, + void *CallBackRef, u8 Priority, u8 Trigger); + +/*****************************************************************************/ +/* +* +* Initialize Analog Device related configuration profile. This is a HARDWARE- +* ASSOTIATED function, which may differ between different board. +* +* @param None. +* +* @return +* - ADIERR_OK if configuration profile exists, +* - ADIERR_FAILED if onfiguration profile does not exist +* +* @note None. +* +******************************************************************************/ +int HW_adiCfgProfileInit(void); + +/******************************************************************************/ +/** +* +* This function conducts AD9528 device configuration initializing procedure. +* +* @param clockAD9528_device is a pointer to the data structure holding +* AD9528 settings, which contains basic AD9528 settings such as +* spi and gpio. +* +* @return +* - ADIERR_OK if successful. +* - ADIERR_FAILED if not successful. +* +* @note None. +* +*******************************************************************************/ +int HW_9528Config(ad9528Device_t *clockAD9528_device); + +/******************************************************************************/ +/** +* +* This function read AD9528 reg508 status, to check whether ad9528 is locked or +* not. +* +* @param clockAD9528_device is a pointer to the data structure holding +* AD9528 settings, which contains basic AD9528 settings. +* +* @return +* - ADIERR_OK if successful. +* - ADIERR_FAILED if not successful. +* +* @note None. +* +*******************************************************************************/ +int HW_9528GetLockStatus(ad9528Device_t *device, uint8_t *reg508); + +/******************************************************************************/ +/** +* +* Conduct AD9371 device configuration initializing procedure. +* +* @param clockAD9528_device is a pointer to the data structure holding +* AD9528 settings, which contains basic AD9528 settings. +* @param mykDevice is ADI hardware layer settings pointer specific to +* a Mykonos instance which contains basic settings such as spi, +* gpio, tx/rx and jesd configurations. +* +* @return +* - ADIERR_OK if successful. +* - ADIERR_FAILED if not successful. +* +* @note None. +* +*******************************************************************************/ +int HW_9371Config(ad9528Device_t *clockAD9528_device, mykonosDevice_t *mykDevice); + +/******************************************************************************/ +/** +* +* Read AD9371's RX framer, ORX framer and TX deframer status, to check jesd204b +* sync status. +* +* @param mykDevice is ADI hardware layer settings pointer specific to +* a Mykonos instance which contains basic settings such as spi, +* gpio, tx/rx and jesd configurations. +* @param framerStatus is the RX framer status byte read +* framerStatus | Description +* -------------|----------------------------------------------------------------------------- +* [7] | SYSREF phase error ? a new SYSREF had different timing than the first that set the LMFC timing. +* [6] | Framer lane FIFO read/write pointer delta has changed. Can help debug issues with deterministic latency. +* [5] | Framer has received the SYSREF and has retimed its LMFC +* [4:2] | Framer ILAS state: 0=CGS, 1= 1st Multframe, 2= 2nd Multiframe, 3= 3rd Multiframe, 4= 4th multiframe, 5= Last multiframe, 6=invalid, 7= ILAS complete +* [1:0] | Framer Tx state: 0=CGS, 1= ILAS, 2 = ADC Data +* @param obsFramerStatus is the ORX framer status byte read +* obsFramerStatus | Description +* ----------------|----------------------------------------------------------------------------- +* [7] | SYSREF phase error ? a new SYSREF had different timing than the first that set the LMFC timing. +* [6] | Framer lane FIFO read/write pointer delta has changed. Can help debug issues with deterministic latency. +* [5] | Framer has received the SYSREF and has retimed its LMFC +* [4:2] | Framer ILAS state: 0=CGS, 1= 1st Multframe, 2= 2nd Multiframe, 3= 3rd Multiframe, 4= 4th multiframe, 5= Last multiframe, 6=invalid, 7= ILAS complete +* [1:0] | Framer Tx state: 0=CGS, 1= ILAS, 2 = ADC Data +* @param deframerStatus is the TX deframer status byte read +* deframerStatus | Bit Name | Description +* ----------------|--------------------------|--------------------------------------------- +* [7] | Unused | Unused +* [6] | Deframer IRQ | This bit indicates that the IRQ interrupt was asserted. +* [5] | Deframer SYSREF Received | When this bit is set, it indicates that the SYSREF pulse was received by the deframer IP +* [4] | Deframer Receiver Error | This bit is set when PRBS has received an error. +* [3] | Valid Checksum | This bit is set when the received ILAS checksum is valid. +* [2] | EOF Event | This bit captures the internal status of the framer End of Frame event. Value =1 if framing error during ILAS +* [1] | EOMF Event | This bit captures the internal status of the framer End of Multi-Frame event. Value =1 if framing error during ILAS +* [0] | FS Lost | This bit captures the internal status of the framer Frame Symbol event. Value =1 if framing error during ILAS or user data (invalid replacement characters) +* +* @return +* - ADIERR_OK if successful. +* - ADIERR_FAILED if not successful. +* +* @note None. +* +*******************************************************************************/ +int HW_9371CheckJesdStatus(mykonosDevice_t *mykDevice, uint8_t *framerStatus, + uint8_t *obsFramerStatus, uint8_t *deframerStatus); + +/******************************************************************************/ +/** +* +* This function conducts AD9371/9375 samll RF PLL frequcny change procedure. The +* procedure is performed as follows: +* 1. Move the device into the radio off state. +* 2. Program the new local oscillator (LO) frequency. +* 3. Reset the external channel.(ignored) +* 4. Move the device back into the radio on state. +* 5. Reenable tracking calibrations.(ignored) +* +* @param mykDevice is ADI hardware layer settings pointer specific to +* a Mykonos instance which contains basic settings such as spi, +* gpio, tx/rx and jesd configurations. +* @param freq_Hz is the target frequancy in Hz. +* +* @return None. +* +* @note The procedure is used when a radio frequency (RF) phased-lock loop +* (PLL) change is required with the following conditions: +* - A desire to change the Rx, Tx, and ORx frequencies. +* - The frequency step change is less than 100 MHz. +* - The frequency step does not cross the divide by 2 boundaries outlined +* in AD9371/9375-UG-992-Rev.B-Table 96. +* +*******************************************************************************/ +int HW_9371SmallFrequencyChange(mykonosDevice_t *mykDevice, uint64_t freq_Hz); + +/******************************************************************************/ +/** +* +* This function conducts AD9371/9375 large RF PLL frequcny change procedure. The +* procedure is performed as follows: +* 1. Move the device into the radio off state. +* 2. Program the new local oscillator (LO) frequency. +* 3. Rerun the initialization calibrations. +* 4. Move the device back into the radio on state. +* 5. Reenable tracking calibrations.(ignored) +* +* @param mykDevice is ADI hardware layer settings pointer specific to +* a Mykonos instance which contains basic settings such as spi, +* gpio, tx/rx and jesd configurations. +* @param freq_Hz is the target frequancy in Hz. +* +* @return None. +* +* @note The procedure is used when a radio frequency (RF) phased-lock loop +* (PLL) change is required with the following conditions: +* - A desire to change the Rx, Tx, and ORx frequencies. +* - The frequency step change is more than 100 MHz. +* - The frequency step does cross the divide by 2 boundaries outlined +* in AD9371/9375-UG-992-Rev.B-Table 96. +* +*******************************************************************************/ +int HW_9371LargeFrequencyChange(mykonosDevice_t *mykDevice, uint64_t freq_Hz); + +/******************************************************************************/ +/** +* +* Handles AD9371 TX & RX frequency change axi gpio interruput. +* +* @param CallBackRef is the callback reference, usually the instance +* pointer of the connecting driver. +* +* @return None. +* +* @note None. +* +*******************************************************************************/ +void FreqIntrHandler(void *CallbackRef); + +/******************************************************************************/ +/** +* +* Handles AD9371 Rx gain index change axi gpio interruput. +* +* @param CallBackRef is the callback reference, usually the instance +* pointer of the connecting driver. +* +* @return None. +* +* @note None. +* +*******************************************************************************/ +void GainIntrHandler(void *CallbackRef); + +/******************************************************************************/ +/** +* +* Handles AD9371 Tx attenuation change axi gpio interruput. +* +* @param CallBackRef is the callback reference, usually the instance +* pointer of the connecting driver. +* +* @return None. +* +* @note None. +* +*******************************************************************************/ +void AttnIntrHandler(void *CallbackRef); + +#endif /* SRC_HEADLESS_H_ */ diff --git a/df_datalink_ge/src/hardware/myk_ad9528init.c b/df_datalink_ge/src/hardware/myk_ad9528init.c new file mode 100644 index 0000000..0cb935d --- /dev/null +++ b/df_datalink_ge/src/hardware/myk_ad9528init.c @@ -0,0 +1,189 @@ +///* +// * myk_clock_init.c +// * +// */ +// +///** +//* \page Disclaimer Legal Disclaimer +//* Copyright 2015-2017 Analog Devices Inc. +//* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file. +//* +//*/ +// +//#ifndef MYK_CLOCK_INIT_C_ +//#define MYK_CLOCK_INIT_C_ +//#include +//#include +//#include +//#include "common.h" +// +//#include "ad9528.h" +//#include "t_ad9528.h" +//#include "myk_ad9528init.h" +//#include "parameters.h" +// +//static ad9528pll1Settings_t clockPll1Settings = +//{ +// .refA_Frequency_Hz = 30720000, +// .refA_Divider = 1, +// .refA_bufferCtrl = DISABLED, +// .refB_Frequency_Hz = 0, +// .refB_Divider = 1, +// .refB_bufferCtrl = DISABLED, +// .vcxo_Frequency_Hz = 122880000, +// .vcxoBufferCtrl = NEG_SINGLE_ENDED, +// .nDivider = 4, +// .bypassPll1 = 0 +//}; +// +//static ad9528pll2Settings_t clockPll2Settings = +//{ +// .rfDivider = 4, +// .n2Divider = 10, +// .totalNdiv = 30 +//}; +// +//static ad9528outputSettings_t clockOutputSettings = +//{ +// .outPowerDown = 53237, // 0xCFF5 +// .outSource = { +// CHANNEL_DIV, CHANNEL_DIV, CHANNEL_DIV, SYSREF, +// CHANNEL_DIV, CHANNEL_DIV, CHANNEL_DIV, CHANNEL_DIV, +// CHANNEL_DIV, CHANNEL_DIV, CHANNEL_DIV, CHANNEL_DIV, +// SYSREF, CHANNEL_DIV}, +// .outBufferCtrl = {0,0,0,0,0,0,0,0,0,0,0,0,0,0}, +// .outAnalogDelay = {0,0,0,0,0,0,0,0,0,0,0,0,0,0}, +// .outDigitalDelay = {0,0,0,0,0,0,0,0,0,0,0,0,0,0}, +// .outChannelDiv = {10,10,10,10,10,10,10,10,10,10,10,10,10,10}, +// .outFrequency_Hz = {122880000, 122880000, 122880000, 122880000, 122880000, 122880000, 122880000, 122880000, 122880000, 122880000, 122880000, 122880000, 122880000, 122880000} +//}; +// +//static ad9528sysrefSettings_t clockSysrefSettings = +//{ +// .sysrefRequestMethod = PIN, +// .sysrefSource = INTERNAL, +// .sysrefPinEdgeMode = LEVEL_ACTIVE_HIGH, +// .sysrefPinBufferMode = DISABLED, +// .sysrefPatternMode = NSHOT, +// .sysrefNshotMode = ONE_PULSE, +// .sysrefDivide = 512 +//}; +// +//static spiSettings_t clockSpiSettings = +//{ +// .chipSelectIndex = AD9528_CS, //chip select Index +// .writeBitPolarity = 0, //Write bit polarity +// .longInstructionWord = 1, //16bit instruction word +// .MSBFirst = 1, //MSB first +// .CPHA = 0, //Clock phase +// .CPOL = 0, //Clock polarity +// .enSpiStreaming = 0, //uint8_t enSpiStreaming; +// .autoIncAddrUp = 1, //uint8_t autoIncAddrUp; +// .fourWireMode = 1 //uint8_t fourWireMode; +//}; +// +//ad9528Device_t clockAD9528_ = +//{ +// &clockSpiSettings, +// &clockPll1Settings, +// &clockPll2Settings, +// &clockOutputSettings, +// &clockSysrefSettings +//}; +// +//ad9528Device_t *ad9528Init = &clockAD9528_; +// +//#endif /* MYK_CLOCK_INIT_C_ */ + + +/* AD9528 data structure initialization file */ +#include +#include +#include +#include "common.h" + +#include "./mykonos/ad9528.h" +#include "./mykonos/t_ad9528.h" +#include "myk_ad9528init.h" +#include "parameters.h" + +static ad9528pll1Settings_t clockPll1Settings = { + .refA_Frequency_Hz = 122880000, + .refA_Divider = 1, + .refA_bufferCtrl = SINGLE_ENDED, + .refB_Frequency_Hz = 0, + .refB_Divider = 1, + .refB_bufferCtrl = DISABLED, + .vcxo_Frequency_Hz = 122880000, + .vcxoBufferCtrl = DIFFERENTIAL, + .nDivider = 1, + .bypassPll1 = 0 +}; + +static ad9528pll2Settings_t clockPll2Settings = { + .rfDivider = 3, + .n2Divider = 10, + .totalNdiv = 30 +}; + +/******************************************************************* + * Output Distribution Settings + * 9369CE02A uses the following clock outputs + * OUT 1: FPGA_REF_CLK + * OUT 2: FPGA_AUX_CLK + * OUT 3: FPGA_SYSREF + * OUT 12: SYSREF_IN + * OUT 13: DEV_CLK_IN + ******************************************************************* + */ +static ad9528outputSettings_t clockOutputSettings = { + .outPowerDown = 0x0, + .outSource = { + SYSREF, SYSREF, CHANNEL_DIV, SYSREF, + CHANNEL_DIV, CHANNEL_DIV, SYSREF, SYSREF, + CHANNEL_DIV, CHANNEL_DIV, CHANNEL_DIV, CHANNEL_DIV, + SYSREF , CHANNEL_DIV + }, + .outBufferCtrl = {0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + .outAnalogDelay = {0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + .outDigitalDelay = {0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + .outChannelDiv = {10,10,10,10,10,10,10,10,10,10,10,10,10,10}, + .outFrequency_Hz = { + 122880000, 122880000, 122880000, 122880000, + 122880000, 122880000, 122880000, 122880000, + 122880000, 122880000, 122880000, 122880000, + 122880000, 122880000 + } +}; + +static ad9528sysrefSettings_t clockSysrefSettings = { + .sysrefRequestMethod = SPI, + .sysrefSource = INTERNAL, + .sysrefPinEdgeMode = LEVEL_ACTIVE_HIGH, + .sysrefPinBufferMode = DISABLED, + .sysrefPatternMode = CONTINUOUS, + .sysrefNshotMode = FOUR_PULSES, + .sysrefDivide = 512 +}; + +static spiSettings_t clockSpiSettings = { + .chipSelectIndex = 2, //chip select Index + .writeBitPolarity = 0, //Write bit polarity + .longInstructionWord = 1, //16bit instruction word + .MSBFirst = 1, //MSB first + .CPHA = 0, //Clock phase + .CPOL = 0, //Clock polarity + .enSpiStreaming = 0, //uint8_t enSpiStreaming; + .autoIncAddrUp = 1, //uint8_t autoIncAddrUp; + .fourWireMode = 1 //uint8_t fourWireMode; +}; + +ad9528Device_t clockAD9528_ = { + &clockSpiSettings, + &clockPll1Settings, + &clockPll2Settings, + &clockOutputSettings, + &clockSysrefSettings +}; + +ad9528Device_t *ad9528Init = &clockAD9528_; diff --git a/df_datalink_ge/src/hardware/myk_ad9528init.h b/df_datalink_ge/src/hardware/myk_ad9528init.h new file mode 100644 index 0000000..53e8be6 --- /dev/null +++ b/df_datalink_ge/src/hardware/myk_ad9528init.h @@ -0,0 +1,20 @@ +/* + * myk_clock_init.h + * + */ + +/** +* \page Disclaimer Legal Disclaimer +* Copyright 2015-2017 Analog Devices Inc. +* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file. +* +*/ + +#ifndef MYK_CLOCK_INIT_H_ +#define MYK_CLOCK_INIT_H_ + +#include "./mykonos/ad9528.h" + +extern ad9528Device_t *ad9528Init; + +#endif /* MYK_CLOCK_INIT_H_ */ diff --git a/df_datalink_ge/src/hardware/myk_init.c b/df_datalink_ge/src/hardware/myk_init.c new file mode 100644 index 0000000..d585d1a --- /dev/null +++ b/df_datalink_ge/src/hardware/myk_init.c @@ -0,0 +1,558 @@ +/** + * \file myk_init.c + * + * \brief Contains init setting structure declarations for the _instance API + * + * The top level structure mykonosDevice_t mykDevice uses keyword + * extern to allow the application layer main() to have visibility + * to these settings. + * + * All data structures required for operation have been initialized with values which reflect + * these settings: + * + * Device Clock = $122.88$ Mhz + * Rx enabled channels = $2$ + * Tx enabled channels = $2$ + * + * Mykonos Framer: + * Lane Rate = $4915.2$ Mbs + * L = $2$ + * K = $32$ + * M = $4$ + * F = $4$ + * + * Mykonos Deframer: + * Lane Rate = $4915.2$ Mbs + * L = $2$ + * K = $32$ + * M = $4$ + * F = $4$ + * + * Mykonos Observation framer: + * Lane Rate = $4915.2$ Mbs + * L = $2$ + * K = $32$ + * M = $4$ + * F = $4$ + * + * Using these profiles: + * $Rx 100Mhz, IQrate 122.88Mhz, Dec5$ + * $Tx 100/100Mhz, IQrate 122.88Mhz, Dec5$ + * $ORX 100Mhz, IQrate 122.88Mhz, Dec5$ + * $SRx 20Mhz, IQrate 30.72Mhz, Dec5$ + * + */ + +/** +* \page Disclaimer Legal Disclaimer +* Copyright 2015-2017 Analog Devices Inc. +* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file. +* +*/ + +#include +#include "./mykonos/t_mykonos.h" +#include "myk_init.h" +#include "parameters.h" +#include "./mykonos/mykonos_gpio.h" + +static int16_t txFirCoefs[] = {-94,-26,282,177,-438,-368,756,732,-1170,-1337,1758,2479,-2648,-5088,4064,16760,16759,4110,-4881,-2247,2888,1917,-1440,-1296,745,828,-358,-474,164,298,-16,-94}; + +static mykonosFir_t txFir = +{ + 6, /* Filter gain in dB*/ + 32, /* Number of coefficients in the FIR filter*/ + &txFirCoefs[0] /* A pointer to an array of filter coefficients*/ +}; + +static int16_t rxFirCoefs[] = {-20,6,66,22,-128,-54,240,126,-402,-248,634,444,-956,-756,1400,1244,-2028,-2050,2978,3538,-4646,-7046,9536,30880,30880,9536,-7046,-4646,3538,2978,-2050,-2028,1244,1400,-756,-956,444,634,-248,-402,126,240,-54,-128,22,66,6,-20}; + +static mykonosFir_t rxFir = +{ + -6, /* Filter gain in dB*/ + 48, /* Number of coefficients in the FIR filter*/ + &rxFirCoefs[0] /* A pointer to an array of filter coefficients*/ +}; + +static int16_t obsrxFirCoefs[] = {-14,-19,44,41,-89,-95,175,178,-303,-317,499,527,-779,-843,1184,1317,-1781,-2059,2760,3350,-4962,-7433,9822,32154,32154,9822,-7433,-4962,3350,2760,-2059,-1781,1317,1184,-843,-779,527,499,-317,-303,178,175,-95,-89,41,44,-19,-14}; +static mykonosFir_t obsrxFir = +{ + -6, /* Filter gain in dB*/ + 48, /* Number of coefficients in the FIR filter*/ + &obsrxFirCoefs[0]/* A pointer to an array of filter coefficients*/ +}; + +static int16_t snifferFirCoefs[] = {-1,-5,-14,-23,-16,24,92,137,80,-120,-378,-471,-174,507,1174,1183,98,-1771,-3216,-2641,942,7027,13533,17738,17738,13533,7027,942,-2641,-3216,-1771,98,1183,1174,507,-174,-471,-378,-120,80,137,92,24,-16,-23,-14,-5,-1}; +static mykonosFir_t snifferRxFir= +{ + -6, /* Filter gain in dB*/ + 48, /* Number of coefficients in the FIR filter*/ + &snifferFirCoefs[0]/* A pointer to an array of filter coefficients*/ +}; + +static mykonosJesd204bFramerConfig_t rxFramer = +{ + 0, /* JESD204B Configuration Bank ID -extension to Device ID (Valid 0..15)*/ + 0, /* JESD204B Configuration Device ID - link identification number. (Valid 0..255)*/ + 0, /* JESD204B Configuration starting Lane ID. If more than one lane used, each lane will increment from the Lane0 ID. (Valid 0..31)*/ + 4, /* number of ADCs (0, 2, or 4) - 2 ADCs per receive chain*/ + 32, /* number of frames in a multiframe (default=32), F*K must be a multiple of 4. (F=2*M/numberOfLanes)*/ + 0, /* scrambling off if framerScramble= 0, if framerScramble>0 scramble is enabled.*/ + 1, /* 0=use internal SYSREF, 1= use external SYSREF*/ + 0x03, /* serializerLanesEnabled - bit per lane, [0] = Lane0 enabled, [1] = Lane1 enabled*/ + 0xE4, /* serializerLaneCrossbar*/ + 22, /* serializerAmplitude - default 22 (valid (0-31)*/ + 4, /* preEmphasis - < default 4 (valid 0 - 7)*/ + 0, /* invertLanePolarity - default 0 ([0] will invert lane [0], bit1 will invert lane1)*/ + 0, /* lmfcOffset - LMFC_Offset offset value for deterministic latency setting*/ + 0, /* Flag for determining if SYSREF on relink should be set. Where, if > 0 = set, 0 = not set*/ + 0, /* Flag for determining if auto channel select for the xbar should be set. Where, if > 0 = set, '0' = not set*/ + 0, /* Selects SYNCb input source. Where, 0 = use RXSYNCB for this framer, 1 = use OBSRX_SYNCB for this framer*/ + 0, /* Flag for determining if CMOS mode for RX Sync signal is used. Where, if > 0 = CMOS, '0' = LVDS*/ + 0, /* Selects framer bit repeat or oversampling mode for lane rate matching. Where, 0 = bitRepeat mode (changes effective lanerate), 1 = overSample (maintains same lane rate between ObsRx framer and Rx framer and oversamples the ADC samples)*/ + 0 /* Flag for determining if API will calculate the appropriate settings for framer lane outputs to physical lanes. Where, if '0' = API will set automatic lane crossbar, '1' = set to manual mode and the value in serializerLaneCrossbar will be used*/ +}; + +static mykonosJesd204bFramerConfig_t obsRxFramer = +{ + 0, /* JESD204B Configuration Bank ID -extension to Device ID (Valid 0..15)*/ + 0, /* JESD204B Configuration Device ID - link identification number. (Valid 0..255)*/ + 0, /* JESD204B Configuration starting Lane ID. If more than one lane used, each lane will increment from the Lane0 ID. (Valid 0..31)*/ + 2, /* number of ADCs (0, 2, or 4) - 2 ADCs per receive chain*/ + 32, /* number of frames in a multiframe (default=32), F*K must be a multiple of 4. (F=2*M/numberOfLanes)*/ + 0, /* scrambling off if framerScramble= 0, if framerScramble>0 scramble is enabled.*/ + 1, /* 0=use internal SYSREF, 1= use external SYSREF*/ + 0x04, /* serializerLanesEnabled - bit per lane, [0] = Lane0 enabled, [1] = Lane1 enabled*/ + 0xE4, /* Lane crossbar to map framer lane outputs to physical lanes*/ + 22, /* serializerAmplitude - default 22 (valid (0-31)*/ + 4, /* preEmphasis - < default 4 (valid 0 - 7)*/ + 0, /* invertLanePolarity - default 0 ([0] will invert lane [0], bit1 will invert lane1)*/ + 0, /* lmfcOffset - LMFC_Offset offset value for deterministic latency setting*/ + 0, /* Flag for determining if SYSREF on relink should be set. Where, if > 0 = set, 0 = not set*/ + 0, /* Flag for determining if auto channel select for the xbar should be set. Where, if > 0 = set, '0' = not set*/ + 1, /* Selects SYNCb input source. Where, 0 = use RXSYNCB for this framer, 1 = use OBSRX_SYNCB for this framer*/ + 0, /* Flag for determining if CMOS mode for RX Sync signal is used. Where, if > 0 = CMOS, '0' = LVDS*/ + 0, /* Selects framer bit repeat or oversampling mode for lane rate matching. Where, 0 = bitRepeat mode (changes effective lanerate), 1 = overSample (maintains same lane rate between ObsRx framer and Rx framer and oversamples the ADC samples)*/ + 0 /* Flag for determining if API will calculate the appropriate settings for framer lane outputs to physical lanes. Where, if '0' = API will set automatic lane crossbar, '1' = set to manual mode and the value in serializerLaneCrossbar will be used*/ +}; + +static mykonosJesd204bDeframerConfig_t deframer = +{ + 0, /* bankId extension to Device ID (Valid 0..15)*/ + 0, /* deviceId link identification number. (Valid 0..255)*/ + 0, /* lane0Id Lane0 ID. (Valid 0..31)*/ + 4, /* M number of DACss (0, 2, or 4) - 2 DACs per transmit chain */ + 32, /* K #frames in a multiframe (default=32), F*K=multiple of 4. (F=2*M/numberOfLanes)*/ + 0, /* scramble scrambling off if scramble= 0.*/ + 1, /* External SYSREF select. 0 = use internal SYSREF, 1 = external SYSREF*/ + 0x03, /* Deserializer lane select bit field. Where, [0] = Lane0 enabled, [1] = Lane1 enabled, etc */ + 0xE4, /* Lane crossbar to map physical lanes to deframer lane inputs [1:0] = Deframer Input 0 Lane section, [3:2] = Deframer Input 1 lane select, etc */ + 1, /* Equalizer setting. Applied to all deserializer lanes. Range is 0..4*/ + 0, /* PN inversion per each lane. bit[0] = 1 Invert PN of Lane 0, bit[1] = Invert PN of Lane 1, etc).*/ + 0, /* LMFC_Offset offset value to adjust deterministic latency. Range is 0..31*/ + 0, /* Flag for determining if SYSREF on relink should be set. Where, if > 0 = set, '0' = not set*/ + 0, /* Flag for determining if auto channel select for the xbar should be set. Where, if > 0 = set, '0' = not set*/ + 0, /* Flag for determining if CMOS mode for TX Sync signal is used. Where, if > 0 = CMOS, '0' = LVDS*/ + 0 /* Flag for determining if API will calculate the appropriate settings for deframer lane in to physical lanes. Where, if '0' = API will set automatic lane crossbar, '1' = set to manual mode and the value in deserializerLaneCrossbar will be used*/ +}; + +static mykonosRxGainControl_t rxGainControl = +{ + MGC, /* Current Rx gain control mode setting*/ + 255, /* Rx1 Gain Index, can be used in different ways for manual and AGC gain control*/ + 255, /* Rx2 Gain Index, can be used in different ways for manual and AGC gain control*/ + 255, /* Max gain index for the currently loaded Rx1 Gain table*/ + 195, /* Min gain index for the currently loaded Rx1 Gain table*/ + 255, /* Max gain index for the currently loaded Rx2 Gain table*/ + 195, /* Min gain index for the currently loaded Rx2 Gain table*/ + 0, /* Stores Rx1 RSSI value read back from the Mykonos*/ + 0 /* Stores Rx2 RSSI value read back from the Mykonos*/ +}; + + +static mykonosORxGainControl_t orxGainControl = +{ + MGC, /* Current ORx gain control mode setting*/ + 255, /* ORx1 Gain Index, can be used in different ways for manual and AGC gain control*/ + 255, /* ORx2 Gain Index, can be used in different ways for manual and AGC gain control*/ + 255, /* Max gain index for the currently loaded ORx Gain table*/ + 237 /* Min gain index for the currently loaded ORx Gain table*/ +}; + +static mykonosSnifferGainControl_t snifferGainControl = +{ + MGC, /* Current Sniffer gain control mode setting*/ + 255, /* Current Sniffer gain index. Can be used differently for MANUAL Gain control/AGC*/ + 255, /* Max gain index for the currently loaded Sniffer Gain table*/ + 203 /* Min gain index for the currently loaded Sniffer Gain table*/ +}; + +static mykonosPeakDetAgcCfg_t rxPeakAgc = +{ + 0x0C, /* apdHighThresh: */ + 0x08, /* apdLowThresh */ + 0xB5, /* hb2HighThresh */ + 0x80, /* hb2LowThresh */ + 0x40, /* hb2VeryLowThresh */ + 0x06, /* apdHighThreshExceededCnt */ + 0x04, /* apdLowThreshExceededCnt */ + 0x06, /* hb2HighThreshExceededCnt */ + 0x04, /* hb2LowThreshExceededCnt */ + 0x04, /* hb2VeryLowThreshExceededCnt */ + 0x4, /* apdHighGainStepAttack */ + 0x2, /* apdLowGainStepRecovery */ + 0x4, /* hb2HighGainStepAttack */ + 0x2, /* hb2LowGainStepRecovery */ + 0x4, /* hb2VeryLowGainStepRecovery */ + 0x1, /* apdFastAttack */ + 0x1, /* hb2FastAttack */ + 0x1, /* hb2OverloadDetectEnable */ + 0x1, /* hb2OverloadDurationCnt */ + 0x1 /* hb2OverloadThreshCnt */ +}; + +static mykonosPowerMeasAgcCfg_t rxPwrAgc = +{ + 0x01, /* pmdUpperHighThresh */ + 0x03, /* pmdUpperLowThresh */ + 0x0C, /* pmdLowerHighThresh */ + 0x00, /* pmdLowerLowThresh */ + 0x4, /* pmdUpperHighGainStepAttack */ + 0x2, /* pmdUpperLowGainStepAttack */ + 0x2, /* pmdLowerHighGainStepRecovery */ + 0x4, /* pmdLowerLowGainStepRecovery */ + 0x08, /* pmdMeasDuration */ + 0x02 /* pmdMeasConfig */ +}; + +static mykonosAgcCfg_t rxAgcConfig = +{ + 255, /* agcRx1MaxGainIndex */ + 195, /* agcRx1MinGainIndex */ + 255, /* agcRx2MaxGainIndex */ + 195, /* agcRx2MinGainIndex: */ + 255, /* agcObsRxMaxGainIndex */ + 203, /* agcObsRxMinGainIndex */ + 1, /* agcObsRxSelect */ + 1, /* agcPeakThresholdMode */ + 1, /* agcLowThsPreventGainIncrease */ + 30720, /* agcGainUpdateCounter */ + 3, /* agcSlowLoopSettlingDelay */ + 2, /* agcPeakWaitTime */ + 1, /* agcResetOnRxEnable */ + 0, /* agcEnableSyncPulseForGainCounter */ + &rxPeakAgc, + &rxPwrAgc +}; + +static mykonosPeakDetAgcCfg_t obsRxPeakAgc = +{ + 0x1F, /* apdHighThresh: */ + 0x16, /* apdLowThresh */ + 0xB5, /* hb2HighThresh */ + 0x80, /* hb2LowThresh */ + 0x40, /* hb2VeryLowThresh */ + 0x06, /* apdHighThreshExceededCnt */ + 0x04, /* apdLowThreshExceededCnt */ + 0x06, /* hb2HighThreshExceededCnt */ + 0x04, /* hb2LowThreshExceededCnt */ + 0x04, /* hb2VeryLowThreshExceededCnt */ + 0x4, /* apdHighGainStepAttack */ + 0x2, /* apdLowGainStepRecovery */ + 0x4, /* hb2HighGainStepAttack */ + 0x2, /* hb2LowGainStepRecovery */ + 0x4, /* hb2VeryLowGainStepRecovery */ + 0x1, /* apdFastAttack */ + 0x1, /* hb2FastAttack */ + 0x1, /* hb2OverloadDetectEnable */ + 0x1, /* hb2OverloadDurationCnt */ + 0x1 /* hb2OverloadThreshCnt */ +}; + +static mykonosPowerMeasAgcCfg_t obsRxPwrAgc = +{ + 0x01, /* pmdUpperHighThresh */ + 0x03, /* pmdUpperLowThresh */ + 0x0C, /* pmdLowerHighThresh */ + 0x00, /* pmdLowerLowThresh */ + 0x4, /* pmdUpperHighGainStepAttack */ + 0x2, /* pmdUpperLowGainStepAttack */ + 0x2, /* pmdLowerHighGainStepRecovery */ + 0x4, /* pmdLowerLowGainStepRecovery */ + 0x08, /* pmdMeasDuration */ + 0x02 /* pmdMeasConfig */ +}; + +static mykonosAgcCfg_t obsRxAgcConfig = +{ + 255, /* agcRx1MaxGainIndex */ + 195, /* agcRx1MinGainIndex */ + 255, /* agcRx2MaxGainIndex */ + 195, /* agcRx2MinGainIndex: */ + 255, /* agcObsRxMaxGainIndex */ + 203, /* agcObsRxMinGainIndex */ + 1, /* agcObsRxSelect */ + 1, /* agcPeakThresholdMode */ + 1, /* agcLowThsPreventGainIncrease */ + 30720, /* agcGainUpdateCounter */ + 3, /* agcSlowLoopSettlingDelay */ + 2, /* agcPeakWaitTime */ + 1, /* agcResetOnRxEnable */ + 0, /* agcEnableSyncPulseForGainCounter */ + &obsRxPeakAgc, + &obsRxPwrAgc +}; + + +static mykonosRxProfile_t rxProfile = +{/* Rx 100MHz, IQrate 122.88MSPS, Dec5 */ + 1, /* The divider used to generate the ADC clock*/ + &rxFir, /* Pointer to Rx FIR filter structure*/ + 2, /* Rx FIR decimation (1,2,4)*/ + 5, /* Decimation of Dec5 or Dec4 filter (5,4)*/ + 1, /* If set, and DEC5 filter used, will use a higher rejection DEC5 FIR filter (1=Enabled, 0=Disabled)*/ + 1, /* RX Half band 1 decimation (1 or 2)*/ + 122880, /* Rx IQ data rate in kHz*/ + 100000000, /* The Rx RF passband bandwidth for the profile*/ + 100000, /* Rx BBF 3dB corner in kHz*/ + NULL /* pointer to custom ADC profile*/ +}; + +static mykonosRxProfile_t orxProfile = +{/* ORX 100MHz, IQrate 122.88MSPS, Dec5 */ + 1, /* The divider used to generate the ADC clock*/ + &obsrxFir, /* Pointer to Rx FIR filter structure or NULL*/ + 2, /* Rx FIR decimation (1,2,4)*/ + 5, /* Decimation of Dec5 or Dec4 filter (5,4)*/ + 0, /* If set, and DEC5 filter used, will use a higher rejection DEC5 FIR filter (1=Enabled, 0=Disabled)*/ + 1, /* RX Half band 1 decimation (1 or 2)*/ + 122880, /* Rx IQ data rate in kHz*/ + 100000000, /* The Rx RF passband bandwidth for the profile*/ + 100000, /* Rx BBF 3dB corner in kHz*/ + NULL /* pointer to custom ADC profile*/ +}; + + +static mykonosRxProfile_t snifferProfile = +{ /* SRx 20MHz, IQrate 30.72MSPS, Dec5 */ + 1, /* The divider used to generate the ADC clock*/ + &snifferRxFir, /* Pointer to Rx FIR filter structure or NULL*/ + 4, /* Rx FIR decimation (1,2,4)*/ + 5, /* Decimation of Dec5 or Dec4 filter (5,4)*/ + 0, /* If set, and DEC5 filter used, will use a higher rejection DEC5 FIR filter (1=Enabled, 0=Disabled)*/ + 2, /* RX Half band 1 decimation (1 or 2)*/ + 30720, /* Rx IQ data rate in kHz*/ + 10000000, /* The Rx RF passband bandwidth for the profile*/ + 100000, /* Rx BBF 3dB corner in kHz*/ + NULL /* pointer to custom ADC profile*/ +}; + + + +static mykonosTxProfile_t txProfile = +{ /* Tx 20/100MHz, IQrate 122.88MSPS, Dec5 */ + DACDIV_2p5, /* The divider used to generate the DAC clock*/ + &txFir, /* Pointer to Tx FIR filter structure*/ + 2, /* The Tx digital FIR filter interpolation (1,2,4)*/ + 2, /* Tx Halfband1 filter interpolation (1,2)*/ + 1, /* Tx Halfband2 filter interpolation (1,2)*/ + 1, /* TxInputHbInterpolation (1,2)*/ + 122880, /* Tx IQ data rate in kHz*/ + 100000000, /* Primary Signal BW*/ + 100000000, /* The Tx RF passband bandwidth for the profile*/ + 710539, /* The DAC filter 3dB corner in kHz*/ + 50000, /* Tx BBF 3dB corner in kHz*/ + 0 /* Enable DPD, only valid for AD9373*/ +}; + +static mykonosDigClocks_t mykonosClocks = +{ + 122880, /* CLKPLL and device reference clock frequency in kHz*/ + 9830400, /* CLKPLL VCO frequency in kHz*/ + VCODIV_2, /* CLKPLL VCO divider*/ + 4 /* CLKPLL high speed clock divider*/ +}; + +static mykonosRxSettings_t rxSettings = +{ + &rxProfile, /* Rx datapath profile, 3dB corner frequencies, and digital filter enables*/ + &rxFramer, /* Rx JESD204b framer configuration structure*/ + &rxGainControl, /* Rx Gain control settings structure*/ + &rxAgcConfig, /* Rx AGC control settings structure*/ + RX1_RX2, /* The desired Rx Channels to enable during initialization*/ + 0, /* Internal LO = 0, external LO*2 = 1*/ + 2550000000U, /* Rx PLL LO Frequency (internal or external LO)*/ + 0 /* Flag to choose if complex baseband or real IF data are selected for Rx and ObsRx paths. Where, if > 0 = real IF data, '0' = zero IF (IQ) data*/ +}; + +static mykonosDpdConfig_t dpdConfig = +{ + 5, /* 1/2^(damping + 8) fraction of power `forgotten' per sample (default: `1/8192' = 5, valid 0 to 15), 0 = infinite damping*/ + 1, /* number of weights to use for int8_cpx weights weights member of this structure (default = 1)*/ + 2, /* DPD model version: one of four different generalized polynomial models: 0 = same as R0 silicon, 1-3 are new and the best one depends on the PA (default: 2)*/ + 1, /* 1 = Update saved model whenever peak Tx digital RMS is within 1dB of historical peak Tx RMS*/ + 20, /* Determines how much weight the loaded prior model has on DPD modeling (Valid 0 - 32, default 20)*/ + 0, /* Default off = 0, 1=enables automatic outlier removal during DPD modeling */ + 512, /* Number of samples to capture (default: 512, valid 64-32768)*/ + 4096, /* threshold for sample in AM-AM plot outside of 1:1 line to be thrown out. (default: 50% = 8192/2, valid 8192 to 1)*/ + 0, /* 16th of an ORx sample (16=1sample), (default 0, valid -64 to 64)*/ + 255, /* Default 255 (-30dBFs=(20Log10(value/8192)), (valid range 1 to 8191)*/ + {{64,0},{0,0},{0,0}}/* DPD model error weighting (real/imag valid from -128 to 127)*/ +}; + +static mykonosClgcConfig_t clgcConfig = +{ + -2000, /* (value = 100 * dB (valid range -32768 to 32767) - total gain and attenuation from Mykonos Tx1 output to ORx1 input in (dB * 100)*/ + -2000, /* (value = 100 * dB (valid range -32768 to 32767) - total gain and attenuation from Mykonos Tx2 output to ORx2 input in (dB * 100)*/ + 0, /* (valid range 0 - 40dB), no default, depends on PA, Protects PA by making sure Tx1Atten is not reduced below the limit*/ + 0, /* (valid range 0 - 40dB), no default, depends on PA, Protects PA by making sure Tx2Atten is not reduced below the limit*/ + 75, /* valid range 1-100, default 75*/ + 75, /* valid range 1-100, default 45*/ + 0, /* 0= allow CLGC to run, but Tx1Atten will not be updated. User can still read back power measurements. 1=CLGC runs, and Tx1Atten automatically updated*/ + 0, /* 0= allow CLGC to run, but Tx2Atten will not be updated. User can still read back power measurements. 1=CLGC runs, and Tx2Atten automatically updated*/ + 0, /* 16th of an ORx sample (16=1sample), (default 0, valid -64 to 64)*/ + 255, /* Default 255 (-30dBFs=(20Log10(value/8192)), (valid range 1 to 8191)*/ + 600, /* Threshold for Tx1 in order to stop tracking, value = 100 * dB, default 6db then value = 600*/ + 600, /* Threshold for Tx2 in order to stop tracking, value = 100 * dB, default 6db then value = 600*/ + 0, /* Threshold feature enable for Tx1, 0 = disable, 1 = enable, default = 0*/ + 0 /* Threshold feature enable for Tx1, 0 = disable, 1 = enable, default = 0*/ +}; + +static mykonosVswrConfig_t vswrConfig = +{ + 0, /* 16th of an ORx sample (16=1sample), (default 0, valid -64 to 64)*/ + 255, /* Default 255 (-30dBFs=(20Log10(value/8192)), (valid range 1 to 8191)*/ + 0, /* 3p3V GPIO pin to use to control VSWR switch for Tx1 (valid 0-11) (output from Mykonos)*/ + 1, /* 3p3V GPIO pin to use to control VSWR switch for Tx2 (valid 0-11) (output from Mykonos)*/ + 0, /* 3p3v GPIO pin polarity for forward path of Tx1, opposite used for reflection path (1 = high level, 0 = low level)*/ + 0, /* 3p3v GPIO pin polarity for forward path of Tx2, opposite used for reflection path (1 = high level, 0 = low level)*/ + 50, /* Delay for Tx1 after flipping the VSWR switch until measurement is made. In us resolution*/ + 50 /* Delay for Tx2 after flipping the VSWR switch until measurement is made. In us resolution*/ +}; + +static mykonosTxSettings_t txSettings = +{ + &txProfile, /* Tx datapath profile, 3dB corner frequencies, and digital filter enables*/ + &deframer, /* Mykonos JESD204b deframer config for the Tx data path*/ + TX1_TX2, /* The desired Tx channels to enable during initialization*/ + 0, /* Internal LO=0, external LO*2 if =1*/ + 2500000000U, /* Tx PLL LO frequency (internal or external LO)*/ + TXATTEN_0P05_DB,/* Initial and current Tx1 Attenuation*/ + 10000, /* Initial and current Tx1 Attenuation mdB*/ + 10000, /* Initial and current Tx2 Attenuation mdB*/ + NULL, /* DPD,CLGC,VSWR settings. Only valid for AD9373 device, set pointer to NULL otherwise*/ + NULL, /* CLGC Config Structure. Only valid for AD9373 device, set pointer to NULL otherwise*/ + NULL /* VSWR Config Structure. Only valid for AD9373 device, set pointer to NULL otherwise*/ +}; + + +static mykonosObsRxSettings_t obsRxSettings = +{ + &orxProfile, /* ORx datapath profile, 3dB corner frequencies, and digital filter enables*/ + &orxGainControl,/* ObsRx gain control settings structure*/ + &obsRxAgcConfig,/* ORx AGC control settings structure*/ + &snifferProfile,/* Sniffer datapath profile, 3dB corner frequencies, and digital filter enables*/ + &snifferGainControl,/* SnRx gain control settings structure*/ + &obsRxFramer, /* ObsRx JESD204b framer configuration structure */ + (MYK_ORX1_ORX2 | MYK_SNRXA_B_C),/* obsRxChannel */ + OBSLO_TX_PLL, /* (obsRxLoSource) The Obs Rx mixer can use the Tx Synth(TX_PLL) or Sniffer Synth (SNIFFER_PLL) */ + 2600000000U, /* SnRx PLL LO frequency in Hz */ + 0, /* Flag to choose if complex baseband or real IF data are selected for Rx and ObsRx paths. Where if > 0 = real IF data, '0' = complex data*/ + NULL, /* Custom Loopback ADC profile to set the bandwidth of the ADC response */ + OBS_RXOFF /* Default ObsRx channel to enter when radioOn called */ +}; + +static mykonosArmGpioConfig_t armGpio = +{ + 1, // useRx2EnablePin; /*!< 0= RX1_ENABLE controls RX1 and RX2, 1 = separate RX1_ENABLE/RX2_ENABLE pins */ + 1, // useTx2EnablePin; /*!< 0= TX1_ENABLE controls TX1 and TX2, 1 = separate TX1_ENABLE/TX2_ENABLE pins */ + 1, // txRxPinMode; /*!< 0= ARM command mode, 1 = Pin mode to power up Tx/Rx chains */ + 0, // orxPinMode; /*!< 0= ARM command mode, 1 = Pin mode to power up ObsRx receiver*/ + + /*Mykonos ARM input GPIO pins -- Only valid if orxPinMode = 1 */ + 0, // orxTriggerPin; /*!< Select desired GPIO pin (valid 4-15) */ + 0, // orxMode2Pin; /*!< Select desired GPIO pin (valid 0-18) */ + 0, // orxMode1Pin; /*!< Select desired GPIO pin (valid 0-18) */ + 0, // orxMode0Pin; /*!< Select desired GPIO pin (valid 0-18) */ + + /* Mykonos ARM output GPIO pins -- always available, even when pin mode not enabled*/ + 0, // rx1EnableAck; /*!< Select desired GPIO pin (0-15), [4] = Output Enable */ + 0, // rx2EnableAck; /*!< Select desired GPIO pin (0-15), [4] = Output Enable */ + 0, // tx1EnableAck; /*!< Select desired GPIO pin (0-15), [4] = Output Enable */ + 0, // tx2EnableAck; /*!< Select desired GPIO pin (0-15), [4] = Output Enable */ + 0, // orx1EnableAck; /*!< Select desired GPIO pin (0-15), [4] = Output Enable */ + 0, // orx2EnableAck; /*!< Select desired GPIO pin (0-15), [4] = Output Enable */ + 0, // srxEnableAck; /*!< Select desired GPIO pin (0-15), [4] = Output Enable */ + 0 // txObsSelect; /*!< Select desired GPIO pin (0-15), [4] = Output Enable */ + /* When 2Tx are used with only 1 ORx input, this GPIO tells the BBIC which Tx channel is */ + /* active for calibrations, so BBIC can route correct RF Tx path into the single ORx input*/ +}; + +static mykonosGpio3v3_t gpio3v3 = +{ + 0, /*!< Oe per pin, 1=output, 0 = input */ + GPIO3V3_BITBANG_MODE, /*!< Mode for GPIO3V3[3:0] */ + GPIO3V3_BITBANG_MODE, /*!< Mode for GPIO3V3[7:4] */ + GPIO3V3_BITBANG_MODE, /*!< Mode for GPIO3V3[11:8] */ +}; + +static mykonosGpioLowVoltage_t gpio = +{ + 0,/* Oe per pin, 1=output, 0 = input */ + GPIO_MONITOR_MODE,/* Mode for GPIO[3:0] */ + GPIO_MONITOR_MODE,/* Mode for GPIO[7:4] */ + GPIO_MONITOR_MODE,/* Mode for GPIO[11:8] */ + GPIO_MONITOR_MODE,/* Mode for GPIO[15:12] */ + GPIO_MONITOR_MODE,/* Mode for GPIO[18:16] */ +}; + +static mykonosAuxIo_t mykonosAuxIo = +{ + 0, //auxDacEnableMask uint16_t + {0,0,0,0,0,0,0,0,0,0}, //AuxDacValue uint16[10] + {0,0,0,0,0,0,0,0,0,0}, //AuxDacSlope uint8[10] + {0,0,0,0,0,0,0,0,0,0}, //AuxDacVref uint8[10] + &gpio3v3, //pointer to gpio3v3 struct + &gpio, //pointer to gpio1v8 struct + &armGpio +}; + +static spiSettings_t mykSpiSettings = +{ + 1, /* chip select index - valid 1~8 */ + 0, /* the level of the write bit of a SPI write instruction word, value is inverted for SPI read operation */ + 1, /* 1 = 16-bit instruction word, 0 = 8-bit instruction word */ + 1, /* 1 = MSBFirst, 0 = LSBFirst */ + 0, /* clock phase, sets which clock edge the data updates (valid 0 or 1) */ + 0, /* clock polarity 0 = clock starts low, 1 = clock starts high */ + 0, /* Not implemented in ADIs platform layer. SW feature to improve SPI throughput */ + 1, /* Not implemented in ADIs platform layer. For SPI Streaming, set address increment direction. 1= next addr = addr+1, 0:addr=addr-1 */ + 1 /* 1: Use 4-wire SPI, 0: 3-wire SPI (SDIO pin is bidirectional). NOTE: ADI's FPGA platform always uses 4-wire mode */ +}; + +static mykonosTempSensorConfig_t tempSensor = +{ + 7, /* 3-bit value that controls the AuxADC decimation factor when used for temp sensor calculations; AuxADC_decimation = 256 * 2^tempDecimation*/ + 67, /* 8-bit offset that gets added to temp sensor code internally*/ + 1, /* this bit overrides the factory-calibrated fuse offset and uses the value stored in the offset member*/ + 15, /* 4-bit code with a resolution of 1°C/LSB, each time a temperature measurement is performed, the device compares the current temperature against the previous value.*/ +}; + +static mykonosTempSensorStatus_t tempStatus = +{ + 0, /* 16-bit signed temperature value (in deg C) that is read back*/ + 0, /* If the absolute value of the difference is greater than the value in temperature configuration tempWindow, the windowExceeded flag is set.*/ + 0, /* when windowExceeded member gets set, this bit is set to 1 if current value is greater than previous value, else reset*/ + 0, /* when the reading is complete and a valid temperature value stored in tempCode.*/ +}; + +mykonosDevice_t mykDevice = +{ + &mykSpiSettings, /* SPI settings data structure pointer */ + &rxSettings, /* Rx settings data structure pointer */ + &txSettings, /* Tx settings data structure pointer */ + &obsRxSettings, /* ObsRx settings data structure pointer */ + &mykonosAuxIo, /* Auxiliary IO settings data structure pointer */ + &mykonosClocks, /* Holds settings for CLKPLL and reference clock */ + 0 /* Mykonos initialize function uses this as an output to remember which profile data structure pointers are valid */ +}; diff --git a/df_datalink_ge/src/hardware/myk_init.h b/df_datalink_ge/src/hardware/myk_init.h new file mode 100644 index 0000000..ef11bad --- /dev/null +++ b/df_datalink_ge/src/hardware/myk_init.h @@ -0,0 +1,24 @@ +/** + * \file myk_init.h + * + * \brief Contains structure definitions for myk_init.c + * + * The top level structure mykonosDevice_t mykDevice uses keyword + * extern to allow the application layer main() to have visibility + * to these settings. + */ + +/** +* \page Disclaimer Legal Disclaimer +* Copyright 2015-2017 Analog Devices Inc. +* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file. +* +*/ + +#ifndef MYK_INIT_H_ +#define MYK_INIT_H_ + + +extern mykonosDevice_t mykDevice; + +#endif diff --git a/df_datalink_ge/src/hardware/mykonos/Mykonos_M3.c b/df_datalink_ge/src/hardware/mykonos/Mykonos_M3.c new file mode 100644 index 0000000..369ad92 --- /dev/null +++ b/df_datalink_ge/src/hardware/mykonos/Mykonos_M3.c @@ -0,0 +1,8518 @@ +/** + +SOFTWARE LICENSE AGREEMENT +20180301-AD937X-CTSLA + +This Software License Agreement (the 鈥淎greement鈥�) is a legal agreement +between Analog Devices, Inc., a Massachusetts corporation, with its principal +office at One Technology Way, Norwood, Massachusetts, USA 02062 (鈥淎nalog +Devices鈥�) and you (personally or on behalf of your employer, as applicable) +(鈥淟icensee鈥�) for the software and related documentation that accompanies +this Agreement (the 鈥淟icensed Software鈥�). YOU AGREE THAT YOU ARE BOUND BY +THE TERMS AND CONDITIONS OF THIS AGREEMENT BY DOWNLOADING, INSTALLING, COPYING +OR USING THE SOFTWARE. IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY OR +USE THE SOFTWARE. + +1. Development License. Subject to terms of this Agreement, Analog Devices +grants to Licensee a non-exclusive, non-transferable, non-sublicensable +license, without charge, to incorporate Licensed Software in object code form +into Licensee products solely for use within Analog Devices products that are +incorporated into such Licensee products. The licenses granted under Sections +1 and 2 of this Agreement are limited to the specific Analog Devices products +identified in Appendix A to this Agreement. + +2. Distribution License. Subject to the terms of this Agreement, Analog +Devices grants to Licensee a non-exclusive, non-transferrable, +non-sublicensable license, to copy and distribute Licensed Software in object +code form solely for use within Analog Devices products that are incorporated +into Licensee products. Distribution is limited to Licensed Software in object +code form that is incorporated into Licensee products. + +3. License to Analog Devices. During the term of this Agreement Licensee +grants to Analog Devices (and its affiliates) under any and all Licensee (and +its affiliates) patents a non-exclusive, worldwide, fully paid-up, royalty-free +license to make, use, sell, import, export, copy, distribute and otherwise +exploit Licensed Software in-whole or in-part (including updated versions of +Licensed Software), and to directly or indirectly sub-license others to do the +same. + +4. Restrictions. Licensee shall not modify, reverse engineer, decompile, +disassemble or create derivative works of Licensed Software. Licensee may only +copy the Licensed Software as expressly authorized in Sections 1 and 2 above. +In no event shall Licensee deliver or disclose the Licensed Software apart from +Licensee products to any third party without entering into a written license +agreement with Analog Devices expressly permitting such distribution. The +Licensed Software may not be used with any products other than Analog +Devices鈥� products or for any other purpose. + +Licensee shall not use or distribute the Licensed Software in any manner that +would cause Licensed Software, in whole or in part to become subject to any +terms of an Excluded License. An 鈥淓xcluded License鈥� means any license, +including licenses for 鈥渙pen source鈥� code (as defined by the Free Software +Foundation), that requires as a condition of use, modification, and/or +distribution of software subject to the Excluded License, that such software or +other software combined and/or distributed with such software be (i) disclosed +or distributed in source code form; (ii) licensed for the purpose of making +derivative works; or (iii) redistributable at no charge. The restrictions of +this section apply regardless of whether the Licensed Software is intended or +designed to run in an environment that includes software under an Excluded +License. Any license, agreement or other document issued, entered into or +granted by Licensee that purports to apply any Excluded License to any portion +of Licensed Software shall be null and void with regard to Licensed Software. +Under no circumstances will Licensee offer, provide, distribute, or license any +Licensed Software (whether in source code form or object code form) under any +form of Excluded License. + +All rights not expressly granted in this Agreement are reserved to Analog +Devices and its licensors. Analog Devices and its licensors retain all right, +title and interest in the Licensed Software and modifications thereof, +including all related patent, copyright and other intellectual property rights, +and Licensee shall not take any action inconsistent with such ownership. Any +use of the Licensed Software for any purpose other than as expressly licensed +hereunder is outside the scope of this Agreement. It is agreed that because of +the proprietary nature of the Licensed Software, Analog Devices鈥� remedies at +law for a breach by the Licensee of its obligations under this License or for +use of the Licensed Software beyond the scope of the license granted herein +will be inadequate and that Analog Devices will, in the event of such breach, +be entitled to equitable relief, including injunctive relief, without the +posting of any bond, in addition to all other remedies provided under this +License or available at law. + +If Analog Devices elects to make any update, upgrade or new version of the +Licensed Software (鈥淯pdates鈥�) available to Licensee, such Updates shall be +deemed to be Licensed Software under this Agreement. If requested by Analog +Devices, Licensee shall only use the latest version of the Licensed Software +(including Updates). Analog Devices shall have no obligation to provide +support or Updates. + +5. Publicity. Notwithstanding anything in this Agreement, Licensee may not use +any trademark or trade name of Analog Devices or make any public announcement +regarding the existence of this Agreement without Analog Devices鈥� prior +written consent. Licensee may not publish or provide the results of any +benchmark or comparison tests run on the Licensed Software to any third party +without the prior written consent of Analog Devices. + +6. Feedback. Licensee may from time to time provide suggestions, ideas, +comments or other feedback (鈥淔eedback鈥�) to Analog Devices with respect to +the Licensed Software. Licensee agrees that all Feedback is and shall be given +entirely voluntarily. To the extent Licensee provides such Feedback, however, +Licensee hereby grants to Analog Devices a non-exclusive, irrevocable, +perpetual, worldwide, royalty-free, transferable license, with the right to +sublicense, under Licensee鈥檚 intellectual property, to use and disclose +Feedback in any manner Analog Devices chooses and to display, perform, copy, +make, have made, use, sell, and otherwise dispose of Analog Devices鈥� and its +licensee鈥檚 products embodying such Feedback in any manner and via any media +Analog Devices chooses, without reference to its source or other obligation to +Analog Devices, even if the Feedback is designated as confidential. + +7. Confidentiality. Licensed Software in source code form and accompanying +documentation shall be regarded as 鈥æ·�onfidential Information鈥� of Analog +Devices and Licensee agrees to protect the confidentiality of Analog Devices鈥� +Confidential Information with at least the same degree of care that it utilizes +with respect to its own similar proprietary information (but in no event less +than a reasonable degree of care), including without limitation agreeing (i) +not to disclose or otherwise permit any other person or entity access to +Confidential Information or to use Confidential Information or any part thereof +in any form whatsoever, except that such disclosure or access shall be +permitted to an employee or consultant of Licensee requiring access to +Confidential Information in connection with this Agreement who has signed an +agreement obligating the employee/consultant to maintain the confidentiality of +confidential information in Licensee鈥檚 possession, (ii) to notify Analog +Devices promptly and in writing of the circumstances surrounding any suspected +possessions, use, or knowledge of Confidential Information other than those +authorized by this Agreement, and (iii) not to use Confidential Information for +any purpose other than as explicitly set forth herein. Nothing shall restrict +Licensee with respect to information or data that is independently developed or +is available to the general public otherwise than through any act or default of +Licensee. + +8. Copyright Notice. In no event shall Licensee remove any copyright or other +intellectual property notice or other legend contained on or in copies of +Licensed Software or displayed by any Licensed Software. + +9. Third Party Software. The Licensed Software may be accompanied by or +include software made available by one or more third parties (鈥淭hird Party +Software鈥�). Each portion of Third Party Software is subject to its own +separate software license terms and conditions (鈥淭hird Party Licenses鈥�). +The Third Party Licenses for Third Party Software delivered with the Licensed +Software may be set forth or identified (by URL or otherwise) in (i) Appendix A +to this license (if any), (ii) the applicable software header or footer text, +(iii) a text file located in the directory of the applicable Third Party +Software component and/or (iv) such other location customarily used for +licensing terms. The use of each portion of Third Party Software is subject to +the Third Party Licenses, and you agree that your use of any Third Party +Software is bound by the applicable Third Party License. You agree to review +and comply with all applicable Third Party Licenses prior to any use or +distribution of any Third Party Software. Third Party Software is provided on +an 鈥æ¸�s is鈥� basis without any representation, warranty or liability of any +kind. Analog Devices (including its licensors) shall have no liability or +responsibility for the operation or performance of the Third Party Software and +shall not be liable for any damages, costs, or expenses, direct or indirect, +arising out of the performance or failure to perform of the Third Party +Software. Analog Devices (including its licensors) shall be entitled to the +benefit of any and all limitations of liability and disclaimers of warranties +contained in the Third Party Licenses. + +In the event that Third Party Software has only been provided to you in object +code form under this Agreement, and the Third Party License requires +distribution of the corresponding source code, you may contact +software.licensing@analog.com regarding receiving a copy of such source code. + +10. Licensee Requirements. Licensee acknowledges that use or distribution of +the Licensed Software may require Licensee to obtain licenses to intellectual +property or other consents from one or more third parties. Licensee is +responsible for obtaining any and all such required licenses, or permissions +regarding the Licensed Software and for the performance of any and all required +tests or analysis necessary or appropriate for the determination of the +suitability of the Licensed Software for its or its customers鈥� purposes. +Licensee shall defend, indemnify and hold Analog Devices, its licensors, and +their respective officers, directors, employees and agents (each an +鈥淚ndemnified Party鈥�) harmless from and against any damages, fines, +penalties, assessments, liabilities, costs and expenses (including reasonable +attorneys鈥� fees and court costs) in the event that any claim is brought +against an Indemnified Party (i) arising or alleged to arise from Licensee鈥檚 +use or distribution of Licensed Software or Third Party Software, or (ii) on +account of Licensee鈥檚 failure to obtain any required license or consent to +use or distribute Licensed Software or Third Party Software. Licensee shall +bear any and all expenses and pay any and all taxes that may be payable in +relation to this Agreement. + +11. Audit. Analog Devices shall have the right upon ten (10) days prior +written notice to audit Licensee鈥檚 compliance with the terms of this +Agreement during normal business hours. In connection with such audit Analog +Devices shall have access to all reasonably requested documents, equipment, +information and personnel. Licensee shall maintain complete and accurate +records of its use of the Licensed Software for a period of at least three +years from the applicable use of the Licensed Software. + +12. License Term; Term of Agreement. This Agreement is effective upon receipt +of the Licensed Software and shall continue for three (3) years, unless earlier +terminated as permitted in this Agreement. This Agreement will automatically +renew for additional one (1) year terms unless indicated otherwise in writing +by either of the parties thirty (30) days prior to any renewal date. Licensee +may terminate this Agreement at any time by giving written notice to Analog +Devices. Analog Devices may terminate this Agreement at any time in the event +of any failure by Licensee to comply with any term or condition of the +Agreement. In the event of termination, Licensee must permanently delete all +copies of Licensed Software and all of its component parts, including any +backup or archival copies. Licenses granted to end users prior to termination +shall survive. The provisions of Sections 3-22 shall survive any termination +or expiration of this Agreement according to their terms. + +13. DISCLAIMER AND LIMITATION OF WARRANTIES. LICENSED SOFTWARE AND THIRD PARTY +SOFTWARE ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, AND ANALOG DEVICES, +FOR ITSELF AND ITS LICENSORS, HEREBY DISCLAIMS ALL WARRANTIES, WHETHER EXPRESS +OR IMPLIED, ORAL OR WRITTEN, WITH RESPECT TO THE LICENSED SOFTWARE AND THIRD +PARTY SOFTWARE, INCLUDING, BUT NOT LIMITED TO, ANY EXPRESS AND IMPLIED +WARRANTIES OF MERCHANTABILITY; FITNESS FOR PARTICULAR PURPOSE AND SYSTEM +INTEGRATION; CONDITIONS OF QUALITY AND ACCURACY OF INFORMATIONAL CONTENT; +NON-INFRINGEMENT; QUIET ENJOYMENT; AND TITLE. LICENSEE AGREES THAT ANY EFFORTS +BY ANALOG DEVICES TO MODIFY OR UPDATE LICENSED SOFTWARE OR THIRD PARTY SOFTWARE +SHALL NOT BE DEEMED A WAIVER OF THESE LIMITATIONS, AND THAT ANY ANALOG DEVICES +WARRANTIES SHALL NOT BE DEEMED TO HAVE FAILED OF THEIR ESSENTIAL PURPOSE. + +14. Limitation of Liability. TO THE MAXIMUM EXTENT PERMITTED BY LAW ANALOG +DEVICES (INCLUDING ITS LICENSORS) SHALL NOT BE LIABLE FOR ANY DAMAGES ARISING +FROM OR RELATED TO THE LICENSED SOFTWARE, THIRD PARTY SOFTWARE, THEIR USE OR +ANY RELATED INFORMATION AND/OR SERVICES, INCLUDING BUT NOT LIMITED TO ANY +INDIRECT, INCIDENTAL, SPECIAL, PUNITIVE, EXEMPLARY, CONSEQUENTIAL OR ANALOGOUS +DAMAGES (INCLUDING WITHOUT LIMITATION ANY DAMAGES RESULTING FROM LOSS OF USE, +DATA, REVENUE, PROFITS, OR SAVINGS, COMPUTER DAMAGE OR ANY OTHER CAUSE), UNDER +ANY LEGAL THEORY (INCLUDING WITHOUT LIMITATION CONTRACT, WARRANTY, TORT, +NEGLIGENCE, STRICT OR PRODUCT LIABILITY), EVEN IF IT HAS BEEN INFORMED OF THE +POSSIBILITY OF SUCH DAMAGES. + +IN NO EVENT SHALL ANALOG DEVICES鈥� OR ITS LICENSORS鈥� CUMULATIVE LIABILITY +FOR DAMAGES TO LICENSEE FOR ANY AND ALL CAUSES WHATSOEVER, REGARDLESS OF THE +FORM OF ANY CLAIMS OR ACTIONS, EXCEED THE GREATER OF (1) ONE HUNDRED U.S. +DOLLARS ($100.00 U.S.) OR (2) THE AMOUNT PAID TO ANALOG DEVICES HEREUNDER FOR +THE LICENSED SOFTWARE. + +Some jurisdictions do not permit the exclusion or limitation of liability for +consequential or incidental damages, and, as such, some portion of the above +limitation may not apply to Licensee. In such jurisdictions, Analog Devices' +liability is limited to the greatest extent permitted by law. + +15. HIGH RISK APPLICATIONS. THE LICENSED SOFTWARE IS NOT DESIGNED OR INTENDED +FOR USE IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE PERFORMANCE, INCLUDING, +WITHOUT LIMITATION, IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT NAVIGATION +OR CONTROL SYSTEMS, AIR TRAFFIC CONTROL, LIFE SUPPORT MACHINES, WEAPONS +SYSTEMS, OR ANY OTHER APPLICATION IN WHICH THE FAILURE OF THE LICENSED SOFTWARE +COULD LEAD TO DEATH, PERSONAL INJURY OR SEVERE PHYSICAL OR ENVIRONMENTAL +DAMAGES (鈥淗IGH RISK ACTIVITIES鈥�). LICENSED SOFTWARE IS NOT DESIGNED, +AUTHORIZED, OR WARRANTED TO BE SUITABLE FOR USE IN CONNECTION WITH HIGH RISK +ACTIVITIES. USE OF LICENSED SOFTWARE IN CONNECTION WITH HIGH RISK ACTIVITIES +IS UNDERSTOOD TO BE FULLY AT LICENSEE鈥橲 RISK. + +16. Choice of Law. This Agreement and any dispute related to the Licensed +Software shall be governed by the laws of the Commonwealth of Massachusetts, +United States of America, without reference to its principles of conflicts of +laws, and, as to matters affecting copyrights, trademarks and patents, in +addition, by applicable United States federal law. The parties agree that the +jurisdiction and venue of any action with respect to this Agreement shall be in +a court of competent subject matter jurisdiction located in the Commonwealth of +Massachusetts, and each of the parties hereby agrees to submit itself to the +exclusive jurisdiction and venue of such courts for the purpose of any such +action, except that Analog Devices may seek injunctive relief in any venue of +its choosing. Licensee hereby submits to personal jurisdiction in such courts. +The parties hereto specifically exclude the United Nations Convention on +Contracts for the International Sale of Goods and the Uniform Computer +Information Transactions Act from this Agreement and any transaction between +them that may be implemented in connection with this Agreement. The original of +this Agreement has been written in English. The parties hereto waive any +statute, law, or regulation that might provide an alternative law or forum or +to have this Agreement written in any language other than English. + +17. U.S. Government Restricted Rights. Licensed Software is provided with +RESTRICTED RIGHTS. Use, duplication, or disclosure by the Government is +subject to restrictions as set forth in subparagraphs (a) through (d) of the +Commercial Computer Software - Restricted Rights clause at FAR 52.227-19, +(c)(1)(ii) of The Rights in Technical Data and Computer Software clause at +DFARS 252.227-7013, and in similar clauses in the NASA FAR Supplement, as +applicable. The contractor/manufacturer of this Licensed Software is Analog +Devices, Inc., One Technology Way, Norwood, Massachusetts 02062 USA, or its +authorized licensors. + +18. Export. Licensee shall not export, directly or indirectly, Licensed +Software, or other information or materials provided by Analog Devices or its +suppliers hereunder, to any country for which the United States or any other +relevant jurisdiction requires any export license or other governmental +approval at the time of export without first obtaining such license or +approval. Licensee shall defend indemnify and hold harmless Analog Devices +from and against any damages, fines, penalties, assessments, liabilities, costs +and expenses (including reasonable attorneys鈥� fees and court costs) arising +out of any failure by Licensee to comply with this Section. + +19. Compliance with Laws of Other Jurisdictions. Licensee shall comply with +all laws, legislation, rules, regulations, governmental requirements and +industry standards with respect to Licensed Software, and the performance by +Licensee of its obligations hereunder, existing in any applicable jurisdiction. + +20. Assignment. This Agreement is personal to Licensee and Licensee may not +transfer, sublicense, lease, rent, or assign its rights under this License, and +any such attempt shall be null and void. Analog Devices may assign, transfer, +or sublicense this Agreement or any rights or obligations hereunder at any time +in its sole discretion. + +21. Waiver; Modification; Severability. No waiver, consent, modification or +change of terms of this Agreement shall bind either party unless in writing +signed by both parties, and then such waiver, consent, modification or change +shall be effective only in the specific instance and for the specific purpose +given. If any provision of this Agreement is unenforceable, such provision +shall be enforced to the extent possible under applicable law, and the +remaining provisions will remain in effect. + +22. Entire Agreement. This Agreement supersedes any and all other agreements, +either oral or in writing, between the parties with respect to the matters +stated herein. If, for any reason, any provision of this Agreement is held +invalid, such invalidity shall not affect the remainder of this Agreement, and +this Agreement shall continue in force and effect to the full extent allowed by +law. For the avoidance of doubt, all Licensed Software under this Agreement is +subject to the terms and conditions of this Agreement and not any agreement or +terms for purchase of Analog Devices products, even if the Licensed Software is +delivered with such products. + + +Appendix A + +License limited to Analog Devices transceiver / receiver / transmitter products. + +*/ +#include "Mykonos_M3.h" +// Version 5.2.2 + +unsigned char firmware_Mykonos_M3_bin[] = { + 0x90, 0xbc, 0x00, 0x20, 0x35, 0x6b, 0x01, 0x01, 0xf1, 0x66, 0x01, 0x01, + 0xf1, 0x66, 0x01, 0x01, 0xf1, 0x66, 0x01, 0x01, 0xf1, 0x66, 0x01, 0x01, + 0xf1, 0x66, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf5, 0x6a, 0x01, 0x01, + 0xf7, 0x6a, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x97, 0x7a, 0x00, 0x01, + 0x2d, 0x7a, 0x00, 0x01, 0xf9, 0x6a, 0x01, 0x01, 0xd7, 0x8b, 0x00, 0x01, + 0xe7, 0xeb, 0x00, 0x01, 0x71, 0x52, 0x00, 0x01, 0xfb, 0x6a, 0x01, 0x01, + 0x8d, 0x69, 0x00, 0x01, 0x9d, 0x69, 0x00, 0x01, 0xad, 0x69, 0x00, 0x01, + 0xd9, 0x69, 0x00, 0x01, 0x3f, 0xfd, 0x00, 0x01, 0x07, 0x8d, 0x00, 0x01, + 0x43, 0x8e, 0x00, 0x01, 0xc3, 0x8d, 0x00, 0x01, 0xeb, 0x8e, 0x00, 0x01, + 0xff, 0x32, 0x00, 0x01, 0x31, 0xf1, 0x00, 0x01, 0xd3, 0x8c, 0x00, 0x01, + 0x7b, 0xf2, 0x00, 0x01, 0xfd, 0x6a, 0x01, 0x01, 0x6b, 0x5f, 0x00, 0x01, + 0xff, 0x6a, 0x01, 0x01, 0x01, 0x6b, 0x01, 0x01, 0x03, 0x6b, 0x01, 0x01, + 0x05, 0x6b, 0x01, 0x01, 0x07, 0x6b, 0x01, 0x01, 0x51, 0xf4, 0x00, 0x01, + 0x09, 0x6b, 0x01, 0x01, 0x0b, 0x6b, 0x01, 0x01, 0x93, 0xfd, 0x00, 0x01, + 0x53, 0x8d, 0x00, 0x01, 0x7f, 0x8e, 0x00, 0x01, 0x65, 0x8f, 0x00, 0x01, + 0xbd, 0x9d, 0x00, 0x01, 0x11, 0xf3, 0x00, 0x01, 0x2d, 0xf2, 0x00, 0x01, + 0x5f, 0xf2, 0x00, 0x01, 0x0d, 0x6b, 0x01, 0x01, 0x0f, 0x6b, 0x01, 0x01, + 0x11, 0x6b, 0x01, 0x01, 0x13, 0x6b, 0x01, 0x01, 0x15, 0x6b, 0x01, 0x01, + 0x17, 0x6b, 0x01, 0x01, 0x19, 0x6b, 0x01, 0x01, 0x1b, 0x6b, 0x01, 0x01, + 0x1d, 0x6b, 0x01, 0x01, 0x1f, 0x6b, 0x01, 0x01, 0x21, 0x6b, 0x01, 0x01, + 0xf7, 0x82, 0x00, 0x01, 0x23, 0x6b, 0x01, 0x01, 0xdb, 0x82, 0x00, 0x01, + 0x25, 0x6b, 0x01, 0x01, 0x27, 0x6b, 0x01, 0x01, 0x29, 0x6b, 0x01, 0x01, + 0x2b, 0x6b, 0x01, 0x01, 0x2d, 0x6b, 0x01, 0x01, 0x2f, 0x6b, 0x01, 0x01, + 0x31, 0x6b, 0x01, 0x01, 0x33, 0x6b, 0x01, 0x01, 0x1a, 0xc4, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x1f, 0x15, 0x00, 0x00, 0x74, 0x72, 0x75, 0x6e, + 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf0, 0xb7, 0x00, 0x20, 0xb8, 0x82, 0x00, 0x20, 0x00, 0xf2, 0x00, 0x20, + 0x10, 0xf1, 0x00, 0x20, 0x78, 0x29, 0x00, 0x20, 0xa4, 0x2b, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x8c, 0x09, 0x00, 0x20, 0xf0, 0xb2, 0x00, 0x20, 0x98, 0xb4, 0x00, 0x20, + 0x00, 0x00, 0x70, 0x47, 0x4c, 0xbd, 0x00, 0x20, 0x38, 0xb2, 0x00, 0x20, + 0xe0, 0xb3, 0x00, 0x20, 0xb8, 0x00, 0xff, 0xff, 0xef, 0xf3, 0x11, 0x80, + 0x60, 0x21, 0x81, 0xf3, 0x11, 0x88, 0x70, 0x47, 0x38, 0xb5, 0x14, 0x46, + 0x00, 0x22, 0x82, 0x70, 0x00, 0xf1, 0x4c, 0x05, 0xdf, 0xf8, 0x14, 0x29, + 0x82, 0x61, 0x00, 0x22, 0xc2, 0x61, 0x02, 0x62, 0x02, 0x80, 0x82, 0x81, + 0x01, 0x22, 0xc2, 0x81, 0x02, 0x82, 0x42, 0x82, 0x00, 0x22, 0xa0, 0xf8, + 0x18, 0x22, 0x40, 0x22, 0xea, 0x83, 0x2a, 0x84, 0x00, 0x22, 0x6a, 0x85, + 0x2a, 0x80, 0xaa, 0x61, 0x41, 0xb1, 0x4f, 0xf0, 0x00, 0x41, 0x41, 0x61, + 0x4f, 0xf0, 0xff, 0x31, 0x01, 0x81, 0x41, 0x81, 0x81, 0x80, 0xc1, 0x80, + 0x01, 0xf0, 0x82, 0xf8, 0xdf, 0xf8, 0xd4, 0x08, 0x34, 0xb9, 0x41, 0x78, + 0x02, 0x78, 0x42, 0xea, 0x01, 0x21, 0xc2, 0x78, 0x80, 0x78, 0x05, 0xe0, + 0x41, 0x79, 0x02, 0x79, 0x42, 0xea, 0x01, 0x21, 0xc2, 0x79, 0x80, 0x79, + 0x09, 0xb2, 0x40, 0xea, 0x02, 0x20, 0xb1, 0xf5, 0x00, 0x5f, 0xa8, 0xbf, + 0xa1, 0xf5, 0x80, 0x41, 0x00, 0xb2, 0xb0, 0xf5, 0x00, 0x5f, 0xa8, 0xbf, + 0xa0, 0xf5, 0x80, 0x40, 0x69, 0x84, 0xa8, 0x84, 0x01, 0xf0, 0x96, 0xfd, + 0xdf, 0xf8, 0x94, 0x08, 0x34, 0x21, 0x01, 0xfb, 0x04, 0x04, 0x20, 0x46, + 0x02, 0xf0, 0xb0, 0xfe, 0x64, 0x20, 0x60, 0x60, 0xbd, 0xe8, 0x31, 0x40, + 0x01, 0xf0, 0x9d, 0xbd, 0x2d, 0xe9, 0xf0, 0x41, 0x04, 0x46, 0x0e, 0x46, + 0x15, 0x46, 0xff, 0xf7, 0x9b, 0xff, 0x00, 0x27, 0x80, 0x46, 0xe1, 0x5f, + 0x70, 0x1e, 0x81, 0x42, 0xbc, 0xbf, 0x72, 0x42, 0x8a, 0x42, 0x05, 0xda, + 0xb4, 0xf9, 0x02, 0x10, 0x81, 0x42, 0xb8, 0xbf, 0x8a, 0x42, 0x02, 0xdb, + 0x27, 0x80, 0x67, 0x80, 0x01, 0x27, 0xb4, 0xf9, 0x00, 0x00, 0x00, 0x12, + 0x00, 0xf0, 0x3f, 0x01, 0xa5, 0xb9, 0x40, 0xf6, 0x15, 0x20, 0x02, 0xf0, + 0xc5, 0xfe, 0x20, 0x88, 0xc1, 0xb2, 0x40, 0xf6, 0x14, 0x20, 0x02, 0xf0, + 0xbf, 0xfe, 0x00, 0xf0, 0x2b, 0xf8, 0x40, 0xf6, 0x17, 0x20, 0x02, 0xf0, + 0xb9, 0xfe, 0x60, 0x88, 0xc1, 0xb2, 0x40, 0xf6, 0x16, 0x20, 0x13, 0xe0, + 0x40, 0xf6, 0x19, 0x20, 0x02, 0xf0, 0xb0, 0xfe, 0x20, 0x88, 0xc1, 0xb2, + 0x40, 0xf6, 0x18, 0x20, 0x02, 0xf0, 0xaa, 0xfe, 0x00, 0xf0, 0x16, 0xf8, + 0x40, 0xf6, 0x1b, 0x20, 0x02, 0xf0, 0xa4, 0xfe, 0x60, 0x88, 0xc1, 0xb2, + 0x40, 0xf6, 0x1a, 0x20, 0x02, 0xf0, 0x9e, 0xfe, 0x01, 0x20, 0xa8, 0x40, + 0xc1, 0xb2, 0x40, 0xf6, 0x1c, 0x20, 0x02, 0xf0, 0x97, 0xfe, 0x88, 0xf3, + 0x11, 0x88, 0x38, 0x46, 0xbd, 0xe8, 0xf0, 0x81, 0xb4, 0xf9, 0x02, 0x00, + 0x00, 0x12, 0x00, 0xf0, 0x3f, 0x01, 0x70, 0x47, 0x2d, 0xe9, 0xf8, 0x4f, + 0x80, 0x46, 0xdf, 0xf8, 0x0c, 0x0e, 0x4f, 0xf4, 0x08, 0x71, 0x01, 0xfb, + 0x08, 0x0a, 0xff, 0xf7, 0x3b, 0xff, 0x83, 0x46, 0x40, 0x46, 0x0a, 0xf1, + 0x6a, 0x05, 0x02, 0xf0, 0xe3, 0xff, 0x2a, 0x88, 0xdf, 0xf8, 0xf0, 0x1d, + 0x40, 0x56, 0x56, 0x56, 0x00, 0x24, 0x81, 0x1b, 0x04, 0xd4, 0xb1, 0x46, + 0x06, 0x46, 0x04, 0xd0, 0x01, 0x21, 0x02, 0xe0, 0x81, 0x46, 0x4f, 0xf0, + 0xff, 0x31, 0x40, 0x2a, 0x1f, 0xd0, 0x01, 0x24, 0x00, 0x29, 0x4c, 0xbf, + 0x1f, 0xfa, 0x89, 0xf7, 0xb7, 0xb2, 0xda, 0xe9, 0x82, 0x01, 0x3a, 0x46, + 0x03, 0xf0, 0x64, 0xf8, 0xc0, 0x07, 0x18, 0xd5, 0x0a, 0xeb, 0xc7, 0x00, + 0xb1, 0x45, 0xc1, 0x6f, 0x04, 0xd0, 0x80, 0x6f, 0x40, 0x11, 0xa8, 0x80, + 0x48, 0x11, 0xe8, 0x80, 0x42, 0x46, 0xdf, 0xf8, 0xd8, 0x0d, 0xb0, 0xf9, + 0x24, 0x10, 0x0a, 0xf1, 0x6e, 0x00, 0xff, 0xf7, 0x61, 0xff, 0xac, 0x81, + 0x8b, 0xf3, 0x11, 0x88, 0x00, 0x20, 0xbd, 0xe8, 0xf2, 0x8f, 0x00, 0x24, + 0xf7, 0xe7, 0xf8, 0xb5, 0x04, 0x46, 0x0d, 0x46, 0x26, 0x68, 0x60, 0x68, + 0xb6, 0xf9, 0x34, 0xc0, 0x03, 0xeb, 0x02, 0x17, 0x81, 0x1c, 0x67, 0x44, + 0x3f, 0x11, 0xcf, 0x80, 0xb7, 0x8e, 0x4a, 0x80, 0xff, 0x18, 0xb1, 0xf9, + 0x0a, 0x20, 0x8b, 0x80, 0x07, 0xf0, 0x0f, 0x07, 0x0f, 0x81, 0x00, 0x2a, + 0x14, 0xbf, 0x02, 0x22, 0x01, 0x22, 0xb1, 0xf9, 0x0c, 0x70, 0x13, 0x46, + 0x1f, 0xb1, 0x37, 0x69, 0xe7, 0x61, 0x01, 0x27, 0x08, 0xe0, 0x02, 0x2b, + 0x03, 0xd1, 0x77, 0x69, 0xe7, 0x61, 0x37, 0x8c, 0x02, 0xe0, 0xb7, 0x69, + 0xe7, 0x61, 0x77, 0x8c, 0x27, 0x84, 0xb1, 0xf9, 0x0e, 0x70, 0x00, 0x2f, + 0x01, 0xbf, 0xb1, 0xf9, 0x10, 0x70, 0x00, 0x2f, 0x0f, 0x78, 0xba, 0x42, + 0x24, 0xd0, 0x00, 0xf1, 0x18, 0x07, 0xdf, 0xf8, 0xb4, 0xc6, 0xc7, 0xf8, + 0x00, 0xc0, 0x4f, 0xf0, 0x00, 0x0c, 0xc7, 0xf8, 0x04, 0xc0, 0xc7, 0xf8, + 0x08, 0xc0, 0xb4, 0xf8, 0x12, 0xc0, 0xa4, 0xf8, 0x16, 0xc0, 0x4f, 0xf0, + 0x00, 0x0c, 0xa0, 0xf8, 0x00, 0xc0, 0xa1, 0xf8, 0x0e, 0xc0, 0x0a, 0x70, + 0xc7, 0xf8, 0x4c, 0xc0, 0x32, 0x69, 0xe2, 0x61, 0x01, 0x22, 0x22, 0x84, + 0xb1, 0xf9, 0x0c, 0x20, 0x00, 0x2a, 0x1a, 0xbf, 0x01, 0x2b, 0x08, 0x22, + 0x20, 0x22, 0xba, 0x86, 0xb1, 0xf9, 0x10, 0x10, 0x21, 0xb1, 0x00, 0xf0, + 0x4b, 0xff, 0x61, 0x68, 0x00, 0x20, 0x48, 0x82, 0x25, 0x81, 0xf1, 0xbd, + 0x2d, 0xe9, 0xf9, 0x4f, 0x97, 0xb0, 0x00, 0x20, 0x0c, 0x46, 0x01, 0x90, + 0xe0, 0x8a, 0x17, 0x99, 0x40, 0x08, 0x02, 0x90, 0x01, 0x20, 0x88, 0x40, + 0x11, 0x90, 0x00, 0x21, 0x00, 0x20, 0x03, 0xf0, 0x20, 0xf8, 0x11, 0x98, + 0x02, 0xf0, 0x32, 0xfe, 0x00, 0x25, 0x30, 0xb9, 0x04, 0xf0, 0x99, 0xf8, + 0x18, 0xb9, 0x03, 0xf0, 0x73, 0xf8, 0x02, 0x20, 0x0c, 0xe3, 0x00, 0xf0, + 0x26, 0xfb, 0x02, 0xf0, 0xec, 0xfd, 0xdf, 0xf8, 0x34, 0x0e, 0x00, 0x68, + 0x60, 0x62, 0x04, 0xf1, 0x28, 0x00, 0x04, 0xf0, 0xb6, 0xfe, 0x00, 0xf0, + 0x81, 0xff, 0x00, 0x28, 0x04, 0xf1, 0x2c, 0x00, 0x02, 0xd0, 0x04, 0xf0, + 0xe6, 0xff, 0x01, 0xe0, 0x05, 0xf0, 0x55, 0xfa, 0x17, 0x99, 0x20, 0x46, + 0x00, 0xf0, 0x16, 0xff, 0x06, 0x46, 0x60, 0x68, 0xb0, 0xf9, 0x0c, 0x10, + 0x00, 0x29, 0x17, 0x99, 0x14, 0xbf, 0xb0, 0xf9, 0x08, 0x00, 0xb0, 0xf9, + 0x04, 0x00, 0x00, 0x29, 0x14, 0xbf, 0xdf, 0xf8, 0xf0, 0x1d, 0xdf, 0xf8, + 0xf0, 0x1d, 0x09, 0x68, 0xc9, 0x07, 0x05, 0xd5, 0x01, 0x21, 0xc0, 0x1d, + 0x80, 0x28, 0x02, 0xd3, 0x7f, 0x20, 0x00, 0xe0, 0x00, 0x21, 0x17, 0x9a, + 0xdf, 0xf8, 0xd8, 0x3d, 0x00, 0x04, 0x00, 0xf4, 0xfe, 0x00, 0x40, 0xea, + 0x82, 0x70, 0x40, 0xea, 0xc1, 0x32, 0x1a, 0x43, 0x16, 0x92, 0x00, 0x27, + 0x22, 0x8b, 0xd2, 0x05, 0x02, 0xf0, 0x7e, 0x52, 0x10, 0x43, 0x40, 0xea, + 0xc1, 0x30, 0xdf, 0xf8, 0xb8, 0x1d, 0x08, 0x43, 0x10, 0x90, 0x10, 0x98, + 0x05, 0xf0, 0x3b, 0xfb, 0x20, 0x68, 0xc0, 0x8e, 0x41, 0x42, 0x09, 0xb2, + 0x00, 0xb2, 0x05, 0xf0, 0xa3, 0xfd, 0x60, 0x68, 0xb0, 0xf9, 0x0e, 0x10, + 0x39, 0xb1, 0xdf, 0xf8, 0x84, 0x2d, 0x4f, 0xf4, 0x88, 0x71, 0xd1, 0x61, + 0x11, 0x62, 0x4f, 0xf4, 0x84, 0x77, 0x61, 0x6a, 0xdf, 0xf8, 0x70, 0x2d, + 0x39, 0x43, 0x41, 0xf0, 0x02, 0x01, 0x11, 0x60, 0xd0, 0xf8, 0x6e, 0x00, + 0x03, 0x90, 0x17, 0x98, 0x06, 0xf0, 0x60, 0xf8, 0x04, 0xe0, 0x1f, 0xfa, + 0x89, 0xf8, 0x01, 0x98, 0x40, 0x1c, 0x01, 0x90, 0x02, 0x98, 0x01, 0x99, + 0x88, 0x42, 0xc0, 0xf2, 0x66, 0x82, 0x00, 0x2d, 0x08, 0xbf, 0x00, 0x2e, + 0x40, 0xf0, 0x61, 0x82, 0x08, 0x46, 0x02, 0x99, 0x88, 0x42, 0x08, 0xbf, + 0x4f, 0xf0, 0x01, 0x0a, 0x1c, 0xd0, 0x00, 0xf0, 0x05, 0xff, 0x4f, 0xf0, + 0x00, 0x0a, 0x20, 0xb9, 0x17, 0x98, 0x01, 0x21, 0xc0, 0xb2, 0x05, 0xf0, + 0xfa, 0xf9, 0x20, 0x68, 0x80, 0x8f, 0x06, 0xf0, 0x6d, 0xf9, 0x05, 0xf0, + 0x9c, 0xfa, 0x01, 0x98, 0x17, 0x9a, 0x64, 0x21, 0x48, 0x43, 0x02, 0x99, + 0x90, 0xfb, 0xf1, 0xf0, 0xdf, 0xf8, 0xe8, 0x14, 0x34, 0x23, 0x03, 0xfb, + 0x02, 0x11, 0x48, 0x60, 0x01, 0x98, 0x01, 0x28, 0x2d, 0xdb, 0xdd, 0xe9, + 0x08, 0x01, 0x06, 0xf0, 0xf7, 0xf9, 0x0f, 0x90, 0xdd, 0xe9, 0x06, 0x01, + 0x06, 0xf0, 0xf2, 0xf9, 0xb8, 0xf1, 0x00, 0x0f, 0x0e, 0x90, 0x20, 0xd1, + 0x60, 0x68, 0xdd, 0xe9, 0x14, 0x23, 0xd0, 0xe9, 0x0a, 0x71, 0xba, 0x18, + 0x4b, 0x41, 0xc0, 0xe9, 0x0a, 0x23, 0xd0, 0xe9, 0x0c, 0x71, 0xdd, 0xe9, + 0x12, 0x23, 0xba, 0x18, 0x4b, 0x41, 0xc0, 0xe9, 0x0c, 0x23, 0xd0, 0xe9, + 0x0e, 0x71, 0xdd, 0xe9, 0x08, 0x23, 0xba, 0x18, 0x4b, 0x41, 0xc0, 0xe9, + 0x0e, 0x23, 0xd0, 0xe9, 0x10, 0x71, 0xdd, 0xe9, 0x06, 0x23, 0xba, 0x18, + 0x4b, 0x41, 0xc0, 0xe9, 0x10, 0x23, 0x17, 0x98, 0x02, 0xf0, 0x4e, 0xfe, + 0xdf, 0xf8, 0xc8, 0x2a, 0xdf, 0xf8, 0x48, 0x1d, 0x80, 0x56, 0x31, 0xf8, + 0x10, 0x00, 0x06, 0xf0, 0xfd, 0xf9, 0xdf, 0xf8, 0x40, 0x1d, 0x06, 0xf0, + 0x09, 0xfa, 0x00, 0xf0, 0x6d, 0xfd, 0xba, 0xf1, 0x00, 0x0f, 0x0d, 0x90, + 0x39, 0xd1, 0x05, 0xf0, 0x62, 0xfa, 0x02, 0x28, 0x0c, 0xbf, 0x06, 0x26, + 0x01, 0x28, 0x00, 0xd1, 0x01, 0x25, 0xdf, 0xf8, 0x20, 0x2d, 0xd2, 0xe9, + 0x00, 0x01, 0xcd, 0xe9, 0x14, 0x01, 0xd2, 0xe9, 0x02, 0x01, 0xcd, 0xe9, + 0x12, 0x01, 0xd2, 0xe9, 0x04, 0x01, 0xcd, 0xe9, 0x08, 0x01, 0xd2, 0xe9, + 0x06, 0x01, 0xcd, 0xe9, 0x06, 0x01, 0x60, 0x68, 0xb0, 0xf9, 0x0c, 0x00, + 0xb0, 0xb9, 0x17, 0x98, 0x00, 0x21, 0xc0, 0xb2, 0x05, 0xf0, 0x7d, 0xf9, + 0xdd, 0xe9, 0x08, 0x01, 0x40, 0x42, 0x61, 0xeb, 0x41, 0x01, 0xcd, 0xe9, + 0x08, 0x01, 0xdd, 0xe9, 0x06, 0x01, 0x40, 0x42, 0x61, 0xeb, 0x41, 0x01, + 0xcd, 0xe9, 0x06, 0x01, 0x20, 0x68, 0x80, 0x8f, 0x06, 0xf0, 0xe2, 0xf8, + 0x00, 0x2d, 0x04, 0xbf, 0x00, 0x2e, 0x05, 0xf0, 0x0e, 0xfa, 0x01, 0x98, + 0x02, 0x28, 0xc0, 0xf2, 0xcc, 0x80, 0x0f, 0x98, 0x00, 0x99, 0x06, 0xf0, + 0x3f, 0xfa, 0x0c, 0x90, 0x59, 0x46, 0x0e, 0x98, 0x06, 0xf0, 0x3a, 0xfa, + 0x0b, 0x90, 0xbd, 0xf9, 0x14, 0x10, 0xbd, 0xf9, 0x10, 0x00, 0x40, 0x1a, + 0x06, 0xf0, 0x9a, 0xf9, 0x07, 0x46, 0xbd, 0xf9, 0x12, 0x00, 0xbd, 0xf9, + 0x16, 0x10, 0x40, 0x1a, 0x06, 0xf0, 0x92, 0xf9, 0x00, 0xf0, 0x1c, 0xfd, + 0x83, 0x46, 0x48, 0x46, 0x00, 0xf0, 0xfc, 0xfc, 0x59, 0x46, 0x06, 0xf0, + 0x95, 0xfa, 0x06, 0xf0, 0xd5, 0xfa, 0x00, 0x21, 0x06, 0xf0, 0x0c, 0xfb, + 0x83, 0x46, 0x1d, 0xd0, 0x20, 0x68, 0x30, 0xf8, 0x42, 0x1f, 0x81, 0xb1, + 0x61, 0x68, 0x4c, 0x31, 0x00, 0x91, 0x40, 0x88, 0x06, 0xf0, 0x82, 0xf9, + 0x01, 0x46, 0x00, 0x98, 0x80, 0x69, 0x06, 0xf0, 0x09, 0xfb, 0x04, 0xd3, + 0x00, 0x98, 0x00, 0x88, 0x08, 0x28, 0xc0, 0xf2, 0x90, 0x80, 0x11, 0x98, + 0x02, 0xf0, 0xbe, 0xfc, 0x00, 0x28, 0x03, 0xd0, 0x04, 0x20, 0x02, 0xf0, + 0xab, 0xfc, 0x00, 0x28, 0x00, 0xf0, 0x85, 0x80, 0x0c, 0x98, 0x00, 0xf0, + 0xd6, 0xfc, 0x00, 0x90, 0x49, 0x46, 0x0b, 0x98, 0x06, 0xf0, 0x02, 0xfb, + 0x00, 0x99, 0x06, 0xf0, 0x63, 0xfa, 0x59, 0x46, 0x06, 0xf0, 0x6e, 0xf9, + 0x00, 0x90, 0x39, 0x46, 0x0b, 0x98, 0x06, 0xf0, 0xf7, 0xfa, 0x07, 0x46, + 0x0c, 0x98, 0x00, 0xf0, 0xbb, 0xfc, 0x01, 0x46, 0x38, 0x46, 0x06, 0xf0, + 0xdf, 0xf9, 0x59, 0x46, 0x06, 0xf0, 0x5e, 0xf9, 0x0a, 0x90, 0x4f, 0xf0, + 0x7e, 0x50, 0x18, 0x99, 0x06, 0xf0, 0xd6, 0xf9, 0xb8, 0xf1, 0x00, 0x0f, + 0x81, 0x46, 0x5c, 0xd1, 0x67, 0x68, 0x00, 0xf0, 0xa6, 0xfc, 0x0d, 0x99, + 0x06, 0xf0, 0xdc, 0xfa, 0xb9, 0x69, 0x06, 0xf0, 0x3d, 0xfa, 0xb8, 0x61, + 0x49, 0x46, 0x00, 0x98, 0x06, 0xf0, 0xd4, 0xfa, 0xf9, 0x69, 0x06, 0xf0, + 0x35, 0xfa, 0xf8, 0x61, 0x49, 0x46, 0x0a, 0x98, 0x06, 0xf0, 0xcc, 0xfa, + 0x39, 0x6a, 0x06, 0xf0, 0x2d, 0xfa, 0x38, 0x62, 0x4f, 0xf0, 0x7e, 0x51, + 0x38, 0x6d, 0x06, 0xf0, 0x27, 0xfa, 0x38, 0x65, 0x59, 0x46, 0x0d, 0x98, + 0x06, 0xf0, 0xbe, 0xfa, 0x81, 0x46, 0x00, 0x98, 0x49, 0x46, 0x06, 0xf0, + 0x2b, 0xf9, 0x79, 0x6d, 0x83, 0x46, 0x06, 0xf0, 0xa5, 0xf9, 0x00, 0x90, + 0x39, 0x6d, 0x06, 0xf0, 0x23, 0xf9, 0x79, 0x6d, 0x06, 0xf0, 0x12, 0xfa, + 0x01, 0x46, 0x79, 0x65, 0x00, 0xf0, 0x76, 0xfc, 0x00, 0x99, 0x06, 0xf0, + 0xa7, 0xfa, 0xf9, 0x6d, 0x06, 0xf0, 0x08, 0xfa, 0xf8, 0x65, 0x49, 0x46, + 0x0a, 0x98, 0x06, 0xf0, 0x11, 0xf9, 0xb9, 0x6d, 0x81, 0x46, 0x06, 0xf0, + 0x8b, 0xf9, 0x39, 0x6d, 0x83, 0x46, 0x06, 0xf0, 0x09, 0xf9, 0xb9, 0x6d, + 0x06, 0xf0, 0xf8, 0xf9, 0x01, 0x46, 0xb9, 0x65, 0x48, 0x46, 0x06, 0xf0, + 0x7f, 0xf9, 0x59, 0x46, 0x06, 0xf0, 0x8c, 0xfa, 0x39, 0x6e, 0x06, 0xf0, + 0xed, 0xf9, 0x38, 0x66, 0x01, 0xe0, 0x01, 0x28, 0x03, 0xdb, 0x0f, 0x98, + 0xdd, 0xf8, 0x38, 0xb0, 0x00, 0x90, 0xba, 0xf1, 0x00, 0x0f, 0x04, 0x98, + 0x05, 0x90, 0x03, 0x98, 0x04, 0x90, 0x7f, 0xf4, 0x70, 0xae, 0x60, 0x68, + 0xdf, 0xf8, 0x74, 0x2d, 0x50, 0xf8, 0x14, 0x7f, 0xdf, 0xf8, 0x6c, 0x3d, + 0x07, 0xf0, 0x01, 0x01, 0x51, 0x43, 0x81, 0xea, 0x57, 0x01, 0x00, 0xf0, + 0x05, 0xf9, 0x00, 0xf0, 0x03, 0xf9, 0x01, 0x60, 0x07, 0xf0, 0x01, 0x02, + 0x07, 0xf0, 0x02, 0x01, 0x49, 0x1e, 0x7b, 0x07, 0x05, 0xd5, 0xfb, 0x43, + 0x03, 0xf0, 0x01, 0x03, 0x4b, 0x43, 0x51, 0x43, 0x01, 0xe0, 0x52, 0x00, + 0x53, 0x1e, 0x07, 0x8f, 0x79, 0x43, 0x07, 0xfb, 0x03, 0xf2, 0xb0, 0xf9, + 0x5a, 0x70, 0x13, 0xb2, 0x3b, 0x44, 0xbd, 0xf9, 0x10, 0x70, 0xbb, 0x42, + 0x07, 0xd1, 0xb0, 0xf9, 0x5c, 0x70, 0x0b, 0xb2, 0x3b, 0x44, 0xbd, 0xf9, + 0x12, 0x70, 0xbb, 0x42, 0x04, 0xd0, 0x02, 0x9f, 0x01, 0x9b, 0x7f, 0x1e, + 0xbb, 0x42, 0x01, 0xdb, 0x00, 0x22, 0x00, 0x21, 0x83, 0x8e, 0xd3, 0x18, + 0x83, 0x86, 0xc3, 0x8e, 0xcb, 0x18, 0xc3, 0x86, 0xb0, 0xf8, 0x5a, 0x30, + 0xd2, 0x18, 0xad, 0xf8, 0x0c, 0x20, 0xb0, 0xf8, 0x5c, 0x00, 0x08, 0x18, + 0xad, 0xf8, 0x0e, 0x00, 0x00, 0x2d, 0x08, 0xbf, 0x00, 0x2e, 0x07, 0xd1, + 0x05, 0xf0, 0xfb, 0xf8, 0x02, 0x28, 0x0c, 0xbf, 0x06, 0x26, 0x01, 0x28, + 0x00, 0xd1, 0x01, 0x25, 0xdf, 0xf8, 0x50, 0xca, 0xdd, 0xe9, 0x14, 0x23, + 0xdc, 0xe9, 0x00, 0x01, 0x10, 0x18, 0x59, 0x41, 0xcd, 0xe9, 0x14, 0x01, + 0xdd, 0xe9, 0x12, 0x23, 0xdc, 0xe9, 0x02, 0x01, 0x10, 0x18, 0x59, 0x41, + 0xcd, 0xe9, 0x12, 0x01, 0xdd, 0xe9, 0x08, 0x23, 0xdc, 0xe9, 0x04, 0x01, + 0x10, 0x18, 0x59, 0x41, 0xcd, 0xe9, 0x08, 0x01, 0xdd, 0xe9, 0x06, 0x23, + 0xdc, 0xe9, 0x06, 0x01, 0x10, 0x18, 0x59, 0x41, 0xcd, 0xe9, 0x06, 0x01, + 0x4f, 0xea, 0x68, 0x09, 0x20, 0x68, 0x24, 0x30, 0xc1, 0x8b, 0x00, 0x29, + 0x47, 0xd0, 0x16, 0x98, 0x4f, 0xf0, 0x8a, 0x41, 0x00, 0x2d, 0x08, 0x60, + 0x48, 0xd1, 0x00, 0x2e, 0x7f, 0xf4, 0xe5, 0xad, 0x05, 0xf0, 0xa5, 0xf8, + 0x20, 0x68, 0xb0, 0xf9, 0x24, 0x10, 0x17, 0x9a, 0x03, 0xa8, 0xff, 0xf7, + 0x41, 0xfc, 0x00, 0xf0, 0x96, 0xf8, 0x05, 0xf0, 0xb6, 0xf8, 0x02, 0x28, + 0x0c, 0xbf, 0x06, 0x26, 0x01, 0x28, 0x00, 0xd1, 0x01, 0x25, 0x10, 0x98, + 0x4f, 0xf0, 0x8a, 0x41, 0x08, 0x60, 0x67, 0x68, 0xdf, 0xf8, 0xec, 0x1d, + 0x78, 0x6e, 0x06, 0xf0, 0xd3, 0xf9, 0xdf, 0xf8, 0x90, 0x1d, 0x84, 0x46, + 0xdf, 0xf8, 0xac, 0x09, 0xc7, 0xf8, 0x64, 0xc0, 0xd1, 0xe9, 0x00, 0x23, + 0x00, 0x68, 0x00, 0xf0, 0x68, 0xf8, 0x08, 0xbf, 0x00, 0x28, 0x0b, 0xd0, + 0xdf, 0xf8, 0x70, 0x1d, 0xdf, 0xf8, 0x90, 0x09, 0x80, 0x68, 0xd1, 0xe9, + 0x12, 0x23, 0x00, 0xf0, 0x5c, 0xf8, 0x08, 0xbf, 0x00, 0x28, 0x0d, 0xd1, + 0x4f, 0xf0, 0x7e, 0x51, 0x60, 0x46, 0x06, 0xf0, 0x17, 0xf9, 0x78, 0x66, + 0x06, 0xe0, 0x41, 0x5e, 0x17, 0x9a, 0x03, 0xa8, 0xff, 0xf7, 0x06, 0xfc, + 0x00, 0xf0, 0x5b, 0xf8, 0x00, 0x2d, 0x3f, 0xf4, 0x9c, 0xad, 0x02, 0x98, + 0x80, 0x1c, 0x08, 0xf0, 0x01, 0x01, 0x40, 0x1a, 0x09, 0xf0, 0x01, 0x01, + 0x40, 0x1a, 0x02, 0x90, 0x4f, 0xf0, 0x03, 0x08, 0x91, 0xe5, 0x20, 0x68, + 0xb0, 0xf9, 0x24, 0x10, 0x60, 0x68, 0x17, 0x9a, 0x6e, 0x30, 0xff, 0xf7, + 0xed, 0xfb, 0x00, 0xf0, 0x42, 0xf8, 0x00, 0xf0, 0x3a, 0xf8, 0x02, 0xf0, + 0xed, 0xfa, 0x60, 0x6a, 0xdf, 0xf8, 0x58, 0x18, 0x08, 0x60, 0x00, 0xf0, + 0x99, 0xfc, 0x28, 0xb1, 0x00, 0x21, 0x04, 0xf1, 0x2c, 0x00, 0x04, 0xf0, + 0x10, 0xfd, 0x03, 0xe0, 0x04, 0xf1, 0x2c, 0x00, 0x04, 0xf0, 0x78, 0xff, + 0x04, 0xf1, 0x28, 0x00, 0x04, 0xf0, 0xc4, 0xfb, 0x00, 0x20, 0x02, 0xf0, + 0x69, 0xfd, 0x15, 0xb1, 0x00, 0x2e, 0x3f, 0xf4, 0xe4, 0xac, 0x30, 0x46, + 0x19, 0xb0, 0xbd, 0xe8, 0xf0, 0x8f, 0x00, 0x00, 0xff, 0xe6, 0xdb, 0x2e, + 0x14, 0x0a, 0x00, 0x46, 0x98, 0xf1, 0x00, 0x20, 0x01, 0x60, 0x01, 0xf0, + 0x01, 0x02, 0x5a, 0x43, 0x82, 0xea, 0x51, 0x01, 0x70, 0x47, 0xdb, 0x01, + 0x43, 0xea, 0x52, 0x63, 0x40, 0x43, 0xd2, 0x01, 0xc1, 0x17, 0x10, 0x1a, + 0x73, 0xeb, 0x01, 0x01, 0x70, 0x47, 0x02, 0x22, 0x04, 0xf1, 0x22, 0x01, + 0x0f, 0xf6, 0x68, 0x50, 0x70, 0x47, 0x22, 0x99, 0x09, 0x68, 0x08, 0x43, + 0x22, 0x99, 0x08, 0x60, 0x70, 0x47, 0x2d, 0xe9, 0xf0, 0x4f, 0x8d, 0xb0, + 0x53, 0x78, 0x12, 0x78, 0x04, 0x46, 0x88, 0x46, 0xff, 0xf7, 0x41, 0xfc, + 0x20, 0x8b, 0xc0, 0xb2, 0x05, 0xf0, 0x56, 0xf8, 0x4f, 0xea, 0x40, 0x0b, + 0xe0, 0x69, 0x05, 0xf0, 0x99, 0xff, 0xdf, 0xf8, 0xc8, 0x1c, 0x05, 0xf0, + 0xa5, 0xff, 0x05, 0x90, 0x26, 0x68, 0xf0, 0x8d, 0x05, 0xf0, 0x90, 0xff, + 0xdf, 0xf8, 0xb8, 0x1c, 0x05, 0xf0, 0x9c, 0xff, 0x01, 0x46, 0x06, 0xf0, + 0x27, 0xf9, 0x07, 0x46, 0xe0, 0x8a, 0x05, 0xf0, 0x85, 0xff, 0x00, 0xf0, + 0xf0, 0xfa, 0x07, 0x46, 0x05, 0x99, 0x4f, 0xf0, 0x7e, 0x50, 0x06, 0xf0, + 0x0b, 0xf8, 0x4f, 0xf0, 0x80, 0x41, 0x06, 0xf0, 0x17, 0xf9, 0x01, 0x46, + 0x38, 0x46, 0x05, 0xf0, 0x85, 0xff, 0x82, 0x46, 0x4f, 0xf0, 0x7a, 0x50, + 0x51, 0x46, 0x06, 0xf0, 0x0d, 0xf9, 0x07, 0x90, 0x00, 0x20, 0x63, 0x68, + 0x03, 0xf1, 0x28, 0x02, 0xc2, 0xe9, 0x00, 0x00, 0xc2, 0xe9, 0x02, 0x00, + 0xc2, 0xe9, 0x04, 0x00, 0xc2, 0xe9, 0x06, 0x00, 0x10, 0x84, 0x50, 0x84, + 0x90, 0x62, 0x50, 0x63, 0xd0, 0x62, 0x90, 0x63, 0x10, 0x63, 0xa3, 0xf8, + 0x68, 0x00, 0x04, 0x90, 0x71, 0x8d, 0x90, 0x8c, 0x88, 0x42, 0x26, 0xbf, + 0xb1, 0x8d, 0x81, 0x42, 0x91, 0x84, 0x04, 0xa8, 0x00, 0x90, 0x5a, 0x46, + 0x05, 0x9b, 0x21, 0x46, 0x40, 0x46, 0xff, 0xf7, 0x4d, 0xfc, 0x00, 0x28, + 0x40, 0xf0, 0xa0, 0x82, 0x40, 0x46, 0x02, 0xf0, 0x82, 0xfb, 0x06, 0x46, + 0x40, 0x46, 0x02, 0xf0, 0x87, 0xfb, 0x07, 0x46, 0x40, 0xf2, 0x47, 0x30, + 0x86, 0x42, 0x0d, 0xda, 0x0f, 0xf6, 0xdc, 0x40, 0x30, 0x5c, 0x00, 0xf2, + 0x01, 0x10, 0x80, 0xb2, 0x05, 0xf0, 0x32, 0xff, 0x4f, 0xf0, 0x72, 0x51, + 0x06, 0xf0, 0xcc, 0xf8, 0x06, 0x46, 0x01, 0xe0, 0x4f, 0xf0, 0x82, 0x46, + 0xdf, 0xf8, 0x10, 0x15, 0x0f, 0xf6, 0x54, 0x40, 0x79, 0x56, 0x30, 0xf8, + 0x11, 0x00, 0x05, 0xf0, 0x21, 0xff, 0xdf, 0xf8, 0x88, 0x17, 0x05, 0xf0, + 0x2d, 0xff, 0x00, 0xf0, 0x91, 0xfa, 0x0b, 0x90, 0xe0, 0x8a, 0x40, 0x08, + 0x05, 0xf0, 0x16, 0xff, 0x07, 0x46, 0x60, 0x68, 0x0a, 0x90, 0x00, 0xf1, + 0x18, 0x05, 0xd5, 0xe9, 0x04, 0x01, 0x05, 0xf0, 0xd1, 0xfe, 0x00, 0xf0, + 0x7e, 0xfa, 0x81, 0x46, 0xd5, 0xe9, 0x06, 0x01, 0x05, 0xf0, 0xca, 0xfe, + 0x00, 0xf0, 0x77, 0xfa, 0x06, 0x90, 0xd5, 0xe9, 0x08, 0x01, 0x05, 0xf0, + 0xc3, 0xfe, 0x00, 0xf0, 0x70, 0xfa, 0x09, 0x90, 0xd5, 0xe9, 0x0a, 0x01, + 0x05, 0xf0, 0xbc, 0xfe, 0x00, 0xf0, 0x69, 0xfa, 0x08, 0x90, 0x2f, 0x68, + 0x69, 0x6c, 0xa8, 0x6c, 0x05, 0xf0, 0xf2, 0xff, 0x01, 0x90, 0x00, 0xf0, + 0x6b, 0xfa, 0x00, 0x90, 0xa9, 0x68, 0x00, 0xf0, 0x68, 0xfa, 0x00, 0x99, + 0x05, 0xf0, 0xe8, 0xff, 0x00, 0x90, 0x39, 0x46, 0x38, 0x46, 0x06, 0xf0, + 0x7f, 0xf8, 0x01, 0x46, 0x00, 0x98, 0x05, 0xf0, 0xed, 0xfe, 0x07, 0x46, + 0xa9, 0x6b, 0xdf, 0xf8, 0x54, 0x0b, 0x05, 0xf0, 0xd9, 0xff, 0x00, 0xf0, + 0x42, 0xfa, 0x01, 0x46, 0x01, 0x98, 0x05, 0xf0, 0xe1, 0xfe, 0x01, 0x46, + 0x50, 0x46, 0x06, 0xf0, 0x59, 0xf8, 0x02, 0xd2, 0xa8, 0x8e, 0x40, 0x1c, + 0xa8, 0x86, 0x08, 0x46, 0x07, 0x99, 0x06, 0xf0, 0x51, 0xf8, 0x04, 0xd2, + 0xa9, 0x8e, 0xa1, 0xeb, 0x11, 0x10, 0x40, 0x1e, 0xa8, 0x86, 0x20, 0x68, + 0x00, 0xf1, 0x26, 0x07, 0xb8, 0x8b, 0x02, 0x28, 0x0b, 0xd1, 0xf8, 0x8b, + 0x05, 0xf0, 0xb6, 0xfe, 0xe9, 0x6c, 0x06, 0xf0, 0x3f, 0xf8, 0x04, 0xd2, + 0xa8, 0x8e, 0x08, 0x28, 0xbc, 0xbf, 0x08, 0x20, 0xa8, 0x86, 0x48, 0x46, + 0x00, 0x21, 0x06, 0xf0, 0x35, 0xf8, 0xca, 0x46, 0x38, 0xbf, 0x8a, 0xf0, + 0x00, 0x4a, 0x06, 0x98, 0x06, 0xf0, 0x2e, 0xf8, 0x38, 0xbf, 0x80, 0xf0, + 0x00, 0x40, 0x00, 0x90, 0x58, 0x46, 0x05, 0xf0, 0x91, 0xfe, 0x07, 0x90, + 0x51, 0x46, 0x00, 0x98, 0x05, 0xf0, 0x98, 0xff, 0x82, 0x46, 0xdf, 0xf8, + 0xcc, 0x0a, 0x00, 0xf0, 0xf3, 0xf9, 0x07, 0x99, 0x05, 0xf0, 0x9e, 0xfe, + 0x51, 0x46, 0x06, 0xf0, 0x29, 0xf8, 0xdf, 0xf8, 0xbc, 0x1a, 0x06, 0xf0, + 0x25, 0xf8, 0x06, 0xf0, 0x8f, 0xf8, 0xad, 0xf8, 0x04, 0x00, 0xbd, 0xf8, + 0x04, 0x10, 0xa8, 0x8e, 0x88, 0x42, 0x38, 0xbf, 0x08, 0x46, 0xa8, 0x86, + 0xf9, 0x88, 0xa8, 0x8e, 0x81, 0x42, 0x26, 0xbf, 0xb9, 0x88, 0x88, 0x42, + 0xa9, 0x86, 0x00, 0xf0, 0xf1, 0xf9, 0xa9, 0x68, 0x82, 0x46, 0x00, 0xf0, + 0xee, 0xf9, 0x51, 0x46, 0x05, 0xf0, 0x6e, 0xff, 0x0b, 0x99, 0x06, 0xf0, + 0x07, 0xf8, 0x29, 0x68, 0x05, 0xf0, 0x76, 0xfe, 0x4f, 0xf0, 0x7e, 0x51, + 0x05, 0xf0, 0xee, 0xff, 0x82, 0x46, 0x38, 0xbf, 0x8a, 0x46, 0x09, 0x99, + 0x68, 0x68, 0x05, 0xf0, 0xf9, 0xff, 0x83, 0x46, 0x08, 0x99, 0xa8, 0x68, + 0x05, 0xf0, 0xf4, 0xff, 0x59, 0x46, 0x05, 0xf0, 0x55, 0xff, 0x00, 0xf0, + 0xc1, 0xf9, 0x83, 0x46, 0x08, 0x99, 0x68, 0x68, 0x05, 0xf0, 0xea, 0xff, + 0x00, 0x90, 0x09, 0x99, 0xa8, 0x68, 0x05, 0xf0, 0xe5, 0xff, 0x01, 0x46, + 0x00, 0x98, 0x05, 0xf0, 0xd1, 0xfe, 0x00, 0xf0, 0xb1, 0xf9, 0x00, 0x90, + 0xe0, 0x8a, 0x40, 0x08, 0x05, 0xf0, 0x3c, 0xfe, 0x82, 0x46, 0xb5, 0xf9, + 0x30, 0x00, 0x05, 0xf0, 0x2d, 0xfe, 0x00, 0xf0, 0xa5, 0xf9, 0x00, 0xf0, + 0x9c, 0xf9, 0x83, 0x46, 0xb5, 0xf9, 0x32, 0x00, 0x05, 0xf0, 0x24, 0xfe, + 0x00, 0xf0, 0x9c, 0xf9, 0x01, 0x46, 0x00, 0x98, 0x05, 0xf0, 0xb6, 0xfe, + 0x05, 0x46, 0xb8, 0x89, 0x90, 0xb1, 0x07, 0x99, 0x30, 0x46, 0x05, 0xf0, + 0x31, 0xfe, 0x06, 0x46, 0x48, 0x46, 0x00, 0xf0, 0x7f, 0xf9, 0x00, 0xf0, + 0x84, 0xf9, 0x83, 0x46, 0x06, 0x98, 0x00, 0xf0, 0x79, 0xf9, 0x01, 0x46, + 0x28, 0x46, 0x05, 0xf0, 0xa1, 0xfe, 0x05, 0x46, 0x58, 0x46, 0x06, 0xf0, + 0x3b, 0xf8, 0x06, 0xf0, 0x17, 0xf8, 0xad, 0xf8, 0x0c, 0x00, 0x28, 0x46, + 0x06, 0xf0, 0x34, 0xf8, 0x06, 0xf0, 0x10, 0xf8, 0xad, 0xf8, 0x0e, 0x00, + 0x78, 0x88, 0x05, 0xf0, 0x01, 0xfe, 0x06, 0x46, 0xbd, 0xf8, 0x04, 0x00, + 0x05, 0xf0, 0xfc, 0xfd, 0x01, 0x46, 0xdf, 0xf8, 0x9c, 0x09, 0x05, 0xf0, + 0x85, 0xfe, 0x00, 0xf0, 0x57, 0xf9, 0xdf, 0xf8, 0x94, 0x19, 0x05, 0xf0, + 0x01, 0xfe, 0xdf, 0xf8, 0x90, 0x19, 0x05, 0xf0, 0x79, 0xff, 0x81, 0x46, + 0x38, 0xbf, 0x89, 0x46, 0x00, 0xf0, 0x4d, 0xf9, 0x06, 0xf0, 0x12, 0xf8, + 0x05, 0xf0, 0xee, 0xff, 0xad, 0xf8, 0x08, 0x00, 0x49, 0x46, 0x28, 0x46, + 0x05, 0xf0, 0x7c, 0xff, 0x06, 0xf0, 0x08, 0xf8, 0x05, 0xf0, 0xe4, 0xff, + 0xad, 0xf8, 0x0a, 0x00, 0x0a, 0x98, 0xb0, 0xf8, 0x76, 0x00, 0x28, 0xb3, + 0xbd, 0xf9, 0x0a, 0x00, 0xbd, 0xf9, 0x08, 0x10, 0x23, 0x8c, 0x00, 0xfb, + 0x00, 0xf2, 0x01, 0xfb, 0x01, 0x22, 0x9a, 0x42, 0x1a, 0xda, 0x3a, 0x88, + 0x8a, 0x42, 0xbc, 0xbf, 0x12, 0xb2, 0xad, 0xf8, 0x08, 0x20, 0x39, 0x88, + 0x81, 0x42, 0xb8, 0xbf, 0xad, 0xf8, 0x0a, 0x10, 0x38, 0x88, 0xbd, 0xf9, + 0x08, 0x10, 0x40, 0x42, 0x81, 0x42, 0xb8, 0xbf, 0xad, 0xf8, 0x08, 0x00, + 0x38, 0x88, 0xbd, 0xf9, 0x0a, 0x10, 0x40, 0x42, 0x81, 0x42, 0xb8, 0xbf, + 0xad, 0xf8, 0x0a, 0x00, 0xff, 0xf7, 0x46, 0xf9, 0x06, 0x46, 0x60, 0x68, + 0xbd, 0xf8, 0x0c, 0x20, 0xb0, 0xf9, 0x6e, 0x10, 0xbd, 0xf8, 0x0e, 0x30, + 0x8a, 0x1a, 0xad, 0xf8, 0x0c, 0x20, 0xb0, 0xf8, 0x70, 0x20, 0xd2, 0x1a, + 0xad, 0xf8, 0x0e, 0x20, 0xbd, 0xf8, 0x08, 0x20, 0x89, 0x1a, 0xad, 0xf8, + 0x08, 0x10, 0x42, 0x46, 0xb0, 0xf8, 0x70, 0x00, 0xbd, 0xf8, 0x0a, 0x10, + 0x40, 0x1a, 0xad, 0xf8, 0x0a, 0x00, 0x20, 0x68, 0xb0, 0xf9, 0x24, 0x10, + 0x02, 0xa8, 0xff, 0xf7, 0x81, 0xf9, 0x04, 0x99, 0x08, 0x43, 0x04, 0x90, + 0x61, 0x68, 0x02, 0x98, 0xc1, 0xf8, 0x6e, 0x00, 0x86, 0xf3, 0x11, 0x88, + 0x34, 0x21, 0xdf, 0xf8, 0x4c, 0x04, 0x01, 0xfb, 0x08, 0x06, 0x23, 0x46, + 0x30, 0x69, 0x40, 0x1c, 0x30, 0x61, 0xf0, 0x68, 0x40, 0x1c, 0xf0, 0x60, + 0x04, 0x9a, 0x02, 0x99, 0x03, 0x98, 0xcd, 0xf8, 0x00, 0x80, 0x00, 0xf0, + 0xf4, 0xf8, 0x20, 0x68, 0x30, 0xf8, 0x42, 0x1f, 0x69, 0xb1, 0x61, 0x68, + 0x40, 0x88, 0x01, 0xf1, 0x4c, 0x07, 0x05, 0xf0, 0x63, 0xfd, 0x01, 0x46, + 0xb8, 0x69, 0x05, 0xf0, 0xeb, 0xfe, 0x02, 0xd3, 0x38, 0x88, 0x08, 0x28, + 0x14, 0xdb, 0xff, 0xf7, 0xf3, 0xf8, 0x67, 0x68, 0xb9, 0x69, 0x80, 0x46, + 0x05, 0x98, 0x05, 0xf0, 0xf1, 0xfe, 0xb8, 0x61, 0xf9, 0x69, 0x05, 0x98, + 0x05, 0xf0, 0xec, 0xfe, 0xf8, 0x61, 0x39, 0x6a, 0x05, 0x98, 0x05, 0xf0, + 0xe7, 0xfe, 0x38, 0x62, 0x88, 0xf3, 0x11, 0x88, 0x00, 0xf0, 0xc4, 0xfe, + 0x64, 0x68, 0x04, 0xf1, 0x18, 0x08, 0xd8, 0xf8, 0x04, 0x10, 0xd8, 0xf8, + 0x08, 0x70, 0x00, 0xf0, 0xba, 0xf8, 0x00, 0xf0, 0xbb, 0xf8, 0x49, 0x46, + 0x05, 0xf0, 0x38, 0xfe, 0x05, 0xf0, 0x78, 0xfe, 0x01, 0x46, 0x0b, 0x98, + 0x05, 0xf0, 0xce, 0xfe, 0xd8, 0xf8, 0x00, 0x10, 0x05, 0xf0, 0x3c, 0xfd, + 0xb0, 0x61, 0xd8, 0xf8, 0x08, 0x00, 0xd8, 0xf8, 0x04, 0x10, 0x80, 0xf0, + 0x00, 0x40, 0x05, 0xf0, 0x63, 0xff, 0xf0, 0x61, 0xb8, 0xf8, 0x34, 0x00, + 0x30, 0x86, 0x34, 0xf9, 0x0e, 0x0f, 0x00, 0x28, 0x6a, 0xd1, 0x58, 0x46, + 0x59, 0x46, 0x05, 0xf0, 0xb5, 0xfe, 0x07, 0x46, 0x28, 0x46, 0x29, 0x46, + 0x05, 0xf0, 0xb0, 0xfe, 0x39, 0x46, 0x05, 0xf0, 0x11, 0xfe, 0x05, 0xf0, + 0x51, 0xfe, 0x05, 0x46, 0xb1, 0x6a, 0x4f, 0xf0, 0x7e, 0x50, 0x05, 0xf0, + 0x09, 0xfe, 0xb0, 0x62, 0x28, 0x46, 0x31, 0x6a, 0x05, 0xf0, 0x90, 0xfd, + 0xb1, 0x6a, 0x07, 0x46, 0x05, 0xf0, 0x0e, 0xfd, 0x31, 0x6a, 0x05, 0xf0, + 0xfd, 0xfd, 0x01, 0x46, 0x31, 0x62, 0x28, 0x46, 0x05, 0xf0, 0x84, 0xfd, + 0x00, 0xf0, 0x61, 0xf8, 0x71, 0x6a, 0x05, 0xf0, 0xf3, 0xfd, 0x70, 0x62, + 0xdf, 0xf8, 0x90, 0x17, 0xb0, 0x6a, 0x05, 0xf0, 0x91, 0xff, 0x39, 0xd8, + 0x01, 0x46, 0xdf, 0xf8, 0x70, 0x07, 0xdf, 0xf8, 0x48, 0x57, 0x05, 0xf0, + 0xe5, 0xfd, 0x01, 0x46, 0x70, 0x6a, 0x05, 0xf0, 0xef, 0xfc, 0x01, 0x46, + 0xf1, 0x62, 0xdf, 0xf8, 0x70, 0x07, 0x05, 0xf0, 0xdb, 0xfd, 0x01, 0x46, + 0xdf, 0xf8, 0x68, 0x07, 0x05, 0xf0, 0xe4, 0xfc, 0x05, 0xf0, 0xfe, 0xfe, + 0x05, 0xf0, 0xda, 0xfe, 0xb0, 0x60, 0x65, 0x28, 0x24, 0xbf, 0x64, 0x20, + 0xb0, 0x60, 0xb0, 0x6a, 0x29, 0x46, 0x05, 0xf0, 0x65, 0xfe, 0xdf, 0xf8, + 0x2c, 0x17, 0x05, 0xf0, 0xc5, 0xfd, 0x71, 0x6a, 0x05, 0xf0, 0x5e, 0xfe, + 0x07, 0x46, 0xb1, 0x6a, 0xdf, 0xf8, 0x18, 0x07, 0x05, 0xf0, 0xbc, 0xfd, + 0x01, 0x46, 0x38, 0x46, 0x05, 0xf0, 0xc6, 0xfc, 0x70, 0x62, 0x29, 0x46, + 0xb0, 0x6a, 0x05, 0xf0, 0x4f, 0xfe, 0xb0, 0x62, 0x04, 0x98, 0x20, 0xb1, + 0x01, 0x20, 0x60, 0x80, 0x70, 0x69, 0x40, 0x1c, 0x70, 0x61, 0x00, 0xf0, + 0x3c, 0xfe, 0x00, 0x20, 0x0d, 0xb0, 0xbd, 0xe8, 0xf0, 0x8f, 0x00, 0x00, + 0x48, 0xad, 0x00, 0x20, 0x24, 0x2b, 0x00, 0x20, 0x31, 0x46, 0x05, 0xf0, + 0x39, 0xbe, 0x58, 0x46, 0x49, 0x46, 0x05, 0xf0, 0x35, 0xbe, 0x01, 0x46, + 0x58, 0x46, 0x05, 0xf0, 0x21, 0xbd, 0x39, 0x46, 0x05, 0xf0, 0x2e, 0xbe, + 0x51, 0x46, 0x05, 0xf0, 0x9d, 0xbc, 0x39, 0x46, 0x05, 0xf0, 0x9a, 0xbc, + 0x01, 0x46, 0xdf, 0xf8, 0xd0, 0x06, 0x06, 0xf0, 0x9a, 0xb8, 0x00, 0x00, + 0xdc, 0x2a, 0x00, 0x20, 0x69, 0x68, 0x08, 0x46, 0x05, 0xf0, 0x1c, 0xbe, + 0x81, 0x46, 0x38, 0x46, 0x39, 0x46, 0x05, 0xf0, 0x17, 0xbe, 0x2d, 0xe9, + 0xfa, 0x4f, 0x83, 0xb0, 0x1e, 0x68, 0xd3, 0xf8, 0x04, 0x80, 0x22, 0xb1, + 0x40, 0x46, 0x05, 0xb0, 0xbd, 0xe8, 0xf0, 0x4f, 0xb6, 0xe0, 0x0e, 0x98, + 0x02, 0xf0, 0xb2, 0xf8, 0x08, 0xf1, 0x68, 0x05, 0x83, 0x46, 0xa9, 0x88, + 0xdf, 0xf8, 0x8c, 0x06, 0x09, 0x56, 0x02, 0x91, 0x1b, 0xf9, 0x00, 0x00, + 0x40, 0x1a, 0x7d, 0xd0, 0x28, 0x88, 0x00, 0x28, 0x7a, 0xd1, 0xb8, 0xf9, + 0x0c, 0x00, 0xe8, 0xb1, 0x04, 0x98, 0x40, 0x68, 0x02, 0x9a, 0x00, 0xf5, + 0x02, 0x74, 0xd4, 0xe9, 0x02, 0x01, 0x02, 0xf0, 0x35, 0xf9, 0xc0, 0x07, + 0x12, 0xd4, 0xd4, 0xe9, 0x02, 0x01, 0xcd, 0xe9, 0x00, 0x01, 0x02, 0x9a, + 0x01, 0x20, 0x00, 0x21, 0x06, 0xf0, 0x5c, 0xf8, 0xdd, 0xe9, 0x00, 0x23, + 0x10, 0x43, 0x19, 0x43, 0xc4, 0xe9, 0x02, 0x01, 0x00, 0x26, 0x4f, 0xf0, + 0x7e, 0x5a, 0x0d, 0xe0, 0xf0, 0x69, 0x05, 0xf0, 0x37, 0xfc, 0xdf, 0xf8, + 0x04, 0x16, 0x05, 0xf0, 0x43, 0xfc, 0x06, 0x46, 0x4f, 0xf0, 0x7e, 0x50, + 0x31, 0x46, 0x05, 0xf0, 0xbb, 0xfc, 0x82, 0x46, 0xb5, 0xf9, 0x0a, 0x00, + 0x44, 0x01, 0xb5, 0xf9, 0x0c, 0x00, 0x4f, 0xea, 0x40, 0x19, 0x02, 0x98, + 0x08, 0xeb, 0xc0, 0x07, 0x04, 0x98, 0x42, 0x68, 0xd2, 0xe9, 0x82, 0x01, + 0x02, 0x9a, 0x02, 0xf0, 0x01, 0xf9, 0xc0, 0x07, 0x2b, 0xd5, 0x20, 0x46, + 0x05, 0xf0, 0x0c, 0xfc, 0x01, 0x46, 0x50, 0x46, 0x05, 0xf0, 0xb0, 0xfd, + 0x04, 0x46, 0xb8, 0x6f, 0x05, 0xf0, 0x04, 0xfc, 0x01, 0x46, 0x30, 0x46, + 0x05, 0xf0, 0xa8, 0xfd, 0x01, 0x46, 0x20, 0x46, 0x05, 0xf0, 0x08, 0xfd, + 0x05, 0xf0, 0x0e, 0xfe, 0x04, 0x46, 0x48, 0x46, 0x05, 0xf0, 0xf6, 0xfb, + 0x01, 0x46, 0x50, 0x46, 0x05, 0xf0, 0x9a, 0xfd, 0x82, 0x46, 0xf8, 0x6f, + 0x05, 0xf0, 0xee, 0xfb, 0x01, 0x46, 0x30, 0x46, 0x05, 0xf0, 0x92, 0xfd, + 0x01, 0x46, 0x50, 0x46, 0x05, 0xf0, 0xf2, 0xfc, 0x05, 0xf0, 0xf8, 0xfd, + 0x81, 0x46, 0xfe, 0xf7, 0x85, 0xff, 0xbc, 0x67, 0x06, 0x46, 0xc7, 0xf8, + 0x7c, 0x90, 0x02, 0x98, 0x81, 0xb2, 0x04, 0x98, 0x00, 0xf0, 0xd6, 0xfa, + 0x86, 0xf3, 0x11, 0x88, 0x28, 0x88, 0x48, 0xb9, 0xfe, 0xf7, 0x76, 0xff, + 0x06, 0x46, 0x03, 0x98, 0xc8, 0xf8, 0x72, 0x00, 0xa5, 0xf8, 0x04, 0xb0, + 0x86, 0xf3, 0x11, 0x88, 0x01, 0x20, 0xe8, 0x81, 0x58, 0xe1, 0x38, 0xb5, + 0x14, 0x46, 0xdf, 0xf8, 0x64, 0x15, 0x4f, 0xf4, 0x08, 0x72, 0x02, 0xfb, + 0x00, 0x15, 0xff, 0xf7, 0x1b, 0xf8, 0x05, 0xf1, 0x68, 0x00, 0x01, 0x21, + 0x44, 0x80, 0x01, 0x80, 0x31, 0xbd, 0x00, 0x00, 0x04, 0x00, 0x00, 0x51, + 0x00, 0x00, 0x50, 0x59, 0x00, 0x00, 0x40, 0x59, 0x06, 0x40, 0x80, 0x83, + 0x07, 0x40, 0x00, 0x80, 0x00, 0xf5, 0x02, 0x70, 0x00, 0x22, 0xc0, 0xe9, + 0x00, 0x22, 0xc0, 0xe9, 0x02, 0x22, 0x70, 0x47, 0x70, 0xb5, 0x04, 0x46, + 0x0d, 0x46, 0x00, 0xf0, 0x59, 0xf8, 0x40, 0xf2, 0x42, 0x66, 0x88, 0xb3, + 0xdf, 0xf8, 0x14, 0x05, 0xb0, 0xf8, 0x54, 0x10, 0x28, 0x46, 0x03, 0xf0, + 0xa6, 0xfb, 0x08, 0xb1, 0x07, 0x20, 0x70, 0xbd, 0xdf, 0xf8, 0x04, 0x05, + 0x01, 0x78, 0x03, 0x22, 0x11, 0x42, 0x06, 0xd0, 0x00, 0x7e, 0x00, 0xf0, + 0x03, 0x00, 0x02, 0x28, 0x01, 0xd1, 0x06, 0x20, 0x70, 0xbd, 0xe8, 0xb2, + 0x02, 0xf0, 0xea, 0xfb, 0x00, 0x28, 0xe0, 0x60, 0x01, 0xd5, 0x08, 0x20, + 0x70, 0xbd, 0x00, 0x22, 0x10, 0x21, 0x30, 0x46, 0x01, 0xf0, 0x6c, 0xfe, + 0x08, 0x20, 0x04, 0xf0, 0x03, 0xf9, 0x08, 0xb1, 0x09, 0x20, 0x70, 0xbd, + 0xe0, 0x68, 0x04, 0xf0, 0xbc, 0xf8, 0x04, 0xf0, 0xdb, 0xf8, 0x00, 0xf0, + 0x1f, 0xf8, 0x13, 0xe0, 0xe5, 0x60, 0x01, 0x21, 0xe8, 0xb2, 0x04, 0xf0, + 0xfd, 0xf9, 0x04, 0xf0, 0x38, 0xfa, 0x00, 0xf0, 0x15, 0xf8, 0x00, 0x22, + 0x18, 0x21, 0x40, 0xf2, 0x7a, 0x60, 0x01, 0xf0, 0x4f, 0xfe, 0x00, 0x22, + 0x20, 0x21, 0x30, 0x46, 0x01, 0xf0, 0x4a, 0xfe, 0x00, 0x20, 0x70, 0xbd, + 0x68, 0x18, 0x00, 0x01, 0x00, 0x00, 0xc8, 0xc3, 0xc0, 0x01, 0x00, 0x45, + 0x98, 0xf1, 0x00, 0x20, 0xe0, 0x68, 0x80, 0x1c, 0x28, 0x21, 0x80, 0xb2, + 0x03, 0xf0, 0x46, 0xbf, 0x60, 0x68, 0xb0, 0xf9, 0x0c, 0x00, 0x70, 0x47, + 0x2d, 0xe9, 0xf0, 0x4f, 0xdf, 0xf8, 0x64, 0x04, 0x85, 0xb0, 0x80, 0x7a, + 0x00, 0xf0, 0x03, 0x00, 0x04, 0x90, 0x0c, 0x46, 0xdf, 0xf8, 0x58, 0x04, + 0x20, 0x60, 0x20, 0x46, 0x00, 0xf0, 0x8c, 0xf9, 0x05, 0x00, 0x40, 0xf0, + 0xc0, 0x80, 0x00, 0x26, 0x0f, 0xf2, 0x74, 0x4a, 0x04, 0x98, 0xf0, 0x40, + 0xc0, 0x07, 0x40, 0xf1, 0xb4, 0x80, 0x34, 0x20, 0x00, 0xfb, 0x06, 0xfb, + 0xdf, 0xf8, 0x34, 0x04, 0xdf, 0xf8, 0x30, 0x14, 0x0b, 0xeb, 0x00, 0x09, + 0x00, 0x20, 0x4b, 0xf8, 0x01, 0x00, 0xc9, 0xf8, 0x04, 0x00, 0x4f, 0xf4, + 0x08, 0x71, 0xdf, 0xf8, 0x08, 0x04, 0x01, 0xfb, 0x06, 0x00, 0x60, 0x60, + 0x00, 0x21, 0x81, 0x81, 0x01, 0x21, 0xc1, 0x81, 0x01, 0x82, 0x41, 0x82, + 0xff, 0xf7, 0x5e, 0xff, 0x60, 0x68, 0x00, 0x21, 0x20, 0xf8, 0x6e, 0x1f, + 0x41, 0x80, 0x32, 0x46, 0x21, 0x68, 0xb1, 0xf9, 0x24, 0x10, 0xfe, 0xf7, + 0x01, 0xff, 0x30, 0x46, 0x01, 0xf0, 0x4e, 0xff, 0x80, 0x46, 0x60, 0x68, + 0xa0, 0xf8, 0x6a, 0x80, 0x69, 0x46, 0x30, 0x46, 0x05, 0xf0, 0x28, 0xff, + 0xdd, 0xe9, 0x00, 0x01, 0xcd, 0xe9, 0x02, 0x01, 0x02, 0xaa, 0x00, 0x20, + 0x8d, 0xf8, 0x0a, 0x00, 0x01, 0x21, 0x30, 0x46, 0x05, 0xf0, 0x53, 0xff, + 0x20, 0x68, 0x90, 0xf8, 0x3a, 0x00, 0x3a, 0xf8, 0x10, 0x10, 0x00, 0xf0, + 0x79, 0xf8, 0x60, 0x8a, 0xe0, 0x82, 0x31, 0x46, 0x01, 0x20, 0x20, 0x82, + 0x00, 0xf0, 0xca, 0xf8, 0x05, 0x46, 0x02, 0x20, 0x20, 0x82, 0x31, 0x46, + 0x60, 0x8a, 0x00, 0x09, 0xe0, 0x82, 0x00, 0xf0, 0xc1, 0xf8, 0x05, 0xb9, + 0x05, 0x46, 0x20, 0x68, 0x90, 0xf8, 0x3a, 0x00, 0x47, 0x1c, 0x09, 0xe0, + 0x3a, 0xf8, 0x17, 0x10, 0x00, 0xf0, 0x5e, 0xf8, 0x01, 0x20, 0x00, 0xf0, + 0xb1, 0xf8, 0x05, 0xb9, 0x05, 0x46, 0x7f, 0x1c, 0x20, 0x68, 0x90, 0xf8, + 0x3b, 0x00, 0xbf, 0xb2, 0xb8, 0x42, 0xef, 0xd2, 0x07, 0x46, 0x12, 0xe0, + 0x20, 0x68, 0x90, 0xf8, 0x3b, 0x00, 0x02, 0xeb, 0xc0, 0x00, 0x00, 0xf1, + 0x70, 0x0c, 0x02, 0xeb, 0xc7, 0x02, 0xdc, 0xe9, 0x00, 0x01, 0x78, 0x32, + 0xc2, 0xe9, 0x00, 0x01, 0x39, 0x46, 0x20, 0x46, 0x00, 0xf0, 0xa4, 0xf9, + 0x7f, 0x1c, 0xbf, 0xb2, 0x62, 0x68, 0x32, 0x2f, 0xe8, 0xdb, 0xa2, 0xf8, + 0x6c, 0x80, 0x69, 0x46, 0x30, 0x46, 0x05, 0xf0, 0xef, 0xfe, 0x00, 0xf0, + 0x2e, 0xf8, 0x03, 0x20, 0x00, 0xf0, 0x84, 0xf8, 0x05, 0xb9, 0x05, 0x46, + 0x1d, 0xb9, 0x61, 0x68, 0x01, 0x20, 0xa1, 0xf8, 0x18, 0x02, 0x00, 0xf0, + 0x28, 0xf8, 0x30, 0xf8, 0x02, 0x1c, 0x00, 0xf0, 0x21, 0xf8, 0x00, 0xf0, + 0x1c, 0xf8, 0x00, 0xf0, 0x20, 0xf8, 0x30, 0xf8, 0x04, 0x1c, 0x00, 0xf0, + 0x19, 0xf8, 0x00, 0xf0, 0x14, 0xf8, 0x69, 0x46, 0x30, 0x46, 0x05, 0xf0, + 0xcf, 0xfe, 0x00, 0xf0, 0x0e, 0xf8, 0x64, 0x20, 0xc9, 0xf8, 0x04, 0x00, + 0xb6, 0x48, 0x4b, 0xf8, 0x00, 0x50, 0x76, 0x1c, 0x02, 0x2e, 0xff, 0xf4, + 0x43, 0xaf, 0x28, 0x46, 0x05, 0xb0, 0xbd, 0xe8, 0xf0, 0x8f, 0x30, 0x46, + 0xfe, 0xf7, 0xc6, 0xbe, 0x30, 0x46, 0x05, 0xf0, 0x1d, 0xbf, 0x20, 0x68, + 0x90, 0xf8, 0x3b, 0x00, 0x0a, 0xeb, 0x40, 0x00, 0x70, 0x47, 0x2d, 0xe9, + 0xf0, 0x47, 0x0c, 0x46, 0xa8, 0x48, 0xa7, 0x49, 0x20, 0x60, 0x49, 0x89, + 0xc0, 0x8f, 0x08, 0x40, 0x00, 0xf0, 0x03, 0x08, 0x20, 0x46, 0x00, 0xf0, + 0xab, 0xf8, 0x05, 0x00, 0x37, 0xd1, 0x00, 0x26, 0xdf, 0xf8, 0x88, 0xa2, + 0x28, 0xfa, 0x06, 0xf0, 0xc0, 0x07, 0x2d, 0xd5, 0x00, 0xf0, 0xd0, 0xfb, + 0x34, 0x20, 0x00, 0xfb, 0x06, 0xf9, 0x09, 0xeb, 0x0a, 0x07, 0x00, 0x20, + 0x78, 0x60, 0x49, 0xf8, 0x0a, 0x00, 0x00, 0xf0, 0xda, 0xfb, 0x94, 0x48, + 0x4f, 0xf4, 0x08, 0x71, 0x01, 0xfb, 0x06, 0x00, 0x60, 0x60, 0x01, 0x21, + 0x81, 0x81, 0xc1, 0x81, 0x21, 0x82, 0x31, 0x46, 0x60, 0x8a, 0xe0, 0x82, + 0x00, 0xf0, 0x1c, 0xf8, 0x05, 0x46, 0xa0, 0x8a, 0xe0, 0x82, 0x31, 0x46, + 0x02, 0x20, 0x20, 0x82, 0x00, 0xf0, 0x14, 0xf8, 0x05, 0xb9, 0x05, 0x46, + 0x00, 0xf0, 0xaa, 0xfb, 0x64, 0x20, 0x78, 0x60, 0x49, 0xf8, 0x0a, 0x50, + 0x00, 0xf0, 0xb9, 0xfb, 0x76, 0x1c, 0x02, 0x2e, 0xca, 0xd3, 0x28, 0x46, + 0xbd, 0xe8, 0xf0, 0x87, 0x49, 0x03, 0x00, 0x80, 0x20, 0x82, 0x31, 0x46, + 0x20, 0x46, 0xad, 0xe0, 0x2d, 0xe9, 0xf8, 0x43, 0x80, 0x46, 0x0d, 0x46, + 0x7f, 0x48, 0x80, 0x4f, 0x28, 0x60, 0x4f, 0xf4, 0x08, 0x71, 0x79, 0x48, + 0x01, 0xfb, 0x08, 0x00, 0x68, 0x60, 0x00, 0xf0, 0x89, 0xfb, 0x34, 0x20, + 0x00, 0xfb, 0x08, 0xf6, 0xf4, 0x19, 0x00, 0x20, 0x60, 0x60, 0xf0, 0x51, + 0x00, 0xf0, 0x95, 0xfb, 0x28, 0x46, 0x00, 0xf0, 0x4d, 0xf8, 0x5f, 0xea, + 0x00, 0x09, 0x2b, 0xd1, 0x68, 0x68, 0xb0, 0xf8, 0x18, 0x12, 0x11, 0xb9, + 0x4f, 0xf0, 0x04, 0x09, 0x24, 0xe0, 0x30, 0xf9, 0x0c, 0x1f, 0x00, 0x29, + 0x02, 0xbf, 0x29, 0x68, 0xb1, 0xf8, 0x40, 0x10, 0x00, 0x29, 0x10, 0xd1, + 0x01, 0x21, 0x01, 0x80, 0x03, 0x21, 0x29, 0x82, 0x00, 0x21, 0x41, 0x80, + 0x01, 0x20, 0x00, 0xf0, 0x1e, 0xf8, 0x81, 0x46, 0x02, 0x20, 0x00, 0xf0, + 0x1a, 0xf8, 0xb9, 0xf1, 0x00, 0x0f, 0x0b, 0xd1, 0x09, 0xe0, 0x01, 0x21, + 0x29, 0x82, 0x00, 0x21, 0x41, 0x80, 0x41, 0x46, 0xa8, 0x8a, 0xe8, 0x82, + 0x28, 0x46, 0x00, 0xf0, 0x65, 0xf8, 0x81, 0x46, 0x00, 0xf0, 0x4c, 0xfb, + 0x64, 0x20, 0x60, 0x60, 0x46, 0xf8, 0x07, 0x90, 0x00, 0xf0, 0x5b, 0xfb, + 0x48, 0x46, 0xbd, 0xe8, 0xf2, 0x83, 0x28, 0x82, 0x41, 0x46, 0x28, 0x46, + 0x54, 0xe0, 0x80, 0xb5, 0x53, 0x49, 0x56, 0x4a, 0x09, 0x6c, 0xa0, 0xfb, + 0x01, 0x01, 0x00, 0x23, 0x05, 0xf0, 0xc4, 0xfe, 0x04, 0xf0, 0x76, 0xfa, + 0xbd, 0xe8, 0x02, 0x40, 0x04, 0xf0, 0x68, 0xba, 0x70, 0xb5, 0x04, 0x46, + 0x00, 0x20, 0x02, 0xf0, 0x7b, 0xfd, 0x06, 0x46, 0x20, 0x68, 0x01, 0x88, + 0x0a, 0x25, 0x8e, 0x42, 0xb8, 0xbf, 0x0e, 0x46, 0x03, 0xdb, 0x40, 0x88, + 0xb0, 0x42, 0xb8, 0xbf, 0x06, 0x46, 0x10, 0x2e, 0x18, 0xdb, 0x40, 0xf2, + 0xee, 0x20, 0xff, 0xf7, 0xda, 0xff, 0x05, 0x46, 0xa6, 0xf1, 0x0f, 0x00, + 0xff, 0xf7, 0xd5, 0xff, 0x06, 0x46, 0x04, 0xf0, 0x53, 0xfa, 0x20, 0x83, + 0x20, 0x68, 0x41, 0x68, 0x69, 0x43, 0xb1, 0xfb, 0xf6, 0xf1, 0x61, 0x82, + 0x80, 0x68, 0x68, 0x43, 0xb0, 0xfb, 0xf6, 0xf0, 0xa0, 0x82, 0x00, 0x25, + 0x28, 0x46, 0x70, 0xbd, 0x70, 0xb5, 0x00, 0x24, 0x38, 0x4d, 0x31, 0x4e, + 0x4f, 0xf4, 0x08, 0x70, 0x22, 0x46, 0x01, 0x21, 0x00, 0xfb, 0x04, 0x60, + 0xfe, 0xf7, 0x16, 0xfd, 0x2b, 0x46, 0x00, 0x22, 0xe1, 0xb2, 0x00, 0x20, + 0x01, 0xf0, 0x7c, 0xfd, 0x64, 0x1c, 0x02, 0x2c, 0xee, 0xd3, 0x70, 0xbd, + 0x00, 0x01, 0x00, 0x45, 0x70, 0xb5, 0x04, 0x46, 0x0d, 0x46, 0x00, 0x20, + 0x05, 0xf0, 0x5b, 0xff, 0x90, 0xb1, 0x29, 0x46, 0x00, 0x20, 0x05, 0xf0, + 0x5b, 0xff, 0x06, 0x46, 0x32, 0x46, 0x29, 0x46, 0x20, 0x46, 0xff, 0xf7, + 0xae, 0xf9, 0x21, 0x8a, 0x49, 0x1e, 0x21, 0x82, 0x09, 0xb2, 0x01, 0x29, + 0x03, 0xdb, 0x00, 0x28, 0xf2, 0xd0, 0x70, 0xbd, 0x03, 0x20, 0x70, 0xbd, + 0x18, 0x49, 0xc2, 0x07, 0x44, 0xbf, 0x01, 0x22, 0x0a, 0x82, 0x80, 0x07, + 0x44, 0xbf, 0x01, 0x20, 0xa1, 0xf8, 0x30, 0x02, 0x70, 0x47, 0x00, 0x00, + 0xa4, 0x70, 0x7d, 0x3f, 0x11, 0x49, 0xc2, 0x07, 0x44, 0xbf, 0x01, 0x22, + 0x4a, 0x82, 0x80, 0x07, 0x44, 0xbf, 0x01, 0x20, 0xa1, 0xf8, 0x32, 0x02, + 0x70, 0x47, 0x00, 0x00, 0x00, 0x24, 0x74, 0x49, 0x00, 0x00, 0x7a, 0x44, + 0x00, 0x00, 0x80, 0xbf, 0x02, 0x56, 0xfd, 0x37, 0x00, 0x00, 0x34, 0x44, + 0x00, 0xa0, 0x8c, 0x47, 0xcd, 0xcc, 0x4c, 0x3d, 0x01, 0x00, 0x80, 0x3f, + 0xff, 0xe6, 0xdb, 0x2e, 0x00, 0x00, 0xc8, 0x42, 0x00, 0x00, 0x20, 0x41, + 0x24, 0x2b, 0x00, 0x20, 0x48, 0xad, 0x00, 0x20, 0x4c, 0x1f, 0x00, 0x20, + 0x48, 0x04, 0x00, 0x46, 0x78, 0x29, 0x00, 0x20, 0xdc, 0x2a, 0x00, 0x20, + 0x98, 0xf1, 0x00, 0x20, 0x80, 0x8d, 0x5b, 0x00, 0xbf, 0x12, 0x00, 0x01, + 0xd0, 0xb5, 0x44, 0x68, 0x0a, 0x46, 0xd4, 0xe9, 0x82, 0x67, 0x01, 0x20, + 0x00, 0x21, 0x05, 0xf0, 0x1b, 0xfd, 0x30, 0x43, 0x39, 0x43, 0xc4, 0xe9, + 0x82, 0x01, 0xd0, 0xbd, 0x42, 0x06, 0x7a, 0x06, 0x00, 0x00, 0x06, 0x00, + 0x0c, 0x00, 0x0f, 0x00, 0x15, 0x00, 0x1b, 0x00, 0x1e, 0x00, 0x24, 0x00, + 0x28, 0x00, 0x2f, 0x00, 0x32, 0x00, 0x37, 0x00, 0x3e, 0x00, 0x41, 0x00, + 0x46, 0x00, 0x4b, 0x00, 0x52, 0x00, 0x56, 0x00, 0x5b, 0x00, 0x60, 0x00, + 0x65, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x73, 0x00, 0x79, 0x00, 0x7e, 0x00, + 0x84, 0x00, 0x91, 0x00, 0x96, 0x00, 0x9d, 0x00, 0xab, 0x00, 0xba, 0x00, + 0xc3, 0x00, 0xd3, 0x00, 0xdd, 0x00, 0xe7, 0x00, 0xf1, 0x00, 0x09, 0x01, + 0x15, 0x01, 0x23, 0x01, 0x32, 0x01, 0x55, 0x01, 0x6b, 0x01, 0x83, 0x01, + 0x9d, 0x01, 0xbe, 0x01, 0xe2, 0x01, 0x14, 0x02, 0x5a, 0x02, 0xd3, 0x02, + 0xff, 0xfc, 0xf9, 0xf6, 0xf4, 0xf1, 0xfe, 0xfb, 0xf8, 0xf5, 0xf2, 0xef, + 0xfd, 0xfa, 0xf7, 0xfd, 0xfa, 0xf7, 0xf4, 0xf1, 0xee, 0xfd, 0xfa, 0xf7, + 0xf4, 0xf1, 0xee, 0xfd, 0xfa, 0xf7, 0xfe, 0xfb, 0xf8, 0xf5, 0xf2, 0xef, + 0xff, 0xfd, 0xfa, 0xf7, 0xfe, 0xfb, 0xf8, 0xf5, 0xf2, 0xef, 0xec, 0xfd, + 0xfb, 0xf8, 0xff, 0xfc, 0xf9, 0xf6, 0xf4, 0xfb, 0xf8, 0xf5, 0xf3, 0xf0, + 0xed, 0xea, 0xfd, 0xfa, 0xf7, 0xff, 0xfd, 0xfa, 0xf7, 0xf4, 0xfd, 0xfa, + 0xf7, 0xf4, 0xf1, 0xfa, 0xf7, 0xf4, 0xf1, 0xee, 0xec, 0xe9, 0xfe, 0xfb, + 0xf8, 0xf5, 0xff, 0xfc, 0xfa, 0xf7, 0xf4, 0xfe, 0xfb, 0xf8, 0xf5, 0xf2, + 0xfd, 0xfa, 0xf7, 0xf4, 0xf1, 0xfc, 0xf9, 0xf6, 0xf3, 0xff, 0xfc, 0xf9, + 0xf6, 0xf3, 0xff, 0xfc, 0xf9, 0xf6, 0xf3, 0xff, 0xfd, 0xfa, 0xf7, 0xf4, + 0xf1, 0xfe, 0xfb, 0xf8, 0xf5, 0xf2, 0xff, 0xfc, 0xf9, 0xf6, 0xf3, 0xf1, + 0xfe, 0xfb, 0xf8, 0xf5, 0xf3, 0xf0, 0xed, 0xea, 0xe7, 0xe4, 0xe2, 0xdf, + 0xdc, 0xfb, 0xf8, 0xf5, 0xf2, 0xf0, 0xff, 0xfc, 0xf9, 0xf6, 0xf3, 0xf1, + 0xee, 0xfe, 0xfb, 0xf8, 0xf5, 0xf2, 0xef, 0xec, 0xea, 0xe7, 0xe4, 0xe1, + 0xde, 0xdc, 0xd9, 0xfd, 0xfb, 0xf8, 0xf5, 0xf2, 0xef, 0xec, 0xe9, 0xe6, + 0xe4, 0xe1, 0xde, 0xdb, 0xd9, 0xd6, 0xfe, 0xfb, 0xf8, 0xf5, 0xf2, 0xef, + 0xec, 0xea, 0xe7, 0xfb, 0xf8, 0xf5, 0xf2, 0xf0, 0xed, 0xea, 0xe7, 0xe4, + 0xe1, 0xdf, 0xdc, 0xd9, 0xd6, 0xd4, 0xd1, 0xff, 0xfc, 0xf9, 0xf6, 0xf4, + 0xf1, 0xee, 0xeb, 0xe8, 0xe5, 0xfd, 0xfa, 0xf8, 0xf5, 0xf2, 0xef, 0xec, + 0xe9, 0xe6, 0xe4, 0xfd, 0xfa, 0xf7, 0xf4, 0xf2, 0xef, 0xec, 0xe9, 0xe6, + 0xe3, 0xff, 0xfc, 0xf9, 0xf6, 0xf3, 0xf0, 0xed, 0xeb, 0xe8, 0xe5, 0xe2, + 0xdf, 0xdd, 0xda, 0xd7, 0xd4, 0xd2, 0xcf, 0xcc, 0xca, 0xc7, 0xc4, 0xc2, + 0xbf, 0xfc, 0xf9, 0xf7, 0xf4, 0xf1, 0xee, 0xeb, 0xe8, 0xe5, 0xe3, 0xe0, + 0xdd, 0xff, 0xfc, 0xf9, 0xf6, 0xf3, 0xf0, 0xee, 0xeb, 0xe8, 0xe5, 0xe2, + 0xe0, 0xdd, 0xda, 0xff, 0xfc, 0xf9, 0xf6, 0xf3, 0xf0, 0xed, 0xea, 0xe8, + 0xe5, 0xe2, 0xdf, 0xdd, 0xda, 0xd7, 0xff, 0xfc, 0xf9, 0xf6, 0xf3, 0xf0, + 0xee, 0xeb, 0xe8, 0xe5, 0xe2, 0xe0, 0xdd, 0xda, 0xd7, 0xd5, 0xd2, 0xcf, + 0xcd, 0xca, 0xc7, 0xc5, 0xc2, 0xc0, 0xbd, 0xba, 0xb8, 0xb5, 0xb3, 0xb0, + 0xae, 0xab, 0xa9, 0xa6, 0xa4, 0xff, 0xfc, 0xf9, 0xf6, 0xf3, 0xf0, 0xed, + 0xea, 0xe8, 0xe5, 0xe2, 0xdf, 0xdc, 0xda, 0xd7, 0xd4, 0xd2, 0xcf, 0xcc, + 0xca, 0xc7, 0xc4, 0xfa, 0xf7, 0xf4, 0xf1, 0xef, 0xec, 0xe9, 0xe6, 0xe3, + 0xe0, 0xde, 0xdb, 0xd8, 0xd6, 0xd3, 0xd0, 0xcd, 0xcb, 0xc8, 0xc6, 0xc3, + 0xc0, 0xbe, 0xbb, 0xf8, 0xf5, 0xf2, 0xef, 0xec, 0xe9, 0xe7, 0xe4, 0xe1, + 0xde, 0xdc, 0xd9, 0xd6, 0xd3, 0xd1, 0xce, 0xcb, 0xc9, 0xc6, 0xc3, 0xc1, + 0xbe, 0xbc, 0xb9, 0xb7, 0xb4, 0xfa, 0xf7, 0xf4, 0xf1, 0xee, 0xec, 0xe9, + 0xe6, 0xe3, 0xe0, 0xde, 0xdb, 0xd8, 0xd5, 0xd3, 0xd0, 0xcd, 0xcb, 0xc8, + 0xc6, 0xc3, 0xc0, 0xbe, 0xbb, 0xb9, 0xb6, 0xb4, 0xb1, 0xaf, 0xac, 0xaa, + 0xa7, 0xa5, 0xf6, 0xf3, 0xf0, 0xee, 0xeb, 0xe8, 0xe5, 0xe2, 0xe0, 0xdd, + 0xda, 0xd7, 0xd5, 0xd2, 0xcf, 0xcd, 0xca, 0xc7, 0xc5, 0xc2, 0xbf, 0xbd, + 0xba, 0xb8, 0xb5, 0xb3, 0xb0, 0xae, 0xab, 0xa9, 0xa6, 0xa4, 0xa2, 0x9f, + 0x9d, 0x9a, 0xfe, 0xfb, 0xf8, 0xf5, 0xf3, 0xf0, 0xed, 0xea, 0xe7, 0xe4, + 0xe2, 0xdf, 0xdc, 0xd9, 0xd7, 0xd4, 0xd1, 0xcf, 0xcc, 0xc9, 0xc7, 0xc4, + 0xc1, 0xbf, 0xbc, 0xba, 0xb7, 0xb5, 0xb2, 0xb0, 0xad, 0xab, 0xa8, 0xa6, + 0xa3, 0xa1, 0x9f, 0x9c, 0x9a, 0x97, 0x95, 0x93, 0x90, 0x8e, 0x8c, 0x8a, + 0x87, 0x85, 0x83, 0x81, 0xfe, 0xfb, 0xf8, 0xf5, 0xf3, 0xf0, 0xed, 0xea, + 0xe7, 0xe4, 0xe2, 0xdf, 0xdc, 0xd9, 0xd7, 0xd4, 0xd1, 0xcf, 0xcc, 0xc9, + 0xc7, 0xc4, 0xc1, 0xbf, 0xbc, 0xba, 0xb7, 0xb5, 0xb2, 0xb0, 0xad, 0xab, + 0xa8, 0xa6, 0xa3, 0xa1, 0x9f, 0x9c, 0x9a, 0x97, 0x95, 0x93, 0x90, 0x8e, + 0x8c, 0x8a, 0x87, 0x85, 0x83, 0x81, 0x7e, 0x7c, 0x7a, 0x78, 0x76, 0x73, + 0x71, 0x6f, 0x6d, 0x6b, 0x69, 0x67, 0x65, 0x63, 0x61, 0x5f, 0x5d, 0x5b, + 0x59, 0x57, 0xff, 0xfc, 0xfa, 0xf7, 0xf4, 0xf1, 0xee, 0xeb, 0xe8, 0xe6, + 0xe3, 0xe0, 0xdd, 0xda, 0xd8, 0xd5, 0xd2, 0xd0, 0xcd, 0xca, 0xc8, 0xc5, + 0xc3, 0xc0, 0xbd, 0xbb, 0xb8, 0xb6, 0xb3, 0xb1, 0xae, 0xac, 0xa9, 0xa7, + 0xa4, 0xa2, 0xa0, 0x9d, 0x9b, 0x98, 0x96, 0x94, 0x91, 0x8f, 0x8d, 0x8b, + 0x88, 0x86, 0x84, 0x82, 0x7f, 0x7d, 0x7b, 0x79, 0x77, 0x74, 0x72, 0x70, + 0x6e, 0x6c, 0x6a, 0x68, 0x66, 0x64, 0x62, 0x60, 0x5e, 0x5c, 0x5a, 0x58, + 0x56, 0x54, 0x52, 0x50, 0x4e, 0x4c, 0x4a, 0x48, 0x46, 0x44, 0x42, 0x41, + 0x3f, 0x3d, 0x3b, 0x39, 0x37, 0x36, 0x34, 0x32, 0x30, 0x2f, 0x2d, 0x2b, + 0x29, 0x28, 0x26, 0x24, 0x23, 0x21, 0x1f, 0x1e, 0x1c, 0x1a, 0x19, 0x17, + 0x15, 0x14, 0x12, 0x11, 0x0f, 0x0e, 0x0c, 0x0b, 0x09, 0x07, 0x06, 0x04, + 0x03, 0x01, 0x00, 0xfe, 0xfb, 0xf8, 0xf5, 0xf2, 0xef, 0xec, 0xea, 0xe7, + 0xe4, 0xe1, 0xde, 0xdc, 0xd9, 0xd6, 0xd3, 0xd1, 0xce, 0xcb, 0xc9, 0xc6, + 0xc4, 0xc1, 0xbe, 0xbc, 0xb9, 0xb7, 0xb4, 0xb2, 0xaf, 0xad, 0xaa, 0xa8, + 0xa5, 0xa3, 0xa1, 0x9e, 0x9c, 0x99, 0x97, 0x95, 0x92, 0x90, 0x8e, 0x8b, + 0x89, 0x87, 0x85, 0x82, 0x80, 0x7e, 0x7c, 0x7a, 0x77, 0x75, 0x73, 0x71, + 0x6f, 0x6d, 0x6b, 0x69, 0x67, 0x64, 0x62, 0x60, 0x5e, 0x5c, 0x5a, 0x58, + 0x56, 0x54, 0x52, 0x50, 0x4f, 0x4d, 0x4b, 0x49, 0x47, 0x45, 0x43, 0x41, + 0x3f, 0x3e, 0x3c, 0x3a, 0x38, 0x36, 0x35, 0x33, 0x31, 0x2f, 0x2e, 0x2c, + 0x2a, 0x28, 0x27, 0x25, 0x23, 0x22, 0x20, 0x1e, 0x1d, 0x1b, 0x19, 0x18, + 0x16, 0x15, 0x13, 0x11, 0x10, 0x0e, 0x0d, 0x0b, 0x0a, 0x08, 0x07, 0x00, + 0x70, 0xb5, 0x86, 0xb0, 0x05, 0xf0, 0xac, 0xfe, 0xdf, 0xf8, 0x14, 0x19, + 0xdf, 0xf8, 0x14, 0x49, 0x00, 0x20, 0x08, 0x60, 0x20, 0x70, 0x60, 0x70, + 0xa0, 0x71, 0x60, 0x71, 0x20, 0x61, 0xe0, 0x61, 0x20, 0x72, 0x20, 0x71, + 0x00, 0x21, 0x04, 0xf1, 0x0c, 0x00, 0xa1, 0x70, 0x01, 0x60, 0xe1, 0x70, + 0xa1, 0x62, 0x21, 0x62, 0x04, 0xf5, 0x45, 0x75, 0x4f, 0xf4, 0xfc, 0x61, + 0x28, 0x46, 0x00, 0xf0, 0x78, 0xf9, 0x64, 0x21, 0x04, 0xf1, 0x30, 0x00, + 0x00, 0xf0, 0x73, 0xf9, 0x00, 0x20, 0xad, 0xa1, 0x54, 0x22, 0x02, 0xfb, + 0x00, 0x43, 0x03, 0xf5, 0x45, 0x76, 0x40, 0x1c, 0x03, 0xf5, 0x5a, 0x73, + 0x17, 0x28, 0x73, 0x61, 0xf1, 0x64, 0xf4, 0xd3, 0x02, 0xfb, 0x00, 0x40, + 0x00, 0xf5, 0x45, 0x70, 0x00, 0x22, 0x42, 0x61, 0xc1, 0x64, 0x65, 0x62, + 0xe2, 0x62, 0x04, 0xf1, 0x94, 0x05, 0x4f, 0xf4, 0xa0, 0x71, 0x28, 0x46, + 0x00, 0xf0, 0x55, 0xf9, 0x00, 0x20, 0x00, 0x23, 0x04, 0xeb, 0x00, 0x11, + 0x01, 0xf1, 0x94, 0x02, 0x40, 0x1c, 0xa4, 0x31, 0x13, 0x28, 0x13, 0x70, + 0x51, 0x60, 0xf5, 0xd3, 0x04, 0xeb, 0x00, 0x10, 0x00, 0xf8, 0x94, 0x3f, + 0x43, 0x60, 0x65, 0x61, 0x00, 0xf0, 0xea, 0xfb, 0x00, 0xf0, 0x5c, 0xfd, + 0x03, 0x21, 0x04, 0x91, 0x00, 0x21, 0x03, 0x91, 0x80, 0x21, 0x02, 0x91, + 0x4f, 0xf6, 0xff, 0x71, 0xdf, 0xf8, 0x64, 0x08, 0x01, 0x90, 0x00, 0x91, + 0x00, 0xf5, 0xfe, 0x72, 0x18, 0x23, 0x00, 0x21, 0x0f, 0xf2, 0xc1, 0x30, + 0x00, 0xf0, 0x0d, 0xfe, 0x05, 0xaa, 0x0f, 0xf2, 0x14, 0x01, 0x18, 0x20, + 0x00, 0xf0, 0xbe, 0xfe, 0x01, 0xf0, 0x74, 0xf8, 0xc0, 0x46, 0xc0, 0x46, + 0x06, 0xb0, 0x70, 0xbd, 0x75, 0x43, 0x2f, 0x4f, 0x53, 0x2d, 0x49, 0x49, + 0x20, 0x49, 0x64, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x38, 0xb5, 0x00, 0xf0, + 0x31, 0xf8, 0x1e, 0xd1, 0x05, 0xf0, 0x9a, 0xfe, 0x05, 0x46, 0x20, 0x78, + 0x08, 0xb1, 0x40, 0x1e, 0x20, 0x70, 0x20, 0x78, 0x61, 0x78, 0x08, 0x43, + 0x11, 0xd1, 0x00, 0xf0, 0x2c, 0xf9, 0xe0, 0x78, 0xa2, 0x78, 0x04, 0xeb, + 0x80, 0x01, 0x90, 0x42, 0x09, 0x6b, 0xa1, 0x62, 0x07, 0xd0, 0x88, 0x6b, + 0x40, 0x1c, 0x88, 0x63, 0x20, 0x69, 0x40, 0x1c, 0x20, 0x61, 0x05, 0xf0, + 0x9a, 0xfe, 0x28, 0x46, 0x15, 0xe1, 0x31, 0xbd, 0x10, 0xb5, 0x00, 0xf0, + 0x0d, 0xf8, 0x0a, 0xd1, 0x05, 0xf0, 0x76, 0xfe, 0x21, 0x78, 0x21, 0xb9, + 0x61, 0x78, 0xff, 0x29, 0x1c, 0xbf, 0x49, 0x1c, 0x61, 0x70, 0x00, 0xf0, + 0xe3, 0xbe, 0x10, 0xbd, 0xdf, 0xf8, 0xb4, 0x47, 0x60, 0x79, 0x01, 0x28, + 0x70, 0x47, 0x10, 0xb5, 0xff, 0xf7, 0xf8, 0xff, 0x10, 0xd1, 0x05, 0xf0, + 0x61, 0xfe, 0x21, 0x78, 0x51, 0xb9, 0x61, 0x78, 0x41, 0xb1, 0x49, 0x1e, + 0x61, 0x70, 0xc9, 0xb2, 0x21, 0xb9, 0x80, 0xf3, 0x11, 0x88, 0xbd, 0xe8, + 0x10, 0x40, 0xcf, 0xe0, 0x00, 0xf0, 0xc8, 0xbe, 0x10, 0xbd, 0x10, 0xb5, + 0xdf, 0xf8, 0x7c, 0x47, 0x60, 0x79, 0x60, 0xb9, 0x00, 0xf0, 0xe7, 0xf8, + 0xe0, 0x78, 0xa0, 0x70, 0x04, 0xeb, 0x80, 0x00, 0x00, 0x6b, 0xa0, 0x62, + 0x20, 0x62, 0xbd, 0xe8, 0x10, 0x40, 0x05, 0xf0, 0x48, 0xbe, 0x10, 0xbd, + 0x70, 0xb5, 0x05, 0xf0, 0x14, 0xfe, 0x05, 0xf0, 0x39, 0xfe, 0xdf, 0xf8, + 0x4c, 0x17, 0xdf, 0xf8, 0x4c, 0x47, 0x0a, 0x68, 0x52, 0x1c, 0x0a, 0x60, + 0x80, 0xf3, 0x11, 0x88, 0x60, 0x79, 0x01, 0x28, 0x35, 0xd1, 0xe0, 0x79, + 0x38, 0xb1, 0x02, 0x28, 0x01, 0xd0, 0x30, 0xd3, 0x01, 0xe0, 0x01, 0x20, + 0x00, 0xe0, 0x00, 0x20, 0xe0, 0x71, 0xe6, 0x6a, 0x12, 0xe0, 0x69, 0x77, + 0x29, 0x7f, 0x09, 0x07, 0x0b, 0xd4, 0x06, 0xf1, 0x34, 0x01, 0x22, 0x79, + 0x8b, 0x78, 0x1a, 0x43, 0x22, 0x71, 0x0a, 0x78, 0x49, 0x78, 0x12, 0x19, + 0x13, 0x7b, 0x19, 0x43, 0x11, 0x73, 0x2e, 0x68, 0x80, 0xf3, 0x11, 0x88, + 0x06, 0xf1, 0x14, 0x05, 0xa8, 0x7f, 0x18, 0x28, 0x11, 0xd0, 0x05, 0xf0, + 0x07, 0xfe, 0xa9, 0x69, 0x00, 0x29, 0xf2, 0xd0, 0x49, 0x1e, 0xa9, 0x61, + 0xef, 0xd1, 0x29, 0x7f, 0x37, 0x22, 0x11, 0x42, 0x1d, 0xbf, 0x01, 0xf0, + 0xc8, 0x01, 0x29, 0x77, 0x01, 0x21, 0x00, 0x21, 0xd5, 0xe7, 0x70, 0xbd, + 0xf8, 0xb5, 0x85, 0x7a, 0x0f, 0xf2, 0x38, 0x14, 0xdf, 0xf8, 0xc0, 0x76, + 0x2e, 0x5d, 0x35, 0x18, 0x4f, 0xf0, 0x00, 0x0e, 0xed, 0x7a, 0x2c, 0x5d, + 0x04, 0xeb, 0xc6, 0x05, 0xed, 0xb2, 0x07, 0xeb, 0x85, 0x04, 0x24, 0x6b, + 0x04, 0xf1, 0x20, 0x0c, 0xcc, 0xf8, 0x00, 0x10, 0xcc, 0xf8, 0x0c, 0xe0, + 0x8c, 0xf8, 0x11, 0x30, 0x9c, 0xf8, 0x10, 0x10, 0x91, 0x43, 0x8c, 0xf8, + 0x10, 0x10, 0x9c, 0xf8, 0x10, 0x10, 0x09, 0x07, 0x0a, 0xd4, 0x39, 0x79, + 0x9c, 0xf8, 0x16, 0x20, 0x11, 0x43, 0x39, 0x71, 0xf1, 0x19, 0x9c, 0xf8, + 0x15, 0x30, 0x0a, 0x7b, 0x1a, 0x43, 0x0a, 0x73, 0x01, 0x46, 0x20, 0x46, + 0x00, 0xf0, 0x26, 0xf8, 0x28, 0x46, 0xf2, 0xbd, 0x10, 0xb5, 0xdf, 0xf8, + 0x60, 0x16, 0x0a, 0x6a, 0x42, 0xf8, 0x1c, 0x0f, 0x13, 0x7e, 0x52, 0x7e, + 0x1b, 0x18, 0xdc, 0x7a, 0x22, 0x43, 0xda, 0x72, 0x0b, 0x6a, 0x82, 0x7a, + 0x93, 0xf8, 0x36, 0x30, 0x1a, 0x43, 0x82, 0x72, 0x08, 0x6a, 0x10, 0xf8, + 0x34, 0x2f, 0x44, 0x78, 0x52, 0x18, 0x13, 0x7b, 0xa3, 0x43, 0x13, 0x73, + 0x04, 0xd1, 0x0a, 0x79, 0x80, 0x78, 0x22, 0xea, 0x00, 0x00, 0x08, 0x71, + 0x10, 0xbd, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x10, 0xb5, 0x10, 0xf8, + 0x34, 0x2f, 0x44, 0x78, 0x52, 0x18, 0xd3, 0x7a, 0xa3, 0x43, 0xd3, 0x72, + 0x04, 0xd1, 0x8a, 0x7a, 0x80, 0x78, 0x22, 0xea, 0x00, 0x00, 0x88, 0x72, + 0x10, 0xbd, 0x00, 0x21, 0x81, 0x72, 0x0b, 0x30, 0x04, 0x21, 0x01, 0xf0, + 0x2f, 0xb8, 0x00, 0x29, 0x18, 0xbf, 0x01, 0xf0, 0x2b, 0xb8, 0x70, 0x47, + 0x38, 0xb5, 0x05, 0xf0, 0x81, 0xfd, 0xdf, 0xf8, 0xe0, 0x55, 0x69, 0x78, + 0x04, 0x46, 0x28, 0x78, 0x08, 0x43, 0x11, 0xd1, 0x00, 0xf0, 0x15, 0xf8, + 0xe8, 0x78, 0xaa, 0x78, 0x05, 0xeb, 0x80, 0x01, 0x90, 0x42, 0x09, 0x6b, + 0xa9, 0x62, 0x07, 0xd0, 0x88, 0x6b, 0x40, 0x1c, 0x88, 0x63, 0x28, 0x69, + 0x40, 0x1c, 0x28, 0x61, 0x05, 0xf0, 0x7f, 0xfd, 0x20, 0x46, 0xbd, 0xe8, + 0x32, 0x40, 0x05, 0xf0, 0x69, 0xbd, 0xdf, 0xf8, 0xa4, 0x05, 0x0f, 0xf2, + 0x14, 0x01, 0x02, 0x79, 0x52, 0x5c, 0x13, 0x18, 0x1b, 0x7b, 0x59, 0x5c, + 0x01, 0xeb, 0xc2, 0x01, 0xc1, 0x70, 0x70, 0x47, 0x00, 0x00, 0x01, 0x00, + 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, + 0x02, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, + 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x06, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, + 0x02, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, + 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, + 0x02, 0x00, 0x01, 0x00, 0x07, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, + 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x05, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, + 0x02, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x06, 0x00, 0x01, 0x00, + 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, + 0x02, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, + 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x80, 0xb5, 0x05, 0xf0, 0xd3, 0xfc, 0xdf, 0xf8, 0x84, 0x14, 0xca, 0x69, + 0x52, 0x1c, 0xca, 0x61, 0x80, 0xf3, 0x11, 0x88, 0x05, 0xf0, 0x60, 0xfc, + 0xf3, 0xe7, 0x2d, 0xe9, 0xf8, 0x43, 0x04, 0x46, 0x0f, 0x46, 0x91, 0x46, + 0x98, 0x46, 0x05, 0xf0, 0xc1, 0xfc, 0xdf, 0xf8, 0x60, 0x54, 0x6e, 0x6a, + 0x00, 0x2e, 0x58, 0xd0, 0x71, 0x69, 0x69, 0x62, 0x80, 0xf3, 0x11, 0x88, + 0x37, 0x60, 0x00, 0x20, 0x06, 0xf1, 0x30, 0x07, 0xbc, 0x70, 0x38, 0x70, + 0x78, 0x70, 0xf0, 0x62, 0x01, 0x22, 0x09, 0x98, 0x70, 0x60, 0x04, 0xf0, + 0x07, 0x01, 0x08, 0x98, 0xf0, 0x60, 0xc6, 0xf8, 0x08, 0x90, 0x0a, 0x98, + 0x30, 0x82, 0xa6, 0xf8, 0x12, 0x80, 0x00, 0x20, 0xf8, 0x71, 0xf9, 0x70, + 0xe0, 0x08, 0x38, 0x71, 0x02, 0xfa, 0x00, 0xf0, 0xb8, 0x71, 0x02, 0xfa, + 0x01, 0xf0, 0x78, 0x71, 0x00, 0x20, 0xf0, 0x61, 0x70, 0x62, 0x30, 0x62, + 0xb8, 0x60, 0x38, 0x61, 0xf8, 0x60, 0x78, 0x61, 0xb8, 0x61, 0x4d, 0xa0, + 0xf8, 0x61, 0x00, 0x20, 0x38, 0x62, 0x30, 0x46, 0x05, 0xf0, 0x5f, 0xfc, + 0x05, 0xf0, 0x86, 0xfc, 0x05, 0xeb, 0x84, 0x01, 0x0e, 0x63, 0x80, 0xf3, + 0x11, 0x88, 0x30, 0x46, 0x05, 0xf0, 0x10, 0xfc, 0x05, 0xf0, 0x7c, 0xfc, + 0xe9, 0x6a, 0x71, 0x61, 0x00, 0x21, 0xb1, 0x61, 0xe9, 0x6a, 0x01, 0xb1, + 0x8e, 0x61, 0xee, 0x62, 0x29, 0x79, 0xba, 0x79, 0x11, 0x43, 0x29, 0x71, + 0x39, 0x79, 0x7b, 0x79, 0x49, 0x19, 0x0a, 0x7b, 0x1a, 0x43, 0x0a, 0x73, + 0xa9, 0x79, 0x49, 0x1c, 0xa9, 0x71, 0x80, 0xf3, 0x11, 0x88, 0x00, 0x20, + 0x02, 0xe0, 0x80, 0xf3, 0x11, 0x88, 0x42, 0x20, 0xbd, 0xe8, 0xf2, 0x83, + 0x00, 0x00, 0x00, 0x00, 0x2d, 0xe9, 0xf0, 0x41, 0x05, 0x46, 0x88, 0x46, + 0x28, 0x78, 0x05, 0x28, 0x17, 0x46, 0x1c, 0x46, 0x02, 0xd0, 0x00, 0xf0, + 0x7c, 0xfa, 0x36, 0xe0, 0x38, 0x06, 0x46, 0xbf, 0x07, 0xf0, 0x7f, 0x07, + 0x01, 0x26, 0x00, 0x26, 0x00, 0x20, 0x20, 0x70, 0x05, 0xf0, 0x46, 0xfc, + 0x03, 0x2f, 0x24, 0xd8, 0xdf, 0xe8, 0x07, 0xf0, 0x15, 0x1b, 0x02, 0x0c, + 0x29, 0x89, 0x08, 0xea, 0x01, 0x07, 0x47, 0x45, 0x08, 0xd0, 0x70, 0x21, + 0x21, 0x70, 0x80, 0xf3, 0x11, 0x88, 0x1b, 0xe0, 0x29, 0x89, 0x18, 0xea, + 0x01, 0x07, 0xf6, 0xd0, 0x00, 0x2e, 0xf6, 0xd0, 0xb9, 0x43, 0x29, 0x81, + 0xf3, 0xe7, 0x29, 0x89, 0x28, 0xea, 0x01, 0x07, 0x47, 0x45, 0xec, 0xd1, + 0x03, 0xe0, 0x29, 0x89, 0x38, 0xea, 0x01, 0x07, 0xe7, 0xd0, 0x00, 0x2e, + 0xe7, 0xd0, 0x39, 0x43, 0xef, 0xe7, 0x80, 0xf3, 0x11, 0x88, 0x6f, 0x20, + 0x00, 0x27, 0x20, 0x70, 0x38, 0x46, 0xbd, 0xe8, 0xf0, 0x81, 0xf8, 0xb5, + 0xdf, 0xf8, 0x08, 0x73, 0x06, 0x46, 0x38, 0x78, 0x0c, 0x46, 0x10, 0xb1, + 0x10, 0x20, 0x00, 0xf0, 0xb2, 0xbd, 0x05, 0xf0, 0x0b, 0xfc, 0xb9, 0x69, + 0x0d, 0x00, 0x0c, 0xd0, 0x49, 0x68, 0xb9, 0x61, 0x05, 0x21, 0x29, 0x70, + 0x2e, 0x81, 0x00, 0x21, 0x69, 0x60, 0x06, 0xa1, 0xe9, 0x60, 0x80, 0xf3, + 0x11, 0x88, 0x00, 0x20, 0x02, 0xe0, 0x80, 0xf3, 0x11, 0x88, 0x72, 0x20, + 0xff, 0xe7, 0x20, 0x70, 0x28, 0x46, 0xf2, 0xbd, 0x3f, 0x00, 0x00, 0x00, + 0x2d, 0xe9, 0xf8, 0x4f, 0x86, 0xb0, 0xdf, 0xf8, 0x3c, 0x65, 0x10, 0x9d, + 0x04, 0x46, 0x30, 0x78, 0x8a, 0x46, 0x93, 0x46, 0x08, 0xb1, 0x02, 0x20, + 0x7a, 0xe0, 0x70, 0x78, 0x08, 0xb1, 0x0d, 0x20, 0x76, 0xe0, 0x20, 0x78, + 0x05, 0x28, 0x18, 0xbf, 0x01, 0x20, 0x71, 0xd1, 0x5f, 0xea, 0x0b, 0x60, + 0x46, 0xbf, 0x0b, 0xf0, 0x7f, 0x0b, 0x4f, 0xf0, 0x01, 0x08, 0x4f, 0xf0, + 0x00, 0x08, 0x05, 0xf0, 0xd1, 0xfb, 0xbb, 0xf1, 0x03, 0x0f, 0x81, 0x46, + 0x5f, 0xd8, 0xdf, 0xe8, 0x0b, 0xf0, 0x33, 0x39, 0x02, 0x2a, 0x20, 0x89, + 0x0a, 0xea, 0x00, 0x07, 0x57, 0x45, 0x26, 0xd0, 0x06, 0x98, 0x00, 0x90, + 0x5b, 0x46, 0x52, 0x46, 0x01, 0xa9, 0x20, 0x46, 0x00, 0xf0, 0xae, 0xf8, + 0x00, 0xf0, 0x30, 0xf9, 0xff, 0xf7, 0x34, 0xfe, 0x05, 0xf0, 0xb6, 0xfb, + 0x81, 0x46, 0x30, 0x6a, 0x28, 0x30, 0x47, 0x7a, 0x57, 0xb3, 0x00, 0x21, + 0x41, 0x72, 0x01, 0xa8, 0x00, 0xf0, 0x0b, 0xf9, 0x31, 0x6a, 0x00, 0x20, + 0x81, 0xf8, 0x30, 0x00, 0x00, 0xf0, 0x1c, 0xf9, 0x02, 0x2f, 0x14, 0xbf, + 0x0a, 0x20, 0x0e, 0x20, 0x36, 0xe0, 0x20, 0x89, 0x1a, 0xea, 0x00, 0x07, + 0xd8, 0xd0, 0xb8, 0xf1, 0x00, 0x0f, 0x10, 0xd0, 0xb8, 0x43, 0x0d, 0xe0, + 0x20, 0x89, 0x2a, 0xea, 0x00, 0x07, 0x57, 0x45, 0xce, 0xd1, 0x03, 0xe0, + 0x20, 0x89, 0x3a, 0xea, 0x00, 0x07, 0xc9, 0xd0, 0xb8, 0xf1, 0x00, 0x0f, + 0x01, 0xd0, 0x38, 0x43, 0x20, 0x81, 0x30, 0x6a, 0x07, 0x85, 0x0d, 0xe0, + 0x07, 0x88, 0xb8, 0xf1, 0x00, 0x0f, 0x09, 0xd0, 0xbb, 0xf1, 0x01, 0x0f, + 0x0e, 0xd9, 0xab, 0xf1, 0x02, 0x00, 0x01, 0x28, 0x0d, 0xd8, 0x20, 0x89, + 0xb8, 0x43, 0x20, 0x81, 0x00, 0xf0, 0xec, 0xf8, 0x00, 0x20, 0x28, 0x70, + 0x38, 0x46, 0x07, 0xb0, 0xbd, 0xe8, 0xf0, 0x8f, 0x20, 0x89, 0x38, 0x43, + 0xf3, 0xe7, 0x00, 0xf0, 0xe1, 0xf8, 0x6f, 0x20, 0x28, 0x70, 0x00, 0x20, + 0xf3, 0xe7, 0x00, 0x00, 0x2d, 0xe9, 0xf0, 0x41, 0x04, 0x46, 0x0f, 0x46, + 0x20, 0x78, 0x05, 0x28, 0x16, 0x46, 0x1d, 0x46, 0x18, 0xbf, 0x01, 0x20, + 0x3a, 0xd1, 0x05, 0xf0, 0x59, 0xfb, 0x80, 0x46, 0x16, 0xb1, 0x01, 0x2e, + 0x06, 0xd0, 0x08, 0xe0, 0x20, 0x89, 0xb8, 0x43, 0x20, 0x81, 0x00, 0x27, + 0x66, 0x68, 0x13, 0xe0, 0x20, 0x89, 0x38, 0x43, 0xf8, 0xe7, 0x80, 0xf3, + 0x11, 0x88, 0x71, 0x20, 0x26, 0xe0, 0x30, 0x8a, 0x21, 0x89, 0x01, 0x40, + 0x81, 0x42, 0x06, 0xd1, 0x00, 0x22, 0x30, 0x46, 0x00, 0xf0, 0x7f, 0xf8, + 0x01, 0x28, 0x08, 0xbf, 0x01, 0x27, 0x36, 0x68, 0xde, 0xb1, 0xb0, 0x7c, + 0x03, 0x28, 0x12, 0xd8, 0xdf, 0xe8, 0x00, 0xf0, 0x08, 0x0d, 0x02, 0x03, + 0xe9, 0xe7, 0x20, 0x89, 0x31, 0x8a, 0x01, 0x40, 0xf1, 0xd0, 0xe9, 0xe7, + 0x30, 0x8a, 0x21, 0x89, 0x20, 0xea, 0x01, 0x01, 0xe2, 0xe7, 0x20, 0x89, + 0x31, 0x8a, 0x81, 0x43, 0xf4, 0xe7, 0x00, 0xf0, 0x4e, 0xfa, 0x6f, 0x20, + 0x28, 0x70, 0x00, 0x20, 0x0c, 0xe0, 0x00, 0xf0, 0x48, 0xfa, 0x0f, 0xb1, + 0xff, 0xf7, 0x94, 0xfd, 0x05, 0xf0, 0x16, 0xfb, 0x24, 0x89, 0x80, 0xf3, + 0x11, 0x88, 0x00, 0x20, 0x28, 0x70, 0x20, 0x46, 0xbd, 0xe8, 0xf0, 0x81, + 0x70, 0xb5, 0xdf, 0xf8, 0x78, 0x43, 0x25, 0x6a, 0x95, 0xf8, 0x30, 0x60, + 0x46, 0xf0, 0x20, 0x06, 0x85, 0xf8, 0x30, 0x60, 0x00, 0x25, 0x26, 0x6a, + 0x86, 0xf8, 0x31, 0x50, 0x25, 0x6a, 0x04, 0x9e, 0xee, 0x62, 0x69, 0x62, + 0x0a, 0x82, 0x8b, 0x74, 0x22, 0x6a, 0x8a, 0x60, 0x43, 0x68, 0x0b, 0x60, + 0xc8, 0x60, 0x00, 0x23, 0x4b, 0x60, 0x43, 0x68, 0x03, 0xb1, 0x59, 0x60, + 0x41, 0x60, 0x02, 0xf1, 0x34, 0x00, 0x01, 0x78, 0x43, 0x78, 0x09, 0x19, + 0x0a, 0x7b, 0x9a, 0x43, 0x0a, 0x73, 0x04, 0xd1, 0x21, 0x79, 0x80, 0x78, + 0x21, 0xea, 0x00, 0x00, 0x20, 0x71, 0x70, 0xbd, 0x70, 0xb5, 0x27, 0x4c, + 0x04, 0xf5, 0xea, 0x75, 0x4f, 0xf4, 0xa0, 0x71, 0x28, 0x46, 0xff, 0xf7, + 0x4e, 0xfd, 0x00, 0x20, 0x23, 0xa1, 0x00, 0x26, 0x04, 0xeb, 0x00, 0x12, + 0x02, 0xf5, 0xea, 0x73, 0x40, 0x1c, 0x02, 0xf5, 0xf2, 0x72, 0x13, 0x28, + 0x1e, 0x70, 0x5a, 0x60, 0xd9, 0x60, 0xf3, 0xd3, 0x04, 0xeb, 0x00, 0x10, + 0x00, 0xf5, 0xea, 0x70, 0x06, 0x70, 0x46, 0x60, 0xc1, 0x60, 0xa5, 0x61, + 0x70, 0xbd, 0x10, 0xb5, 0x83, 0x68, 0x28, 0x33, 0x00, 0x24, 0x19, 0x80, + 0x5c, 0x60, 0x5a, 0x72, 0x19, 0x7a, 0x01, 0xf0, 0xdf, 0x01, 0x19, 0x72, + 0x19, 0x7a, 0x61, 0xb9, 0xdf, 0xf8, 0xc0, 0x12, 0x9c, 0x7b, 0x0a, 0x79, + 0x22, 0x43, 0x0a, 0x71, 0x01, 0x24, 0x1a, 0x7b, 0x5b, 0x7b, 0x51, 0x18, + 0x0a, 0x7b, 0x1a, 0x43, 0x0a, 0x73, 0x00, 0xf0, 0x02, 0xf8, 0x20, 0x46, + 0x10, 0xbd, 0x41, 0x68, 0x02, 0x68, 0x21, 0xb9, 0xc1, 0x68, 0x4a, 0x60, + 0x22, 0xb1, 0x00, 0x21, 0x01, 0xe0, 0x0a, 0x60, 0x02, 0xb1, 0x51, 0x60, + 0x80, 0x68, 0x00, 0x21, 0x41, 0x62, 0x70, 0x47, 0x90, 0xf3, 0x00, 0x20, + 0x20, 0xbd, 0x00, 0x20, 0x3f, 0x00, 0x00, 0x00, 0x68, 0x7a, 0x00, 0x20, + 0x48, 0x46, 0x05, 0xf0, 0x8d, 0xba, 0x2d, 0xe9, 0xf0, 0x41, 0xdf, 0xf8, + 0x68, 0x62, 0x04, 0x46, 0x30, 0x78, 0x88, 0x46, 0x08, 0xb1, 0x00, 0x20, + 0x2e, 0xe0, 0x05, 0xf0, 0x7b, 0xfa, 0x71, 0x69, 0x0f, 0x00, 0x1c, 0xbf, + 0x49, 0x68, 0x71, 0x61, 0x05, 0xf0, 0x7a, 0xfa, 0x1f, 0xb3, 0x05, 0xf0, + 0x71, 0xfa, 0xdf, 0xf8, 0xb4, 0x15, 0x0a, 0x68, 0x15, 0x00, 0x16, 0xd0, + 0x12, 0x68, 0x0a, 0x60, 0x80, 0xf3, 0x11, 0x88, 0x6c, 0x60, 0x04, 0xeb, + 0x88, 0x00, 0xa8, 0x60, 0xec, 0x60, 0x2c, 0x61, 0xa5, 0xf8, 0x14, 0x80, + 0x00, 0x20, 0xe8, 0x82, 0x02, 0x20, 0x38, 0x70, 0x00, 0x20, 0x38, 0x81, + 0x7d, 0x60, 0x38, 0x46, 0xff, 0xf7, 0xc7, 0xfc, 0x05, 0xe0, 0x71, 0x69, + 0x79, 0x60, 0x77, 0x61, 0x80, 0xf3, 0x11, 0x88, 0x00, 0x27, 0x38, 0x46, + 0xbd, 0xe8, 0xf0, 0x81, 0x10, 0xb5, 0x04, 0x46, 0x05, 0xf0, 0x48, 0xfa, + 0x61, 0x68, 0x4a, 0x68, 0xca, 0x60, 0x4a, 0x68, 0x0a, 0x61, 0x00, 0x22, + 0xca, 0x82, 0x80, 0xf3, 0x11, 0x88, 0x00, 0x20, 0x10, 0xbd, 0x2d, 0xe9, + 0xf0, 0x41, 0x07, 0x46, 0x0e, 0x46, 0x38, 0x78, 0x02, 0x28, 0x14, 0x46, + 0x18, 0xbf, 0x01, 0x20, 0x07, 0xd1, 0x71, 0x4d, 0x28, 0x78, 0x08, 0xb1, + 0x02, 0x20, 0x02, 0xe0, 0x68, 0x78, 0x18, 0xb1, 0x0d, 0x20, 0x20, 0x70, + 0x00, 0x20, 0x50, 0xe0, 0x05, 0xf0, 0x26, 0xfa, 0x80, 0x46, 0x78, 0x68, + 0xc1, 0x8a, 0x89, 0xb1, 0x02, 0x69, 0x12, 0x1d, 0x02, 0x61, 0x49, 0x1e, + 0x52, 0xf8, 0x04, 0x7d, 0x82, 0x68, 0xc1, 0x82, 0x01, 0x69, 0x91, 0x42, + 0x04, 0xbf, 0x41, 0x68, 0x01, 0x61, 0x00, 0xf0, 0x40, 0xf9, 0x00, 0x20, + 0x20, 0x70, 0x37, 0xe0, 0x28, 0x6a, 0x90, 0xf8, 0x30, 0x10, 0x41, 0xf0, + 0x04, 0x01, 0x80, 0xf8, 0x30, 0x10, 0x00, 0x20, 0x29, 0x6a, 0x81, 0xf8, + 0x31, 0x00, 0x28, 0x6a, 0xc6, 0x62, 0x38, 0x46, 0xff, 0xf7, 0x3e, 0xfc, + 0x00, 0xf0, 0x2b, 0xf9, 0xff, 0xf7, 0x78, 0xfc, 0x05, 0xf0, 0xfa, 0xf9, + 0x06, 0x46, 0x28, 0x6a, 0x00, 0xf1, 0x20, 0x01, 0x4a, 0x7c, 0x12, 0xb1, + 0x02, 0x2a, 0x03, 0xd0, 0x05, 0xe0, 0x0f, 0x68, 0x00, 0x20, 0x07, 0xe0, + 0x00, 0x27, 0x0e, 0x20, 0x04, 0xe0, 0x39, 0x46, 0xff, 0xf7, 0x4a, 0xfc, + 0x00, 0x27, 0x0a, 0x20, 0x20, 0x70, 0x00, 0x20, 0x29, 0x6a, 0x81, 0xf8, + 0x30, 0x00, 0x29, 0x6a, 0x81, 0xf8, 0x31, 0x00, 0x00, 0x21, 0x28, 0x6a, + 0xc1, 0x61, 0x01, 0x62, 0x00, 0xf0, 0x69, 0xf8, 0x38, 0x46, 0xbd, 0xe8, + 0xf0, 0x81, 0x01, 0x20, 0x20, 0x70, 0x00, 0x20, 0x70, 0x47, 0x70, 0xb5, + 0x06, 0x46, 0x0c, 0x46, 0x30, 0x78, 0x02, 0x28, 0x01, 0xd0, 0x01, 0x20, + 0x70, 0xbd, 0x05, 0xf0, 0xc7, 0xf9, 0x05, 0x46, 0xb0, 0x7a, 0x30, 0xb1, + 0x00, 0xf0, 0x46, 0xf8, 0x00, 0xf0, 0x4e, 0xf8, 0xff, 0xf7, 0x3a, 0xfc, + 0x14, 0xe0, 0x70, 0x68, 0xc1, 0x8a, 0x82, 0x8a, 0x91, 0x42, 0x00, 0xd3, + 0x40, 0xe0, 0xc2, 0x68, 0x12, 0x1d, 0xc2, 0x60, 0x49, 0x1c, 0x42, 0xf8, + 0x04, 0x4d, 0xc1, 0x82, 0x82, 0x68, 0xc1, 0x68, 0x91, 0x42, 0x04, 0xbf, + 0x41, 0x68, 0xc1, 0x60, 0x00, 0xf0, 0x36, 0xf8, 0x00, 0x20, 0x70, 0xbd, + 0x70, 0xb5, 0x06, 0x46, 0x0c, 0x46, 0x30, 0x78, 0x02, 0x28, 0x01, 0xd0, + 0x01, 0x20, 0x70, 0xbd, 0x05, 0xf0, 0x9c, 0xf9, 0x05, 0x46, 0xb0, 0x7a, + 0x30, 0xb1, 0x00, 0xf0, 0x1b, 0xf8, 0x00, 0xf0, 0x23, 0xf8, 0xff, 0xf7, + 0x0f, 0xfc, 0x13, 0xe0, 0x70, 0x68, 0xc1, 0x8a, 0x82, 0x8a, 0x91, 0x42, + 0x00, 0xd3, 0x15, 0xe0, 0x02, 0x69, 0x43, 0x68, 0x9a, 0x42, 0x04, 0xbf, + 0x82, 0x68, 0x02, 0x61, 0x02, 0x69, 0x12, 0x1f, 0x02, 0x61, 0x14, 0x60, + 0x49, 0x1c, 0xc1, 0x82, 0x00, 0xf0, 0x0c, 0xf8, 0x00, 0x20, 0x70, 0xbd, + 0x00, 0x23, 0x04, 0x22, 0x21, 0x46, 0x30, 0x46, 0xff, 0xf7, 0x80, 0xbb, + 0x00, 0xf0, 0x02, 0xf8, 0x1e, 0x20, 0x70, 0xbd, 0x28, 0x46, 0x05, 0xf0, + 0x75, 0xb9, 0x30, 0x46, 0x05, 0xf0, 0x72, 0xb9, 0x10, 0xb5, 0xdf, 0xf8, + 0x60, 0x46, 0x4f, 0xf4, 0x90, 0x71, 0x20, 0x46, 0xff, 0xf7, 0xdb, 0xfb, + 0x00, 0x20, 0x18, 0x21, 0x01, 0xfb, 0x00, 0xf2, 0x13, 0x19, 0x18, 0x33, + 0x40, 0x1c, 0x13, 0x51, 0x0b, 0x28, 0xf7, 0xd3, 0x01, 0xfb, 0x00, 0x40, + 0x00, 0x22, 0x02, 0x60, 0xdf, 0xf8, 0x7c, 0x03, 0x04, 0x60, 0x10, 0xbd, + 0x00, 0x00, 0x00, 0x00, 0x20, 0xbd, 0x00, 0x20, 0x70, 0xb5, 0x00, 0xf0, + 0x17, 0xf8, 0x08, 0xb1, 0x00, 0x20, 0x70, 0xbd, 0x05, 0xf0, 0x46, 0xf9, + 0x69, 0x69, 0x0e, 0x00, 0x1c, 0xbf, 0x49, 0x68, 0x69, 0x61, 0x05, 0xf0, + 0x45, 0xf9, 0x3e, 0xb1, 0x03, 0x20, 0x30, 0x70, 0x34, 0x81, 0x00, 0x20, + 0x70, 0x60, 0x30, 0x46, 0xff, 0xf7, 0xa7, 0xfb, 0x30, 0x46, 0x70, 0xbd, + 0xdf, 0xf8, 0x20, 0x57, 0x04, 0x46, 0x28, 0x78, 0x70, 0x47, 0xdf, 0xf8, + 0x84, 0x77, 0x38, 0x78, 0x70, 0x47, 0x01, 0x22, 0x00, 0x21, 0x20, 0x46, + 0xff, 0xf7, 0x30, 0xbb, 0x2d, 0xe9, 0xf0, 0x41, 0x00, 0xf0, 0x52, 0xf8, + 0x18, 0xbf, 0x01, 0x20, 0x12, 0xd1, 0xff, 0xf7, 0xee, 0xff, 0x08, 0xb1, + 0x02, 0x20, 0x0d, 0xe0, 0x78, 0x78, 0x08, 0xb1, 0x0d, 0x20, 0x09, 0xe0, + 0x05, 0xf0, 0x14, 0xf9, 0x80, 0x46, 0x28, 0x89, 0x30, 0xb1, 0x40, 0x1e, + 0x28, 0x81, 0x00, 0xf0, 0x3a, 0xf8, 0x00, 0x20, 0x20, 0x70, 0x34, 0xe0, + 0x38, 0x6a, 0x90, 0xf8, 0x30, 0x10, 0x41, 0xf0, 0x01, 0x01, 0x80, 0xf8, + 0x30, 0x10, 0x00, 0x20, 0x39, 0x6a, 0x81, 0xf8, 0x31, 0x00, 0x38, 0x6a, + 0xc6, 0x62, 0x28, 0x46, 0xff, 0xf7, 0x38, 0xfb, 0x00, 0xf0, 0x25, 0xf8, + 0xff, 0xf7, 0x72, 0xfb, 0x05, 0xf0, 0xf4, 0xf8, 0x06, 0x46, 0x38, 0x6a, + 0x90, 0xf8, 0x31, 0x10, 0x11, 0xb1, 0x02, 0x29, 0x02, 0xd0, 0x03, 0xe0, + 0x00, 0x20, 0x05, 0xe0, 0x0e, 0x20, 0x03, 0xe0, 0x29, 0x46, 0xff, 0xf7, + 0x47, 0xfb, 0x0a, 0x20, 0x20, 0x70, 0x00, 0x20, 0x39, 0x6a, 0x81, 0xf8, + 0x30, 0x00, 0x39, 0x6a, 0x81, 0xf8, 0x31, 0x00, 0x39, 0x6a, 0xc8, 0x61, + 0x30, 0x46, 0xbd, 0xe8, 0xf0, 0x41, 0x05, 0xf0, 0xdb, 0xb8, 0xbd, 0xe8, + 0xf0, 0x81, 0x40, 0x46, 0x05, 0xf0, 0xd6, 0xb8, 0x05, 0x46, 0x0e, 0x46, + 0x28, 0x78, 0x03, 0x28, 0x14, 0x46, 0x70, 0x47, 0x38, 0xb5, 0x04, 0x46, + 0x20, 0x78, 0x03, 0x28, 0x01, 0xd0, 0x01, 0x20, 0x32, 0xbd, 0x05, 0xf0, + 0xc1, 0xf8, 0x05, 0x46, 0xa0, 0x7a, 0x38, 0xb1, 0x00, 0x23, 0xff, 0xf7, + 0x90, 0xff, 0xff, 0xf7, 0x47, 0xff, 0xff, 0xf7, 0x33, 0xfb, 0x08, 0xe0, + 0x20, 0x89, 0x4f, 0xf6, 0xff, 0x71, 0x88, 0x42, 0x05, 0xd0, 0x40, 0x1c, + 0x20, 0x81, 0xff, 0xf7, 0x3b, 0xff, 0x00, 0x20, 0x32, 0xbd, 0xff, 0xf7, + 0x37, 0xff, 0x33, 0x20, 0x32, 0xbd, 0x2d, 0xe9, 0xf1, 0x4f, 0x84, 0xb0, + 0x8b, 0x46, 0x90, 0x46, 0x99, 0x46, 0x05, 0xf0, 0x9f, 0xf8, 0xdf, 0xf8, + 0x64, 0x56, 0x29, 0x78, 0x19, 0xb1, 0x80, 0xf3, 0x11, 0x88, 0x3c, 0x20, + 0x33, 0xe0, 0x05, 0xeb, 0x89, 0x06, 0x31, 0x6b, 0x61, 0xbb, 0x01, 0x21, + 0x31, 0x63, 0x80, 0xf3, 0x11, 0x88, 0xdd, 0xf8, 0x3c, 0xa0, 0x10, 0x9f, + 0x12, 0x9c, 0x22, 0x46, 0x39, 0x46, 0x50, 0x46, 0x00, 0xf0, 0xc6, 0xf8, + 0x04, 0x98, 0x23, 0x46, 0x42, 0x46, 0x59, 0x46, 0x05, 0xf0, 0x1a, 0xf8, + 0x01, 0x46, 0x11, 0x98, 0x02, 0x94, 0x01, 0x90, 0x00, 0x97, 0x52, 0x46, + 0x0e, 0x9b, 0x48, 0x46, 0xff, 0xf7, 0xad, 0xfb, 0x04, 0x00, 0x05, 0xd1, + 0x68, 0x79, 0x01, 0x28, 0x08, 0xd1, 0xff, 0xf7, 0xeb, 0xfa, 0x05, 0xe0, + 0x05, 0xf0, 0x6c, 0xf8, 0x00, 0x21, 0x31, 0x63, 0x80, 0xf3, 0x11, 0x88, + 0x20, 0x46, 0x02, 0xe0, 0x80, 0xf3, 0x11, 0x88, 0x28, 0x20, 0x05, 0xb0, + 0xbd, 0xe8, 0xf0, 0x8f, 0x2d, 0xe9, 0xf0, 0x41, 0xdf, 0xf8, 0x74, 0x45, + 0x06, 0x46, 0x20, 0x78, 0x08, 0xb1, 0x40, 0x20, 0x64, 0xe0, 0x18, 0x2e, + 0x08, 0xbf, 0x3e, 0x20, 0x60, 0xd0, 0x05, 0xf0, 0x51, 0xf8, 0x80, 0x46, + 0xff, 0x2e, 0x04, 0xbf, 0x20, 0x6a, 0x90, 0xf8, 0x32, 0x60, 0x04, 0xeb, + 0x86, 0x05, 0x2e, 0x6b, 0x1e, 0xb9, 0xff, 0xf7, 0x72, 0xff, 0x43, 0x20, + 0x50, 0xe0, 0x01, 0x2e, 0x03, 0xd1, 0xff, 0xf7, 0x6c, 0xff, 0x3d, 0x20, + 0x4a, 0xe0, 0x06, 0xf1, 0x30, 0x07, 0x38, 0x79, 0x7a, 0x79, 0x00, 0x19, + 0x01, 0x7b, 0x91, 0x43, 0x01, 0x73, 0x38, 0x79, 0x00, 0x19, 0x00, 0x7b, + 0x18, 0xb9, 0x20, 0x79, 0xb9, 0x79, 0x88, 0x43, 0x20, 0x71, 0xf1, 0x69, + 0x11, 0xb1, 0x30, 0x46, 0xff, 0xf7, 0x8a, 0xfa, 0x70, 0x6a, 0x08, 0xb1, + 0xff, 0xf7, 0x83, 0xfd, 0x00, 0x20, 0xf0, 0x62, 0x38, 0x70, 0x78, 0x70, + 0x60, 0x78, 0xff, 0x28, 0x1c, 0xbf, 0x40, 0x1c, 0x60, 0x70, 0xff, 0xf7, + 0x46, 0xff, 0x05, 0xf0, 0x17, 0xf8, 0x80, 0x46, 0x60, 0x78, 0x08, 0xb1, + 0x40, 0x1e, 0x60, 0x70, 0x30, 0x46, 0x04, 0xf0, 0xa3, 0xff, 0xa0, 0x79, + 0x40, 0x1e, 0xa0, 0x71, 0x00, 0x20, 0x28, 0x63, 0xb1, 0x69, 0x70, 0x69, + 0x19, 0xb9, 0x81, 0x61, 0x70, 0x69, 0xe0, 0x62, 0x03, 0xe0, 0x48, 0x61, + 0x71, 0x69, 0xb0, 0x69, 0x88, 0x61, 0x60, 0x6a, 0x70, 0x61, 0x66, 0x62, + 0x1c, 0xa0, 0xf8, 0x61, 0xff, 0xf7, 0x25, 0xff, 0x60, 0x79, 0x01, 0x28, + 0x08, 0xbf, 0xff, 0xf7, 0x6f, 0xfa, 0x00, 0x20, 0xbd, 0xe8, 0xf0, 0x81, + 0xf8, 0xb5, 0xdf, 0xf8, 0x04, 0x75, 0x05, 0x46, 0x38, 0x78, 0x0e, 0x46, + 0x14, 0x46, 0x08, 0xb1, 0x12, 0x20, 0x15, 0xe0, 0x04, 0xf0, 0xe4, 0xff, + 0xff, 0x2d, 0x04, 0xbf, 0x39, 0x6a, 0x91, 0xf8, 0x32, 0x50, 0x07, 0xeb, + 0x85, 0x01, 0x09, 0x6b, 0x00, 0x29, 0x18, 0xbf, 0x01, 0x29, 0x03, 0xd1, + 0x04, 0xf0, 0xdc, 0xff, 0x43, 0x20, 0x03, 0xe0, 0xce, 0x64, 0x80, 0xf3, + 0x11, 0x88, 0x00, 0x20, 0x20, 0x70, 0xf1, 0xbd, 0x80, 0xb5, 0xdf, 0xf8, + 0xc0, 0x04, 0x00, 0x6a, 0x04, 0xf0, 0x60, 0xff, 0xbd, 0xe8, 0x02, 0x40, + 0xff, 0x20, 0x63, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, + 0x02, 0xf0, 0x03, 0x02, 0x03, 0x2a, 0x04, 0xd1, 0x00, 0x29, 0x1c, 0xbf, + 0x89, 0x00, 0x05, 0xf0, 0x09, 0xb8, 0x70, 0x47, 0x70, 0xb5, 0xff, 0xf7, + 0x7f, 0xfe, 0x00, 0x28, 0x04, 0xbf, 0x68, 0x78, 0x00, 0x28, 0x16, 0xd1, + 0xac, 0xb1, 0x04, 0xf0, 0xab, 0xff, 0x29, 0x6a, 0x2c, 0x31, 0x0a, 0x7a, + 0x4e, 0x7a, 0x52, 0x19, 0x13, 0x7b, 0xb3, 0x43, 0x13, 0x73, 0x03, 0xd1, + 0x2a, 0x79, 0x8b, 0x7a, 0x9a, 0x43, 0x2a, 0x71, 0x0c, 0x60, 0x80, 0xf3, + 0x11, 0x88, 0xbd, 0xe8, 0x70, 0x40, 0xff, 0xf7, 0x13, 0xba, 0x70, 0xbd, + 0x8c, 0xf3, 0x00, 0x20, 0x10, 0xb5, 0x04, 0xf0, 0x91, 0xff, 0xdf, 0xf8, + 0x50, 0x14, 0x0c, 0x68, 0x80, 0xf3, 0x11, 0x88, 0x20, 0x46, 0x10, 0xbd, + 0xbd, 0xe8, 0x10, 0x40, 0x04, 0xf0, 0x8c, 0xbf, 0x2d, 0xe9, 0xf8, 0x43, + 0x06, 0x46, 0xdf, 0xf8, 0xc0, 0x03, 0x0a, 0x9c, 0x00, 0x78, 0x0f, 0x46, + 0x90, 0x46, 0x99, 0x46, 0x08, 0xb1, 0x8b, 0x20, 0x08, 0xe0, 0xff, 0xf7, + 0xfb, 0xf8, 0xdf, 0xf8, 0x20, 0x04, 0x05, 0x69, 0x2d, 0xb9, 0xff, 0xf7, + 0x0a, 0xf9, 0x86, 0x20, 0x20, 0x70, 0x00, 0x20, 0x20, 0xe0, 0xe9, 0x68, + 0x01, 0x61, 0x00, 0x21, 0xe9, 0x60, 0x29, 0x61, 0x41, 0x88, 0x49, 0x1c, + 0x41, 0x80, 0x01, 0x88, 0x49, 0x1e, 0x01, 0x80, 0x05, 0xf1, 0x24, 0x00, + 0x01, 0x21, 0x41, 0x70, 0x29, 0x1d, 0x4e, 0x61, 0x8f, 0x61, 0x80, 0xf8, + 0x00, 0x80, 0xc1, 0xf8, 0x00, 0x90, 0x08, 0x98, 0x48, 0x60, 0x09, 0x98, + 0x00, 0xb9, 0x8b, 0xa0, 0xc8, 0x61, 0xff, 0xf7, 0xe8, 0xf8, 0x00, 0x20, + 0x20, 0x70, 0x28, 0x46, 0xbd, 0xe8, 0xf2, 0x83, 0x00, 0x00, 0x00, 0x00, + 0x38, 0xb5, 0x00, 0xf0, 0x74, 0xf8, 0x18, 0xbf, 0x89, 0x20, 0x1c, 0xd1, + 0x00, 0xf0, 0x6c, 0xf8, 0x08, 0xb1, 0x8b, 0x20, 0x17, 0xe0, 0xff, 0xf7, + 0xbf, 0xf8, 0x95, 0xf8, 0x25, 0x00, 0x03, 0x28, 0x0e, 0xd8, 0xdf, 0xe8, + 0x00, 0xf0, 0x09, 0x05, 0x05, 0x02, 0x28, 0x46, 0x00, 0xf0, 0x6c, 0xf9, + 0x28, 0x46, 0x00, 0xf0, 0xd9, 0xf8, 0x84, 0xe0, 0xff, 0xf7, 0xc3, 0xf8, + 0x87, 0x20, 0x02, 0xe0, 0xff, 0xf7, 0xbf, 0xf8, 0x8d, 0x20, 0x20, 0x70, + 0x00, 0x20, 0x32, 0xbd, 0x70, 0xb5, 0x00, 0xf0, 0x4e, 0xf8, 0x18, 0xbf, + 0x89, 0x20, 0x2c, 0xd1, 0x00, 0xf0, 0x46, 0xf8, 0x08, 0xb1, 0x8b, 0x20, + 0x27, 0xe0, 0xff, 0xf7, 0x99, 0xf8, 0x05, 0xf1, 0x24, 0x00, 0x41, 0x78, + 0x03, 0x29, 0x1d, 0xd8, 0xdf, 0xe8, 0x01, 0xf0, 0x18, 0x07, 0x13, 0x02, + 0xd2, 0x49, 0x68, 0x69, 0x49, 0x68, 0x46, 0x1a, 0x05, 0xe0, 0x00, 0x78, + 0xae, 0x69, 0x02, 0x28, 0x04, 0xbf, 0x00, 0x2e, 0xee, 0x69, 0xff, 0xf7, + 0x98, 0xf8, 0x00, 0x20, 0x20, 0x70, 0x30, 0x46, 0x70, 0xbd, 0xff, 0xf7, + 0x92, 0xf8, 0x00, 0x20, 0x20, 0x70, 0x70, 0xbd, 0xff, 0xf7, 0x8d, 0xf8, + 0x87, 0x20, 0x02, 0xe0, 0xff, 0xf7, 0x89, 0xf8, 0x8d, 0x20, 0x20, 0x70, + 0x00, 0x20, 0x70, 0xbd, 0x38, 0xb5, 0x00, 0xf0, 0x18, 0xf8, 0x18, 0xbf, + 0x89, 0x20, 0x03, 0xd1, 0x00, 0xf0, 0x10, 0xf8, 0x08, 0xb1, 0x8b, 0x20, + 0xbb, 0xe7, 0xff, 0xf7, 0x63, 0xf8, 0x95, 0xf8, 0x25, 0x50, 0x03, 0x2d, + 0x94, 0xbf, 0x00, 0x20, 0x8d, 0x20, 0x20, 0x70, 0xff, 0xf7, 0x6f, 0xf8, + 0x28, 0x46, 0x32, 0xbd, 0xb3, 0x48, 0x00, 0x78, 0x70, 0x47, 0x05, 0x46, + 0x0c, 0x46, 0x28, 0x78, 0x64, 0x28, 0x70, 0x47, 0x38, 0xb5, 0xff, 0xf7, + 0xf8, 0xff, 0x18, 0xbf, 0x89, 0x20, 0x1d, 0xd1, 0xff, 0xf7, 0xf0, 0xff, + 0x08, 0xb1, 0x8b, 0x20, 0x18, 0xe0, 0xff, 0xf7, 0x43, 0xf8, 0x95, 0xf8, + 0x25, 0x00, 0x03, 0x28, 0x0f, 0xd8, 0xdf, 0xe8, 0x00, 0xf0, 0x0a, 0x05, + 0x05, 0x02, 0x28, 0x46, 0x00, 0xf0, 0xf0, 0xf8, 0x00, 0x21, 0x28, 0x46, + 0x00, 0xf0, 0xca, 0xf8, 0x07, 0xe0, 0xff, 0xf7, 0x46, 0xf8, 0x87, 0x20, + 0x02, 0xe0, 0xff, 0xf7, 0x42, 0xf8, 0x8d, 0x20, 0x81, 0xe7, 0xff, 0xf7, + 0x3e, 0xf8, 0x00, 0x20, 0x20, 0x70, 0x01, 0x20, 0x32, 0xbd, 0x00, 0x00, + 0xf8, 0xb5, 0x05, 0x46, 0x0f, 0x46, 0x28, 0x78, 0x64, 0x28, 0x16, 0x46, + 0x1c, 0x46, 0x18, 0xbf, 0x89, 0x20, 0x3a, 0xd1, 0xff, 0xf7, 0xc0, 0xff, + 0x08, 0xb1, 0x8b, 0x20, 0x35, 0xe0, 0xff, 0xf7, 0x13, 0xf8, 0x95, 0xf8, + 0x25, 0x00, 0x03, 0x28, 0x2c, 0xd8, 0xdf, 0xe8, 0x00, 0xf0, 0x27, 0x21, + 0x21, 0x02, 0x28, 0x46, 0x00, 0xf0, 0xc0, 0xf8, 0x00, 0x20, 0x20, 0x70, + 0xaf, 0xb1, 0x03, 0x2f, 0x02, 0xd0, 0x04, 0x2f, 0x06, 0xd0, 0x0e, 0xe0, + 0x6a, 0x68, 0x10, 0x00, 0x18, 0xbf, 0xa9, 0x68, 0x04, 0xd1, 0x06, 0xe0, + 0x6a, 0x68, 0x10, 0x00, 0x03, 0xd0, 0x31, 0x46, 0x28, 0x46, 0x90, 0x47, + 0x03, 0xe0, 0x8f, 0x20, 0x00, 0xe0, 0x84, 0x20, 0x20, 0x70, 0xff, 0xf7, + 0x02, 0xf8, 0x03, 0xe0, 0xfe, 0xf7, 0xff, 0xff, 0x8e, 0x20, 0x20, 0x70, + 0x01, 0x20, 0xf2, 0xbd, 0xfe, 0xf7, 0xf9, 0xff, 0x87, 0x20, 0x02, 0xe0, + 0xfe, 0xf7, 0xf5, 0xff, 0x8d, 0x20, 0x20, 0x70, 0x00, 0x20, 0xf2, 0xbd, + 0x78, 0x48, 0xc0, 0x68, 0xff, 0xf7, 0x8a, 0xbd, 0x00, 0xf1, 0x24, 0x01, + 0x00, 0x22, 0x4a, 0x70, 0x0a, 0x70, 0x09, 0xa1, 0x01, 0x62, 0xc2, 0x61, + 0x42, 0x61, 0x42, 0x60, 0x82, 0x60, 0x02, 0x61, 0x70, 0x49, 0x0a, 0x69, + 0xc2, 0x60, 0x08, 0x61, 0x48, 0x88, 0x40, 0x1e, 0x48, 0x80, 0x08, 0x88, + 0x40, 0x1c, 0x08, 0x80, 0x70, 0x47, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, + 0x74, 0xec, 0x00, 0x20, 0x70, 0xb5, 0x68, 0x4c, 0x86, 0xb0, 0x4f, 0xf4, + 0x70, 0x71, 0x04, 0xf1, 0x54, 0x00, 0xff, 0xf7, 0xa6, 0xf8, 0x40, 0x21, + 0x04, 0xf1, 0x14, 0x00, 0xff, 0xf7, 0xa1, 0xf8, 0x00, 0x20, 0x5f, 0xa1, + 0x28, 0x22, 0x02, 0xfb, 0x00, 0x43, 0x03, 0xf1, 0x54, 0x05, 0x64, 0x26, + 0x2e, 0x70, 0x40, 0x1c, 0x00, 0x26, 0x7c, 0x33, 0x17, 0x28, 0x85, 0xf8, + 0x25, 0x60, 0xeb, 0x60, 0x29, 0x62, 0xf0, 0xd3, 0x02, 0xfb, 0x00, 0x40, + 0x64, 0x22, 0x00, 0xf8, 0x54, 0x2f, 0x80, 0xf8, 0x25, 0x60, 0xc6, 0x60, + 0x01, 0x62, 0x18, 0x20, 0x20, 0x80, 0x66, 0x60, 0x04, 0xf1, 0x54, 0x00, + 0x20, 0x61, 0x66, 0x80, 0x01, 0x20, 0xff, 0xf7, 0xb7, 0xfc, 0xa0, 0x60, + 0x00, 0x20, 0xff, 0xf7, 0xb3, 0xfc, 0x03, 0x21, 0x04, 0x91, 0xe0, 0x60, + 0x80, 0x21, 0x02, 0x91, 0x4f, 0xf6, 0xfd, 0x71, 0x4a, 0x48, 0x01, 0x90, + 0x00, 0x91, 0x00, 0xf5, 0xfe, 0x72, 0x03, 0x96, 0x02, 0x23, 0x00, 0x21, + 0x0f, 0xf2, 0xa1, 0x00, 0xff, 0xf7, 0x47, 0xfd, 0x05, 0xaa, 0x0f, 0xf2, + 0x14, 0x11, 0x02, 0x20, 0xff, 0xf7, 0xf8, 0xfd, 0x06, 0xb0, 0x70, 0xbd, + 0x10, 0xb5, 0x03, 0x22, 0x80, 0xf8, 0x25, 0x20, 0x01, 0x29, 0x3d, 0x4a, + 0x53, 0x68, 0x1a, 0xbf, 0x81, 0x69, 0x00, 0x29, 0xc1, 0x69, 0x59, 0x18, + 0x41, 0x61, 0x01, 0x7d, 0x01, 0xf0, 0x07, 0x01, 0x02, 0xeb, 0xc1, 0x01, + 0x14, 0x31, 0x8a, 0x88, 0x0b, 0x68, 0x1b, 0xb9, 0x00, 0x22, 0xc2, 0x60, + 0x01, 0x22, 0x02, 0xe0, 0xc3, 0x60, 0x18, 0x61, 0x52, 0x1c, 0x8a, 0x80, + 0x08, 0x60, 0x00, 0x21, 0x01, 0x61, 0x10, 0xbd, 0x10, 0xb5, 0x00, 0xf1, + 0x0c, 0x01, 0x2d, 0x4a, 0x0b, 0x7a, 0x03, 0xf0, 0x07, 0x03, 0x02, 0xeb, + 0xc3, 0x02, 0x52, 0xf8, 0x14, 0x4f, 0x0b, 0x68, 0x84, 0x42, 0x05, 0xd1, + 0x18, 0x00, 0x10, 0x60, 0x06, 0xd0, 0x00, 0x23, 0x03, 0x61, 0x03, 0xe0, + 0x48, 0x68, 0xc3, 0x60, 0x03, 0xb1, 0x18, 0x61, 0x01, 0x20, 0x48, 0x76, + 0x00, 0x20, 0x08, 0x60, 0x48, 0x60, 0x90, 0x88, 0x40, 0x1e, 0x90, 0x80, + 0x10, 0xbd, 0x00, 0x00, 0x20, 0xbd, 0x00, 0x20, 0xf8, 0xb5, 0x1c, 0x4c, + 0x01, 0xe0, 0xfe, 0xf7, 0x34, 0xff, 0xe0, 0x68, 0x6a, 0x46, 0x00, 0x21, + 0xff, 0xf7, 0x70, 0xfc, 0xfe, 0xf7, 0x18, 0xff, 0x60, 0x68, 0x40, 0x1c, + 0x60, 0x60, 0x00, 0xf0, 0x07, 0x00, 0x04, 0xeb, 0xc0, 0x00, 0x45, 0x69, + 0x00, 0x2d, 0x08, 0xe0, 0x02, 0x21, 0x41, 0x70, 0x32, 0x68, 0x10, 0x00, + 0x02, 0xd0, 0x71, 0x68, 0x28, 0x46, 0x90, 0x47, 0x3d, 0x00, 0xe2, 0xd0, + 0x2e, 0x1d, 0x60, 0x68, 0x31, 0x69, 0xb7, 0x68, 0x88, 0x42, 0xf7, 0xd1, + 0x28, 0x46, 0xff, 0xf7, 0xb3, 0xff, 0x05, 0xf1, 0x24, 0x00, 0x01, 0x78, + 0x02, 0x29, 0xe7, 0xd1, 0x01, 0x21, 0x28, 0x46, 0xff, 0xf7, 0x88, 0xff, + 0xe4, 0xe7, 0x00, 0x00, 0x20, 0xbd, 0x00, 0x20, 0x3f, 0x00, 0x00, 0x00, + 0x90, 0xf3, 0x00, 0x20, 0x68, 0xdb, 0x00, 0x20, 0x68, 0x78, 0x00, 0x20, + 0x75, 0x43, 0x2f, 0x4f, 0x53, 0x2d, 0x49, 0x49, 0x20, 0x54, 0x6d, 0x72, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x04, 0xf0, 0xb1, 0xbd, 0xf0, 0xb4, + 0x01, 0x68, 0x44, 0x68, 0x83, 0x68, 0x09, 0x18, 0x01, 0xeb, 0x54, 0x02, + 0xe4, 0x07, 0x48, 0xbf, 0x4b, 0x44, 0x0c, 0x30, 0x91, 0x42, 0x2b, 0xd0, + 0x11, 0xf8, 0x01, 0x4b, 0x14, 0xf0, 0x03, 0x05, 0x04, 0xbf, 0x11, 0xf8, + 0x01, 0x5b, 0xed, 0x1c, 0x26, 0x09, 0x0f, 0x2e, 0x07, 0xd1, 0x11, 0xf8, + 0x01, 0x6b, 0x0f, 0x36, 0x03, 0xe0, 0x11, 0xf8, 0x01, 0x7b, 0x03, 0xf8, + 0x01, 0x7b, 0x6d, 0x1e, 0xf9, 0xd1, 0x00, 0x2e, 0xe6, 0xd0, 0xa4, 0x08, + 0x11, 0xf8, 0x01, 0x5b, 0x04, 0xf0, 0x03, 0x04, 0x03, 0x2c, 0x08, 0xbf, + 0x11, 0xf8, 0x01, 0x4b, 0x05, 0xeb, 0x04, 0x24, 0x1c, 0x1b, 0xb5, 0x1c, + 0xd8, 0xd0, 0x14, 0xf8, 0x01, 0x6b, 0x03, 0xf8, 0x01, 0x6b, 0x6d, 0x1e, + 0xf9, 0xd1, 0xd1, 0xe7, 0xf0, 0xbc, 0x70, 0x47, 0x10, 0xb5, 0xef, 0xf3, + 0x10, 0x82, 0x72, 0xb6, 0x66, 0x4b, 0x4f, 0xf6, 0xfe, 0x64, 0x00, 0xf1, + 0x8c, 0x40, 0x44, 0xe0, 0x30, 0xb5, 0x00, 0xf1, 0x8c, 0x40, 0xef, 0xf3, + 0x10, 0x83, 0x72, 0xb6, 0x60, 0x4c, 0x4f, 0xf6, 0xfe, 0x65, 0x25, 0x60, + 0x05, 0x78, 0x8d, 0x43, 0x11, 0x40, 0x29, 0x43, 0x01, 0x70, 0x00, 0x20, + 0x20, 0x60, 0x83, 0xf3, 0x10, 0x88, 0x30, 0xbd, 0xf0, 0xb5, 0x00, 0xf0, + 0x23, 0xf8, 0x0b, 0xe0, 0x72, 0xb6, 0x4f, 0xf6, 0xfe, 0x66, 0x2e, 0x60, + 0x30, 0xf8, 0x14, 0x70, 0x66, 0x5c, 0x07, 0xf1, 0x8c, 0x47, 0x3e, 0x70, + 0x00, 0xf0, 0x10, 0xf8, 0x94, 0x42, 0xf1, 0xd3, 0xf0, 0xbd, 0x10, 0xb5, + 0x00, 0x23, 0x06, 0xe0, 0x30, 0xf8, 0x13, 0x40, 0x04, 0xf1, 0x8c, 0x44, + 0x24, 0x78, 0x5c, 0x54, 0x5b, 0x1c, 0x93, 0x42, 0xf6, 0xd3, 0x10, 0xbd, + 0x00, 0x26, 0x2e, 0x60, 0x83, 0xf3, 0x10, 0x88, 0x64, 0x1c, 0x70, 0x47, + 0xef, 0xf3, 0x10, 0x83, 0x00, 0x24, 0x45, 0x4d, 0x70, 0x47, 0x10, 0xb5, + 0x00, 0xf0, 0x0a, 0xf8, 0x1c, 0x60, 0x01, 0x60, 0x01, 0xe0, 0x1c, 0x60, + 0x01, 0x70, 0x00, 0x20, 0x18, 0x60, 0x82, 0xf3, 0x10, 0x88, 0x10, 0xbd, + 0xef, 0xf3, 0x10, 0x82, 0x72, 0xb6, 0x3c, 0x4b, 0x3c, 0x4c, 0x70, 0x47, + 0x3c, 0x49, 0x09, 0x78, 0x01, 0xf0, 0x07, 0x02, 0x06, 0x2a, 0x02, 0xbf, + 0xc1, 0xf3, 0xc2, 0x01, 0x01, 0x40, 0x81, 0x42, 0x0c, 0xbf, 0x01, 0x20, + 0x00, 0x20, 0x70, 0x47, 0x35, 0x49, 0x09, 0x78, 0x01, 0xf0, 0x07, 0x02, + 0x06, 0x2a, 0x03, 0xbf, 0x00, 0xea, 0x91, 0x11, 0x81, 0x42, 0x01, 0x20, + 0x00, 0x20, 0x70, 0x47, 0x1c, 0xb5, 0x0f, 0xf2, 0xcc, 0x02, 0x18, 0xca, + 0x69, 0x46, 0x03, 0x28, 0x18, 0xc1, 0x01, 0xd3, 0x00, 0x20, 0x16, 0xbd, + 0x00, 0xf0, 0x03, 0x00, 0x3d, 0xf8, 0x10, 0x00, 0x00, 0xf1, 0x8c, 0x41, + 0x00, 0x22, 0x08, 0x78, 0x01, 0xe0, 0x00, 0x22, 0x18, 0x46, 0x0b, 0x78, + 0x83, 0x42, 0xfa, 0xd1, 0x52, 0x1c, 0x05, 0x2a, 0xf9, 0xd3, 0x16, 0xbd, + 0x38, 0xb5, 0x04, 0x46, 0x00, 0x22, 0x04, 0x21, 0x40, 0xf2, 0x16, 0x50, + 0xff, 0xf7, 0x70, 0xff, 0x1e, 0x4d, 0x0c, 0xb9, 0x28, 0x78, 0x32, 0xbd, + 0x01, 0x2c, 0x01, 0xd1, 0x28, 0x79, 0x32, 0xbd, 0xa0, 0x1e, 0xc2, 0x00, + 0xd2, 0xb2, 0x18, 0x21, 0x40, 0xf2, 0x17, 0x50, 0xff, 0xf7, 0x60, 0xff, + 0x28, 0x7a, 0x32, 0xbd, 0x80, 0xb5, 0xff, 0xf7, 0xe3, 0xff, 0x0f, 0xf2, + 0x64, 0x01, 0x40, 0x56, 0x02, 0xbd, 0x38, 0xb5, 0x02, 0x00, 0x0c, 0x46, + 0x10, 0x4d, 0x40, 0xf2, 0x16, 0x50, 0x07, 0xd1, 0x0c, 0x22, 0x1c, 0x21, + 0xff, 0xf7, 0x4c, 0xff, 0x00, 0xf0, 0x1a, 0xf8, 0x28, 0x78, 0x0a, 0xe0, + 0x01, 0x2a, 0x07, 0xd1, 0x14, 0x22, 0x1c, 0x21, 0xff, 0xf7, 0x42, 0xff, + 0x00, 0xf0, 0x10, 0xf8, 0x28, 0x79, 0x00, 0xe0, 0x00, 0x20, 0x0f, 0xf2, + 0x28, 0x01, 0x40, 0x56, 0x32, 0xbd, 0x00, 0x00, 0x48, 0x00, 0x00, 0x50, + 0x00, 0x00, 0xab, 0xab, 0xb3, 0x01, 0x00, 0x46, 0x0b, 0x05, 0x00, 0x46, + 0x21, 0x46, 0x4f, 0xf4, 0xa0, 0x60, 0x21, 0xe7, 0xb0, 0x04, 0xb3, 0x04, + 0xb6, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfd, 0xfd, 0xfd, + 0xfd, 0xfd, 0xfc, 0xfc, 0xfc, 0xfc, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfa, + 0xfa, 0xfa, 0xf9, 0xf9, 0xf9, 0xf9, 0xf8, 0xf8, 0xf7, 0xf7, 0xf7, 0xf6, + 0xf6, 0xf5, 0xf5, 0xf4, 0xf4, 0xf3, 0xf3, 0xf2, 0xf1, 0xf1, 0xf0, 0xef, + 0xee, 0xed, 0xeb, 0xea, 0xe8, 0xe5, 0xe2, 0xdc, 0x10, 0xb5, 0x01, 0x20, + 0x04, 0xf0, 0x13, 0xfe, 0x79, 0x4c, 0x18, 0x21, 0x04, 0xf1, 0x14, 0x00, + 0xff, 0xf7, 0xb6, 0xfe, 0x01, 0x22, 0x02, 0x21, 0x20, 0x1d, 0x04, 0xf0, + 0x61, 0xfc, 0xa0, 0x1c, 0x00, 0x21, 0x01, 0x80, 0x0e, 0x20, 0x04, 0xf0, + 0x56, 0xfe, 0x00, 0x22, 0x80, 0x21, 0x40, 0xf6, 0x6e, 0x10, 0xff, 0xf7, + 0xed, 0xfe, 0x6f, 0x48, 0x4f, 0xf0, 0x40, 0x71, 0xc1, 0x62, 0x01, 0x60, + 0x0e, 0x20, 0x06, 0x21, 0x04, 0xf0, 0x53, 0xfe, 0x0e, 0x20, 0x04, 0xf0, + 0x35, 0xfe, 0xbd, 0xe8, 0x10, 0x40, 0x19, 0xe0, 0x03, 0x28, 0x00, 0xdb, + 0x70, 0x47, 0x30, 0xb5, 0x02, 0x29, 0x0b, 0xda, 0x63, 0x4c, 0x01, 0xeb, + 0x41, 0x05, 0x2d, 0x19, 0x45, 0x19, 0x2a, 0x72, 0x0c, 0x22, 0x02, 0xfb, + 0x01, 0x41, 0x01, 0xeb, 0x80, 0x00, 0x43, 0x61, 0x30, 0xbd, 0x00, 0x23, + 0x00, 0x22, 0xe9, 0xe7, 0x0e, 0x20, 0x04, 0xf0, 0x28, 0xbe, 0x00, 0xbf, + 0x0e, 0x20, 0x04, 0xf0, 0x1b, 0xbe, 0x70, 0xb5, 0x04, 0x46, 0x57, 0x4d, + 0x66, 0x19, 0xb0, 0x78, 0x70, 0xb9, 0x01, 0x20, 0xa0, 0x40, 0xff, 0xf7, + 0x17, 0xff, 0x48, 0xb1, 0x05, 0xeb, 0x44, 0x00, 0x00, 0xf1, 0x10, 0x01, + 0x32, 0x46, 0x20, 0x46, 0x04, 0xf0, 0x84, 0xf8, 0x01, 0x20, 0xb0, 0x70, + 0x70, 0xbd, 0x10, 0xb5, 0x04, 0x46, 0xff, 0xf7, 0xe6, 0xff, 0x4b, 0x48, + 0x00, 0xeb, 0x44, 0x00, 0x00, 0x8a, 0x10, 0xbd, 0x10, 0xb5, 0x04, 0x46, + 0xff, 0xf7, 0xdd, 0xff, 0x46, 0x48, 0x20, 0x5c, 0x10, 0xbd, 0x2d, 0xe9, + 0xf8, 0x4f, 0x00, 0x20, 0x00, 0x90, 0x00, 0x27, 0x42, 0x4c, 0xe8, 0x46, + 0x0d, 0xf1, 0x02, 0x06, 0x00, 0xe0, 0x0f, 0xb9, 0x1b, 0x20, 0x00, 0xe0, + 0x1c, 0x20, 0x04, 0xf0, 0x5e, 0xfe, 0x0f, 0xf2, 0x04, 0x10, 0x3e, 0x49, + 0x50, 0xf8, 0x27, 0x00, 0x08, 0x60, 0x01, 0x20, 0xb8, 0x40, 0xff, 0xf7, + 0xe1, 0xfe, 0x10, 0xb3, 0x04, 0xeb, 0x47, 0x0a, 0x17, 0xf8, 0x04, 0x90, + 0xba, 0xf8, 0x10, 0xb0, 0x3d, 0x19, 0x2a, 0x46, 0x0a, 0xf1, 0x10, 0x01, + 0x38, 0x46, 0x04, 0xf0, 0x49, 0xf8, 0xa8, 0x78, 0x10, 0xb9, 0x01, 0x20, + 0xb8, 0x55, 0x09, 0xe0, 0xba, 0xf8, 0x10, 0x00, 0x58, 0x45, 0x14, 0xbf, + 0x01, 0x20, 0x00, 0x20, 0xb8, 0x55, 0x38, 0x5d, 0x48, 0x45, 0x01, 0xd0, + 0x01, 0x20, 0x00, 0xe0, 0x00, 0x20, 0x07, 0xf8, 0x08, 0x00, 0x01, 0x20, + 0xa8, 0x70, 0x7f, 0x1c, 0x02, 0x2f, 0xc8, 0xd3, 0x00, 0x27, 0x38, 0x19, + 0x00, 0x79, 0x00, 0xb3, 0x00, 0x25, 0x17, 0xf8, 0x08, 0x00, 0x48, 0xb9, + 0xb8, 0x5d, 0xb8, 0xb1, 0x04, 0xf1, 0x08, 0x00, 0x07, 0xeb, 0x47, 0x01, + 0x08, 0x18, 0x28, 0x5c, 0x01, 0x28, 0x0f, 0xd1, 0x04, 0xf1, 0x14, 0x00, + 0x0c, 0x21, 0x01, 0xfb, 0x07, 0x00, 0x50, 0xf8, 0x25, 0x30, 0x18, 0x00, + 0x06, 0xd0, 0x04, 0xf1, 0x10, 0x00, 0x30, 0xf8, 0x17, 0x10, 0x3a, 0x5d, + 0xf8, 0xb2, 0x98, 0x47, 0x6d, 0x1c, 0x03, 0x2d, 0xdf, 0xd3, 0x7f, 0x1c, + 0x02, 0x2f, 0xd8, 0xd3, 0xbd, 0xe8, 0xf1, 0x8f, 0x12, 0x48, 0x4f, 0xf4, + 0x40, 0x51, 0x01, 0x60, 0xc1, 0x68, 0x41, 0xf4, 0x40, 0x51, 0xc1, 0x60, + 0x70, 0x47, 0x00, 0x28, 0x0c, 0xbf, 0x4f, 0xf4, 0x00, 0x50, 0x4f, 0xf4, + 0x80, 0x50, 0x0b, 0x4a, 0x01, 0x29, 0x0c, 0xbf, 0x11, 0x68, 0x51, 0x68, + 0x08, 0x40, 0x70, 0x47, 0x00, 0x28, 0x07, 0x49, 0x0c, 0xbf, 0x4f, 0xf4, + 0x00, 0x50, 0x4f, 0xf4, 0x80, 0x50, 0x08, 0x60, 0x70, 0x47, 0x00, 0x00, + 0x3c, 0xee, 0x00, 0x20, 0x14, 0x00, 0x00, 0x50, 0x40, 0x00, 0x00, 0x50, + 0x40, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, + 0xd2, 0xb2, 0x20, 0x3a, 0x22, 0xbf, 0x21, 0xfa, 0x02, 0xf0, 0x00, 0x21, + 0x70, 0x47, 0x20, 0x32, 0xd1, 0x41, 0xd0, 0x40, 0x48, 0x40, 0x91, 0x40, + 0xd1, 0x40, 0x48, 0x40, 0x70, 0x47, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, + 0x10, 0xb5, 0x04, 0x46, 0x18, 0x22, 0x63, 0x00, 0x01, 0x20, 0x00, 0x21, + 0x9a, 0x40, 0x03, 0xf0, 0x17, 0xff, 0x02, 0x46, 0x04, 0xf1, 0x18, 0x00, + 0x0b, 0x46, 0x40, 0x00, 0x04, 0xf0, 0x52, 0xfe, 0xc0, 0xb2, 0x10, 0xbd, + 0x38, 0xb5, 0xdf, 0xf8, 0x00, 0x4d, 0x25, 0x68, 0x00, 0xf0, 0x6b, 0xfb, + 0x05, 0x28, 0x04, 0xbf, 0x28, 0x0c, 0x60, 0xf3, 0x82, 0x05, 0x00, 0xf0, + 0x78, 0xfb, 0x06, 0x28, 0x04, 0xbf, 0x68, 0x0c, 0x60, 0xf3, 0xc3, 0x05, + 0x65, 0x60, 0x31, 0xbd, 0x38, 0xb5, 0x04, 0x46, 0x0d, 0x00, 0x14, 0xbf, + 0x01, 0x20, 0x00, 0x20, 0x04, 0xf0, 0xd3, 0xfc, 0x68, 0x68, 0x00, 0xf0, + 0xc5, 0xfa, 0xdf, 0xf8, 0x30, 0x0d, 0x00, 0xeb, 0x84, 0x00, 0x45, 0x60, + 0xfe, 0xf7, 0x50, 0xfc, 0x01, 0x21, 0x28, 0x46, 0x00, 0xf0, 0x38, 0xfe, + 0x88, 0xe1, 0xf0, 0xb5, 0x83, 0xb0, 0x0c, 0x46, 0xef, 0xf3, 0x05, 0x80, + 0x08, 0xb1, 0x00, 0xf0, 0xbb, 0xfe, 0x00, 0xf0, 0xaf, 0xfe, 0x06, 0x46, + 0x00, 0xf0, 0x64, 0xfa, 0x05, 0x00, 0x14, 0xbf, 0x01, 0x20, 0x00, 0x20, + 0x04, 0xf0, 0xb1, 0xfc, 0x05, 0xf1, 0x1c, 0x07, 0x30, 0x02, 0x40, 0xf0, + 0x02, 0x00, 0x38, 0x60, 0x07, 0x20, 0x04, 0xf0, 0x6c, 0xfd, 0x68, 0x68, + 0xdf, 0xf8, 0xdc, 0x6c, 0x01, 0xab, 0x00, 0x22, 0x17, 0x21, 0xfe, 0xf7, + 0x3d, 0xff, 0x30, 0x68, 0x39, 0x46, 0xff, 0xf7, 0xce, 0xf8, 0x8d, 0xf8, + 0x04, 0x00, 0x40, 0x1e, 0x00, 0xf0, 0x45, 0xfc, 0x0d, 0xf1, 0x05, 0x00, + 0x00, 0x90, 0x23, 0x46, 0x68, 0x68, 0x82, 0x22, 0x02, 0x21, 0xfe, 0xf7, + 0x9f, 0xfe, 0x9d, 0xf8, 0x05, 0x10, 0x00, 0xf0, 0x37, 0xfc, 0x02, 0x20, + 0x04, 0xf0, 0x54, 0xfe, 0xef, 0xf3, 0x11, 0x84, 0x60, 0x20, 0x80, 0xf3, + 0x11, 0x88, 0xdf, 0xf8, 0xa8, 0x7c, 0xdf, 0xf8, 0xa8, 0x1c, 0x3d, 0x68, + 0x4f, 0xf0, 0x00, 0x40, 0x08, 0x60, 0x04, 0xf0, 0xd9, 0xfe, 0x03, 0x28, + 0x04, 0xbf, 0x96, 0xf8, 0x54, 0x03, 0x03, 0x28, 0x03, 0xd1, 0xdf, 0xf8, + 0xbc, 0x1c, 0x01, 0x20, 0x08, 0x70, 0x05, 0xf0, 0x00, 0x40, 0x38, 0x60, + 0x84, 0xf3, 0x11, 0x88, 0x00, 0x20, 0xfe, 0xbd, 0x38, 0xb5, 0xef, 0xf3, + 0x05, 0x80, 0x08, 0xb1, 0x00, 0xf0, 0x60, 0xfe, 0x00, 0xf0, 0x54, 0xfe, + 0x00, 0xf0, 0x09, 0xfa, 0x05, 0x00, 0x14, 0xbf, 0x01, 0x20, 0x00, 0x20, + 0x04, 0xf0, 0x57, 0xfc, 0x20, 0x02, 0x40, 0xf0, 0x03, 0x00, 0x45, 0xf8, + 0x1c, 0x0f, 0x00, 0x21, 0x08, 0x20, 0x04, 0xf0, 0x22, 0xfd, 0xdf, 0xf8, + 0x2c, 0x0c, 0x00, 0x68, 0x29, 0x46, 0xff, 0xf7, 0x7a, 0xf8, 0x40, 0x1e, + 0x00, 0xf0, 0xf3, 0xfb, 0x00, 0x20, 0x32, 0xbd, 0x70, 0xb5, 0x0c, 0x46, + 0xef, 0xf3, 0x05, 0x80, 0x08, 0xb1, 0x00, 0xf0, 0x3b, 0xfe, 0x00, 0xf0, + 0x2f, 0xfe, 0x05, 0x46, 0x00, 0xf0, 0xe4, 0xf9, 0x06, 0x00, 0x14, 0xbf, + 0x01, 0x20, 0x00, 0x20, 0x04, 0xf0, 0x31, 0xfc, 0x06, 0xf1, 0x1c, 0x01, + 0x44, 0xea, 0x05, 0x20, 0x08, 0x60, 0xdf, 0xf8, 0xe8, 0x0b, 0x00, 0x68, + 0xff, 0xf7, 0x59, 0xf8, 0x40, 0x1e, 0x00, 0xf0, 0xd2, 0xfb, 0x00, 0x20, + 0x70, 0xbd, 0x10, 0xb5, 0x04, 0x46, 0x03, 0x20, 0x04, 0xf0, 0xe1, 0xfc, + 0x20, 0x46, 0xbd, 0xe8, 0x10, 0x40, 0x04, 0x21, 0xd4, 0xe7, 0x10, 0xb5, + 0x04, 0x46, 0x20, 0x68, 0xc0, 0xb2, 0x81, 0x42, 0x0c, 0xbf, 0x01, 0x20, + 0x00, 0x20, 0x04, 0xf0, 0x0e, 0xfc, 0xdf, 0xf8, 0xac, 0x0b, 0x00, 0x68, + 0x21, 0x46, 0xff, 0xf7, 0x65, 0xf8, 0x40, 0x1e, 0x00, 0xf0, 0xb3, 0xfb, + 0x00, 0x20, 0x10, 0xbd, 0xdf, 0xf8, 0x94, 0x1b, 0x91, 0xf8, 0x60, 0x23, + 0x0a, 0xb1, 0x00, 0x20, 0x70, 0x47, 0x01, 0x22, 0x81, 0xf8, 0x60, 0x23, + 0x00, 0x21, 0xde, 0xe7, 0x01, 0x21, 0xdc, 0xe7, 0x10, 0xb5, 0x04, 0x46, + 0x17, 0x20, 0x04, 0xf0, 0xb4, 0xfc, 0x20, 0x46, 0xbd, 0xe8, 0x10, 0x40, + 0x08, 0x21, 0xd2, 0xe7, 0x70, 0xb5, 0x04, 0x46, 0x0d, 0x46, 0x82, 0xb0, + 0x21, 0x46, 0x09, 0x20, 0x04, 0xf0, 0xc6, 0xfc, 0x01, 0x21, 0x08, 0x20, + 0x04, 0xf0, 0xb3, 0xfc, 0xe0, 0xb2, 0x00, 0xf0, 0xcb, 0xfd, 0x06, 0x46, + 0x03, 0x20, 0x30, 0x76, 0x0c, 0xb1, 0xc5, 0xf3, 0x02, 0x10, 0xdf, 0xf8, + 0x3c, 0x5b, 0x85, 0xf8, 0x54, 0x03, 0x02, 0x20, 0x04, 0xf0, 0x7e, 0xfd, + 0x70, 0x68, 0x6b, 0x46, 0x01, 0x22, 0x02, 0x21, 0xfe, 0xf7, 0x66, 0xfe, + 0x05, 0xf1, 0x4c, 0x00, 0x01, 0x21, 0x81, 0x72, 0x04, 0x80, 0x00, 0x21, + 0xc1, 0x72, 0x00, 0xf0, 0x6b, 0xfb, 0x00, 0x20, 0x76, 0xbd, 0x70, 0xb5, + 0x04, 0x46, 0xdf, 0xf8, 0x08, 0x5b, 0x60, 0x88, 0x1c, 0x21, 0x01, 0xfb, + 0x00, 0x50, 0x00, 0x2c, 0x90, 0xf8, 0x40, 0x61, 0x14, 0xbf, 0x01, 0x20, + 0x00, 0x20, 0x04, 0xf0, 0xae, 0xfb, 0x00, 0x20, 0x20, 0x63, 0x00, 0x2e, + 0x0c, 0xbf, 0x05, 0xf5, 0x4b, 0x70, 0x05, 0xf5, 0x4c, 0x70, 0x01, 0x68, + 0x11, 0xb9, 0x04, 0x60, 0x70, 0xbd, 0x01, 0x46, 0x08, 0x6b, 0x00, 0x28, + 0xfb, 0xd1, 0x0c, 0x63, 0x70, 0xbd, 0x10, 0xb5, 0x04, 0x46, 0xfe, 0xf7, + 0x1f, 0xfb, 0xdf, 0xf8, 0xc0, 0x0a, 0x00, 0xf5, 0x4b, 0x71, 0x00, 0x2c, + 0x0c, 0xbf, 0x09, 0x68, 0x49, 0x68, 0x71, 0xb1, 0x89, 0x78, 0x1c, 0x22, + 0x02, 0xfb, 0x01, 0x04, 0x94, 0xf8, 0x30, 0x01, 0x03, 0x28, 0x06, 0xd1, + 0x84, 0xf8, 0x30, 0x01, 0xfe, 0xf7, 0x1f, 0xfb, 0x04, 0xf5, 0x98, 0x70, + 0x10, 0xbd, 0xc9, 0xe0, 0x70, 0xb5, 0x04, 0x00, 0x14, 0xbf, 0x01, 0x26, + 0x00, 0x26, 0x30, 0x46, 0x04, 0xf0, 0x77, 0xfb, 0x30, 0x46, 0x04, 0xf0, + 0x74, 0xfb, 0x61, 0x88, 0xdf, 0xf8, 0x74, 0x0a, 0x1c, 0x22, 0x02, 0xfb, + 0x01, 0x01, 0x91, 0xf8, 0x40, 0x11, 0x00, 0x29, 0x0c, 0xbf, 0x00, 0xf5, + 0x4b, 0x70, 0x00, 0xf5, 0x4c, 0x70, 0x01, 0x68, 0xa1, 0x42, 0x06, 0xd1, + 0x09, 0x6b, 0x01, 0x60, 0x00, 0x20, 0x20, 0x63, 0x70, 0xbd, 0x0d, 0x46, + 0x09, 0x6b, 0x00, 0x29, 0x18, 0xbf, 0xa1, 0x42, 0xf9, 0xd1, 0xa1, 0x42, + 0x03, 0xd1, 0x08, 0x6b, 0x28, 0x63, 0x00, 0x20, 0x08, 0x63, 0x70, 0xbd, + 0x38, 0xb5, 0xdf, 0xf8, 0x30, 0x1a, 0x1c, 0x22, 0x02, 0xfb, 0x00, 0x11, + 0x01, 0xf5, 0x98, 0x74, 0x00, 0xf0, 0xf4, 0xf8, 0x05, 0x46, 0xfe, 0xf7, + 0xcb, 0xfa, 0x20, 0x78, 0x01, 0x28, 0x1c, 0xbf, 0x03, 0x28, 0x02, 0x28, + 0x02, 0xd1, 0x28, 0x46, 0xff, 0xf7, 0xbc, 0xff, 0xbd, 0xe8, 0x31, 0x40, + 0xfe, 0xf7, 0xd3, 0xba, 0x10, 0xb5, 0x82, 0xb0, 0x04, 0x46, 0xfe, 0xf7, + 0xb9, 0xfa, 0x00, 0xf0, 0xa4, 0xf8, 0x0c, 0xbf, 0x4c, 0x68, 0x8c, 0x68, + 0xac, 0xb1, 0xa2, 0x78, 0x1c, 0x23, 0x03, 0xfb, 0x02, 0x00, 0x90, 0xf8, + 0x30, 0x21, 0x03, 0x2a, 0x00, 0xd0, 0x8c, 0xe0, 0x4f, 0xf0, 0xff, 0x32, + 0x0a, 0x60, 0x04, 0x21, 0x80, 0xf8, 0x30, 0x11, 0x20, 0x46, 0xff, 0xf7, + 0x9b, 0xff, 0x00, 0xf0, 0x86, 0xf8, 0x00, 0xf0, 0xc1, 0xfa, 0xfe, 0xf7, + 0xb0, 0xfa, 0x00, 0x20, 0x16, 0xbd, 0x2d, 0xe9, 0xf0, 0x43, 0x83, 0xb0, + 0x88, 0x46, 0x14, 0x46, 0xef, 0xf3, 0x05, 0x80, 0x08, 0xb1, 0x00, 0xf0, + 0x07, 0xfd, 0xfe, 0xf7, 0x8d, 0xfa, 0x00, 0xf0, 0xf9, 0xfc, 0xc7, 0xb2, + 0x38, 0x46, 0x00, 0xf0, 0xef, 0xfc, 0x05, 0x46, 0xdf, 0xf8, 0x8c, 0x99, + 0x1c, 0x20, 0x00, 0xfb, 0x07, 0x90, 0x00, 0xf5, 0x98, 0x76, 0x01, 0x20, + 0x30, 0x70, 0x39, 0x46, 0x0a, 0x20, 0x04, 0xf0, 0xd5, 0xfb, 0x28, 0x46, + 0xff, 0xf7, 0x31, 0xff, 0x38, 0x02, 0x40, 0xf0, 0x07, 0x00, 0x70, 0x61, + 0x06, 0xf1, 0x14, 0x01, 0xdf, 0xf8, 0x98, 0x0c, 0x00, 0x68, 0xfe, 0xf7, + 0x16, 0xff, 0x40, 0x1e, 0x00, 0xf0, 0x8f, 0xfa, 0xfe, 0xf7, 0x7b, 0xfa, + 0x01, 0xa8, 0x00, 0x90, 0x43, 0x46, 0x68, 0x68, 0x83, 0x22, 0x10, 0x21, + 0xfe, 0xf7, 0xe8, 0xfc, 0x9d, 0xf8, 0x04, 0x10, 0x00, 0xf0, 0x80, 0xfa, + 0x03, 0x20, 0x04, 0xf0, 0x9d, 0xfc, 0x09, 0xf6, 0x6c, 0x40, 0x20, 0x60, + 0x00, 0x20, 0xbd, 0xe8, 0xfe, 0x83, 0x10, 0xb5, 0xef, 0xf3, 0x05, 0x80, + 0x08, 0xb1, 0x00, 0xf0, 0xc3, 0xfc, 0xfe, 0xf7, 0x49, 0xfa, 0x00, 0xf0, + 0xb5, 0xfc, 0x00, 0xf0, 0x6a, 0xf8, 0xdf, 0xf8, 0x0c, 0x19, 0xe4, 0xb2, + 0x1c, 0x22, 0x02, 0xfb, 0x04, 0x11, 0x00, 0x20, 0x81, 0xf8, 0x30, 0x01, + 0xfe, 0xf7, 0x4f, 0xfa, 0x00, 0x20, 0x10, 0xbd, 0x10, 0xb5, 0x82, 0xb0, + 0x04, 0x46, 0xfe, 0xf7, 0x33, 0xfa, 0x00, 0xf0, 0x1e, 0xf8, 0x0c, 0xbf, + 0x4c, 0x68, 0x8c, 0x68, 0x7c, 0xb1, 0xa2, 0x78, 0x0a, 0x60, 0x1c, 0x23, + 0x03, 0xfb, 0x02, 0x00, 0x02, 0x21, 0x80, 0xf8, 0x30, 0x11, 0x03, 0x20, + 0x04, 0xf0, 0x4a, 0xfc, 0x00, 0xf0, 0x07, 0xf8, 0x00, 0xf0, 0x42, 0xfa, + 0x7f, 0xe7, 0xfe, 0xf7, 0x30, 0xfa, 0x01, 0x20, 0x16, 0xbd, 0x60, 0x68, + 0x6b, 0x46, 0x01, 0x22, 0x10, 0x21, 0xfe, 0xf7, 0x29, 0xbd, 0xdf, 0xf8, + 0xa8, 0x08, 0x00, 0xf5, 0x4a, 0x71, 0x00, 0x2c, 0x70, 0x47, 0x2d, 0xe9, + 0xfc, 0x41, 0x04, 0x46, 0x88, 0x46, 0x16, 0x46, 0xef, 0xf3, 0x05, 0x80, + 0x08, 0xb1, 0x00, 0xf0, 0x7b, 0xfc, 0xfe, 0xf7, 0x01, 0xfa, 0x00, 0xf0, + 0x6d, 0xfc, 0x05, 0x46, 0x00, 0xf0, 0x22, 0xf8, 0x07, 0x46, 0xdf, 0xf8, + 0x78, 0x08, 0xed, 0xb2, 0x1c, 0x21, 0x01, 0xfb, 0x05, 0x01, 0x01, 0xf5, + 0x98, 0x71, 0x03, 0x22, 0x00, 0xf6, 0x6c, 0x40, 0x0a, 0x70, 0x48, 0x60, + 0xce, 0x60, 0x0c, 0x74, 0xfe, 0xf7, 0xff, 0xf9, 0x01, 0xa8, 0x00, 0x90, + 0x43, 0x46, 0x78, 0x68, 0x83, 0x22, 0x10, 0x21, 0xfe, 0xf7, 0x6c, 0xfc, + 0x9d, 0xf8, 0x04, 0x10, 0x00, 0xf0, 0x04, 0xfa, 0x00, 0x20, 0xbd, 0xe8, + 0xf6, 0x81, 0x04, 0x46, 0xc0, 0xb2, 0x00, 0xf0, 0x3f, 0xbc, 0x30, 0xb5, + 0xdf, 0xf8, 0x2c, 0x48, 0x87, 0xb0, 0x14, 0x21, 0x04, 0xf2, 0x84, 0x40, + 0xfe, 0xf7, 0xc3, 0xfd, 0x20, 0x60, 0x00, 0xf0, 0x39, 0xf8, 0x03, 0x21, + 0x04, 0x91, 0x00, 0x21, 0x03, 0x91, 0x80, 0x21, 0x02, 0x91, 0x03, 0x21, + 0xdf, 0xf8, 0x68, 0x0c, 0x01, 0x90, 0x00, 0x91, 0x00, 0xf5, 0xfe, 0x72, + 0x03, 0x23, 0x00, 0x21, 0x0f, 0xf6, 0xa9, 0x10, 0xfe, 0xf7, 0x8d, 0xff, + 0x40, 0x1e, 0x00, 0xf0, 0xdc, 0xf9, 0x05, 0xaa, 0x0f, 0xf2, 0x38, 0x01, + 0x03, 0x20, 0xff, 0xf7, 0x3b, 0xf8, 0x04, 0xf1, 0x4c, 0x00, 0x00, 0x21, + 0x01, 0x81, 0x04, 0xf5, 0x51, 0x75, 0x4f, 0xf6, 0xff, 0x71, 0x01, 0x80, + 0x4f, 0xf0, 0xff, 0x31, 0x29, 0x60, 0x69, 0x60, 0x00, 0x21, 0x81, 0x72, + 0x04, 0xf5, 0x59, 0x70, 0xe8, 0x60, 0x00, 0xf0, 0x44, 0xf8, 0x00, 0x20, + 0x28, 0x72, 0x28, 0x77, 0x07, 0xb0, 0x30, 0xbd, 0x43, 0x74, 0x72, 0x6c, + 0x54, 0x73, 0x6b, 0x00, 0x00, 0xb1, 0x01, 0x20, 0x04, 0xf0, 0x07, 0xba, + 0xf8, 0xb5, 0x00, 0x25, 0x00, 0x21, 0xdf, 0xf8, 0x98, 0x67, 0x20, 0xfa, + 0x01, 0xf2, 0xd2, 0x07, 0x03, 0xd5, 0x06, 0xeb, 0x81, 0x02, 0xd4, 0x6f, + 0x34, 0xb9, 0x49, 0x1c, 0x07, 0x29, 0xf4, 0xd3, 0x28, 0x46, 0xf2, 0xbd, + 0x00, 0x25, 0x14, 0x46, 0xe2, 0x6a, 0x00, 0x2a, 0xf5, 0xd0, 0x63, 0x7b, + 0xa5, 0x7b, 0x2b, 0x42, 0xf6, 0xd0, 0x01, 0x21, 0x20, 0x46, 0x00, 0xf0, + 0x7d, 0xfb, 0x20, 0x7b, 0x01, 0x25, 0x07, 0x46, 0x07, 0x28, 0xb4, 0xbf, + 0x01, 0x20, 0x00, 0x20, 0x04, 0xf0, 0xdf, 0xf9, 0x00, 0x20, 0xe0, 0x62, + 0x06, 0xeb, 0x87, 0x00, 0xc1, 0x6f, 0xc4, 0x67, 0x00, 0x29, 0xdf, 0xd0, + 0xe1, 0x62, 0xdd, 0xe7, 0xdf, 0xf8, 0x38, 0x07, 0x90, 0xf8, 0x54, 0x03, + 0x70, 0x47, 0xdf, 0xf8, 0xfc, 0x0b, 0x40, 0x89, 0x00, 0xf0, 0x03, 0x01, + 0xc0, 0xf3, 0x01, 0x10, 0x03, 0x28, 0x04, 0xd1, 0x03, 0x29, 0x0c, 0xd1, + 0x01, 0x20, 0x02, 0x21, 0x1f, 0xe0, 0x01, 0x28, 0x18, 0xbf, 0x02, 0x28, + 0x0d, 0xd1, 0x03, 0x29, 0x09, 0xd1, 0x01, 0x28, 0x13, 0xd1, 0x03, 0x20, + 0x14, 0xe0, 0x01, 0x29, 0x18, 0xbf, 0x02, 0x29, 0x0f, 0xd1, 0x08, 0x46, + 0x0f, 0xe0, 0x01, 0x28, 0x01, 0xd0, 0x02, 0x28, 0x09, 0xd1, 0x01, 0x29, + 0x18, 0xbf, 0x02, 0x29, 0x05, 0xd1, 0x01, 0x28, 0x01, 0xd1, 0x08, 0x46, + 0x02, 0xe0, 0x00, 0x20, 0x01, 0xe0, 0x00, 0x20, 0x00, 0x21, 0x40, 0xea, + 0x81, 0x00, 0xdf, 0xf8, 0xd0, 0x16, 0x81, 0xf8, 0xb8, 0x03, 0x70, 0x47, + 0xdf, 0xf8, 0xc4, 0x26, 0x92, 0xf8, 0xb8, 0x23, 0x01, 0x23, 0x03, 0xfa, + 0x00, 0xf0, 0x00, 0x21, 0x00, 0xea, 0x02, 0x03, 0x13, 0xf0, 0x03, 0x0f, + 0x18, 0xbf, 0x01, 0x21, 0x05, 0xd1, 0x00, 0xea, 0x92, 0x00, 0x10, 0xf0, + 0x03, 0x0f, 0x18, 0xbf, 0x02, 0x21, 0xdf, 0xf8, 0x68, 0x0b, 0x40, 0x89, + 0x01, 0xea, 0x10, 0x10, 0x40, 0x1e, 0x40, 0xb2, 0x70, 0x47, 0xdf, 0xf8, + 0x8c, 0x06, 0xd0, 0xf8, 0x64, 0x13, 0xca, 0x03, 0x05, 0xd5, 0x90, 0xf8, + 0xba, 0x23, 0x05, 0x2a, 0x01, 0xd1, 0x05, 0x20, 0x70, 0x47, 0x49, 0x07, + 0x03, 0xd5, 0x90, 0xf8, 0xba, 0x03, 0x01, 0x28, 0x00, 0xd0, 0xff, 0x20, + 0x70, 0x47, 0xdf, 0xf8, 0x64, 0x06, 0xd0, 0xf8, 0x64, 0x13, 0x8a, 0x03, + 0x05, 0xd5, 0x90, 0xf8, 0xbb, 0x23, 0x06, 0x2a, 0x01, 0xd1, 0x06, 0x20, + 0x70, 0x47, 0x09, 0x07, 0x03, 0xd5, 0x90, 0xf8, 0xbb, 0x03, 0x02, 0x28, + 0x00, 0xd0, 0xff, 0x20, 0x70, 0x47, 0x10, 0xb5, 0x04, 0x46, 0x00, 0xf0, + 0x47, 0xfb, 0x84, 0x42, 0x0c, 0xbf, 0x01, 0x20, 0x00, 0x20, 0x10, 0xbd, + 0x2d, 0xe9, 0xf1, 0x4f, 0x0c, 0x46, 0xdf, 0xf8, 0x24, 0x86, 0xdf, 0xf8, + 0xf0, 0xaa, 0x15, 0x46, 0x01, 0x26, 0x04, 0xf0, 0x04, 0x0b, 0x08, 0xf2, + 0xb9, 0x39, 0x00, 0x98, 0xf0, 0x40, 0xc0, 0x07, 0x6d, 0xd5, 0x08, 0xeb, + 0x86, 0x00, 0xc7, 0x6f, 0x23, 0xe0, 0x38, 0x78, 0x05, 0x28, 0x09, 0xd1, + 0xff, 0xf7, 0xb5, 0xff, 0x85, 0x42, 0x66, 0xd0, 0x03, 0x2d, 0x03, 0xd1, + 0x99, 0xf8, 0x03, 0x00, 0x00, 0x28, 0x60, 0xd1, 0x38, 0x78, 0x06, 0x28, + 0x09, 0xd1, 0xff, 0xf7, 0xbc, 0xff, 0x85, 0x42, 0x59, 0xd0, 0x03, 0x2d, + 0x03, 0xd1, 0x99, 0xf8, 0x03, 0x00, 0x00, 0x28, 0x53, 0xd1, 0x38, 0x78, + 0x01, 0x28, 0x01, 0xd1, 0xe1, 0x07, 0x4e, 0xd4, 0x02, 0x28, 0x01, 0xd1, + 0xa0, 0x07, 0x4a, 0xd4, 0xff, 0x6a, 0x00, 0x2f, 0x43, 0xd0, 0x78, 0x7b, + 0x00, 0x28, 0xf9, 0xd0, 0x79, 0x88, 0xd8, 0xf8, 0x48, 0x03, 0x11, 0xf8, + 0x0a, 0x10, 0xc8, 0x40, 0xc0, 0x07, 0xf1, 0xd5, 0x38, 0x7b, 0x01, 0x28, + 0x18, 0xbf, 0x04, 0x28, 0x25, 0xd0, 0x05, 0x28, 0xc7, 0xd0, 0x02, 0x28, + 0x1f, 0xd1, 0x39, 0x78, 0x99, 0xf8, 0x00, 0x00, 0x03, 0x29, 0x0c, 0xd1, + 0xbb, 0xf1, 0x00, 0x0f, 0xe0, 0xd0, 0x03, 0x2d, 0x29, 0xd0, 0x01, 0x2d, + 0x02, 0xd1, 0xc0, 0x07, 0xda, 0xd5, 0x24, 0xe0, 0x02, 0x2d, 0xd7, 0xd1, + 0x0b, 0xe0, 0x04, 0x29, 0xd4, 0xd1, 0x21, 0x07, 0xd2, 0xd5, 0x03, 0x2d, + 0x1b, 0xd0, 0x02, 0x2d, 0x01, 0xd1, 0x00, 0x07, 0xf0, 0xe7, 0x01, 0x2d, + 0xca, 0xd1, 0x80, 0x07, 0xec, 0xe7, 0x03, 0x28, 0xc6, 0xd1, 0x39, 0x78, + 0x03, 0x29, 0x03, 0xd1, 0xbb, 0xf1, 0x00, 0x0f, 0x04, 0xd1, 0xbf, 0xe7, + 0x04, 0x29, 0xbd, 0xd1, 0x20, 0x07, 0xbb, 0xd5, 0x03, 0x2d, 0xb9, 0xd1, + 0x03, 0xe0, 0x76, 0x1c, 0x07, 0x2e, 0x8a, 0xdb, 0x00, 0x27, 0x38, 0x46, + 0xbd, 0xe8, 0xf2, 0x8f, 0x2d, 0xe9, 0xf0, 0x41, 0xdf, 0xf8, 0xec, 0x59, + 0x80, 0x46, 0x95, 0xf8, 0x4c, 0x00, 0xc0, 0x07, 0x0e, 0x46, 0x04, 0xd5, + 0x28, 0x7a, 0x01, 0x28, 0x08, 0xbf, 0x00, 0x20, 0x2d, 0xd0, 0x2c, 0x6d, + 0xc6, 0xf3, 0x02, 0x17, 0x4c, 0xb1, 0x20, 0x46, 0xff, 0xf7, 0xaa, 0xfe, + 0x28, 0xb1, 0x3a, 0x46, 0x31, 0x46, 0x20, 0x46, 0xff, 0xf7, 0x5e, 0xff, + 0x20, 0xb9, 0x3a, 0x46, 0x31, 0x46, 0x7f, 0x20, 0xff, 0xf7, 0x58, 0xff, + 0x00, 0x28, 0xa9, 0x7a, 0x14, 0xbf, 0x07, 0x7b, 0x00, 0x27, 0x79, 0xb1, + 0x2e, 0x88, 0xf0, 0xb2, 0x00, 0xf0, 0x8a, 0xfa, 0xb8, 0xf1, 0x00, 0x0f, + 0x04, 0xbf, 0x00, 0x7b, 0xb8, 0x42, 0x0c, 0xd0, 0xe8, 0x7a, 0x50, 0xb9, + 0xf0, 0xb2, 0x00, 0xf0, 0x07, 0xf9, 0x06, 0xe0, 0x00, 0x2e, 0x04, 0xd4, + 0x18, 0xb1, 0x40, 0x88, 0x31, 0x46, 0xff, 0xf7, 0x9d, 0xfc, 0x00, 0x20, + 0xbd, 0xe8, 0xf0, 0x81, 0x70, 0xb5, 0x04, 0x00, 0x14, 0xbf, 0x01, 0x20, + 0x00, 0x20, 0x04, 0xf0, 0x7e, 0xf8, 0x20, 0x68, 0x0f, 0x28, 0x00, 0xf0, + 0x28, 0xf8, 0x25, 0x68, 0xdf, 0xf8, 0x80, 0x24, 0xd2, 0xf8, 0xbc, 0x60, + 0x28, 0x46, 0x41, 0x08, 0x02, 0xeb, 0xc1, 0x01, 0x01, 0xf1, 0xc0, 0x03, + 0xf8, 0x31, 0xc6, 0x40, 0xf6, 0x07, 0x04, 0xd5, 0xbd, 0xe8, 0x70, 0x40, + 0x01, 0x21, 0x04, 0xf0, 0xa7, 0xb9, 0x1d, 0x60, 0x01, 0x25, 0x64, 0x68, + 0x5c, 0x60, 0x05, 0xfa, 0x00, 0xf0, 0xd2, 0xf8, 0xbc, 0x40, 0x20, 0x43, + 0xc2, 0xf8, 0xbc, 0x00, 0x0d, 0x60, 0x4b, 0x60, 0x08, 0x46, 0xbd, 0xe8, + 0x70, 0x40, 0x5d, 0xe4, 0x9d, 0xf8, 0x00, 0x10, 0x48, 0x1e, 0x80, 0x41, + 0xc0, 0x0f, 0x04, 0xf0, 0x4e, 0xb8, 0xf8, 0xb5, 0x06, 0x46, 0x37, 0x68, + 0x0e, 0x2f, 0x20, 0xd2, 0x00, 0x21, 0x38, 0x46, 0xdf, 0xf8, 0x1c, 0x44, + 0x04, 0xf0, 0x6e, 0xf9, 0x04, 0xf1, 0x54, 0x05, 0xf8, 0xb2, 0x29, 0x78, + 0x05, 0xf0, 0x56, 0xfb, 0x00, 0x28, 0x40, 0xf0, 0xa6, 0x80, 0x6f, 0xb1, + 0x02, 0x2f, 0x10, 0xd0, 0x04, 0x2f, 0x19, 0xd0, 0x06, 0x2f, 0x5f, 0xd0, + 0x08, 0x2f, 0x4f, 0xd0, 0x0a, 0x2f, 0x69, 0xd0, 0x0c, 0x2f, 0x00, 0xf0, + 0x80, 0x80, 0x93, 0xe0, 0x70, 0x68, 0x00, 0xf0, 0x8f, 0xfb, 0x00, 0x20, + 0xf2, 0xbd, 0x74, 0x68, 0x0e, 0x20, 0x04, 0xf0, 0xe6, 0xf8, 0x01, 0x20, + 0x28, 0x70, 0x00, 0x21, 0x20, 0x46, 0x05, 0xf0, 0xbd, 0xfb, 0xf2, 0xe7, + 0x10, 0x20, 0x04, 0xf0, 0xdc, 0xf8, 0x04, 0xf0, 0x0c, 0xfe, 0x01, 0x00, + 0x06, 0xd0, 0x04, 0x20, 0x04, 0xf0, 0x52, 0xf9, 0x04, 0x20, 0x00, 0xf0, + 0x62, 0xfb, 0xe4, 0xe7, 0x04, 0x20, 0x28, 0x70, 0x1c, 0x21, 0x00, 0x20, + 0xa8, 0x64, 0x04, 0xf1, 0xa0, 0x00, 0x03, 0xf0, 0x59, 0xfe, 0x00, 0xf0, + 0xfd, 0xfb, 0x48, 0xb1, 0x4f, 0xf0, 0x7f, 0x42, 0x40, 0xf6, 0xff, 0x73, + 0x00, 0x20, 0x00, 0xf0, 0x0d, 0xf9, 0x68, 0x46, 0x05, 0xf0, 0x7d, 0xfb, + 0xff, 0xf7, 0x06, 0xfb, 0x07, 0x22, 0x00, 0x23, 0x03, 0x20, 0x00, 0xf0, + 0x03, 0xf9, 0x04, 0x20, 0x00, 0xf0, 0x41, 0xfb, 0x00, 0x25, 0x6c, 0x20, + 0x00, 0xfb, 0x05, 0x40, 0x00, 0xf2, 0x14, 0x50, 0x05, 0xf0, 0x32, 0xfc, + 0x6d, 0x1c, 0x12, 0x2d, 0xf5, 0xd3, 0xb8, 0xe7, 0x74, 0x68, 0x12, 0x20, + 0x04, 0xf0, 0xa1, 0xf8, 0x21, 0x46, 0x00, 0x20, 0x05, 0xf0, 0x2a, 0xfc, + 0x01, 0x46, 0x08, 0x20, 0x04, 0xf0, 0x16, 0xf9, 0x08, 0x20, 0xc2, 0xe7, + 0x74, 0x68, 0x11, 0x20, 0x04, 0xf0, 0x93, 0xf8, 0x21, 0x46, 0x01, 0x20, + 0x05, 0xf0, 0x1c, 0xfc, 0x01, 0x46, 0x06, 0x20, 0x04, 0xf0, 0x08, 0xf9, + 0x06, 0x20, 0xb4, 0xe7, 0x74, 0x68, 0x14, 0x20, 0x04, 0xf0, 0x85, 0xf8, + 0x29, 0x78, 0xe0, 0xb2, 0x05, 0xf0, 0xc6, 0xfa, 0x48, 0xb9, 0xc4, 0xf3, + 0x42, 0x10, 0x03, 0x28, 0x04, 0xd1, 0x01, 0x21, 0x20, 0x46, 0x00, 0xf0, + 0xf9, 0xfb, 0x00, 0xe0, 0x04, 0x20, 0x01, 0x46, 0x0a, 0x20, 0x04, 0xf0, + 0xef, 0xf8, 0x0a, 0x20, 0x9b, 0xe7, 0x74, 0x68, 0x20, 0x06, 0x45, 0x0f, + 0x13, 0x20, 0x04, 0xf0, 0x6a, 0xf8, 0x03, 0x2d, 0x18, 0xbf, 0x02, 0x2d, + 0x11, 0xbf, 0x04, 0x20, 0x00, 0x21, 0x20, 0x46, 0x00, 0xf0, 0xe2, 0xfb, + 0x01, 0x46, 0x0c, 0x20, 0x04, 0xf0, 0xda, 0xf8, 0x0c, 0x20, 0x86, 0xe7, + 0x03, 0xf0, 0x95, 0xff, 0x6b, 0xe7, 0x80, 0x28, 0x03, 0xd1, 0x38, 0x46, + 0x00, 0xf0, 0xe3, 0xfa, 0x65, 0xe7, 0x01, 0x46, 0x38, 0x46, 0x04, 0xf0, + 0xcb, 0xf8, 0xf6, 0xe7, 0x10, 0xb5, 0x82, 0xb0, 0x00, 0xf0, 0x74, 0xf9, + 0x04, 0x46, 0x20, 0x7e, 0x05, 0x28, 0x1c, 0xbf, 0x04, 0x20, 0x20, 0x76, + 0x02, 0x20, 0x04, 0xf0, 0x2b, 0xf9, 0x60, 0x68, 0x6b, 0x46, 0x01, 0x22, + 0x01, 0x21, 0xfe, 0xf7, 0x13, 0xfa, 0xff, 0xf7, 0x1f, 0xff, 0xdf, 0xf8, + 0x70, 0x1b, 0x01, 0x20, 0x81, 0xf8, 0x57, 0x00, 0x06, 0x20, 0x04, 0xf0, + 0x30, 0xf8, 0x00, 0x20, 0x16, 0xbd, 0x70, 0xb5, 0x04, 0x46, 0x0d, 0x46, + 0xff, 0xf7, 0x12, 0xfd, 0x06, 0x46, 0xb0, 0x7b, 0x28, 0xb1, 0xe0, 0xb2, + 0x00, 0xf0, 0xb2, 0xf8, 0x05, 0x20, 0x04, 0xf0, 0x20, 0xf8, 0x00, 0x20, + 0x70, 0x73, 0xb0, 0x73, 0x01, 0x21, 0x30, 0x46, 0x00, 0xf0, 0xea, 0xf8, + 0xe0, 0xb2, 0x05, 0xf0, 0x57, 0xfb, 0xdf, 0xf8, 0x2c, 0x1b, 0x01, 0xeb, + 0x84, 0x01, 0x00, 0x20, 0x48, 0x60, 0x30, 0x69, 0xff, 0xf7, 0x3e, 0xfd, + 0x70, 0x6a, 0x33, 0x69, 0x00, 0x22, 0x29, 0x46, 0x98, 0x47, 0x00, 0x20, + 0x70, 0xbd, 0xf0, 0xb5, 0x83, 0xb0, 0x07, 0x46, 0x00, 0xf0, 0x2c, 0xf9, + 0x04, 0x46, 0x02, 0x20, 0x04, 0xf0, 0x06, 0xf9, 0x20, 0x7e, 0xdf, 0xf8, + 0xf8, 0x5a, 0x05, 0x28, 0x05, 0xf1, 0x4c, 0x06, 0x11, 0xd1, 0x01, 0x21, + 0x38, 0x46, 0xff, 0xf7, 0xc4, 0xff, 0x30, 0x7a, 0x05, 0x28, 0x0a, 0xd1, + 0x03, 0x20, 0x30, 0x72, 0x04, 0xf0, 0x13, 0xfc, 0x00, 0xf0, 0x35, 0xf8, + 0x04, 0xf0, 0x1e, 0xf9, 0x00, 0x20, 0x00, 0xf0, 0x74, 0xfa, 0x00, 0x20, + 0x60, 0x73, 0x02, 0x20, 0x20, 0x76, 0x4f, 0xf6, 0xff, 0x70, 0x30, 0x80, + 0x00, 0x20, 0x70, 0x81, 0x00, 0x2f, 0x04, 0xbf, 0x30, 0x7a, 0x05, 0x28, + 0x0a, 0xd1, 0x08, 0x20, 0x00, 0x90, 0x4f, 0xf0, 0xff, 0x30, 0x01, 0x90, + 0x68, 0x46, 0x00, 0xf0, 0x20, 0xf8, 0x00, 0x20, 0x00, 0xf0, 0x5b, 0xfa, + 0x20, 0x7b, 0x05, 0xeb, 0x80, 0x01, 0x01, 0x22, 0xc9, 0x6f, 0x04, 0xe0, + 0x4b, 0x7b, 0x01, 0x2b, 0x08, 0xbf, 0x00, 0x22, 0xc9, 0x6a, 0x00, 0x29, + 0xf8, 0xd1, 0x32, 0xb1, 0xf1, 0x6c, 0x01, 0x22, 0x02, 0xfa, 0x00, 0xf0, + 0x21, 0xea, 0x00, 0x00, 0xf0, 0x64, 0x00, 0x20, 0xfe, 0xbd, 0x07, 0x22, + 0x00, 0x23, 0x02, 0x20, 0x00, 0x21, 0x04, 0xf0, 0x39, 0xb8, 0xf8, 0xb5, + 0x06, 0x46, 0x00, 0x20, 0x00, 0xf0, 0xd4, 0xf8, 0xdf, 0xf8, 0x50, 0x5a, + 0xd5, 0xf8, 0xc8, 0x70, 0x05, 0xf1, 0x54, 0x04, 0xa0, 0x6e, 0x80, 0x08, + 0x00, 0xf0, 0x01, 0x00, 0x03, 0xf0, 0xd9, 0xfe, 0x02, 0x2f, 0x0c, 0xbf, + 0x01, 0x20, 0x00, 0x20, 0x03, 0xf0, 0xd3, 0xfe, 0x71, 0x68, 0xc9, 0xb2, + 0x38, 0x46, 0x04, 0xf0, 0x0f, 0xf8, 0x38, 0x46, 0x00, 0xf0, 0x1f, 0xfa, + 0x70, 0x68, 0x70, 0xb9, 0x05, 0xf0, 0x93, 0xfc, 0x48, 0xb1, 0x03, 0x20, + 0x20, 0x70, 0x01, 0x20, 0x85, 0xf8, 0x4c, 0x03, 0x04, 0xf0, 0xab, 0xfb, + 0xff, 0xf7, 0xcd, 0xff, 0x08, 0xe0, 0x02, 0x20, 0x05, 0xe0, 0x95, 0xf8, + 0x4c, 0x03, 0x00, 0x28, 0x14, 0xbf, 0x03, 0x20, 0x02, 0x20, 0x20, 0x70, + 0x01, 0x21, 0x00, 0x20, 0xff, 0xf7, 0x45, 0xff, 0x00, 0x20, 0xf2, 0xbd, + 0x80, 0xb5, 0x00, 0xf0, 0x99, 0xf8, 0x00, 0x21, 0x81, 0x73, 0x02, 0x7b, + 0xdf, 0xf8, 0xd4, 0x19, 0x01, 0xeb, 0x82, 0x02, 0xd2, 0xf8, 0xa0, 0x30, + 0x5b, 0x1e, 0xc2, 0xf8, 0xa0, 0x30, 0x00, 0x7b, 0x01, 0xeb, 0x80, 0x02, + 0xd2, 0xf8, 0xa0, 0x20, 0x42, 0xb9, 0xd1, 0xf8, 0x9c, 0x20, 0x01, 0x23, + 0x03, 0xfa, 0x00, 0xf0, 0x22, 0xea, 0x00, 0x00, 0xc1, 0xf8, 0x9c, 0x00, + 0x00, 0x20, 0x02, 0xbd, 0x70, 0xb5, 0x04, 0x46, 0x0d, 0x46, 0x20, 0x7b, + 0x06, 0x46, 0x07, 0x28, 0xb4, 0xbf, 0x01, 0x20, 0x00, 0x20, 0x03, 0xf0, + 0x82, 0xfe, 0x00, 0x20, 0xe0, 0x62, 0x00, 0x2d, 0x23, 0x48, 0x0c, 0xbf, + 0x60, 0x30, 0x7c, 0x30, 0x50, 0xf8, 0x26, 0x10, 0x19, 0xb9, 0x40, 0xf8, + 0x26, 0x40, 0x04, 0xe0, 0x01, 0x46, 0xc8, 0x6a, 0x00, 0x28, 0xfb, 0xd1, + 0xcc, 0x62, 0x00, 0x20, 0x70, 0xbd, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x20, + 0xf8, 0xb5, 0x06, 0x46, 0x0f, 0x46, 0x30, 0x7b, 0x04, 0x46, 0x07, 0x28, + 0xb4, 0xbf, 0x01, 0x20, 0x00, 0x20, 0x03, 0xf0, 0x60, 0xfe, 0xdf, 0xf8, + 0x48, 0x19, 0x00, 0x2f, 0x0c, 0xbf, 0x01, 0xf1, 0x60, 0x02, 0x01, 0xf1, + 0x7c, 0x02, 0x52, 0xf8, 0x24, 0x00, 0xb0, 0x42, 0x11, 0xd1, 0xc3, 0x6a, + 0x42, 0xf8, 0x24, 0x30, 0x3b, 0xb9, 0x04, 0x7b, 0xd1, 0xf8, 0x98, 0x20, + 0x01, 0x23, 0xa3, 0x40, 0x9a, 0x43, 0xc1, 0xf8, 0x98, 0x20, 0x00, 0x21, + 0xc1, 0x62, 0x00, 0x20, 0xf2, 0xbd, 0x05, 0x46, 0xc0, 0x6a, 0x00, 0x28, + 0x18, 0xbf, 0xb0, 0x42, 0xf9, 0xd1, 0xb0, 0x42, 0x02, 0xd1, 0xc1, 0x6a, + 0xe9, 0x62, 0xf0, 0xe7, 0x01, 0x20, 0xf2, 0xbd, 0xb8, 0x04, 0x00, 0x20, + 0xdf, 0xf8, 0xf0, 0x18, 0xdf, 0xf8, 0xc4, 0x24, 0xd1, 0xf8, 0x50, 0x13, + 0x80, 0x5c, 0x1d, 0xe0, 0x00, 0xe1, 0x00, 0xe0, 0x80, 0xe1, 0x00, 0xe0, + 0x10, 0xb5, 0x04, 0x46, 0x04, 0x2c, 0xb4, 0xbf, 0x01, 0x20, 0x00, 0x20, + 0x03, 0xf0, 0x21, 0xfe, 0xdf, 0xf8, 0xc8, 0x08, 0x00, 0xeb, 0x84, 0x00, + 0xd0, 0xf8, 0xa8, 0x43, 0x04, 0xf0, 0x4a, 0xf8, 0xa0, 0x42, 0x34, 0xbf, + 0x20, 0x1a, 0x00, 0x20, 0x10, 0xbd, 0x00, 0x00, 0x65, 0x2c, 0x00, 0x20, + 0xdf, 0xf8, 0xa8, 0x18, 0x01, 0xeb, 0x80, 0x00, 0x40, 0x68, 0x70, 0x47, + 0x80, 0xb5, 0xef, 0xf3, 0x05, 0x80, 0x08, 0xb1, 0x00, 0xf0, 0x04, 0xf8, + 0xdf, 0xf8, 0x94, 0x08, 0x00, 0x68, 0x02, 0xbd, 0x00, 0x20, 0x03, 0xf0, + 0xfe, 0xbd, 0x80, 0xb5, 0xff, 0xf7, 0xf0, 0xff, 0xdf, 0xf8, 0x54, 0x14, + 0x40, 0x5c, 0x02, 0xbd, 0x10, 0xb5, 0xdf, 0xf8, 0x78, 0x48, 0x20, 0x68, + 0x10, 0xf1, 0x01, 0x0f, 0x14, 0xbf, 0x01, 0x20, 0x00, 0x20, 0x03, 0xf0, + 0xec, 0xfd, 0xef, 0xf3, 0x05, 0x80, 0x08, 0xb1, 0xff, 0xf7, 0xe6, 0xff, + 0x20, 0x68, 0xc0, 0xb2, 0xff, 0xf7, 0xd2, 0xff, 0x04, 0x00, 0x14, 0xbf, + 0x01, 0x20, 0x00, 0x20, 0x03, 0xf0, 0xdd, 0xfd, 0x60, 0x68, 0x10, 0xbd, + 0xf8, 0xb5, 0x00, 0xf0, 0x56, 0xf8, 0x0e, 0x46, 0x14, 0xbf, 0x01, 0x20, + 0x00, 0x20, 0x03, 0xf0, 0xd2, 0xfd, 0xef, 0xf3, 0x05, 0x80, 0x08, 0xb1, + 0xff, 0xf7, 0xcc, 0xff, 0x67, 0x00, 0x01, 0x20, 0x00, 0x21, 0x07, 0xf1, + 0x18, 0x02, 0x02, 0xf0, 0xe5, 0xff, 0x04, 0x46, 0x0d, 0x46, 0x01, 0x20, + 0x00, 0x21, 0x07, 0xf1, 0x19, 0x02, 0x02, 0xf0, 0xdd, 0xff, 0x03, 0x2e, + 0x14, 0xd8, 0xdf, 0xe8, 0x06, 0xf0, 0x02, 0x07, 0x0a, 0x0d, 0x22, 0x46, + 0x2b, 0x46, 0x20, 0x46, 0x29, 0x46, 0x09, 0xe0, 0x22, 0x46, 0x2b, 0x46, + 0x04, 0xe0, 0x02, 0x46, 0x0b, 0x46, 0x03, 0xe0, 0x02, 0x46, 0x0b, 0x46, + 0x00, 0x20, 0x00, 0x21, 0x03, 0xf0, 0xf6, 0xfe, 0x00, 0x20, 0xf2, 0xbd, + 0x10, 0xb5, 0x82, 0xb0, 0xff, 0xf7, 0x96, 0xff, 0xc0, 0xb2, 0xff, 0xf7, + 0x8d, 0xff, 0x00, 0xf0, 0x1a, 0xf8, 0x14, 0xbf, 0x01, 0x20, 0x00, 0x20, + 0x03, 0xf0, 0x97, 0xfd, 0xef, 0xf3, 0x05, 0x80, 0x08, 0xb1, 0xff, 0xf7, + 0x91, 0xff, 0x60, 0x68, 0x6b, 0x46, 0x00, 0x22, 0x08, 0x21, 0xfe, 0xf7, + 0x29, 0xf8, 0xff, 0xf7, 0x35, 0xfd, 0xa0, 0x6a, 0x69, 0x46, 0xfe, 0xf7, + 0xbd, 0xfc, 0xff, 0xf7, 0x2f, 0xfd, 0x00, 0x20, 0x16, 0xbd, 0x04, 0x46, + 0xdf, 0xf8, 0x8c, 0x07, 0x00, 0x68, 0x10, 0xf1, 0x01, 0x0f, 0x70, 0x47, + 0x00, 0xb5, 0xdf, 0xf8, 0x80, 0x07, 0x83, 0xb0, 0x00, 0x68, 0x10, 0xf1, + 0x01, 0x0f, 0x14, 0xbf, 0x01, 0x20, 0x00, 0x20, 0x03, 0xf0, 0x6f, 0xfd, + 0xef, 0xf3, 0x05, 0x80, 0x08, 0xb1, 0xff, 0xf7, 0x69, 0xff, 0xff, 0xf7, + 0x71, 0xff, 0x01, 0xa9, 0x00, 0x91, 0x00, 0x23, 0x82, 0x22, 0x08, 0x21, + 0xfd, 0xf7, 0x72, 0xff, 0x00, 0x20, 0x0e, 0xbd, 0x2d, 0xe9, 0xf0, 0x47, + 0x82, 0xb0, 0x04, 0xf0, 0xa8, 0xf8, 0xdf, 0xf8, 0x44, 0x07, 0xdf, 0xf8, + 0x38, 0x47, 0x03, 0xf0, 0x5b, 0xfe, 0x04, 0xf1, 0x54, 0x05, 0x02, 0x20, + 0x28, 0x70, 0x01, 0x26, 0x00, 0x20, 0xc0, 0x46, 0x07, 0x22, 0x00, 0x23, + 0x01, 0x20, 0xff, 0xf7, 0x5b, 0xfe, 0x03, 0xf0, 0x9d, 0xff, 0x20, 0x65, + 0x09, 0xe0, 0x40, 0x46, 0xff, 0xf7, 0x57, 0xfe, 0x21, 0x6d, 0x48, 0x46, + 0xff, 0xf7, 0x76, 0xfc, 0x01, 0x20, 0x03, 0xf0, 0x07, 0xff, 0x20, 0x68, + 0x6a, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0xfb, 0xf8, 0x80, 0x46, 0x01, 0x20, + 0xd8, 0xf8, 0x00, 0xa0, 0x03, 0xf0, 0xde, 0xfe, 0x5f, 0xfa, 0x8a, 0xf0, + 0x0a, 0x28, 0x4f, 0xea, 0x1a, 0x27, 0x4f, 0xf0, 0x00, 0x09, 0xe5, 0xd8, + 0xdf, 0xe8, 0x00, 0xf0, 0x08, 0x13, 0x37, 0x46, 0x4a, 0x06, 0x06, 0x06, + 0x07, 0x56, 0x69, 0x00, 0xdc, 0xe7, 0xd8, 0xe7, 0x84, 0xf8, 0x60, 0x93, + 0x03, 0xf0, 0x70, 0xff, 0x01, 0x46, 0x21, 0x65, 0x02, 0x20, 0x03, 0xf0, + 0xf7, 0xfd, 0xb1, 0x46, 0xd0, 0xe7, 0xb4, 0xf8, 0xc0, 0x03, 0xd8, 0xf8, + 0x04, 0x30, 0x04, 0xeb, 0xc0, 0x00, 0x00, 0xf5, 0x71, 0x72, 0xd3, 0xe9, + 0x00, 0x01, 0xc2, 0xe9, 0x00, 0x01, 0xd8, 0xf8, 0x04, 0x00, 0xff, 0xf7, + 0xb4, 0xfc, 0xb4, 0xf8, 0xc0, 0x03, 0xdf, 0xf8, 0x94, 0x16, 0x09, 0x68, + 0x04, 0xeb, 0x80, 0x00, 0xc0, 0xf8, 0x44, 0x14, 0xb4, 0xf8, 0xc0, 0x03, + 0x40, 0x1c, 0xa4, 0xf8, 0xc0, 0x03, 0x80, 0xb2, 0x10, 0x28, 0xaf, 0xdb, + 0xa4, 0xf8, 0xc0, 0x93, 0xac, 0xe7, 0x28, 0x78, 0x05, 0x28, 0xa9, 0xd0, + 0xf8, 0xb2, 0xff, 0xf7, 0xd7, 0xfe, 0x02, 0x7b, 0x69, 0x6c, 0x06, 0xfa, + 0x02, 0xf2, 0x11, 0x43, 0x69, 0x64, 0x06, 0x76, 0x46, 0x73, 0x9d, 0xe7, + 0xf8, 0xb2, 0xff, 0xf7, 0x9a, 0xfd, 0x99, 0xe7, 0xf8, 0xb2, 0xff, 0xf7, + 0xc7, 0xfe, 0x07, 0x46, 0x01, 0x21, 0xff, 0xf7, 0x69, 0xfe, 0x01, 0x21, + 0x38, 0x46, 0xff, 0xf7, 0x43, 0xfe, 0x8d, 0xe7, 0xf8, 0xb2, 0xff, 0xf7, + 0xbb, 0xfe, 0x02, 0x7b, 0xa9, 0x6c, 0x06, 0xfa, 0x02, 0xf2, 0x11, 0x43, + 0xa9, 0x64, 0x01, 0x7b, 0x04, 0xeb, 0x81, 0x01, 0xd1, 0xf8, 0xa0, 0x20, + 0x52, 0x1c, 0xc1, 0xf8, 0xa0, 0x20, 0x86, 0x73, 0x7a, 0xe7, 0xf8, 0xb2, + 0xff, 0xf7, 0x0c, 0xfe, 0x76, 0xe7, 0xdf, 0xf8, 0x08, 0x06, 0xdf, 0xf8, + 0xf8, 0x25, 0x00, 0x68, 0x41, 0x68, 0x11, 0x60, 0x90, 0xf8, 0x32, 0x10, + 0x01, 0x20, 0x03, 0xf0, 0x8f, 0xbd, 0x10, 0xb5, 0x04, 0x46, 0x72, 0xb6, + 0x03, 0xf0, 0xc1, 0xfd, 0xdf, 0xf8, 0xd4, 0x05, 0xd0, 0xf8, 0xbc, 0x10, + 0x01, 0x22, 0xa2, 0x40, 0x91, 0x43, 0xc0, 0xf8, 0xbc, 0x10, 0x62, 0xb6, + 0x10, 0xbd, 0x00, 0x00, 0x88, 0xf2, 0x00, 0x20, 0xfe, 0xb5, 0x0f, 0x20, + 0xdf, 0xf8, 0xb4, 0x55, 0x03, 0xf0, 0x57, 0xfd, 0x05, 0xf1, 0x4c, 0x04, + 0x20, 0x7a, 0x01, 0x28, 0x10, 0xd1, 0xa0, 0x7a, 0x28, 0xb1, 0x05, 0x20, + 0x20, 0x72, 0x00, 0x20, 0xff, 0xf7, 0xfe, 0xfc, 0x3f, 0xe0, 0x08, 0x20, + 0x01, 0x90, 0x4f, 0xf0, 0xff, 0x30, 0x02, 0x90, 0x01, 0xa8, 0xff, 0xf7, + 0x94, 0xfd, 0x33, 0xe0, 0x68, 0x46, 0x05, 0xf0, 0x25, 0xfb, 0x68, 0x46, + 0x05, 0xf0, 0xf5, 0xfa, 0x05, 0x20, 0x20, 0x72, 0x01, 0x26, 0x04, 0xf0, + 0x54, 0xf9, 0x05, 0xeb, 0x86, 0x00, 0x47, 0x68, 0x8f, 0xb1, 0x78, 0x88, + 0x22, 0x88, 0xc1, 0xb2, 0x91, 0x42, 0x08, 0xd1, 0x39, 0x7e, 0x05, 0x29, + 0x05, 0xd0, 0xc0, 0xb2, 0xff, 0xf7, 0xda, 0xfc, 0x05, 0x20, 0x38, 0x76, + 0x03, 0xe0, 0x01, 0x21, 0xc0, 0xb2, 0xff, 0xf7, 0xf2, 0xfc, 0x76, 0x1c, + 0x12, 0x2e, 0xe6, 0xdb, 0x20, 0x88, 0x4f, 0xf6, 0xff, 0x71, 0x88, 0x42, + 0x0d, 0xd1, 0x05, 0xf0, 0x1e, 0xfa, 0x50, 0xb1, 0x03, 0x20, 0x20, 0x72, + 0x04, 0xf0, 0x39, 0xf9, 0xff, 0xf7, 0x5b, 0xfd, 0x03, 0xf0, 0x44, 0xfe, + 0x00, 0x20, 0xff, 0xf7, 0x9a, 0xff, 0x00, 0x20, 0xfe, 0xbd, 0x10, 0xb5, + 0x82, 0xb0, 0xef, 0xf3, 0x05, 0x80, 0x08, 0xb1, 0xff, 0xf7, 0x3c, 0xfe, + 0xff, 0xf7, 0x30, 0xfe, 0xff, 0xf7, 0x42, 0xfe, 0x04, 0x00, 0x14, 0xbf, + 0x01, 0x20, 0x00, 0x20, 0x03, 0xf0, 0x33, 0xfc, 0x6b, 0x46, 0x02, 0x22, + 0x01, 0x21, 0x20, 0x46, 0xfd, 0xf7, 0xd4, 0xfd, 0x00, 0xf0, 0x01, 0x00, + 0x16, 0xbd, 0x10, 0xb5, 0x00, 0x24, 0xc0, 0xf3, 0x47, 0x12, 0x00, 0x2a, + 0x18, 0xbf, 0x01, 0x2a, 0x00, 0xf0, 0x1f, 0x00, 0x14, 0xd1, 0x02, 0x29, + 0x10, 0xd2, 0x0c, 0x23, 0x58, 0x43, 0x00, 0x2a, 0x0c, 0xbf, 0xdf, 0xf8, + 0xd0, 0x24, 0xdf, 0xf8, 0xd0, 0x24, 0x80, 0x18, 0x82, 0x68, 0x50, 0xf8, + 0x21, 0x10, 0xdf, 0xf8, 0xc8, 0x04, 0x05, 0xf0, 0x1d, 0xfb, 0x02, 0xe0, + 0x05, 0x24, 0x00, 0xe0, 0x04, 0x24, 0x20, 0x46, 0x10, 0xbd, 0x00, 0x00, + 0x68, 0x76, 0x00, 0x20, 0xf8, 0xb5, 0xdf, 0xf8, 0x90, 0x04, 0xd0, 0xf8, + 0x50, 0x03, 0x05, 0x68, 0x16, 0x48, 0x44, 0x89, 0x04, 0xf0, 0x03, 0x00, + 0xc4, 0xf3, 0x83, 0x01, 0x41, 0xea, 0x00, 0x11, 0x41, 0xea, 0x80, 0x11, + 0x41, 0xea, 0x00, 0x21, 0x41, 0xea, 0x80, 0x21, 0x41, 0xea, 0x00, 0x30, + 0x00, 0xea, 0x05, 0x06, 0xff, 0xf7, 0x6d, 0xfa, 0x05, 0x28, 0x0c, 0xbf, + 0x01, 0x27, 0x00, 0x27, 0xff, 0xf7, 0x7b, 0xfa, 0x06, 0x28, 0x0c, 0xbf, + 0x01, 0x20, 0x00, 0x20, 0x47, 0xea, 0x40, 0x00, 0x15, 0xea, 0x00, 0x40, + 0x07, 0xd0, 0x00, 0x90, 0x00, 0x98, 0x80, 0x0b, 0x00, 0xea, 0x94, 0x00, + 0x00, 0xf0, 0x0c, 0x00, 0x06, 0x43, 0x30, 0x46, 0xf2, 0xbd, 0x00, 0x00, + 0x78, 0x29, 0x00, 0x20, 0xf4, 0x1e, 0x00, 0x20, 0x04, 0x05, 0x00, 0x20, + 0xdf, 0xf8, 0x1c, 0x14, 0xd1, 0xf8, 0x64, 0x13, 0xc1, 0x40, 0x01, 0xf0, + 0x01, 0x00, 0x70, 0x47, 0x10, 0xb5, 0x04, 0x46, 0xff, 0xf7, 0xba, 0xff, + 0xe0, 0x40, 0x00, 0xf0, 0x01, 0x00, 0x10, 0xbd, 0x2d, 0xe9, 0xf0, 0x43, + 0x00, 0x24, 0x85, 0xb0, 0x03, 0x46, 0xde, 0xb2, 0x0f, 0x46, 0x18, 0x0a, + 0x40, 0x2e, 0x4f, 0xea, 0x13, 0x4c, 0x00, 0xf0, 0x0f, 0x01, 0xdf, 0xf8, + 0xe4, 0x83, 0xdf, 0xf8, 0xfc, 0x53, 0x18, 0xbf, 0x41, 0x2e, 0x0c, 0xf0, + 0x01, 0x0e, 0x00, 0xf0, 0x03, 0x00, 0xc3, 0xf3, 0x07, 0x22, 0x08, 0xf5, + 0x51, 0x79, 0x2b, 0xd0, 0x42, 0x2e, 0x2e, 0xd0, 0x43, 0x2e, 0x32, 0xd0, + 0x44, 0x2e, 0x25, 0xd0, 0x60, 0x2e, 0x35, 0xd0, 0x61, 0x2e, 0x00, 0xf0, + 0x73, 0x81, 0x62, 0x2e, 0x68, 0xd0, 0x63, 0x2e, 0x00, 0xf0, 0x4d, 0x81, + 0x64, 0x2e, 0x00, 0xf0, 0x7b, 0x81, 0x65, 0x2e, 0x00, 0xf0, 0x80, 0x80, + 0x66, 0x2e, 0x00, 0xf0, 0x9c, 0x80, 0x67, 0x2e, 0x00, 0xf0, 0x1f, 0x81, + 0x69, 0x2e, 0x00, 0xf0, 0x39, 0x81, 0x6a, 0x2e, 0x00, 0xf0, 0x7a, 0x81, + 0x6b, 0x2e, 0x00, 0xf0, 0x7f, 0x81, 0x6c, 0x2e, 0x03, 0xd0, 0x6d, 0x2e, + 0x00, 0xf0, 0x3e, 0x81, 0x7d, 0xe1, 0x00, 0x2f, 0x00, 0xf0, 0x7a, 0x81, + 0x05, 0xf0, 0x17, 0xfb, 0x77, 0xe1, 0xc3, 0xf3, 0x07, 0x41, 0x10, 0x46, + 0xff, 0xf7, 0x3f, 0xff, 0x3f, 0xe1, 0x14, 0x22, 0xdf, 0xf8, 0x74, 0x13, + 0x28, 0x46, 0x05, 0xf0, 0x71, 0xfa, 0x6a, 0xe1, 0x16, 0x46, 0xe0, 0x46, + 0x30, 0x46, 0x05, 0xf0, 0x15, 0xfb, 0x00, 0x28, 0x00, 0xf0, 0xfb, 0x80, + 0x00, 0x2f, 0x30, 0x46, 0x11, 0xd0, 0x05, 0xf0, 0x6b, 0xfb, 0x18, 0xb9, + 0x08, 0xf0, 0x1f, 0x01, 0x00, 0x22, 0x06, 0xe0, 0x4f, 0xea, 0x08, 0x62, + 0x10, 0x0f, 0x08, 0xf0, 0x0f, 0x01, 0x00, 0xf0, 0x01, 0x02, 0x30, 0x46, + 0x05, 0xf0, 0x37, 0xfb, 0x4d, 0xe1, 0x05, 0xf0, 0x20, 0xfb, 0x07, 0x46, + 0x30, 0x46, 0x05, 0xf0, 0x4b, 0xfb, 0x80, 0x46, 0x30, 0x46, 0x05, 0xf0, + 0x51, 0xfb, 0x3f, 0x02, 0x18, 0xb9, 0x08, 0xf0, 0x1f, 0x00, 0x38, 0x43, + 0x36, 0xe1, 0xb8, 0xf1, 0x13, 0x0f, 0x08, 0xbf, 0x2f, 0x60, 0xe9, 0xd0, + 0x08, 0xf0, 0x0f, 0x00, 0x38, 0x43, 0x40, 0xf0, 0x10, 0x00, 0x2b, 0xe1, + 0x00, 0x2f, 0x40, 0xf0, 0x2f, 0x81, 0x00, 0x20, 0xfe, 0xf7, 0x69, 0xfd, + 0x06, 0x46, 0x00, 0x20, 0xfe, 0xf7, 0x6e, 0xfd, 0x46, 0xea, 0x00, 0x40, + 0x04, 0x90, 0x01, 0x20, 0xfe, 0xf7, 0x5f, 0xfd, 0x06, 0x46, 0x01, 0x20, + 0xfe, 0xf7, 0x64, 0xfd, 0x46, 0xea, 0x00, 0x40, 0x03, 0x90, 0x04, 0x22, + 0x04, 0xa9, 0x28, 0x46, 0x05, 0xf0, 0x1c, 0xfa, 0x04, 0x22, 0x03, 0xa9, + 0x28, 0x1d, 0x02, 0xe1, 0xd9, 0xf8, 0x00, 0x00, 0x00, 0x2f, 0xda, 0xd0, + 0x0f, 0x29, 0x03, 0xd1, 0x28, 0x68, 0xc9, 0xf8, 0x00, 0x00, 0x11, 0xe0, + 0xc3, 0xf3, 0x00, 0x32, 0x02, 0xeb, 0x41, 0x01, 0x14, 0x29, 0x28, 0xbf, + 0x04, 0x24, 0x01, 0x22, 0x02, 0xfa, 0x01, 0xf1, 0x9a, 0x04, 0x4c, 0xbf, + 0x08, 0x43, 0x88, 0x43, 0x00, 0x2c, 0xc9, 0xf8, 0x00, 0x00, 0x01, 0xd1, + 0xfe, 0xf7, 0xfc, 0xfd, 0xf3, 0xe0, 0x56, 0x1e, 0x07, 0x2e, 0xc3, 0xf3, + 0x01, 0x41, 0xbc, 0xd8, 0xdf, 0xe8, 0x06, 0xf0, 0x04, 0x20, 0x57, 0x62, + 0x4c, 0x4c, 0x6c, 0x12, 0x00, 0x2f, 0x67, 0xd0, 0x5f, 0xfa, 0x8c, 0xf1, + 0x01, 0xf0, 0x03, 0x00, 0x49, 0x07, 0x02, 0xd5, 0xfc, 0xf7, 0x9c, 0xff, + 0xdd, 0xe0, 0xfc, 0xf7, 0x8b, 0xff, 0xda, 0xe0, 0x00, 0x2f, 0x76, 0x46, + 0x58, 0xd0, 0x29, 0x46, 0x30, 0x46, 0x03, 0xf0, 0x34, 0xf8, 0x00, 0x28, + 0x52, 0xd0, 0x29, 0x46, 0x30, 0x46, 0x02, 0xf0, 0xe4, 0xff, 0xcc, 0xe0, + 0xc3, 0xf3, 0x83, 0x46, 0x00, 0x2f, 0x18, 0xbf, 0x00, 0x2e, 0x0d, 0x46, + 0x46, 0xd0, 0x00, 0x27, 0x25, 0xfa, 0x07, 0xf0, 0xc0, 0x07, 0x1b, 0xd5, + 0x00, 0x2f, 0x14, 0xbf, 0x09, 0x20, 0x08, 0x20, 0x98, 0xf8, 0x54, 0x10, + 0x03, 0x29, 0x04, 0xd0, 0xd9, 0xf8, 0x20, 0x10, 0xc1, 0x40, 0xc8, 0x07, + 0x04, 0xd4, 0x31, 0x46, 0x38, 0x46, 0x05, 0xf0, 0xe5, 0xfd, 0x09, 0xe0, + 0x38, 0x46, 0x05, 0xf0, 0xc4, 0xfd, 0x08, 0xb1, 0x01, 0x24, 0xa8, 0xe0, + 0x31, 0x46, 0x38, 0x46, 0x05, 0xf0, 0xc7, 0xfd, 0x7f, 0x1c, 0x02, 0x2f, + 0xdc, 0xd3, 0xa0, 0xe0, 0x00, 0x2f, 0x1f, 0xd0, 0x05, 0x2a, 0x0c, 0xbf, + 0x00, 0x20, 0x01, 0x20, 0x0f, 0xfa, 0x8c, 0xf1, 0x06, 0xf0, 0x6e, 0xfb, + 0x95, 0xe0, 0x00, 0x2f, 0x14, 0xd0, 0x0d, 0x46, 0x28, 0x46, 0x07, 0xf0, + 0x6f, 0xff, 0x29, 0x46, 0x00, 0x20, 0x05, 0xf0, 0x56, 0xfd, 0x8a, 0xe0, + 0x00, 0x2f, 0x09, 0xd0, 0x0d, 0x46, 0x01, 0x20, 0x05, 0xf0, 0x4f, 0xfd, + 0x28, 0x46, 0x07, 0xf0, 0x73, 0xff, 0x80, 0xe0, 0x00, 0x2f, 0x0c, 0x46, + 0x7c, 0xd0, 0x98, 0xf8, 0x54, 0x00, 0x03, 0x28, 0x78, 0xd1, 0x00, 0x25, + 0x24, 0xfa, 0x05, 0xf0, 0xc0, 0x07, 0x44, 0xbf, 0x28, 0x46, 0x05, 0xf0, + 0x9c, 0xfd, 0x6d, 0x1c, 0x02, 0x2d, 0xf5, 0xd3, 0x6c, 0xe0, 0x0e, 0xeb, + 0x41, 0x00, 0xc0, 0xb2, 0x06, 0x46, 0x13, 0x2e, 0x01, 0xdb, 0x05, 0x24, + 0x65, 0xe0, 0x7f, 0xb1, 0xfe, 0xf7, 0x58, 0xfd, 0x00, 0x28, 0x60, 0xd1, + 0x56, 0x48, 0x30, 0x5c, 0x08, 0xeb, 0x80, 0x00, 0x02, 0xab, 0x40, 0x68, + 0x40, 0x68, 0x01, 0x22, 0x28, 0x21, 0xfd, 0xf7, 0xe9, 0xfc, 0x54, 0xe0, + 0xfe, 0xf7, 0x48, 0xfd, 0x28, 0x70, 0x50, 0xe0, 0x00, 0x2f, 0x4d, 0xd0, + 0xff, 0xf7, 0x42, 0xfc, 0x4b, 0xe0, 0x27, 0xb1, 0xd5, 0xe9, 0x00, 0x23, + 0x04, 0xf0, 0xa2, 0xfc, 0x13, 0xe0, 0x07, 0xf0, 0xcd, 0xff, 0xc5, 0xe9, + 0x00, 0x01, 0x40, 0xe0, 0x4f, 0xea, 0x8c, 0x56, 0x18, 0x0b, 0xb6, 0x0d, + 0x00, 0xf0, 0x03, 0x00, 0x4f, 0xb1, 0x02, 0x28, 0xa8, 0xbf, 0x07, 0x24, + 0x35, 0xda, 0x0a, 0x46, 0x31, 0x46, 0x08, 0xf0, 0x58, 0xfc, 0x04, 0x46, + 0x2f, 0xe0, 0xea, 0x1c, 0x29, 0x46, 0x08, 0xf0, 0x7a, 0xfc, 0x2a, 0xe0, + 0x7f, 0xb9, 0x03, 0xf0, 0x7f, 0xfc, 0x06, 0x46, 0x04, 0x2e, 0x05, 0xd1, + 0x04, 0xf0, 0x3d, 0xfc, 0x46, 0xea, 0x00, 0x10, 0x00, 0x90, 0x00, 0xe0, + 0x00, 0x96, 0x04, 0x22, 0x69, 0x46, 0x09, 0xe0, 0x0f, 0xb1, 0x02, 0x24, + 0x17, 0xe0, 0x03, 0xf0, 0x63, 0xfc, 0x00, 0xf0, 0x0f, 0x00, 0x01, 0x90, + 0x04, 0x22, 0x01, 0xa9, 0x28, 0x46, 0x05, 0xf0, 0x13, 0xf9, 0x0c, 0xe0, + 0x17, 0xb1, 0x04, 0xf0, 0x20, 0xfc, 0x08, 0xe0, 0x04, 0xf0, 0x21, 0xfc, + 0x28, 0x60, 0x04, 0xe0, 0x17, 0xb1, 0x08, 0xf0, 0x3f, 0xff, 0x00, 0xe0, + 0x03, 0x24, 0xe0, 0xb2, 0x05, 0xb0, 0xbd, 0xe8, 0xf0, 0x83, 0x38, 0xb5, + 0x04, 0x46, 0x1a, 0x48, 0x90, 0xf8, 0xb8, 0x03, 0x0d, 0x46, 0x00, 0xf0, + 0x03, 0x01, 0x03, 0x29, 0xc0, 0xf3, 0x81, 0x00, 0x01, 0xd1, 0xb0, 0xb9, + 0x03, 0xe0, 0x00, 0x29, 0x08, 0xbf, 0x03, 0x28, 0x11, 0xd1, 0x0b, 0x20, + 0x05, 0xf0, 0xea, 0xf9, 0x13, 0x28, 0x01, 0xd1, 0x01, 0x20, 0x32, 0xbd, + 0x1c, 0xb9, 0x0b, 0x20, 0x05, 0xf0, 0x9c, 0xf9, 0x02, 0xe0, 0x0b, 0x20, + 0x05, 0xf0, 0x8f, 0xf9, 0x28, 0x46, 0x01, 0xf0, 0xf9, 0xfe, 0x00, 0x20, + 0x32, 0xbd, 0x08, 0x48, 0xd0, 0xf8, 0xa8, 0x03, 0x70, 0x47, 0x06, 0x48, + 0xd0, 0xf8, 0xb4, 0x03, 0x70, 0x47, 0x04, 0x48, 0xd0, 0xf8, 0xac, 0x03, + 0x70, 0x47, 0x02, 0x48, 0x90, 0xf8, 0x54, 0x00, 0x70, 0x47, 0x00, 0x00, + 0xb8, 0x04, 0x00, 0x20, 0x60, 0xf3, 0x00, 0x20, 0x49, 0x3d, 0x00, 0x01, + 0x08, 0x00, 0x00, 0x49, 0x48, 0xbd, 0x00, 0x20, 0x98, 0x68, 0x01, 0x01, + 0xa8, 0x6f, 0x01, 0x01, 0x00, 0x00, 0x00, 0x20, 0xe8, 0xf2, 0x00, 0x20, + 0xc8, 0x20, 0x00, 0x20, 0xdf, 0xf8, 0x84, 0x07, 0x00, 0x68, 0x70, 0x47, + 0x28, 0x21, 0x42, 0xf6, 0x2c, 0x40, 0xf8, 0xb5, 0x04, 0x46, 0x0d, 0x46, + 0x00, 0x22, 0x00, 0xf0, 0x44, 0xf8, 0x40, 0xf2, 0xc9, 0x66, 0x80, 0x21, + 0x30, 0x46, 0xfe, 0xf7, 0x7b, 0xfa, 0x00, 0x21, 0x30, 0x46, 0xfe, 0xf7, + 0x77, 0xfa, 0xdf, 0xf8, 0x5c, 0x07, 0xdf, 0xf8, 0x5c, 0x17, 0x40, 0x6b, + 0x46, 0x00, 0x30, 0x46, 0x00, 0x27, 0x01, 0xe0, 0x40, 0x08, 0x7f, 0x1c, + 0x88, 0x42, 0xfb, 0xd2, 0x06, 0x2f, 0xb4, 0xbf, 0x01, 0x20, 0x00, 0x20, + 0x03, 0xf0, 0x7d, 0xf9, 0x7a, 0x01, 0xd2, 0xb2, 0xe0, 0x21, 0x00, 0xf0, + 0x23, 0xf8, 0xdf, 0xf8, 0x28, 0x07, 0xfe, 0x40, 0x06, 0x60, 0x04, 0x22, + 0x00, 0xf0, 0x1b, 0xf8, 0xdf, 0xf8, 0x24, 0x07, 0xdf, 0xf8, 0x24, 0x17, + 0xdf, 0xf8, 0x24, 0x27, 0x04, 0x80, 0x45, 0x80, 0x30, 0x20, 0x08, 0x80, + 0xdf, 0xf8, 0x1c, 0x17, 0x08, 0x80, 0x0f, 0x21, 0xdf, 0xf8, 0x18, 0x07, + 0x01, 0x80, 0x30, 0x21, 0x11, 0x80, 0x01, 0x80, 0x70, 0x21, 0x01, 0x80, + 0xb0, 0x21, 0x01, 0x80, 0xf0, 0x21, 0x01, 0x80, 0xf1, 0xbd, 0x04, 0x21, + 0x4f, 0xf4, 0x8c, 0x70, 0xfe, 0xf7, 0x42, 0xba, 0x2d, 0xe9, 0xf8, 0x4f, + 0xdf, 0xf8, 0xf4, 0x66, 0xdf, 0xf8, 0xf4, 0x16, 0xdf, 0xf8, 0xd0, 0x26, + 0x18, 0xb9, 0xd2, 0xe9, 0x06, 0x5b, 0xc8, 0x6a, 0x03, 0xe0, 0xd2, 0xe9, + 0x08, 0x5b, 0x08, 0x6c, 0x50, 0x36, 0x30, 0x21, 0xb0, 0xfb, 0xf1, 0xf9, + 0x50, 0x21, 0x30, 0x46, 0x02, 0xf0, 0x8e, 0xff, 0x01, 0x27, 0x09, 0xfb, + 0x07, 0xf0, 0x00, 0x21, 0x15, 0xeb, 0x00, 0x08, 0x4b, 0xeb, 0x01, 0x0a, + 0x28, 0x1a, 0x6b, 0xeb, 0x01, 0x01, 0x08, 0xf0, 0x83, 0xff, 0x01, 0x21, + 0x00, 0x28, 0x01, 0xfa, 0x07, 0xf4, 0x03, 0xd5, 0xb0, 0x6c, 0x20, 0x43, + 0xb0, 0x64, 0x04, 0xe0, 0x06, 0xeb, 0x80, 0x00, 0x41, 0x6a, 0x21, 0x43, + 0x41, 0x62, 0x40, 0x46, 0x51, 0x46, 0x08, 0xf0, 0x71, 0xff, 0x00, 0x28, + 0x03, 0xd5, 0xf0, 0x6c, 0x20, 0x43, 0xf0, 0x64, 0x04, 0xe0, 0x56, 0xf8, + 0x20, 0x10, 0x21, 0x43, 0x46, 0xf8, 0x20, 0x10, 0x7f, 0x1c, 0x18, 0x2f, + 0xd3, 0xd3, 0xbd, 0xe8, 0xf1, 0x8f, 0x2d, 0xe9, 0xf8, 0x4f, 0x89, 0x46, + 0x17, 0x46, 0xdf, 0xf8, 0x48, 0x16, 0xdf, 0xf8, 0x64, 0x26, 0x15, 0x68, + 0x00, 0x28, 0x07, 0xbf, 0xd0, 0x6a, 0xd1, 0xe9, 0x00, 0x48, 0x10, 0x6c, + 0xd1, 0xe9, 0x02, 0x48, 0x01, 0x09, 0x00, 0x07, 0x2a, 0x46, 0x00, 0x23, + 0x02, 0xf0, 0x08, 0xfc, 0x30, 0x22, 0x00, 0x23, 0x02, 0xf0, 0x04, 0xfc, + 0x06, 0x46, 0x8a, 0x46, 0xdf, 0xb1, 0x07, 0xf1, 0x18, 0x00, 0x31, 0x28, + 0x17, 0xd2, 0xfa, 0x17, 0xa6, 0xfb, 0x07, 0x01, 0x06, 0xfb, 0x02, 0x11, + 0x0a, 0xfb, 0x07, 0x11, 0x27, 0x1a, 0x28, 0x46, 0x68, 0xeb, 0x01, 0x0b, + 0xa0, 0xfb, 0x07, 0x23, 0x00, 0xfb, 0x0b, 0x33, 0x12, 0x0f, 0x42, 0xea, + 0x03, 0x10, 0x19, 0x0f, 0x08, 0xf0, 0x2a, 0xff, 0x05, 0x46, 0x00, 0x2d, + 0x01, 0xd5, 0x00, 0x20, 0x20, 0xe0, 0x3a, 0x46, 0x5b, 0x46, 0x48, 0x46, + 0x08, 0xf0, 0x78, 0xfe, 0x2a, 0x46, 0x20, 0x46, 0x41, 0x46, 0x08, 0xf0, + 0x38, 0xfe, 0x04, 0x46, 0x0f, 0x46, 0x2a, 0x46, 0x30, 0x46, 0x51, 0x46, + 0x08, 0xf0, 0x31, 0xfe, 0x06, 0x46, 0xdf, 0xf8, 0xd8, 0x25, 0x24, 0x09, + 0x00, 0x0f, 0x44, 0xea, 0x07, 0x74, 0x40, 0xea, 0x01, 0x10, 0x14, 0x60, + 0x40, 0xf4, 0x00, 0x40, 0x10, 0x81, 0x30, 0x01, 0x50, 0x60, 0x01, 0x20, + 0xbd, 0xe8, 0xf2, 0x8f, 0xdf, 0xf8, 0xb8, 0x15, 0x08, 0x80, 0x70, 0x47, + 0x4f, 0xf0, 0x82, 0x41, 0x02, 0x68, 0x0a, 0x60, 0x42, 0x68, 0x4a, 0x60, + 0x02, 0x89, 0x0a, 0x81, 0x42, 0x89, 0x4a, 0x81, 0x82, 0x89, 0x8a, 0x81, + 0xc2, 0x89, 0xca, 0x87, 0xdf, 0xf8, 0x98, 0x15, 0x02, 0x8a, 0x0a, 0x80, + 0x40, 0x8a, 0x48, 0x80, 0x00, 0x21, 0xdf, 0xf8, 0x90, 0x05, 0x41, 0x80, + 0x81, 0x82, 0xc1, 0x82, 0x1f, 0x21, 0x01, 0x80, 0x00, 0x21, 0x81, 0x80, + 0xc1, 0x80, 0x70, 0x47, 0x38, 0xb5, 0x0c, 0x46, 0x01, 0xf0, 0x8a, 0xfe, + 0xdf, 0xf8, 0x74, 0x15, 0x02, 0xf0, 0x24, 0xf8, 0x05, 0x46, 0x20, 0x46, + 0x01, 0xf0, 0x82, 0xfe, 0x29, 0x46, 0x02, 0xf0, 0x1d, 0xf8, 0xdf, 0xf8, + 0x64, 0x15, 0x01, 0xf0, 0x8b, 0xfe, 0x08, 0xf0, 0x17, 0xff, 0x04, 0x46, + 0x03, 0xf0, 0xab, 0xf8, 0x20, 0x28, 0x28, 0xbf, 0x1f, 0x20, 0x01, 0x21, + 0x01, 0xfa, 0x00, 0xf2, 0x43, 0x1e, 0xa2, 0x1a, 0x99, 0x40, 0x8a, 0x42, + 0x28, 0xbf, 0x40, 0xf0, 0x20, 0x00, 0x80, 0xb2, 0x32, 0xbd, 0x00, 0xf0, + 0x1f, 0x01, 0x01, 0x22, 0x8a, 0x40, 0xc0, 0xf3, 0x40, 0x10, 0x49, 0x1e, + 0x88, 0x40, 0x80, 0x18, 0x70, 0x47, 0xdf, 0xf8, 0x24, 0x25, 0x4f, 0xf6, + 0xff, 0x73, 0x13, 0x81, 0x01, 0xb1, 0x04, 0x21, 0x00, 0xf0, 0x03, 0x00, + 0x08, 0x18, 0x00, 0x02, 0x40, 0xf4, 0x10, 0x40, 0x10, 0x80, 0x70, 0x47, + 0xdf, 0xf8, 0x04, 0x05, 0x01, 0x88, 0x01, 0xf4, 0x73, 0x61, 0x41, 0xf0, + 0x80, 0x01, 0x01, 0x80, 0x70, 0x47, 0xf0, 0xb5, 0x04, 0x46, 0x0d, 0x46, + 0x83, 0xb0, 0x00, 0xf0, 0x0c, 0xf9, 0xdf, 0xf8, 0xec, 0x64, 0xdf, 0xf8, + 0xec, 0x74, 0xff, 0xf7, 0x3b, 0xfa, 0x30, 0x60, 0x06, 0x21, 0x03, 0x20, + 0x03, 0xf0, 0x8d, 0xf8, 0x4f, 0xf6, 0xff, 0x70, 0xb8, 0x80, 0x4f, 0xf6, + 0xf5, 0x30, 0xb8, 0x81, 0x03, 0x20, 0x03, 0xf0, 0x69, 0xf8, 0x03, 0x20, + 0x03, 0xf0, 0x6c, 0xf8, 0x30, 0x68, 0x00, 0xf0, 0xed, 0xf8, 0x29, 0x46, + 0xe0, 0xb2, 0xff, 0xf7, 0xc4, 0xff, 0x01, 0xa8, 0x00, 0x90, 0x41, 0xf2, + 0x88, 0x33, 0x30, 0x68, 0x03, 0x22, 0x05, 0x21, 0xfd, 0xf7, 0x22, 0xfa, + 0x39, 0x88, 0xc0, 0x07, 0x04, 0xd5, 0x2f, 0x20, 0x03, 0xf0, 0xcf, 0xf8, + 0x01, 0x24, 0x0d, 0xe0, 0x40, 0xf2, 0x0a, 0x40, 0x08, 0x40, 0x02, 0x28, + 0x04, 0xd1, 0x30, 0x20, 0x03, 0xf0, 0xc5, 0xf8, 0x00, 0x24, 0x03, 0xe0, + 0x31, 0x20, 0x03, 0xf0, 0xc0, 0xf8, 0x03, 0x24, 0x00, 0xf0, 0x68, 0xf8, + 0x03, 0x20, 0x03, 0xf0, 0x4a, 0xf8, 0x00, 0x21, 0x00, 0xf0, 0xc8, 0xf8, + 0x20, 0x46, 0xfe, 0xbd, 0x00, 0x28, 0x08, 0xd5, 0xdf, 0xf8, 0x60, 0x34, + 0x40, 0x42, 0x53, 0xf8, 0x20, 0x30, 0x13, 0x60, 0xdf, 0xf8, 0x58, 0x24, + 0x06, 0xe0, 0xdf, 0xf8, 0x58, 0x34, 0x53, 0xf8, 0x20, 0x30, 0x13, 0x60, + 0xdf, 0xf8, 0x50, 0x24, 0x52, 0xf8, 0x20, 0x00, 0x08, 0x60, 0x70, 0x47, + 0xdf, 0xf8, 0x48, 0x14, 0xdf, 0xf8, 0x48, 0x34, 0x08, 0x22, 0x0a, 0x80, + 0x00, 0x22, 0x4a, 0x83, 0x8a, 0x83, 0x00, 0x21, 0xdf, 0xf8, 0x3c, 0x24, + 0x11, 0x80, 0x30, 0xf8, 0x11, 0x20, 0x23, 0xf8, 0x11, 0x20, 0x49, 0x1c, + 0x18, 0x29, 0xf8, 0xd3, 0xdf, 0xf8, 0x2c, 0x14, 0x42, 0x8e, 0x0a, 0x80, + 0xc2, 0x8e, 0x4a, 0x82, 0x02, 0x8f, 0x8a, 0x82, 0x42, 0x8f, 0xca, 0x82, + 0x82, 0x8f, 0x0a, 0x83, 0xc2, 0x8f, 0x4a, 0x83, 0xb0, 0xf8, 0x40, 0x00, + 0x88, 0x83, 0x00, 0x20, 0x48, 0x80, 0x88, 0x80, 0x70, 0x47, 0x10, 0xb5, + 0x01, 0xb1, 0x04, 0x21, 0x00, 0xf0, 0x03, 0x00, 0x08, 0x18, 0xdf, 0xf8, + 0xd0, 0x13, 0xdf, 0xf8, 0xc0, 0x33, 0x00, 0x02, 0x08, 0x80, 0x40, 0xf4, + 0x30, 0x40, 0x94, 0x8e, 0x5c, 0x82, 0x40, 0xf0, 0x40, 0x00, 0x4f, 0xf6, + 0xff, 0x74, 0x0c, 0x81, 0x9c, 0x8a, 0x44, 0xf4, 0x7f, 0x44, 0x9c, 0x82, + 0x1c, 0x8b, 0x44, 0xf4, 0x00, 0x44, 0x1c, 0x83, 0x12, 0x8e, 0x1a, 0x80, + 0x08, 0x80, 0x10, 0xbd, 0xdf, 0xf8, 0x98, 0x03, 0x01, 0x88, 0x01, 0xf4, + 0x73, 0x61, 0x41, 0xf4, 0x03, 0x51, 0x01, 0x80, 0x70, 0x47, 0x2d, 0xe9, + 0xfc, 0x41, 0x06, 0x46, 0x0f, 0x46, 0x90, 0x46, 0x00, 0xf0, 0x55, 0xf8, + 0xdf, 0xf8, 0x7c, 0x43, 0xdf, 0xf8, 0x7c, 0x53, 0xff, 0xf7, 0x84, 0xf9, + 0x20, 0x60, 0x06, 0x21, 0x03, 0x20, 0x02, 0xf0, 0xd6, 0xff, 0x4f, 0xf6, + 0xff, 0x70, 0xa8, 0x80, 0x4f, 0xf6, 0x35, 0x30, 0xa8, 0x81, 0x03, 0x20, + 0x02, 0xf0, 0xb2, 0xff, 0x03, 0x20, 0x02, 0xf0, 0xb5, 0xff, 0x42, 0x46, + 0x39, 0x46, 0x30, 0x46, 0xff, 0xf7, 0xb3, 0xff, 0x01, 0xa8, 0x00, 0x90, + 0x41, 0xf2, 0x88, 0x33, 0x20, 0x68, 0x03, 0x22, 0x05, 0x21, 0xfd, 0xf7, + 0x6d, 0xf9, 0x02, 0x46, 0x28, 0x88, 0xd2, 0x07, 0x04, 0xd5, 0x2f, 0x20, + 0x03, 0xf0, 0x19, 0xf8, 0x01, 0x25, 0x13, 0xe0, 0x4f, 0xf4, 0x99, 0x62, + 0x10, 0x42, 0x04, 0xd0, 0x31, 0x20, 0x03, 0xf0, 0x10, 0xf8, 0x02, 0x25, + 0x0a, 0xe0, 0x80, 0x07, 0x04, 0xd5, 0x30, 0x20, 0x03, 0xf0, 0x09, 0xf8, + 0x00, 0x25, 0x03, 0xe0, 0x31, 0x20, 0x03, 0xf0, 0x04, 0xf8, 0x03, 0x25, + 0xff, 0xf7, 0xac, 0xff, 0x03, 0x20, 0x02, 0xf0, 0x8e, 0xff, 0x20, 0x68, + 0x00, 0xf0, 0x06, 0xf8, 0x00, 0x21, 0x00, 0xf0, 0x09, 0xf8, 0x28, 0x46, + 0xbd, 0xe8, 0xf6, 0x81, 0x01, 0xab, 0x00, 0x22, 0x04, 0x21, 0xfd, 0xf7, + 0xc9, 0xb9, 0x01, 0x21, 0x2d, 0x20, 0x02, 0xf0, 0xfc, 0xbf, 0x00, 0xf5, + 0x4a, 0x70, 0x00, 0x23, 0x03, 0x60, 0x01, 0x71, 0x42, 0x71, 0x70, 0x47, + 0x30, 0xb5, 0x00, 0x24, 0x00, 0x23, 0x50, 0xf8, 0x24, 0x20, 0x01, 0xeb, + 0xc4, 0x05, 0x64, 0x1c, 0xc5, 0xe9, 0x00, 0x23, 0x18, 0x2c, 0xf6, 0xd3, + 0x30, 0xbd, 0x30, 0xb5, 0x00, 0x24, 0x50, 0xf8, 0x24, 0x20, 0x01, 0xeb, + 0xc4, 0x05, 0xd3, 0x17, 0xc5, 0xe9, 0x00, 0x23, 0x64, 0x1c, 0x18, 0x2c, + 0xf5, 0xd3, 0x30, 0xbd, 0x70, 0xb5, 0x02, 0x46, 0x0b, 0x46, 0x00, 0x26, + 0x03, 0xeb, 0xc6, 0x00, 0x00, 0x21, 0xd0, 0xe9, 0x00, 0x45, 0x52, 0xf8, + 0x26, 0x00, 0x00, 0xf0, 0x11, 0xf8, 0xf5, 0xd3, 0x70, 0xbd, 0x70, 0xb5, + 0x02, 0x46, 0x0b, 0x46, 0x00, 0x26, 0x03, 0xeb, 0xc6, 0x00, 0xd0, 0xe9, + 0x00, 0x45, 0x52, 0xf8, 0x26, 0x00, 0xc1, 0x17, 0x00, 0xf0, 0x02, 0xf8, + 0xf5, 0xd3, 0x70, 0xbd, 0x20, 0x18, 0x03, 0xeb, 0xc6, 0x04, 0x69, 0x41, + 0xc4, 0xe9, 0x00, 0x01, 0x76, 0x1c, 0x18, 0x2e, 0x70, 0x47, 0x2d, 0xe9, + 0xf0, 0x47, 0x04, 0x46, 0x04, 0xf5, 0x16, 0x75, 0xd4, 0xf8, 0x28, 0x13, + 0xdf, 0xf8, 0x3c, 0x82, 0xdf, 0xf8, 0x3c, 0x92, 0xdf, 0xf8, 0x2c, 0xa2, + 0xdf, 0xf8, 0x2c, 0x02, 0x00, 0x29, 0x04, 0xf5, 0xc8, 0x76, 0x04, 0xf1, + 0xc8, 0x07, 0x21, 0x46, 0x11, 0xd0, 0xff, 0xf7, 0xc1, 0xff, 0x39, 0x46, + 0x50, 0x46, 0xff, 0xf7, 0xbd, 0xff, 0x31, 0x46, 0x48, 0x46, 0xff, 0xf7, + 0xc8, 0xff, 0x29, 0x46, 0x40, 0x46, 0xff, 0xf7, 0xc4, 0xff, 0xd4, 0xf8, + 0x28, 0x03, 0x40, 0x1c, 0x0e, 0xe0, 0xff, 0xf7, 0x95, 0xff, 0x39, 0x46, + 0x50, 0x46, 0xff, 0xf7, 0x91, 0xff, 0x31, 0x46, 0x48, 0x46, 0xff, 0xf7, + 0x9a, 0xff, 0x29, 0x46, 0x40, 0x46, 0xff, 0xf7, 0x96, 0xff, 0x01, 0x20, + 0xc4, 0xf8, 0x28, 0x03, 0xbd, 0xe8, 0xf0, 0x87, 0xc1, 0xb2, 0x01, 0xeb, + 0x10, 0x20, 0x70, 0x47, 0xf0, 0xb5, 0x4b, 0x6e, 0x03, 0x66, 0x01, 0x22, + 0x00, 0x24, 0x00, 0x25, 0x00, 0x23, 0x17, 0x26, 0x02, 0x27, 0x0a, 0xe0, + 0x01, 0xeb, 0x83, 0x0c, 0xdc, 0xf8, 0x04, 0xc0, 0xa4, 0x45, 0xd8, 0xbf, + 0x64, 0x46, 0x65, 0x45, 0xb8, 0xbf, 0x65, 0x46, 0x5b, 0x1c, 0x9e, 0x42, + 0xf2, 0xd2, 0x19, 0x23, 0x2f, 0x26, 0x7f, 0x1e, 0xf9, 0xd1, 0x23, 0x46, + 0x2c, 0x46, 0x6f, 0xf3, 0x0b, 0x04, 0xb4, 0xf1, 0x00, 0x6f, 0x6f, 0xf3, + 0x0b, 0x03, 0x04, 0xdc, 0x13, 0xf1, 0x00, 0x6f, 0x04, 0xdb, 0x00, 0x24, + 0x17, 0xe0, 0xb4, 0xf1, 0x80, 0x5f, 0x05, 0xda, 0x13, 0xf1, 0x80, 0x5f, + 0x05, 0xdb, 0x01, 0x24, 0x01, 0x25, 0x13, 0xe0, 0xb4, 0xf1, 0x00, 0x5f, + 0x04, 0xda, 0x13, 0xf1, 0x00, 0x5f, 0x04, 0xdb, 0x02, 0x24, 0x06, 0xe0, + 0xb4, 0xf1, 0x80, 0x4f, 0x05, 0xda, 0x13, 0xf1, 0x80, 0x4f, 0x02, 0xdb, + 0x03, 0x24, 0x25, 0x46, 0x02, 0xe0, 0x03, 0x24, 0x03, 0x25, 0x00, 0x22, + 0x00, 0x23, 0x17, 0x26, 0x02, 0x27, 0x08, 0xe0, 0x01, 0xeb, 0x83, 0x0c, + 0xdc, 0xf8, 0x04, 0xc0, 0x4c, 0xfa, 0x05, 0xfc, 0x40, 0xf8, 0x23, 0xc0, + 0x5b, 0x1c, 0x9e, 0x42, 0xf4, 0xd2, 0x19, 0x23, 0x2f, 0x26, 0x7f, 0x1e, + 0xf9, 0xd1, 0x44, 0xf0, 0x30, 0x03, 0x20, 0xf8, 0xc0, 0x3f, 0x09, 0x68, + 0x41, 0x60, 0x10, 0x46, 0xf0, 0xbd, 0x3e, 0xb5, 0x0f, 0xf2, 0x34, 0x12, + 0x38, 0xca, 0x69, 0x46, 0x03, 0x28, 0x38, 0xc1, 0x34, 0xbf, 0x5d, 0xf8, + 0x20, 0x00, 0x00, 0x20, 0x3e, 0xbd, 0x70, 0xb5, 0x0f, 0xf2, 0x10, 0x13, + 0x84, 0xb0, 0x70, 0xcb, 0x6a, 0x46, 0x03, 0x28, 0x70, 0xc2, 0x11, 0xd2, + 0x5d, 0xf8, 0x20, 0x00, 0x01, 0xfa, 0x00, 0xf2, 0x03, 0x23, 0x03, 0xfa, + 0x00, 0xf0, 0x19, 0x42, 0x40, 0xf0, 0xc0, 0x00, 0x06, 0xd0, 0x81, 0xb2, + 0x92, 0xb2, 0x24, 0x48, 0x00, 0xf0, 0xaf, 0xf8, 0x01, 0x20, 0x00, 0xe0, + 0x00, 0x20, 0x04, 0xb0, 0x70, 0xbd, 0x20, 0x49, 0x09, 0x88, 0x01, 0x80, + 0x32, 0x49, 0x09, 0x88, 0x41, 0x80, 0x70, 0x47, 0x10, 0xb5, 0x04, 0x46, + 0x1b, 0x48, 0x21, 0x88, 0x00, 0xf0, 0xfa, 0xf8, 0x61, 0x88, 0x2d, 0x48, + 0xbd, 0xe8, 0x10, 0x40, 0x00, 0xf0, 0xf4, 0xb8, 0x10, 0xb5, 0x00, 0x03, + 0x0c, 0x46, 0x00, 0xf4, 0x40, 0x52, 0x4f, 0xf4, 0x40, 0x51, 0x13, 0x48, + 0x00, 0xf0, 0xfa, 0xf8, 0x04, 0xf0, 0x3c, 0x01, 0xbd, 0xe8, 0x10, 0x40, + 0xff, 0xe7, 0x23, 0x48, 0x00, 0xf0, 0xe2, 0xb8, 0x80, 0xb5, 0x22, 0x49, + 0x4f, 0xf6, 0xff, 0x70, 0x08, 0x80, 0x6b, 0x46, 0x14, 0x48, 0x00, 0x68, + 0x01, 0x22, 0x04, 0x21, 0xfd, 0xf7, 0x82, 0xf8, 0x01, 0xbd, 0x00, 0x00, + 0x80, 0xf3, 0x00, 0x20, 0x00, 0xf2, 0x00, 0x20, 0x01, 0xd0, 0x12, 0x13, + 0xfc, 0x01, 0x00, 0x41, 0xc0, 0x02, 0x00, 0x41, 0xc0, 0x06, 0x00, 0x41, + 0xc0, 0x04, 0x00, 0x41, 0x02, 0x08, 0x00, 0x41, 0x08, 0xef, 0x00, 0x20, + 0x78, 0x29, 0x00, 0x20, 0x40, 0x00, 0x00, 0x41, 0x0c, 0x00, 0x00, 0x41, + 0x58, 0x00, 0x00, 0x41, 0xb0, 0x00, 0x00, 0x41, 0xbd, 0x37, 0x86, 0x35, + 0x00, 0x00, 0x40, 0x42, 0x00, 0x08, 0x00, 0x41, 0x7c, 0xf3, 0x00, 0x20, + 0x08, 0x08, 0x00, 0x41, 0x00, 0x16, 0x00, 0x41, 0x80, 0x16, 0x00, 0x41, + 0x00, 0x17, 0x00, 0x41, 0x80, 0x17, 0x00, 0x41, 0x3e, 0x00, 0x00, 0x41, + 0x80, 0x00, 0x00, 0x41, 0x04, 0x08, 0x00, 0x41, 0xb2, 0x00, 0x00, 0x41, + 0xfe, 0x01, 0x00, 0x41, 0x14, 0x08, 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x41, + 0x00, 0x04, 0x00, 0x41, 0x00, 0x06, 0x00, 0x41, 0xdf, 0xf8, 0x10, 0x14, + 0x28, 0x22, 0x02, 0xfb, 0x00, 0x10, 0x81, 0x7f, 0xc2, 0x7f, 0x90, 0xf8, + 0x20, 0x00, 0x41, 0xea, 0x02, 0x21, 0x41, 0xea, 0x00, 0x40, 0x70, 0x47, + 0xdf, 0xf8, 0xf4, 0x13, 0x28, 0x22, 0x02, 0xfb, 0x00, 0x10, 0x10, 0xf8, + 0x21, 0x1f, 0x40, 0x78, 0x00, 0xf0, 0x07, 0x00, 0x41, 0xea, 0x00, 0x20, + 0x70, 0x47, 0xef, 0xf3, 0x11, 0x80, 0x60, 0x21, 0x81, 0xf3, 0x11, 0x88, + 0xdf, 0xf8, 0xd4, 0x13, 0xdf, 0xf8, 0xd4, 0x33, 0x09, 0x68, 0x4f, 0xf0, + 0x00, 0x42, 0x1a, 0x60, 0x70, 0x47, 0xdf, 0xf8, 0xc4, 0x33, 0x01, 0xf0, + 0x00, 0x42, 0x1a, 0x60, 0x80, 0xf3, 0x11, 0x88, 0x70, 0x47, 0x70, 0xb5, + 0x00, 0xf0, 0x56, 0xf8, 0x00, 0xf0, 0x79, 0xf8, 0xbd, 0xe8, 0x70, 0x40, + 0xef, 0xe7, 0x2d, 0xe9, 0xf0, 0x41, 0x06, 0x46, 0x88, 0x46, 0xff, 0xf7, + 0xdc, 0xff, 0x00, 0xf0, 0x36, 0xf8, 0x20, 0xb1, 0x41, 0x46, 0x30, 0x46, + 0xfd, 0xf7, 0x3e, 0xfe, 0x01, 0x27, 0x20, 0x46, 0x29, 0x46, 0xff, 0xf7, + 0xde, 0xff, 0x38, 0x46, 0xbd, 0xe8, 0xf0, 0x81, 0xf8, 0xb5, 0x04, 0x46, + 0x0d, 0x46, 0x16, 0x46, 0x01, 0x20, 0x00, 0x27, 0x00, 0xe0, 0x7f, 0x1c, + 0xb7, 0x42, 0x06, 0xd2, 0x79, 0x5d, 0x34, 0xf8, 0x17, 0x00, 0xff, 0xf7, + 0xdc, 0xff, 0x00, 0x28, 0xf5, 0xd1, 0xf2, 0xbd, 0x2d, 0xe9, 0xf8, 0x43, + 0x06, 0x46, 0x89, 0x46, 0x90, 0x46, 0xff, 0xf7, 0xb4, 0xff, 0x00, 0xf0, + 0x0e, 0xf8, 0x28, 0xb1, 0x42, 0x46, 0x49, 0x46, 0x30, 0x46, 0xfd, 0xf7, + 0x1f, 0xfe, 0x01, 0x27, 0x20, 0x46, 0x29, 0x46, 0xff, 0xf7, 0xb5, 0xff, + 0x38, 0x46, 0xbd, 0xe8, 0xf2, 0x83, 0x04, 0x46, 0xdf, 0xf8, 0x2c, 0x03, + 0x00, 0x78, 0x00, 0x27, 0x0d, 0x46, 0x70, 0x47, 0x70, 0xb5, 0x00, 0xf0, + 0x06, 0xf8, 0x00, 0xf0, 0x17, 0xf8, 0x0a, 0xb1, 0x25, 0x70, 0x01, 0x26, + 0x0e, 0xe0, 0x04, 0x46, 0x0d, 0x46, 0x90, 0xe7, 0x04, 0x46, 0x0d, 0x46, + 0x16, 0x46, 0x8c, 0xe7, 0x70, 0xb5, 0xff, 0xf7, 0xf6, 0xff, 0x00, 0xf0, + 0x07, 0xf8, 0x0a, 0xb1, 0x25, 0x80, 0x01, 0x26, 0xff, 0xf7, 0x91, 0xff, + 0x30, 0x46, 0x70, 0xbd, 0xba, 0x4a, 0x12, 0x78, 0x00, 0x26, 0x70, 0x47, + 0xf8, 0xb5, 0xff, 0xf7, 0xe9, 0xff, 0x00, 0xf0, 0x08, 0xf8, 0x12, 0xb1, + 0x00, 0xf0, 0x09, 0xf8, 0x01, 0x27, 0xff, 0xf7, 0x80, 0xff, 0x38, 0x46, + 0xf2, 0xbd, 0xb2, 0x4a, 0x12, 0x78, 0x00, 0x27, 0x70, 0x47, 0x22, 0x88, + 0xaa, 0x43, 0x05, 0xea, 0x06, 0x03, 0x1a, 0x43, 0x22, 0x80, 0x70, 0x47, + 0x70, 0xb5, 0xff, 0xf7, 0xce, 0xff, 0xff, 0xf7, 0xdf, 0xff, 0x0a, 0xb1, + 0x25, 0x60, 0x01, 0x26, 0xd6, 0xe7, 0x10, 0xb5, 0x04, 0x46, 0x04, 0x22, + 0x21, 0x46, 0x0f, 0xf2, 0xb4, 0x20, 0xfd, 0xf7, 0xee, 0xfd, 0x01, 0x22, + 0x21, 0x1d, 0x0f, 0xf2, 0xb0, 0x20, 0xfd, 0xf7, 0xe8, 0xfd, 0xa2, 0x48, + 0x00, 0x68, 0xa0, 0x60, 0x10, 0xbd, 0x38, 0xb5, 0x04, 0x46, 0x0d, 0x46, + 0x04, 0x22, 0x21, 0x46, 0x0f, 0xf2, 0x8c, 0x20, 0xff, 0xf7, 0x74, 0xff, + 0x55, 0xb9, 0xa0, 0x68, 0x9a, 0x49, 0x08, 0x60, 0x21, 0x1d, 0xbd, 0xe8, + 0x38, 0x40, 0x01, 0x22, 0x0f, 0xf2, 0x7c, 0x20, 0xfd, 0xf7, 0xbc, 0xbd, + 0x31, 0xbd, 0x38, 0xb5, 0x20, 0xb9, 0x01, 0x24, 0x40, 0xf6, 0x12, 0x05, + 0x80, 0x21, 0x03, 0xe0, 0x02, 0x24, 0x40, 0xf6, 0x13, 0x05, 0x40, 0x21, + 0x00, 0x22, 0x40, 0xf6, 0x14, 0x00, 0xff, 0xf7, 0x69, 0xff, 0x00, 0x22, + 0xc0, 0x21, 0x28, 0x46, 0xff, 0xf7, 0x64, 0xff, 0x21, 0x46, 0x4f, 0xf4, + 0x82, 0x70, 0xff, 0xf7, 0x38, 0xff, 0xbd, 0xe8, 0x38, 0x40, 0x00, 0x22, + 0x33, 0x21, 0x4f, 0xf4, 0xa9, 0x60, 0x57, 0xe7, 0x80, 0xb5, 0x85, 0x48, + 0x01, 0x6d, 0x03, 0x20, 0x01, 0xf0, 0x0e, 0xfa, 0x03, 0x20, 0x01, 0xf0, + 0x23, 0xfa, 0x18, 0xb9, 0xff, 0xf7, 0x45, 0xf8, 0x00, 0x28, 0xf7, 0xd0, + 0xbd, 0xe8, 0x02, 0x40, 0x03, 0x20, 0x01, 0xf0, 0x91, 0xb9, 0x77, 0x48, + 0x90, 0xf8, 0x43, 0x20, 0x04, 0xe0, 0x75, 0x48, 0x90, 0xf8, 0x6b, 0x00, + 0x40, 0xf0, 0x20, 0x02, 0x3f, 0x21, 0x40, 0xf6, 0x15, 0x00, 0x37, 0xe7, + 0x2d, 0xe9, 0xf1, 0x4f, 0x84, 0xb0, 0x07, 0xf0, 0x0c, 0xfd, 0x01, 0x20, + 0xff, 0xf7, 0xde, 0xfe, 0x04, 0x46, 0x01, 0x20, 0xff, 0xf7, 0xcc, 0xfe, + 0x82, 0x46, 0x03, 0x20, 0xff, 0xf7, 0xd6, 0xfe, 0x05, 0x46, 0x03, 0x20, + 0xff, 0xf7, 0xc4, 0xfe, 0x06, 0x46, 0x6c, 0x48, 0x6c, 0x4a, 0x41, 0x78, + 0x00, 0x78, 0x13, 0x78, 0x40, 0xea, 0x01, 0x20, 0x40, 0x05, 0x40, 0x0d, + 0x01, 0x21, 0x03, 0xf0, 0x03, 0x07, 0x02, 0x2f, 0x4f, 0xf0, 0x00, 0x0b, + 0x08, 0xbf, 0x02, 0x21, 0x02, 0xd0, 0x03, 0x2f, 0x08, 0xbf, 0x04, 0x21, + 0xdf, 0x06, 0x48, 0xbf, 0x49, 0x00, 0x9b, 0x06, 0x48, 0xbf, 0x49, 0x00, + 0x52, 0x78, 0x52, 0x07, 0x4c, 0xbf, 0x01, 0xeb, 0x81, 0x01, 0x89, 0x00, + 0x00, 0x91, 0x02, 0x27, 0x54, 0x49, 0x91, 0xf8, 0x89, 0x20, 0x91, 0xf8, + 0x39, 0x10, 0x8b, 0x1a, 0x01, 0x2b, 0x03, 0xdb, 0x07, 0xfa, 0x01, 0xf1, + 0x01, 0x27, 0x08, 0xe0, 0x00, 0x2b, 0x03, 0xd5, 0x59, 0x42, 0x8c, 0x40, + 0x0a, 0xfa, 0x01, 0xfa, 0x07, 0xfa, 0x02, 0xf1, 0x00, 0x27, 0x05, 0xfa, + 0x07, 0xf2, 0xa2, 0x1a, 0x50, 0x4b, 0x03, 0xfb, 0x02, 0xa2, 0x01, 0x92, + 0x48, 0x43, 0x01, 0x9b, 0x00, 0x9a, 0xc1, 0x17, 0x06, 0xfa, 0x07, 0xf4, + 0xcd, 0xe9, 0x02, 0x01, 0x1b, 0x1b, 0x83, 0xfb, 0x02, 0x89, 0x00, 0x25, + 0x07, 0xe0, 0xae, 0x19, 0x01, 0x99, 0x00, 0x98, 0x06, 0xfa, 0x07, 0xf2, + 0x89, 0x1a, 0x81, 0xfb, 0x00, 0x89, 0xdd, 0xe9, 0x02, 0x23, 0x40, 0x46, + 0x49, 0x46, 0x01, 0xf0, 0xf9, 0xfe, 0xdd, 0xe9, 0x02, 0x23, 0x04, 0x46, + 0x8a, 0x46, 0xa2, 0xfb, 0x04, 0x01, 0x02, 0xfb, 0x0a, 0x11, 0x03, 0xfb, + 0x04, 0x11, 0xb8, 0xeb, 0x00, 0x00, 0x79, 0xeb, 0x01, 0x01, 0x08, 0xbf, + 0x00, 0x28, 0x08, 0xd0, 0x00, 0x2d, 0xde, 0xd1, 0x38, 0x48, 0x86, 0x42, + 0xac, 0xbf, 0x4f, 0xf0, 0xff, 0x35, 0x01, 0x25, 0xd7, 0xe7, 0xb5, 0xb1, + 0x30, 0x02, 0x01, 0x0e, 0x40, 0xf2, 0x45, 0x30, 0xff, 0xf7, 0x81, 0xfe, + 0x30, 0x04, 0x01, 0x0e, 0x4f, 0xf4, 0x51, 0x70, 0xff, 0xf7, 0x7b, 0xfe, + 0xf1, 0xb2, 0x40, 0xf2, 0x43, 0x30, 0xff, 0xf7, 0x76, 0xfe, 0x00, 0x22, + 0x00, 0x21, 0x40, 0xf2, 0x41, 0x30, 0xff, 0xf7, 0x97, 0xfe, 0x60, 0x42, + 0x00, 0x02, 0x23, 0x4e, 0x00, 0x0a, 0x40, 0xf0, 0x40, 0x70, 0x30, 0x60, + 0x20, 0x22, 0x4f, 0xf4, 0x80, 0x50, 0x70, 0x60, 0x20, 0x21, 0x40, 0xf6, + 0x15, 0x00, 0xff, 0xf7, 0x87, 0xfe, 0x00, 0x22, 0x01, 0x21, 0x4f, 0xf4, + 0x60, 0x70, 0xfd, 0xf7, 0xaf, 0xfc, 0x04, 0x98, 0x01, 0x28, 0x23, 0xdb, + 0x30, 0x68, 0x04, 0x99, 0x20, 0xf0, 0xf0, 0x40, 0x40, 0xea, 0xc1, 0x60, + 0x40, 0xf0, 0x80, 0x60, 0x30, 0x60, 0x4f, 0xf4, 0x7a, 0x71, 0x03, 0x20, + 0x01, 0xf0, 0x2c, 0xf9, 0x30, 0x68, 0x40, 0x01, 0x07, 0xd5, 0x03, 0x20, + 0x01, 0xf0, 0x3e, 0xf9, 0x18, 0xb9, 0xfe, 0xf7, 0x60, 0xff, 0x00, 0x28, + 0xf4, 0xd0, 0x30, 0x68, 0x40, 0x01, 0x04, 0xd5, 0xfe, 0xf7, 0x59, 0xff, + 0x08, 0xb9, 0x4f, 0xf0, 0x01, 0x0b, 0x03, 0x20, 0x01, 0xf0, 0xa6, 0xf8, + 0x58, 0x46, 0x05, 0xb0, 0xbd, 0xe8, 0xf0, 0x8f, 0x68, 0xee, 0x00, 0x20, + 0x00, 0xe1, 0x00, 0xe0, 0x80, 0xe1, 0x00, 0xe0, 0x65, 0x2c, 0x00, 0x20, + 0x10, 0x00, 0x00, 0x45, 0x4c, 0x1f, 0x00, 0x20, 0x41, 0x01, 0x00, 0x46, + 0x01, 0x01, 0x00, 0x46, 0x00, 0xf8, 0x7f, 0x00, 0x01, 0xfc, 0x3f, 0x00, + 0x48, 0x05, 0x12, 0x08, 0x13, 0x08, 0x14, 0x08, 0x80, 0x03, 0x00, 0x00, + 0x10, 0xb5, 0x00, 0x24, 0x00, 0x21, 0xe0, 0xb2, 0x00, 0xf0, 0xad, 0xf8, + 0x01, 0x21, 0xe0, 0xb2, 0x00, 0xf0, 0xe1, 0xf8, 0x64, 0x1c, 0x02, 0x2c, + 0xf4, 0xd3, 0x10, 0xbd, 0x70, 0xb5, 0x04, 0x46, 0x0d, 0x46, 0xff, 0xf7, + 0xe4, 0xfe, 0x00, 0x2c, 0x0c, 0xbf, 0x01, 0x21, 0x10, 0x21, 0x40, 0xf2, + 0x49, 0x50, 0xfd, 0xf7, 0x45, 0xfc, 0x2e, 0x00, 0x18, 0xbf, 0x01, 0x2d, + 0x04, 0xd1, 0x7e, 0x21, 0x40, 0xf2, 0x0b, 0x20, 0xfd, 0xf7, 0x3c, 0xfc, + 0x00, 0x2c, 0x0c, 0xbf, 0x00, 0x20, 0x04, 0x20, 0x05, 0xf0, 0x03, 0x01, + 0x01, 0xfa, 0x00, 0xf2, 0x03, 0x21, 0x81, 0x40, 0xd2, 0xb2, 0xc9, 0xb2, + 0x4f, 0xf4, 0xa9, 0x60, 0xff, 0xf7, 0x08, 0xfe, 0x01, 0x2d, 0x18, 0xbf, + 0x02, 0x2d, 0x10, 0xd1, 0x00, 0x2c, 0x07, 0xbf, 0x08, 0x24, 0x40, 0xf2, + 0x42, 0x50, 0x10, 0x24, 0x40, 0xf2, 0x43, 0x50, 0x00, 0x22, 0xc0, 0x21, + 0xff, 0xf7, 0xf8, 0xfd, 0x21, 0x46, 0x4f, 0xf4, 0x82, 0x70, 0xff, 0xf7, + 0xcc, 0xfd, 0x01, 0x20, 0x70, 0xbd, 0xff, 0xf7, 0x97, 0xbe, 0x00, 0xb1, + 0x04, 0x20, 0x41, 0x49, 0x09, 0x78, 0xc1, 0x40, 0x01, 0xf0, 0x03, 0x00, + 0x70, 0x47, 0x10, 0xb5, 0x02, 0x46, 0x00, 0x21, 0x53, 0x68, 0x18, 0x46, + 0x01, 0xf0, 0xca, 0xfb, 0x08, 0xd2, 0x10, 0x68, 0x3a, 0x4c, 0x19, 0x46, + 0x01, 0xf0, 0x2e, 0xf9, 0x20, 0x60, 0x00, 0x20, 0xc4, 0xe9, 0x02, 0x00, + 0x10, 0xbd, 0x38, 0xb5, 0x36, 0x4a, 0x35, 0x4d, 0xd2, 0xe9, 0x08, 0x01, + 0xd5, 0xe9, 0x02, 0x23, 0x99, 0x42, 0x08, 0xbf, 0x90, 0x42, 0x3f, 0xd0, + 0xc5, 0xe9, 0x02, 0x01, 0x31, 0x4a, 0x00, 0x23, 0x01, 0xf0, 0x16, 0xfe, + 0x00, 0x24, 0x80, 0xb2, 0xb0, 0xf5, 0x95, 0x7f, 0xb8, 0xbf, 0xff, 0x24, + 0x1a, 0xdb, 0xb0, 0xf5, 0xd5, 0x6f, 0x17, 0xdc, 0x40, 0xf2, 0x29, 0x11, + 0x40, 0x1a, 0x00, 0xb2, 0x41, 0x11, 0x00, 0xeb, 0x91, 0x61, 0x89, 0x02, + 0x09, 0x0c, 0x0f, 0xf2, 0x74, 0x12, 0x8b, 0x5c, 0xa0, 0xeb, 0x81, 0x10, + 0x89, 0x18, 0x00, 0xb2, 0x49, 0x78, 0x59, 0x1a, 0x48, 0x43, 0x41, 0x11, + 0x00, 0xeb, 0x91, 0x60, 0xa3, 0xeb, 0xa0, 0x14, 0xe0, 0xb2, 0x01, 0xf0, + 0xe3, 0xf8, 0x29, 0x68, 0x01, 0xf0, 0x7e, 0xfa, 0x01, 0xf0, 0xe8, 0xfa, + 0x84, 0xb2, 0xff, 0x2c, 0xc8, 0xbf, 0xff, 0x24, 0xe1, 0xb2, 0x40, 0xf2, + 0x44, 0x50, 0xfd, 0xf7, 0xb5, 0xfb, 0xe1, 0xb2, 0xbd, 0xe8, 0x34, 0x40, + 0x40, 0xf2, 0x45, 0x50, 0xfd, 0xf7, 0xae, 0xbb, 0x31, 0xbd, 0x00, 0x28, + 0x0c, 0xbf, 0x40, 0xf2, 0x46, 0x50, 0x40, 0xf2, 0x47, 0x50, 0x01, 0xf0, + 0x03, 0x02, 0x03, 0x21, 0xfd, 0xf7, 0xac, 0xbb, 0x70, 0xb5, 0x04, 0x46, + 0x0d, 0x46, 0x08, 0xf0, 0x6d, 0xf9, 0x2f, 0x26, 0x03, 0x28, 0x08, 0xd1, + 0x00, 0x21, 0x8d, 0x42, 0x08, 0x48, 0x03, 0xd8, 0x84, 0x42, 0x38, 0xbf, + 0x2d, 0x26, 0x00, 0xd3, 0x2e, 0x26, 0x30, 0x46, 0x70, 0xbd, 0x00, 0x00, + 0x48, 0x05, 0x00, 0x46, 0x08, 0xf3, 0x00, 0x20, 0x00, 0xf2, 0x00, 0x20, + 0x40, 0x42, 0x0f, 0x00, 0x00, 0x28, 0x6b, 0xee, 0x00, 0x28, 0x0c, 0xbf, + 0x40, 0xf2, 0x5e, 0x40, 0x40, 0xf2, 0x5f, 0x40, 0xfd, 0xf7, 0x7c, 0xbb, + 0x00, 0xf0, 0x0f, 0x02, 0x0f, 0x21, 0x4f, 0xf4, 0xc1, 0x70, 0xfd, 0xf7, + 0x7f, 0xbb, 0x00, 0x28, 0x0c, 0xbf, 0x40, 0xf2, 0x46, 0x50, 0x40, 0xf2, + 0x47, 0x50, 0x89, 0x00, 0x01, 0xf0, 0x0c, 0x02, 0x0c, 0x21, 0xfd, 0xf7, + 0x73, 0xbb, 0x00, 0x28, 0x0c, 0xbf, 0x4f, 0xf4, 0xa8, 0x60, 0x40, 0xf2, + 0x41, 0x50, 0x8a, 0x01, 0xd2, 0xb2, 0xc0, 0x21, 0xfd, 0xf7, 0x68, 0xbb, + 0x00, 0x28, 0x0c, 0xbf, 0x4f, 0xf4, 0xa8, 0x60, 0x40, 0xf2, 0x41, 0x50, + 0x01, 0xf0, 0x3f, 0x02, 0x3f, 0x21, 0xfd, 0xf7, 0x5d, 0xbb, 0x10, 0xb5, + 0x00, 0xf0, 0x17, 0xf8, 0xfd, 0xf7, 0x7f, 0xfb, 0x21, 0x46, 0xbd, 0xe8, + 0x10, 0x40, 0x05, 0x22, 0x0f, 0xf2, 0x48, 0x00, 0xfd, 0xf7, 0x77, 0xbb, + 0x10, 0xb5, 0x00, 0xf0, 0x0a, 0xf8, 0xff, 0xf7, 0x0b, 0xfd, 0x21, 0x46, + 0xbd, 0xe8, 0x10, 0x40, 0x05, 0x22, 0x0f, 0xf2, 0x30, 0x00, 0xfd, 0xf7, + 0x57, 0xbb, 0x04, 0x46, 0x03, 0x22, 0x61, 0x1d, 0x0f, 0xf2, 0x2c, 0x00, + 0x70, 0x47, 0x00, 0xb1, 0x04, 0x20, 0x01, 0xf0, 0x01, 0x01, 0x01, 0xfa, + 0x00, 0xf2, 0x01, 0x21, 0x81, 0x40, 0xd2, 0xb2, 0xc9, 0xb2, 0x4f, 0xf4, + 0xaa, 0x60, 0xfd, 0xf7, 0x2f, 0xbb, 0x00, 0x00, 0x40, 0x05, 0x41, 0x05, + 0x50, 0x05, 0x49, 0x05, 0x0b, 0x02, 0x00, 0x00, 0x48, 0x05, 0x42, 0x05, + 0x43, 0x05, 0x00, 0x00, 0xff, 0xc1, 0x97, 0x7a, 0x65, 0x57, 0x4b, 0x42, + 0x3a, 0x33, 0x2d, 0x27, 0x22, 0x1d, 0x1a, 0x16, 0x13, 0x10, 0x0d, 0x0a, + 0x06, 0x03, 0x00, 0x00, 0x70, 0xb5, 0x04, 0x46, 0x00, 0x25, 0x0f, 0xf2, + 0x60, 0x66, 0x36, 0xf9, 0x15, 0x20, 0xe9, 0xb2, 0x20, 0x46, 0x00, 0xf0, + 0x29, 0xf8, 0x6d, 0x1c, 0x04, 0x2d, 0xf6, 0xd3, 0x70, 0xbd, 0x10, 0xb5, + 0x08, 0x22, 0x08, 0x21, 0x4f, 0xf4, 0x8c, 0x70, 0xfd, 0xf7, 0x02, 0xfb, + 0x00, 0x24, 0x20, 0x46, 0xff, 0xf7, 0xe6, 0xff, 0x64, 0x1c, 0x02, 0x2c, + 0xf9, 0xd3, 0xdf, 0xf8, 0xac, 0x05, 0x4f, 0xf4, 0x80, 0x71, 0x81, 0x61, + 0x42, 0x6a, 0x42, 0xf4, 0x80, 0x72, 0x42, 0x62, 0x01, 0x60, 0x13, 0x20, + 0x06, 0x21, 0x02, 0xf0, 0x5c, 0xfa, 0x13, 0x20, 0x02, 0xf0, 0x3e, 0xfa, + 0xbd, 0xe8, 0x10, 0x40, 0x13, 0x20, 0x02, 0xf0, 0x3f, 0xba, 0x00, 0x00, + 0x2d, 0xe9, 0xf8, 0x43, 0x14, 0x46, 0x05, 0x46, 0x27, 0x12, 0x01, 0x20, + 0x03, 0x29, 0x00, 0xfa, 0x05, 0xf6, 0x40, 0xf6, 0x1c, 0x28, 0x3b, 0xd8, + 0xdf, 0xe8, 0x01, 0xf0, 0x02, 0x1a, 0x21, 0x27, 0x0f, 0xf2, 0xcc, 0x56, + 0xa0, 0x05, 0x01, 0x0e, 0x36, 0xf8, 0x25, 0x00, 0xfd, 0xf7, 0xc2, 0xfa, + 0x06, 0xeb, 0x85, 0x00, 0x04, 0xf0, 0x03, 0x04, 0x45, 0x88, 0x44, 0xf0, + 0x80, 0x01, 0x28, 0x46, 0xfd, 0xf7, 0xb8, 0xfa, 0x00, 0xbf, 0x00, 0xbf, + 0x00, 0xbf, 0x21, 0x46, 0x28, 0x46, 0x1b, 0xe0, 0x0f, 0xf2, 0xa4, 0x59, + 0x00, 0xf0, 0x1e, 0xf8, 0x07, 0xf0, 0x3f, 0x01, 0x0a, 0xe0, 0x0f, 0xf2, + 0xa8, 0x50, 0x30, 0xf8, 0x15, 0x00, 0xe1, 0xb2, 0x0e, 0xe0, 0x0f, 0xf2, + 0xa0, 0x59, 0x00, 0xf0, 0x11, 0xf8, 0xf9, 0xb2, 0x09, 0xeb, 0x85, 0x00, + 0x40, 0x88, 0xfd, 0xf7, 0x9b, 0xfa, 0x00, 0xbf, 0x00, 0xbf, 0x00, 0xbf, + 0xf1, 0xb2, 0x40, 0x46, 0xbd, 0xe8, 0xf4, 0x43, 0xfd, 0xf7, 0x92, 0xba, + 0xbd, 0xe8, 0xf1, 0x83, 0x39, 0xf8, 0x25, 0x00, 0xe1, 0xb2, 0xfd, 0xf7, + 0x8b, 0xba, 0x10, 0xb5, 0x82, 0xb0, 0xdf, 0xf8, 0xe0, 0x44, 0xfe, 0xf7, + 0xa7, 0xfb, 0x20, 0x60, 0x01, 0x21, 0x2e, 0x20, 0x02, 0xf0, 0x6d, 0xfa, + 0x20, 0x68, 0x6b, 0x46, 0x00, 0x22, 0x04, 0x21, 0xfc, 0xf7, 0x30, 0xfc, + 0x4f, 0xf0, 0x8a, 0x40, 0x01, 0x68, 0x61, 0x60, 0x41, 0x68, 0x01, 0xf4, + 0xa0, 0x71, 0x41, 0xf0, 0x11, 0x01, 0x41, 0x60, 0x13, 0xbd, 0x30, 0xb5, + 0x83, 0xb0, 0xfe, 0xf7, 0x8d, 0xfb, 0xdf, 0xf8, 0xa4, 0x14, 0x08, 0x60, + 0x01, 0xa9, 0x00, 0x91, 0x41, 0xf2, 0x88, 0x33, 0x03, 0x22, 0x05, 0x21, + 0xfc, 0xf7, 0x8a, 0xfb, 0xc0, 0x07, 0x4f, 0xf0, 0x8a, 0x44, 0x04, 0xd5, + 0x2f, 0x20, 0x02, 0xf0, 0x36, 0xfa, 0x01, 0x25, 0x0b, 0xe0, 0xa0, 0x68, + 0xc0, 0x07, 0x04, 0xd5, 0x30, 0x20, 0x02, 0xf0, 0x2e, 0xfa, 0x00, 0x25, + 0x03, 0xe0, 0x31, 0x20, 0x02, 0xf0, 0x29, 0xfa, 0x02, 0x25, 0xa0, 0x68, + 0xc0, 0x07, 0x07, 0xd4, 0x20, 0x68, 0x20, 0xf0, 0x7e, 0x50, 0x20, 0x60, + 0x60, 0x68, 0x40, 0xf0, 0x01, 0x00, 0x60, 0x60, 0x00, 0x21, 0x2e, 0x20, + 0x02, 0xf0, 0x29, 0xfa, 0x28, 0x46, 0x3e, 0xbd, 0xdf, 0xf8, 0x44, 0x04, + 0x01, 0x68, 0x41, 0xf0, 0x02, 0x01, 0x01, 0x60, 0x70, 0x47, 0x4f, 0xf0, + 0x8a, 0x41, 0x08, 0x60, 0x70, 0x47, 0x02, 0x68, 0x22, 0xf0, 0x7e, 0x52, + 0x42, 0xea, 0xc1, 0x51, 0x01, 0x60, 0x70, 0x47, 0x01, 0x21, 0x00, 0xf0, + 0x1f, 0x02, 0x91, 0x40, 0xc0, 0xf3, 0x41, 0x10, 0x48, 0x43, 0x01, 0xeb, + 0x90, 0x00, 0x70, 0x47, 0x10, 0xb5, 0x04, 0x46, 0x02, 0xf0, 0x6f, 0xf9, + 0x01, 0x21, 0x81, 0x40, 0x62, 0x1a, 0x89, 0x08, 0xb2, 0xfb, 0xf1, 0xf1, + 0x40, 0xea, 0x41, 0x10, 0xc0, 0xb2, 0x10, 0xbd, 0xdf, 0xf8, 0xf4, 0x13, + 0x0a, 0x68, 0x22, 0xf0, 0xf2, 0x02, 0x00, 0xf0, 0x0f, 0x00, 0x42, 0xea, + 0x00, 0x10, 0x40, 0xf0, 0x04, 0x00, 0x08, 0x60, 0x70, 0x47, 0xdf, 0xf8, + 0xdc, 0x03, 0x01, 0x68, 0x21, 0xf0, 0x04, 0x01, 0xc5, 0xe7, 0x10, 0xb5, + 0xd3, 0x07, 0x12, 0xd5, 0x0f, 0xf2, 0x2c, 0x43, 0x33, 0xf8, 0x20, 0x40, + 0x04, 0xf1, 0x8c, 0x44, 0x03, 0xeb, 0x80, 0x03, 0x24, 0x78, 0xa4, 0x00, + 0x0c, 0x80, 0x5b, 0x88, 0x03, 0xf1, 0x8c, 0x43, 0x1b, 0x78, 0x03, 0xf0, + 0x03, 0x03, 0x23, 0x43, 0x0b, 0x80, 0x92, 0x07, 0x17, 0xd5, 0x0f, 0xf2, + 0x0c, 0x42, 0x32, 0xf8, 0x20, 0x30, 0x03, 0xf1, 0x8c, 0x43, 0x02, 0xeb, + 0x80, 0x00, 0x1b, 0x78, 0x4b, 0x80, 0x40, 0x88, 0x00, 0xf1, 0x8c, 0x40, + 0x00, 0x78, 0x00, 0xf0, 0x3f, 0x00, 0x43, 0xea, 0x00, 0x20, 0x82, 0x04, + 0x48, 0x80, 0x02, 0xd5, 0xde, 0x4a, 0x10, 0x43, 0x48, 0x80, 0x10, 0xbd, + 0x00, 0x21, 0xdd, 0x4a, 0x52, 0xf8, 0x21, 0x20, 0x40, 0xf8, 0x21, 0x20, + 0x49, 0x1c, 0x38, 0x29, 0xf7, 0xd3, 0x70, 0x47, 0x2d, 0xe9, 0xf0, 0x47, + 0x0d, 0x46, 0xd8, 0x49, 0x49, 0x69, 0x92, 0x46, 0xd7, 0x4a, 0x12, 0x78, + 0x04, 0x46, 0x01, 0x20, 0x13, 0x07, 0x48, 0xbf, 0x04, 0x20, 0x02, 0xd4, + 0x52, 0x07, 0x48, 0xbf, 0x02, 0x20, 0x48, 0x43, 0xd2, 0x49, 0x88, 0x42, + 0x2c, 0xbf, 0x0f, 0xf2, 0xc4, 0x38, 0x0f, 0xf2, 0xb4, 0x38, 0x00, 0x27, + 0x05, 0xeb, 0xc7, 0x00, 0x00, 0xf1, 0x60, 0x06, 0xd6, 0xe9, 0x00, 0x01, + 0x00, 0xf0, 0x84, 0xfe, 0x00, 0xf0, 0xdf, 0xf8, 0xe1, 0x68, 0x00, 0xf0, + 0xbd, 0xff, 0xe0, 0x60, 0xd6, 0xe9, 0x06, 0x01, 0x00, 0xf0, 0x7a, 0xfe, + 0x00, 0xf0, 0xd5, 0xf8, 0x21, 0x69, 0x00, 0xf0, 0xb3, 0xff, 0x20, 0x61, + 0xd6, 0xe9, 0x0c, 0x01, 0x00, 0xf0, 0x70, 0xfe, 0x00, 0xf0, 0xcb, 0xf8, + 0x61, 0x69, 0x00, 0xf0, 0xa9, 0xff, 0x60, 0x61, 0xd6, 0xe9, 0x12, 0x01, + 0x00, 0xf0, 0x66, 0xfe, 0x00, 0xf0, 0xc1, 0xf8, 0xa1, 0x69, 0x00, 0xf0, + 0x9f, 0xff, 0x7f, 0x1c, 0x03, 0x2f, 0xa0, 0x61, 0xd0, 0xd3, 0x00, 0x27, + 0x00, 0xf0, 0xbb, 0xf8, 0x00, 0xf0, 0xb2, 0xf8, 0x21, 0x68, 0x00, 0xf0, + 0x93, 0xff, 0x00, 0xf0, 0xbd, 0xf8, 0x00, 0xf0, 0xab, 0xf8, 0x61, 0x68, + 0x00, 0xf0, 0x8c, 0xff, 0x60, 0x60, 0xd9, 0xe9, 0x06, 0x01, 0x00, 0xf0, + 0x49, 0xfe, 0x00, 0xf0, 0xa1, 0xf8, 0xa1, 0x68, 0x00, 0xf0, 0x82, 0xff, + 0x02, 0x2f, 0xa0, 0x60, 0xe4, 0xd3, 0x01, 0x27, 0x00, 0xf0, 0x9f, 0xf8, + 0x00, 0xf0, 0x96, 0xf8, 0x21, 0x68, 0x00, 0xf0, 0x77, 0xff, 0x00, 0xf0, + 0xa1, 0xf8, 0x00, 0xf0, 0x8f, 0xf8, 0x61, 0x68, 0x00, 0xf0, 0x70, 0xff, + 0x60, 0x60, 0xd9, 0xe9, 0x0c, 0x01, 0x00, 0xf0, 0x2d, 0xfe, 0x00, 0xf0, + 0x85, 0xf8, 0xa1, 0x68, 0x00, 0xf0, 0x66, 0xff, 0x02, 0x2f, 0xa0, 0x60, + 0xe4, 0xd3, 0xc0, 0x35, 0xd5, 0xe9, 0x00, 0x01, 0x00, 0xf0, 0x20, 0xfe, + 0xe1, 0x69, 0x00, 0xf0, 0x5b, 0xff, 0xe0, 0x61, 0xd5, 0xe9, 0x02, 0x01, + 0x00, 0xf0, 0x18, 0xfe, 0x21, 0x6a, 0x00, 0xf0, 0x53, 0xff, 0x20, 0x62, + 0xd5, 0xe9, 0x04, 0x01, 0x00, 0xf0, 0x10, 0xfe, 0x61, 0x6a, 0x00, 0xf0, + 0x4b, 0xff, 0x60, 0x62, 0xd5, 0xe9, 0x06, 0x01, 0x00, 0xf0, 0x08, 0xfe, + 0xa1, 0x6a, 0x00, 0xf0, 0x43, 0xff, 0xa0, 0x62, 0x50, 0x46, 0x00, 0xf0, + 0x3d, 0xfe, 0xe1, 0x6a, 0x00, 0xf0, 0x3c, 0xff, 0xe1, 0x69, 0x05, 0x46, + 0xe5, 0x62, 0x08, 0x46, 0x00, 0xf0, 0xd2, 0xff, 0x29, 0x46, 0x00, 0xf0, + 0x41, 0xfe, 0x01, 0x46, 0x20, 0x68, 0x00, 0xf0, 0xbb, 0xfe, 0x60, 0x63, + 0x25, 0x6a, 0x28, 0x46, 0x29, 0x46, 0x00, 0xf0, 0xc5, 0xff, 0x00, 0xf0, + 0x3c, 0xf8, 0x01, 0x46, 0x60, 0x68, 0x00, 0xf0, 0xaf, 0xfe, 0xa0, 0x63, + 0x29, 0x46, 0xe0, 0x69, 0x00, 0xf0, 0xba, 0xff, 0x00, 0xf0, 0x31, 0xf8, + 0x01, 0x46, 0xa0, 0x68, 0x00, 0xf0, 0xa4, 0xfe, 0xe0, 0x63, 0x66, 0x6a, + 0x00, 0xf0, 0x2c, 0xf8, 0x00, 0xf0, 0x27, 0xf8, 0x01, 0x46, 0xe0, 0x68, + 0x00, 0xf0, 0x9a, 0xfe, 0x20, 0x64, 0x29, 0x46, 0x30, 0x46, 0x00, 0xf0, + 0xa5, 0xff, 0x00, 0xf0, 0x1c, 0xf8, 0x01, 0x46, 0x60, 0x69, 0x00, 0xf0, + 0x8f, 0xfe, 0xa0, 0x64, 0xa6, 0x6a, 0x00, 0xf0, 0x17, 0xf8, 0x00, 0xf0, + 0x12, 0xf8, 0x01, 0x46, 0x20, 0x69, 0x00, 0xf0, 0x85, 0xfe, 0x60, 0x64, + 0x29, 0x46, 0x30, 0x46, 0x00, 0xf0, 0x90, 0xff, 0x00, 0xf0, 0x07, 0xf8, + 0x01, 0x46, 0xa0, 0x69, 0x00, 0xf0, 0x7a, 0xfe, 0xe0, 0x64, 0xbd, 0xe8, + 0xf0, 0x87, 0xe1, 0x6a, 0x00, 0xf0, 0xf6, 0xbd, 0xe0, 0x69, 0x31, 0x46, + 0x00, 0xf0, 0x80, 0xbf, 0x71, 0x68, 0x00, 0xf0, 0x7d, 0xbf, 0x58, 0xf8, + 0x27, 0x10, 0x00, 0xf0, 0x79, 0xbf, 0x78, 0x42, 0x05, 0xeb, 0xc7, 0x09, + 0x08, 0xeb, 0x80, 0x06, 0xd9, 0xe9, 0x00, 0x01, 0x00, 0xf0, 0x96, 0xbd, + 0x20, 0x60, 0x7f, 0x1c, 0xd9, 0xe9, 0x12, 0x01, 0x00, 0xf0, 0x90, 0xbd, + 0x30, 0xb5, 0xb9, 0xb0, 0x04, 0x46, 0x0d, 0x46, 0x68, 0x46, 0xff, 0xf7, + 0xd9, 0xfe, 0x2a, 0x46, 0x69, 0x46, 0x20, 0x46, 0xff, 0xf7, 0xde, 0xfe, + 0x39, 0xb0, 0x30, 0xbd, 0x2d, 0xe9, 0xf8, 0x43, 0x04, 0x46, 0x04, 0xf1, + 0xc0, 0x07, 0x0d, 0x46, 0xd7, 0xe9, 0x02, 0x01, 0x90, 0x46, 0x00, 0xf0, + 0x77, 0xfd, 0x06, 0x46, 0xd7, 0xe9, 0x00, 0x01, 0x00, 0xf0, 0x72, 0xfd, + 0x07, 0x46, 0x40, 0x46, 0x00, 0xf0, 0xaa, 0xfd, 0x80, 0x46, 0xd4, 0xe9, + 0x00, 0x01, 0x00, 0xf0, 0x69, 0xfd, 0x81, 0x46, 0x38, 0x46, 0x39, 0x46, + 0x00, 0xf0, 0x3e, 0xff, 0x41, 0x46, 0x00, 0xf0, 0xad, 0xfd, 0x01, 0x46, + 0x48, 0x46, 0x00, 0xf0, 0x27, 0xfe, 0x07, 0x46, 0xd4, 0xe9, 0x12, 0x01, + 0x00, 0xf0, 0x58, 0xfd, 0x04, 0x46, 0x30, 0x46, 0xff, 0xf7, 0xab, 0xff, + 0x41, 0x46, 0x00, 0xf0, 0x9d, 0xfd, 0x01, 0x46, 0x20, 0x46, 0x00, 0xf0, + 0x17, 0xfe, 0x39, 0x46, 0x00, 0xf0, 0x88, 0xfe, 0x41, 0x46, 0x00, 0xf0, + 0x93, 0xfd, 0x29, 0x46, 0x01, 0xf0, 0x26, 0xf8, 0x94, 0xbf, 0x01, 0x20, + 0x00, 0x20, 0xbd, 0xe8, 0xf2, 0x83, 0x10, 0xb5, 0x28, 0x49, 0x20, 0x4c, + 0x82, 0xb0, 0x4f, 0xf4, 0x80, 0x70, 0x08, 0x60, 0x6b, 0x46, 0x20, 0x68, + 0x01, 0x22, 0x04, 0x21, 0xfc, 0xf7, 0x04, 0xfa, 0x60, 0x68, 0x4f, 0xf0, + 0x8a, 0x41, 0x08, 0x60, 0x13, 0xbd, 0x38, 0xb5, 0x04, 0x46, 0x0d, 0x46, + 0x28, 0x46, 0xff, 0xf7, 0xf0, 0xfc, 0x05, 0xf1, 0x08, 0x00, 0xff, 0xf7, + 0x42, 0xf9, 0x01, 0x21, 0xe0, 0xb2, 0xff, 0xf7, 0xe9, 0xfb, 0x1a, 0x4a, + 0xd2, 0xe9, 0x08, 0x01, 0xff, 0xf7, 0x94, 0xfc, 0x01, 0x46, 0xe0, 0xb2, + 0xff, 0xf7, 0xae, 0xfc, 0x00, 0x20, 0xff, 0xf7, 0xb3, 0xfc, 0x03, 0x21, + 0xe0, 0xb2, 0xff, 0xf7, 0xc2, 0xfc, 0x3f, 0x21, 0xe0, 0xb2, 0xff, 0xf7, + 0xc9, 0xfc, 0xff, 0xf7, 0x2c, 0xfc, 0xff, 0xf7, 0x0e, 0xfc, 0x00, 0x2c, + 0x0c, 0xbf, 0x02, 0x20, 0x03, 0x20, 0xbd, 0xe8, 0x34, 0x40, 0x28, 0x21, + 0xff, 0xf7, 0x30, 0xb9, 0x28, 0x00, 0x00, 0x50, 0x58, 0xf3, 0x00, 0x20, + 0x04, 0x00, 0x00, 0x45, 0x04, 0x00, 0x00, 0x51, 0x00, 0xc0, 0xff, 0xff, + 0x00, 0x01, 0x00, 0x45, 0x78, 0x29, 0x00, 0x20, 0x10, 0x09, 0x00, 0x46, + 0x01, 0x1c, 0x4e, 0x0e, 0x40, 0x00, 0x00, 0x50, 0x00, 0xf2, 0x00, 0x20, + 0x38, 0xb5, 0x04, 0x46, 0x0d, 0x46, 0x07, 0xf0, 0x53, 0xfe, 0x28, 0x60, + 0x29, 0x1d, 0x20, 0x46, 0xbd, 0xe8, 0x34, 0x40, 0xaf, 0xe7, 0x10, 0xb5, + 0x04, 0x46, 0x04, 0xf1, 0x08, 0x00, 0xff, 0xf7, 0xfd, 0xf8, 0x20, 0x46, + 0xbd, 0xe8, 0x10, 0x40, 0xff, 0xf7, 0xa8, 0xbc, 0x38, 0xb5, 0x04, 0x46, + 0x0d, 0x46, 0x28, 0x1d, 0xff, 0xf7, 0xef, 0xff, 0x29, 0x68, 0x20, 0x46, + 0xbd, 0xe8, 0x34, 0x40, 0x07, 0xf0, 0x3e, 0xbe, 0x00, 0x07, 0x01, 0x07, + 0x02, 0x07, 0x03, 0x07, 0x12, 0x0a, 0x13, 0x0a, 0x1f, 0x0a, 0x20, 0x0a, + 0xee, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x09, 0xab, 0x09, + 0x10, 0x0a, 0x11, 0x0a, 0x1d, 0x0a, 0x1e, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xb3, 0x7b, 0x72, 0x3e, + 0x99, 0xbb, 0x06, 0x3f, 0xb3, 0x7b, 0x72, 0x3e, 0x0f, 0x4a, 0x80, 0x04, + 0x80, 0x0c, 0x10, 0x60, 0x88, 0x04, 0x80, 0x0c, 0x50, 0x60, 0x70, 0x47, + 0x0c, 0x4a, 0x10, 0x60, 0x51, 0x60, 0x70, 0x47, 0x4f, 0xf0, 0xa2, 0x41, + 0x0a, 0x68, 0x22, 0xf0, 0x80, 0x42, 0x42, 0xea, 0x80, 0x70, 0x08, 0x60, + 0x48, 0x68, 0x40, 0xf0, 0x08, 0x00, 0x48, 0x60, 0x70, 0x47, 0x05, 0x48, + 0x01, 0x68, 0x21, 0xf0, 0x08, 0x01, 0x01, 0x60, 0x70, 0x47, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x51, 0x20, 0x00, 0x00, 0x51, 0x04, 0x00, 0x00, 0x51, + 0x38, 0xb5, 0xdf, 0xf8, 0x90, 0x46, 0xa8, 0x21, 0x20, 0x46, 0x01, 0xf0, + 0x05, 0xfd, 0x00, 0x25, 0xfc, 0xf7, 0x1c, 0xfd, 0x54, 0x21, 0x01, 0xfb, + 0x05, 0x41, 0x6d, 0x1c, 0x02, 0x2d, 0x08, 0x64, 0xf6, 0xd3, 0x0f, 0xf2, + 0xd8, 0x61, 0xdf, 0xf8, 0x70, 0x06, 0x1c, 0xc9, 0x1c, 0xc0, 0x31, 0xbd, + 0x2d, 0xe9, 0xf0, 0x47, 0xdf, 0xf8, 0x64, 0x06, 0x84, 0xb0, 0x80, 0x7a, + 0x0c, 0x46, 0x00, 0xf0, 0x03, 0x09, 0xff, 0xf7, 0xdd, 0xff, 0x00, 0x27, + 0x00, 0x26, 0x0d, 0xf1, 0x04, 0x0a, 0x29, 0xfa, 0x06, 0xf0, 0xc0, 0x07, + 0x4f, 0xd5, 0xdf, 0xf8, 0x40, 0x06, 0x26, 0x60, 0x00, 0xf1, 0x40, 0x01, + 0x61, 0x60, 0x54, 0x22, 0x00, 0xf1, 0x0c, 0x01, 0xa1, 0x60, 0x01, 0x25, + 0xdf, 0xf8, 0x24, 0x16, 0x02, 0xfb, 0x06, 0x18, 0x06, 0x21, 0x01, 0xfb, + 0x06, 0x00, 0x6c, 0x30, 0xe0, 0x61, 0xc4, 0xf8, 0x0c, 0x80, 0x20, 0x46, + 0x00, 0xf0, 0x18, 0xfb, 0x29, 0x46, 0x20, 0x46, 0x00, 0xf0, 0x8c, 0xfa, + 0x07, 0x00, 0x19, 0xd1, 0xe1, 0x69, 0x60, 0x68, 0x01, 0xeb, 0x45, 0x01, + 0x00, 0x91, 0x14, 0x21, 0x01, 0xfb, 0x05, 0x01, 0x0b, 0x1d, 0xb0, 0xf9, + 0x02, 0x20, 0x01, 0x88, 0x20, 0x68, 0x01, 0xf0, 0x5a, 0xfb, 0x00, 0xb1, + 0x05, 0x20, 0x4a, 0xf8, 0x25, 0x00, 0x20, 0xb9, 0xe0, 0x69, 0x10, 0xf8, + 0x15, 0x00, 0x5a, 0x28, 0x00, 0xda, 0x05, 0x27, 0x29, 0x46, 0x20, 0x46, + 0x00, 0xf0, 0xa6, 0xfa, 0xc7, 0xb9, 0xe1, 0x69, 0x11, 0xf8, 0x15, 0x20, + 0x08, 0xeb, 0x85, 0x00, 0x48, 0x30, 0x01, 0xeb, 0x45, 0x01, 0x42, 0x80, + 0x6d, 0x1e, 0x49, 0x78, 0x01, 0x80, 0xcd, 0xd5, 0xe0, 0x68, 0x50, 0x30, + 0x01, 0x21, 0x41, 0x80, 0x01, 0x80, 0x76, 0x1c, 0x02, 0x2e, 0xa8, 0xd3, + 0x38, 0x46, 0x04, 0xb0, 0xbd, 0xe8, 0xf0, 0x87, 0xe0, 0x68, 0x50, 0x30, + 0x00, 0x21, 0x41, 0x80, 0x01, 0x80, 0xf5, 0xe7, 0x70, 0x47, 0x2d, 0xe9, + 0xf0, 0x4f, 0x0c, 0x46, 0x8b, 0xb0, 0xdf, 0xf8, 0x7c, 0x15, 0x20, 0x60, + 0x01, 0xf1, 0x40, 0x02, 0x62, 0x60, 0x54, 0x23, 0x01, 0xf1, 0x0c, 0x02, + 0xa2, 0x60, 0x4f, 0xf4, 0x84, 0x5a, 0xdf, 0xf8, 0x60, 0x25, 0x03, 0xfb, + 0x00, 0x22, 0xe2, 0x60, 0x06, 0x22, 0x02, 0xfb, 0x00, 0x10, 0x6c, 0x30, + 0xe0, 0x61, 0xfb, 0xf7, 0x99, 0xfd, 0xe0, 0x68, 0x01, 0x6c, 0x41, 0x64, + 0xfc, 0xf7, 0x7c, 0xfc, 0x01, 0x46, 0xe0, 0x68, 0x01, 0x64, 0x52, 0x46, + 0xc1, 0x6b, 0x49, 0x1c, 0xc1, 0x63, 0x08, 0x21, 0x07, 0xf0, 0x72, 0xfe, + 0xe0, 0x68, 0xe1, 0x69, 0xb0, 0xf8, 0x4a, 0x00, 0x08, 0x70, 0xe0, 0x68, + 0xe1, 0x69, 0xb0, 0xf8, 0x48, 0x00, 0x48, 0x70, 0xe0, 0x68, 0xe1, 0x69, + 0xb0, 0xf8, 0x4e, 0x00, 0x88, 0x70, 0xe0, 0x68, 0xe1, 0x69, 0xb0, 0xf8, + 0x4c, 0x00, 0xc8, 0x70, 0xfb, 0xf7, 0x89, 0xfd, 0x20, 0x46, 0x00, 0xf0, + 0x8f, 0xfa, 0xe0, 0x68, 0xb0, 0xf8, 0x50, 0x00, 0x10, 0xb9, 0x4f, 0xf0, + 0x05, 0x09, 0x65, 0xe0, 0x01, 0x26, 0x49, 0xf2, 0xb2, 0x27, 0x32, 0x46, + 0x69, 0x46, 0x20, 0x46, 0x00, 0xf0, 0x67, 0xf8, 0x5f, 0xea, 0x00, 0x09, + 0x5a, 0xd1, 0x01, 0x2e, 0x05, 0xd1, 0xe0, 0x68, 0x3a, 0x46, 0x00, 0x21, + 0x07, 0xf0, 0x40, 0xfe, 0xba, 0x46, 0x76, 0x1e, 0xed, 0xd5, 0xfb, 0xf7, + 0x53, 0xfd, 0x00, 0x26, 0xdf, 0xf8, 0xc4, 0xa4, 0xdf, 0xf8, 0xc4, 0x84, + 0x68, 0x46, 0x14, 0x21, 0x01, 0xfb, 0x06, 0x05, 0x01, 0x21, 0x28, 0x68, + 0x07, 0xf0, 0x6e, 0xfe, 0xe7, 0x68, 0x0c, 0x21, 0x01, 0xfb, 0x06, 0x7b, + 0x41, 0x46, 0x00, 0xf0, 0x5d, 0xfd, 0x51, 0x46, 0x00, 0xf0, 0x5a, 0xfd, + 0x00, 0xf0, 0xc4, 0xfd, 0xcb, 0xf8, 0x14, 0x00, 0x51, 0x46, 0x68, 0x68, + 0x00, 0xf0, 0x52, 0xfd, 0x00, 0xf0, 0xbc, 0xfd, 0xcb, 0xf8, 0x18, 0x00, + 0x51, 0x46, 0xa8, 0x68, 0x00, 0xf0, 0x4a, 0xfd, 0x00, 0xf0, 0xb4, 0xfd, + 0xcb, 0xf8, 0x1c, 0x00, 0x01, 0x21, 0xe8, 0x68, 0x07, 0xf0, 0x4c, 0xfe, + 0x01, 0x46, 0x40, 0x46, 0x00, 0xf0, 0x3e, 0xfd, 0x51, 0x46, 0x00, 0xf0, + 0x3b, 0xfd, 0x07, 0xeb, 0xc6, 0x07, 0x00, 0xf0, 0xa3, 0xfd, 0xf8, 0x62, + 0x01, 0x21, 0x28, 0x69, 0x07, 0xf0, 0x3c, 0xfe, 0x41, 0x46, 0x00, 0xf0, + 0x2f, 0xfd, 0x51, 0x46, 0x00, 0xf0, 0x2c, 0xfd, 0x00, 0xf0, 0x96, 0xfd, + 0x76, 0x1c, 0x02, 0x2e, 0x38, 0x63, 0xb9, 0xdb, 0xfb, 0xf7, 0x1b, 0xfd, + 0x49, 0xf6, 0xe4, 0x2a, 0xe0, 0x68, 0x52, 0x46, 0x49, 0x46, 0x07, 0xf0, + 0xe7, 0xfd, 0x48, 0x46, 0x0b, 0xb0, 0xbd, 0xe8, 0xf0, 0x8f, 0x2d, 0xe9, + 0xf7, 0x4f, 0x92, 0xb0, 0x00, 0x24, 0x12, 0x98, 0x03, 0x94, 0x02, 0x94, + 0xa0, 0x46, 0x00, 0x68, 0x14, 0x99, 0x01, 0x90, 0x12, 0x98, 0x00, 0xf0, + 0x83, 0xf9, 0x00, 0x90, 0x10, 0xb1, 0x00, 0xf0, 0xe7, 0xf8, 0xd7, 0xe0, + 0x12, 0x98, 0xc0, 0x69, 0x14, 0x99, 0x10, 0xf8, 0x11, 0x10, 0x01, 0x98, + 0x03, 0xf0, 0x91, 0xfe, 0xa3, 0x46, 0x77, 0xe0, 0x00, 0x26, 0x04, 0xaa, + 0x04, 0xa8, 0x32, 0xf9, 0x26, 0x20, 0x00, 0xeb, 0x86, 0x0a, 0xd3, 0x17, + 0xa2, 0xfb, 0x02, 0x57, 0xba, 0xf9, 0x02, 0x00, 0x02, 0xfb, 0x03, 0x77, + 0x03, 0xfb, 0x02, 0x77, 0xc1, 0x17, 0xa0, 0xfb, 0x00, 0x23, 0x00, 0xfb, + 0x01, 0x33, 0x01, 0xfb, 0x00, 0x33, 0x39, 0x46, 0xa8, 0x18, 0x59, 0x41, + 0x00, 0xf0, 0x06, 0xfb, 0x03, 0x99, 0x00, 0xf0, 0x41, 0xfc, 0x03, 0x90, + 0x0b, 0xa8, 0x00, 0xeb, 0x86, 0x09, 0x30, 0xf9, 0x26, 0x00, 0xc1, 0x17, + 0xa0, 0xfb, 0x00, 0x23, 0xb9, 0xf9, 0x02, 0x50, 0x00, 0xfb, 0x01, 0x33, + 0x01, 0xfb, 0x00, 0x33, 0xef, 0x17, 0xa5, 0xfb, 0x05, 0x01, 0x05, 0xfb, + 0x07, 0x11, 0x07, 0xfb, 0x05, 0x11, 0x10, 0x18, 0x59, 0x41, 0x00, 0xf0, + 0xe9, 0xfa, 0x21, 0x46, 0x00, 0xf0, 0x24, 0xfc, 0x04, 0x46, 0x0b, 0xa8, + 0xb9, 0xf9, 0x02, 0x50, 0x30, 0xf9, 0x26, 0x90, 0xba, 0xf9, 0x02, 0x20, + 0x04, 0xa8, 0xef, 0x17, 0x30, 0xf9, 0x26, 0xc0, 0xa2, 0xfb, 0x05, 0x01, + 0xd3, 0x17, 0x02, 0xfb, 0x07, 0x11, 0x03, 0xfb, 0x05, 0x11, 0xcc, 0xfb, + 0x09, 0x01, 0x00, 0xf0, 0xcf, 0xfa, 0x02, 0x99, 0x00, 0xf0, 0x0a, 0xfc, + 0x02, 0x90, 0x2a, 0x46, 0x04, 0xa8, 0x3b, 0x46, 0x30, 0xf9, 0x26, 0x00, + 0xa0, 0xfb, 0x02, 0x57, 0xc1, 0x17, 0x00, 0xfb, 0x03, 0x77, 0x0b, 0xa8, + 0x01, 0xfb, 0x02, 0x77, 0x30, 0xf9, 0x26, 0x00, 0xba, 0xf9, 0x02, 0x10, + 0x81, 0xfb, 0x00, 0x01, 0x28, 0x1a, 0x67, 0xeb, 0x01, 0x01, 0x00, 0xf0, + 0xb3, 0xfa, 0x41, 0x46, 0x00, 0xf0, 0xee, 0xfb, 0x76, 0x1c, 0x07, 0x2e, + 0x80, 0x46, 0x8a, 0xd3, 0x0b, 0xf1, 0x01, 0x0b, 0x00, 0xf0, 0x5b, 0xf8, + 0x83, 0x45, 0x19, 0xd2, 0x01, 0x98, 0x07, 0x23, 0x04, 0xaa, 0x0b, 0xa9, + 0x03, 0xf0, 0x4e, 0xfe, 0xfe, 0xf7, 0x8f, 0xf8, 0x00, 0x28, 0x3f, 0xf4, + 0x79, 0xaf, 0x12, 0x99, 0xc9, 0x68, 0x06, 0x20, 0x08, 0x60, 0xab, 0xf1, + 0x01, 0x0b, 0x00, 0xf0, 0x4d, 0xf8, 0x14, 0x99, 0x12, 0x98, 0x00, 0xf0, + 0xe1, 0xf8, 0x00, 0x28, 0x00, 0x90, 0xdf, 0xd0, 0x00, 0xf0, 0x44, 0xf8, + 0x00, 0x98, 0x00, 0x28, 0x32, 0xd1, 0x13, 0x98, 0x14, 0x99, 0x14, 0x22, + 0x02, 0xfb, 0x01, 0x06, 0x00, 0xf0, 0x33, 0xf8, 0xc0, 0xeb, 0xc0, 0x00, + 0x00, 0xf0, 0xae, 0xfa, 0x05, 0x46, 0x20, 0x46, 0x29, 0x46, 0x00, 0xf0, + 0xc3, 0xfa, 0x00, 0xf0, 0xf5, 0xfb, 0x00, 0xf0, 0x23, 0xf8, 0xf0, 0x60, + 0x29, 0x46, 0x03, 0x98, 0x00, 0xf0, 0xba, 0xfa, 0x00, 0xf0, 0xec, 0xfb, + 0x00, 0xf0, 0x1a, 0xf8, 0x30, 0x61, 0xf1, 0x68, 0x00, 0xf0, 0xb2, 0xfa, + 0x30, 0x60, 0x21, 0x46, 0x9a, 0x48, 0x00, 0xf0, 0x3b, 0xfc, 0x00, 0xf0, + 0x0f, 0xf8, 0x04, 0x46, 0x02, 0x98, 0x21, 0x46, 0x00, 0xf0, 0xa6, 0xfa, + 0x70, 0x60, 0x21, 0x46, 0x40, 0x46, 0x00, 0xf0, 0xa1, 0xfa, 0xb0, 0x60, + 0x00, 0x98, 0x15, 0xb0, 0xbd, 0xe8, 0xf0, 0x8f, 0x90, 0x49, 0x00, 0xf0, + 0x99, 0xba, 0x12, 0x98, 0x01, 0x99, 0x80, 0x68, 0x00, 0xeb, 0x41, 0x00, + 0x80, 0x8a, 0x70, 0x47, 0x14, 0x99, 0x12, 0x98, 0xce, 0xe0, 0x10, 0xb5, + 0x04, 0x46, 0x21, 0x46, 0x08, 0x29, 0xb1, 0xbf, 0x4f, 0xf4, 0x30, 0x60, + 0x40, 0xf6, 0x01, 0x30, 0x08, 0x39, 0x89, 0xb2, 0x00, 0xf1, 0x8c, 0x42, + 0x01, 0x23, 0x12, 0x78, 0x03, 0xfa, 0x01, 0xf1, 0x8a, 0x43, 0x11, 0x43, + 0xc9, 0xb2, 0xfc, 0xf7, 0x49, 0xfd, 0x04, 0x2c, 0x40, 0xf6, 0x06, 0x30, + 0x7e, 0x49, 0x05, 0xda, 0x09, 0x78, 0x01, 0xf0, 0xf0, 0x01, 0x41, 0xf0, + 0x03, 0x01, 0x0e, 0xe0, 0x08, 0x2c, 0x05, 0xda, 0x09, 0x78, 0x01, 0xf0, + 0x0f, 0x01, 0x41, 0xf0, 0x30, 0x01, 0x06, 0xe0, 0x48, 0x78, 0x00, 0xf0, + 0xf0, 0x00, 0x40, 0xf0, 0x03, 0x01, 0x40, 0xf6, 0x07, 0x30, 0xbd, 0xe8, + 0x10, 0x40, 0xfc, 0xf7, 0x2b, 0xbd, 0x10, 0xb5, 0x08, 0x28, 0xb2, 0xbf, + 0x40, 0xf6, 0x02, 0x32, 0x40, 0xf6, 0x03, 0x32, 0x08, 0x38, 0x02, 0xf1, + 0x8c, 0x43, 0x01, 0x24, 0x1b, 0x78, 0x84, 0x40, 0x23, 0xea, 0x04, 0x00, + 0x01, 0xb1, 0x20, 0x43, 0xbd, 0xe8, 0x10, 0x40, 0xc1, 0xb2, 0x10, 0x46, + 0xfc, 0xf7, 0x14, 0xbd, 0x38, 0xb5, 0x04, 0x46, 0xa0, 0x68, 0x22, 0x68, + 0x00, 0xeb, 0x42, 0x00, 0x01, 0x29, 0x02, 0x89, 0x80, 0x88, 0x02, 0xd1, + 0x52, 0x1e, 0x92, 0x41, 0xd2, 0x0f, 0x11, 0x46, 0xff, 0xf7, 0xd9, 0xff, + 0x5e, 0x48, 0x58, 0x4d, 0x00, 0x68, 0x21, 0x68, 0x05, 0xeb, 0x81, 0x01, + 0x08, 0x63, 0xfc, 0xf7, 0x83, 0xfa, 0x21, 0x68, 0x05, 0xeb, 0x81, 0x01, + 0x88, 0x63, 0x00, 0x21, 0x20, 0x68, 0x05, 0xeb, 0x80, 0x00, 0xbd, 0xe8, + 0x34, 0x40, 0x00, 0x1d, 0xfe, 0xf7, 0x20, 0xbf, 0xf8, 0xb5, 0x04, 0x46, + 0x53, 0x4d, 0x4c, 0x4e, 0x51, 0x48, 0x07, 0x68, 0xfc, 0xf7, 0x6e, 0xfa, + 0x06, 0xf1, 0x38, 0x02, 0x06, 0xf1, 0x30, 0x01, 0x52, 0xf8, 0x24, 0x20, + 0x51, 0xf8, 0x24, 0x10, 0x80, 0x1a, 0x2a, 0x6c, 0xc9, 0x1b, 0x02, 0xfb, + 0x00, 0x10, 0x06, 0xeb, 0x84, 0x01, 0x49, 0x68, 0x49, 0xb9, 0x06, 0xf1, + 0x28, 0x01, 0x51, 0xf8, 0x24, 0x10, 0x88, 0x42, 0x03, 0xd2, 0xfd, 0xf7, + 0xa2, 0xff, 0x00, 0x28, 0xe0, 0xd0, 0xf1, 0xbd, 0x70, 0xb5, 0x04, 0x46, + 0x0d, 0x46, 0x00, 0x21, 0x00, 0x20, 0xfc, 0xf7, 0x18, 0xff, 0x01, 0x2d, + 0x03, 0xd1, 0x01, 0x21, 0x20, 0x46, 0xff, 0xf7, 0xa9, 0xff, 0x20, 0x68, + 0x04, 0xf1, 0x10, 0x01, 0x03, 0xf0, 0xf5, 0xfd, 0x06, 0x00, 0x09, 0xd1, + 0xe0, 0x69, 0x00, 0xeb, 0x45, 0x01, 0x20, 0x68, 0x03, 0xf0, 0x48, 0xfe, + 0x20, 0x68, 0x03, 0xf0, 0x2a, 0xfe, 0x06, 0x46, 0x01, 0x2e, 0x0b, 0xd0, + 0x02, 0x2e, 0x0b, 0xd0, 0x0c, 0x2e, 0x0b, 0xd0, 0x11, 0x2e, 0x0b, 0xd0, + 0x13, 0x2e, 0x0b, 0xd0, 0x14, 0x2e, 0x08, 0xbf, 0x0a, 0x26, 0x08, 0xe0, + 0x02, 0x26, 0x06, 0xe0, 0x01, 0x26, 0x04, 0xe0, 0x0b, 0x26, 0x02, 0xe0, + 0x03, 0x26, 0x00, 0xe0, 0x09, 0x26, 0x20, 0x68, 0xff, 0xf7, 0xa4, 0xff, + 0x30, 0x46, 0x70, 0xbd, 0x38, 0xb5, 0x04, 0x46, 0x0d, 0x46, 0xfd, 0xf7, + 0xcf, 0xf9, 0x03, 0x28, 0x06, 0xd1, 0x07, 0xf0, 0xd5, 0xfe, 0x00, 0x21, + 0x04, 0xf1, 0x10, 0x00, 0xfe, 0xf7, 0xcf, 0xfe, 0x01, 0x2d, 0x03, 0xd1, + 0x00, 0x21, 0x20, 0x46, 0xff, 0xf7, 0x68, 0xff, 0xbd, 0xe8, 0x32, 0x40, + 0x00, 0x20, 0xfc, 0xf7, 0x29, 0xbf, 0x70, 0xb5, 0x11, 0x4b, 0x03, 0xeb, + 0x40, 0x01, 0x00, 0x22, 0x0d, 0x7c, 0x8c, 0x8a, 0x08, 0x2d, 0x02, 0xdb, + 0x08, 0x3d, 0xed, 0xb2, 0x01, 0x22, 0x01, 0x26, 0x06, 0xfa, 0x05, 0xf5, + 0xd6, 0x5c, 0xae, 0x43, 0xd6, 0x54, 0x04, 0xb9, 0x00, 0x25, 0xd2, 0x18, + 0x03, 0xeb, 0x80, 0x00, 0x94, 0x78, 0x2c, 0x43, 0x94, 0x70, 0x01, 0x22, + 0x42, 0x60, 0x0b, 0x4a, 0x09, 0x8b, 0xd2, 0x6b, 0x51, 0x43, 0x81, 0x62, + 0x70, 0xbd, 0x00, 0x00, 0x94, 0xed, 0x00, 0x20, 0xec, 0x2b, 0x00, 0x20, + 0x78, 0x29, 0x00, 0x20, 0x00, 0x00, 0xc8, 0x42, 0x00, 0x00, 0xa0, 0x41, + 0xf4, 0xfd, 0xb4, 0x47, 0x06, 0x0b, 0x00, 0x46, 0x18, 0xe0, 0x00, 0xe0, + 0x00, 0xf2, 0x00, 0x20, 0x10, 0xb5, 0x04, 0x46, 0xe0, 0x69, 0x80, 0x88, + 0xd0, 0xb9, 0xa0, 0x68, 0x21, 0x68, 0x00, 0xeb, 0x41, 0x00, 0x00, 0x8a, + 0x20, 0x28, 0x09, 0xda, 0xff, 0xf7, 0xd5, 0xfe, 0xa0, 0x68, 0x22, 0x68, + 0x00, 0xeb, 0x42, 0x00, 0x01, 0x21, 0x00, 0x8a, 0xff, 0xf7, 0x01, 0xff, + 0xa0, 0x68, 0x21, 0x68, 0x00, 0xeb, 0x41, 0x00, 0x80, 0x88, 0xff, 0xf7, + 0xc6, 0xfe, 0xe1, 0x69, 0x01, 0x20, 0x88, 0x80, 0x10, 0xbd, 0x00, 0x00, + 0xff, 0xff, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x38, 0xb5, 0x75, 0x4d, 0x04, 0x46, 0x15, 0xf8, 0x34, 0x10, 0x48, 0x1e, + 0x80, 0x41, 0xc0, 0x0f, 0x01, 0xf0, 0x29, 0xfb, 0x01, 0x20, 0x3f, 0xe0, + 0xf8, 0xb5, 0x06, 0x46, 0x6e, 0x4d, 0x34, 0x46, 0x15, 0xf8, 0x34, 0x00, + 0x01, 0x28, 0x0f, 0x46, 0x18, 0xbf, 0x00, 0x20, 0x01, 0xf0, 0x1b, 0xfb, + 0x6a, 0x48, 0x87, 0x42, 0x28, 0xbf, 0x6a, 0x4f, 0x28, 0x6b, 0x47, 0x43, + 0x30, 0x46, 0x00, 0xf0, 0x4f, 0xf8, 0x30, 0x46, 0x00, 0xf0, 0x53, 0xf8, + 0x05, 0xeb, 0xc4, 0x00, 0x02, 0x21, 0x40, 0x68, 0x07, 0x60, 0xc1, 0x60, + 0x00, 0x21, 0x81, 0x60, 0xf0, 0x21, 0x81, 0x60, 0x02, 0x20, 0x05, 0xf8, + 0x34, 0x00, 0xf1, 0xbd, 0x10, 0xb5, 0x5c, 0x4a, 0x02, 0xeb, 0xc0, 0x01, + 0x4b, 0x68, 0x59, 0x68, 0x14, 0x6b, 0xb1, 0xfb, 0xf4, 0xf1, 0x00, 0x24, + 0x9c, 0x60, 0x01, 0x23, 0x02, 0xf8, 0x30, 0x30, 0x08, 0x46, 0x10, 0xbd, + 0x38, 0xb5, 0x54, 0x4d, 0x04, 0x46, 0x15, 0xf8, 0x34, 0x10, 0x01, 0x29, + 0x18, 0xbf, 0xff, 0xf7, 0xe7, 0xff, 0x00, 0x20, 0x05, 0xf8, 0x34, 0x00, + 0x31, 0xbd, 0x51, 0x49, 0x0a, 0x68, 0x90, 0x42, 0x09, 0xd3, 0x49, 0x68, + 0x80, 0x1a, 0xb0, 0xfb, 0xf1, 0xf0, 0x00, 0x21, 0x01, 0xe0, 0x00, 0xbf, + 0x49, 0x1c, 0x81, 0x42, 0xfb, 0xd3, 0x70, 0x47, 0x10, 0xb4, 0x46, 0x4b, + 0x1b, 0x6b, 0x03, 0xfb, 0x00, 0xf3, 0x06, 0x24, 0xb3, 0xfb, 0xf4, 0xf3, + 0x19, 0x00, 0x00, 0x23, 0x1a, 0x00, 0x8a, 0x42, 0x02, 0xd2, 0x00, 0xbf, + 0x52, 0x1c, 0xfa, 0xe7, 0x10, 0xbc, 0x70, 0x47, 0x3d, 0x49, 0x01, 0xeb, + 0xc0, 0x00, 0x90, 0xf9, 0x01, 0x00, 0x01, 0xf0, 0x01, 0xbb, 0x10, 0xb5, + 0x39, 0x49, 0x01, 0xeb, 0xc0, 0x00, 0x90, 0xf9, 0x01, 0x40, 0x20, 0x46, + 0x01, 0xf0, 0xf8, 0xfa, 0x20, 0x46, 0xbd, 0xe8, 0x10, 0x40, 0x01, 0xf0, + 0xf9, 0xba, 0x33, 0x49, 0x01, 0xeb, 0xc0, 0x00, 0x90, 0xf9, 0x01, 0x00, + 0x01, 0xf0, 0xfb, 0xba, 0x80, 0xb5, 0x06, 0x21, 0x05, 0x20, 0x01, 0xf0, + 0x02, 0xfb, 0x06, 0x21, 0x06, 0x20, 0x01, 0xf0, 0xfe, 0xfa, 0x06, 0x21, + 0x07, 0x20, 0x01, 0xf0, 0xfa, 0xfa, 0x06, 0x21, 0x08, 0x20, 0x01, 0xf0, + 0xf6, 0xfa, 0x06, 0x21, 0x2f, 0x20, 0x01, 0xf0, 0xf2, 0xfa, 0x06, 0x21, + 0x30, 0x20, 0x01, 0xf0, 0xee, 0xfa, 0x06, 0x21, 0x31, 0x20, 0x01, 0xf0, + 0xea, 0xfa, 0x06, 0x21, 0x32, 0x20, 0x01, 0xf0, 0xe6, 0xfa, 0x23, 0x48, + 0x1e, 0x49, 0xc0, 0x6b, 0x08, 0x63, 0x01, 0xbd, 0x38, 0xb5, 0x04, 0x46, + 0x0d, 0x46, 0xff, 0xf7, 0x49, 0xff, 0x1b, 0x48, 0x85, 0x42, 0x19, 0x48, + 0x28, 0xbf, 0x1a, 0x4d, 0x01, 0x6b, 0x00, 0xeb, 0xc4, 0x00, 0x69, 0x43, + 0x40, 0x68, 0x01, 0x60, 0x02, 0x21, 0xc1, 0x60, 0x00, 0x21, 0xc1, 0x60, + 0x81, 0x60, 0xf0, 0x21, 0x81, 0x60, 0x31, 0xbd, 0x10, 0x49, 0x01, 0xeb, + 0xc0, 0x00, 0x40, 0x68, 0x40, 0x69, 0x70, 0x47, 0x80, 0xb5, 0x00, 0x20, + 0xff, 0xf7, 0xb1, 0xff, 0x00, 0xf0, 0x12, 0xf8, 0x08, 0x70, 0x01, 0xbd, + 0x80, 0xb5, 0x01, 0x20, 0xff, 0xf7, 0xa9, 0xff, 0x00, 0xf0, 0x0a, 0xf8, + 0x08, 0x72, 0x01, 0xbd, 0x80, 0xb5, 0x02, 0x20, 0xff, 0xf7, 0xa1, 0xff, + 0x00, 0xf0, 0x02, 0xf8, 0x08, 0x74, 0x01, 0xbd, 0x01, 0x49, 0x01, 0x20, + 0x70, 0x47, 0x00, 0x00, 0x78, 0x2a, 0x00, 0x20, 0xc1, 0xe1, 0xe4, 0x00, + 0xc0, 0xe1, 0xe4, 0x00, 0xac, 0x2a, 0x00, 0x20, 0x00, 0xf2, 0x00, 0x20, + 0x80, 0xb5, 0x03, 0x20, 0xff, 0xf7, 0x8b, 0xff, 0xff, 0xf7, 0xec, 0xff, + 0x08, 0x76, 0x01, 0xbd, 0x00, 0x29, 0x40, 0xf1, 0x0b, 0x80, 0xf4, 0x46, + 0x49, 0x42, 0x40, 0x42, 0x71, 0xf1, 0x00, 0x01, 0x00, 0xf0, 0x0a, 0xf8, + 0x50, 0xf0, 0x00, 0x40, 0x60, 0x47, 0x00, 0x00, 0x50, 0xea, 0x01, 0x02, + 0x00, 0xf0, 0x0e, 0x80, 0x09, 0x42, 0x00, 0xbf, 0x0b, 0xd1, 0xb0, 0xfa, + 0x80, 0xf1, 0x88, 0x40, 0xc1, 0xf1, 0x9d, 0x01, 0xc9, 0x05, 0x02, 0x06, + 0x72, 0xf1, 0x00, 0x42, 0x41, 0xeb, 0x10, 0x20, 0x70, 0x47, 0xb1, 0xfa, + 0x81, 0xf2, 0x41, 0x40, 0x90, 0x40, 0xc2, 0xf1, 0x20, 0x02, 0x61, 0xfa, + 0x02, 0xf1, 0x81, 0xea, 0x00, 0x00, 0x18, 0xbf, 0x40, 0xf0, 0x01, 0x00, + 0x02, 0xf1, 0x9d, 0x01, 0xe8, 0xe7, 0x00, 0x00, 0x00, 0x28, 0x40, 0xf1, + 0x09, 0x80, 0xf4, 0x46, 0x40, 0x42, 0x00, 0xf0, 0x05, 0xf8, 0x50, 0xf0, + 0x00, 0x40, 0x60, 0x47, 0x00, 0x28, 0x00, 0xbf, 0x0a, 0xd0, 0xb0, 0xfa, + 0x80, 0xf1, 0x88, 0x40, 0xd1, 0xf1, 0x9d, 0x01, 0xc9, 0x05, 0x02, 0x06, + 0x72, 0xf1, 0x00, 0x42, 0x41, 0xeb, 0x10, 0x20, 0x70, 0x47, 0x00, 0x00, + 0x10, 0xb5, 0xff, 0x23, 0x13, 0xea, 0xd0, 0x54, 0x1d, 0xbf, 0x13, 0xea, + 0xd1, 0x52, 0x9c, 0x42, 0x9a, 0x42, 0x39, 0xe0, 0xa4, 0x1a, 0xda, 0x07, + 0x80, 0xea, 0x01, 0x03, 0x13, 0x40, 0x42, 0xea, 0x01, 0x21, 0x42, 0xea, + 0x00, 0x20, 0x42, 0x1a, 0x3c, 0xbf, 0x64, 0x1e, 0x01, 0xeb, 0x42, 0x02, + 0x09, 0x0a, 0xb2, 0xfb, 0xf1, 0xfe, 0x01, 0xfb, 0x1e, 0x22, 0x12, 0x02, + 0xb2, 0xfb, 0xf1, 0xf0, 0x01, 0xfb, 0x10, 0x22, 0x6e, 0xf3, 0x0f, 0x20, + 0x12, 0x02, 0xb2, 0xfb, 0xf1, 0xfe, 0x4e, 0xea, 0x00, 0x20, 0x7f, 0x34, + 0x06, 0xdd, 0xfe, 0x2c, 0x24, 0xda, 0x53, 0xea, 0x50, 0x00, 0x50, 0xeb, + 0xc4, 0x50, 0x10, 0xbd, 0xd4, 0xf1, 0x02, 0x04, 0x01, 0xfb, 0x1e, 0x22, + 0x40, 0xf0, 0x80, 0x71, 0x19, 0x2c, 0x1d, 0xdc, 0x21, 0xfa, 0x04, 0xf0, + 0xc4, 0xf1, 0x20, 0x04, 0xa1, 0x40, 0x11, 0x43, 0x71, 0xf1, 0x00, 0x42, + 0x58, 0x41, 0x10, 0xbd, 0x9c, 0x42, 0x1a, 0xbf, 0x03, 0xea, 0xd1, 0x52, + 0x9a, 0x42, 0x0f, 0xe0, 0x80, 0xea, 0x01, 0x0e, 0x0e, 0xf0, 0x00, 0x43, + 0x40, 0x00, 0x04, 0xd0, 0x49, 0x00, 0x16, 0xd1, 0x43, 0xf0, 0xff, 0x40, + 0x10, 0xbd, 0x49, 0x00, 0x08, 0xbf, 0xd3, 0x43, 0x18, 0x00, 0x10, 0xbd, + 0x9c, 0x42, 0x05, 0xd1, 0xd2, 0x1a, 0xf7, 0xd0, 0x01, 0xf0, 0x00, 0x41, + 0x48, 0x40, 0x10, 0xbd, 0x4a, 0x02, 0x12, 0xbf, 0x08, 0x46, 0x48, 0x40, + 0x00, 0xf0, 0x00, 0x40, 0x10, 0xbd, 0x4a, 0xb9, 0x09, 0x02, 0xb1, 0xfa, + 0x81, 0xf2, 0x91, 0x40, 0x44, 0xb1, 0xa4, 0x18, 0xc0, 0x01, 0x40, 0xf0, + 0x00, 0x40, 0x9e, 0xe7, 0xc9, 0x01, 0x41, 0xf0, 0x00, 0x41, 0x52, 0x42, + 0x00, 0x02, 0xb0, 0xfa, 0x80, 0xf4, 0xa0, 0x40, 0x14, 0x1b, 0x94, 0xe7, + 0x90, 0xea, 0x01, 0x0f, 0x44, 0xbf, 0x81, 0xf0, 0x00, 0x41, 0x00, 0xf0, + 0x75, 0xb8, 0x00, 0xbf, 0x43, 0x1a, 0x4f, 0xf0, 0x00, 0x42, 0x3e, 0xbf, + 0x53, 0x40, 0xc0, 0x1a, 0xc9, 0x18, 0x00, 0xbf, 0xd3, 0x09, 0x5f, 0xea, + 0xd0, 0x5c, 0x13, 0xeb, 0x40, 0x0f, 0x34, 0xbf, 0xb3, 0xeb, 0x41, 0x0f, + 0x40, 0xe0, 0x7c, 0xeb, 0xd1, 0x53, 0x0c, 0xd3, 0x42, 0xea, 0x01, 0x21, + 0x22, 0xd8, 0xd1, 0xeb, 0x40, 0x20, 0x09, 0xd3, 0x40, 0x0a, 0x28, 0xbf, + 0x5f, 0xea, 0x50, 0x01, 0x40, 0xeb, 0xcc, 0x50, 0x70, 0x47, 0x40, 0x1a, + 0x15, 0xd0, 0x40, 0x02, 0xb0, 0xfa, 0x80, 0xf2, 0x52, 0x1c, 0x90, 0x40, + 0x40, 0x0a, 0x4f, 0xea, 0x3c, 0x23, 0xb3, 0xeb, 0x02, 0x63, 0x84, 0xbf, + 0x00, 0xeb, 0x73, 0x00, 0x07, 0xe0, 0x40, 0xf4, 0x00, 0x00, 0x1a, 0x16, + 0xdb, 0x07, 0xc2, 0xf1, 0x01, 0x02, 0xd0, 0x40, 0x18, 0x43, 0x70, 0x47, + 0x18, 0x2b, 0xfc, 0xdc, 0x31, 0xfa, 0x03, 0xf2, 0x02, 0xfa, 0x03, 0xf3, + 0x59, 0x1a, 0x38, 0xbf, 0x42, 0xf0, 0x01, 0x02, 0xd2, 0xeb, 0x40, 0x20, + 0x3c, 0xbf, 0x40, 0x00, 0xac, 0xf1, 0x01, 0x0c, 0x5f, 0xea, 0xcc, 0x5c, + 0xc2, 0x05, 0x72, 0xf1, 0x00, 0x41, 0x4c, 0xeb, 0x50, 0x20, 0x70, 0x47, + 0x13, 0xeb, 0x40, 0x0f, 0x0f, 0xd2, 0x4b, 0x00, 0x09, 0xd0, 0xac, 0xeb, + 0xd1, 0x53, 0x02, 0x2b, 0x03, 0xdb, 0x49, 0x02, 0x17, 0x2b, 0xdd, 0xdd, + 0x70, 0x47, 0x91, 0x43, 0x40, 0x1a, 0x43, 0x00, 0xd5, 0xd1, 0x00, 0x20, + 0x70, 0x47, 0x13, 0xeb, 0x41, 0x0f, 0xd0, 0xd3, 0x6f, 0xf0, 0x00, 0x00, + 0x70, 0x47, 0x00, 0x00, 0x90, 0xea, 0x01, 0x0f, 0x44, 0xbf, 0x81, 0xf0, + 0x00, 0x41, 0xff, 0xf7, 0x8d, 0xbf, 0x00, 0xbf, 0x42, 0x1a, 0x3c, 0xbf, + 0x80, 0x1a, 0x89, 0x18, 0x4f, 0xf0, 0x00, 0x4c, 0xc0, 0xf3, 0xc7, 0x52, + 0xff, 0x2a, 0x24, 0xd0, 0xc1, 0xf3, 0xc7, 0x53, 0x13, 0xb3, 0xd2, 0x1a, + 0xd2, 0xf1, 0x19, 0x03, 0x27, 0xdd, 0x4c, 0xea, 0x01, 0x21, 0x4c, 0xfa, + 0x03, 0xf3, 0x21, 0xea, 0x03, 0x03, 0xd1, 0x40, 0xc2, 0x0d, 0x4c, 0xea, + 0x00, 0x20, 0x40, 0x18, 0x34, 0xbf, 0x20, 0xea, 0x0c, 0x00, 0x4c, 0xea, + 0x50, 0x00, 0xd2, 0x05, 0x53, 0xea, 0x00, 0x63, 0x73, 0xeb, 0x0c, 0x0c, + 0x52, 0xeb, 0x10, 0x20, 0x42, 0x00, 0x12, 0xf1, 0x80, 0x7f, 0x38, 0xbf, + 0x70, 0x47, 0xc0, 0x0d, 0xc0, 0x05, 0x70, 0x47, 0x49, 0x02, 0x12, 0xbf, + 0x9a, 0x42, 0x00, 0xeb, 0x51, 0x20, 0xf8, 0xe7, 0xd2, 0xf1, 0x17, 0x03, + 0xd9, 0xd5, 0x70, 0x47, 0x4f, 0xf4, 0x00, 0x02, 0xc1, 0x0d, 0x23, 0xd0, + 0xff, 0x29, 0x29, 0xd2, 0x30, 0xea, 0xc1, 0x50, 0x10, 0x43, 0x7d, 0x31, + 0x49, 0x08, 0x28, 0xbf, 0x00, 0x18, 0x80, 0x00, 0x4f, 0xf0, 0xc0, 0x73, + 0xb0, 0xf1, 0x90, 0x60, 0x06, 0xd4, 0x52, 0x08, 0x0e, 0xd2, 0xc0, 0x1a, + 0x9b, 0x18, 0xd2, 0xeb, 0x40, 0x00, 0xf8, 0xd5, 0x52, 0x08, 0x06, 0xd2, + 0xc0, 0x18, 0x9b, 0x1a, 0xd2, 0xeb, 0x40, 0x00, 0xf1, 0xd5, 0x52, 0x08, + 0xf8, 0xd3, 0x5b, 0x1e, 0x58, 0x08, 0x50, 0xeb, 0xc1, 0x50, 0x70, 0x47, + 0xb0, 0xfa, 0x80, 0xf1, 0x08, 0x39, 0x88, 0x40, 0xf9, 0xd0, 0xd1, 0xf1, + 0x01, 0x01, 0xd8, 0xe7, 0xff, 0x29, 0xf4, 0xd0, 0xd0, 0x42, 0xf2, 0xd8, + 0x40, 0x00, 0xf0, 0xd0, 0xc8, 0x43, 0x07, 0xf0, 0xd1, 0xbf, 0x00, 0x00, + 0x40, 0xea, 0x01, 0x0c, 0x5f, 0xea, 0x4c, 0x0c, 0x07, 0xd0, 0x88, 0x42, + 0x05, 0xd1, 0x4f, 0xea, 0x40, 0x0c, 0x1c, 0xf1, 0x80, 0x7f, 0x98, 0xbf, + 0x80, 0x42, 0x70, 0x47, 0x4f, 0xf0, 0x80, 0x7c, 0x1c, 0xeb, 0x40, 0x0f, + 0x94, 0xbf, 0x1c, 0xeb, 0x41, 0x0f, 0x05, 0xe0, 0x40, 0xea, 0x01, 0x0c, + 0x5f, 0xea, 0x4c, 0x0c, 0x01, 0xd2, 0x88, 0x42, 0x70, 0x47, 0x18, 0xbf, + 0x81, 0x42, 0x70, 0x47, 0xff, 0x22, 0x12, 0xea, 0xd0, 0x5c, 0x1d, 0xbf, + 0x12, 0xea, 0xd1, 0x53, 0x94, 0x45, 0x93, 0x42, 0x2b, 0xe0, 0x9c, 0x44, + 0xd3, 0x07, 0x80, 0xea, 0x01, 0x02, 0x1a, 0x40, 0x43, 0xea, 0x00, 0x20, + 0x43, 0xea, 0x01, 0x21, 0xa1, 0xfb, 0x00, 0x30, 0x41, 0x00, 0x38, 0xbf, + 0x40, 0x00, 0x7c, 0xf1, 0x7f, 0x01, 0x0b, 0xdb, 0xfe, 0x29, 0x4a, 0xda, + 0x5b, 0x08, 0x42, 0xea, 0xc1, 0x51, 0x53, 0xea, 0x00, 0x63, 0x73, 0xf1, + 0x00, 0x4c, 0x51, 0xeb, 0x10, 0x20, 0x70, 0x47, 0xd1, 0xf1, 0x08, 0x0c, + 0xdc, 0xf1, 0x20, 0x01, 0x2f, 0xdb, 0x5b, 0x08, 0x10, 0xfa, 0x01, 0xf1, + 0x0b, 0x43, 0x73, 0xf1, 0x00, 0x41, 0x20, 0xfa, 0x0c, 0xf0, 0x50, 0x41, + 0x70, 0x47, 0x94, 0x45, 0x1c, 0xbf, 0x02, 0xea, 0xd1, 0x53, 0x93, 0x42, + 0x80, 0xea, 0x01, 0x02, 0x02, 0xf0, 0x00, 0x42, 0x1d, 0xd0, 0x40, 0x00, + 0x19, 0xd0, 0x49, 0x00, 0x17, 0xd0, 0x5b, 0xb9, 0x63, 0x45, 0x14, 0xd0, + 0x09, 0x02, 0xb1, 0xfa, 0x81, 0xf3, 0x99, 0x40, 0xbc, 0xeb, 0x03, 0x0c, + 0xc0, 0x01, 0x40, 0xf0, 0x00, 0x40, 0xc1, 0xe7, 0x00, 0x02, 0xb0, 0xfa, + 0x80, 0xfc, 0x10, 0xfa, 0x0c, 0xf0, 0xb3, 0xeb, 0x0c, 0x0c, 0xc9, 0x01, + 0x41, 0xf0, 0x00, 0x41, 0xb6, 0xe7, 0x10, 0x00, 0x70, 0x47, 0x40, 0x00, + 0x0a, 0xd0, 0x49, 0x00, 0x08, 0xd0, 0x10, 0xf1, 0x80, 0x7f, 0x94, 0xbf, + 0x11, 0xf1, 0x80, 0x7f, 0x02, 0xe0, 0x42, 0xf0, 0xff, 0x40, 0x70, 0x47, + 0xd0, 0x43, 0x70, 0x47, 0x41, 0x00, 0x09, 0x0e, 0x7f, 0x39, 0x15, 0xd4, + 0xd1, 0xf1, 0x1f, 0x01, 0x14, 0xd4, 0x40, 0x00, 0x07, 0xd2, 0xc0, 0x01, + 0x40, 0xf0, 0x00, 0x40, 0xc8, 0x40, 0x48, 0xbf, 0x6f, 0xf0, 0x00, 0x40, + 0x70, 0x47, 0xc0, 0x01, 0x40, 0xf0, 0x00, 0x40, 0xc8, 0x40, 0x4c, 0xbf, + 0x4f, 0xf0, 0x00, 0x40, 0x40, 0x42, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, + 0x00, 0x42, 0x4f, 0xf0, 0x00, 0x40, 0x58, 0xbf, 0xc0, 0x43, 0x70, 0x47, + 0xc0, 0xf3, 0xc7, 0x52, 0x7e, 0x3a, 0x09, 0xdd, 0x18, 0x2a, 0x0c, 0xda, + 0x6f, 0xf0, 0x7f, 0x41, 0xd1, 0x40, 0x20, 0xea, 0x51, 0x00, 0x40, 0x18, + 0x88, 0x43, 0x70, 0x47, 0x00, 0xf0, 0x00, 0x40, 0x08, 0xbf, 0x40, 0xf0, + 0x7e, 0x50, 0x70, 0x47, 0x38, 0xb5, 0x0b, 0x46, 0xc3, 0xf3, 0xc7, 0x51, + 0xff, 0x29, 0x02, 0x46, 0x09, 0xd0, 0x11, 0xb1, 0x4f, 0xf0, 0xff, 0x34, + 0x09, 0xe0, 0x58, 0x02, 0x0c, 0xbf, 0x00, 0x24, 0x6f, 0xf0, 0x01, 0x04, + 0x03, 0xe0, 0x58, 0x02, 0x14, 0xbf, 0x02, 0x24, 0x01, 0x24, 0xc2, 0xf3, + 0xc7, 0x51, 0xff, 0x29, 0x08, 0xd0, 0x11, 0xb1, 0x4f, 0xf0, 0xff, 0x31, + 0x08, 0xe0, 0x50, 0x02, 0x06, 0xd0, 0x6f, 0xf0, 0x01, 0x01, 0x03, 0xe0, + 0x50, 0x02, 0x14, 0xbf, 0x02, 0x21, 0x01, 0x21, 0x01, 0x2c, 0xb8, 0xbf, + 0x01, 0x29, 0x1c, 0xda, 0x00, 0x2a, 0x46, 0xbf, 0x82, 0xf0, 0x00, 0x42, + 0x08, 0x25, 0x00, 0x25, 0x00, 0x2b, 0x44, 0xbf, 0x83, 0xf0, 0x00, 0x43, + 0x85, 0xf0, 0x06, 0x05, 0x18, 0x46, 0x11, 0x46, 0xff, 0xf7, 0x12, 0xff, + 0x02, 0xd2, 0xff, 0xf7, 0x93, 0xfd, 0x1f, 0xe0, 0x00, 0x2c, 0x04, 0xd5, + 0x10, 0x46, 0x19, 0x46, 0xff, 0xf7, 0x8c, 0xfd, 0x1a, 0xe0, 0x00, 0x20, + 0x18, 0xe0, 0x02, 0x29, 0x01, 0xd1, 0x10, 0x46, 0x32, 0xbd, 0x02, 0x2c, + 0x01, 0xd1, 0x18, 0x46, 0x32, 0xbd, 0x8c, 0x42, 0x0c, 0xbf, 0x4f, 0xf0, + 0x7e, 0x50, 0x00, 0x20, 0x00, 0x2a, 0x4c, 0xbf, 0x08, 0x25, 0x00, 0x25, + 0x00, 0x2b, 0x48, 0xbf, 0x85, 0xf0, 0x06, 0x05, 0x01, 0x29, 0x01, 0xd1, + 0x85, 0xf0, 0x02, 0x05, 0x29, 0x46, 0xbd, 0xe8, 0x34, 0x40, 0x07, 0xf0, + 0xaf, 0xbe, 0x00, 0x00, 0x4f, 0xf0, 0x80, 0x7c, 0x1c, 0xeb, 0x40, 0x0f, + 0x94, 0xbf, 0x1c, 0xeb, 0x41, 0x0f, 0x05, 0xe0, 0x40, 0xea, 0x01, 0x0c, + 0x5f, 0xea, 0x4c, 0x0c, 0x01, 0xd2, 0x81, 0x42, 0x70, 0x47, 0x18, 0xbf, + 0x88, 0x42, 0x70, 0x47, 0x2d, 0xe9, 0xf1, 0x4d, 0x83, 0xb0, 0x0c, 0x46, + 0x03, 0x98, 0x01, 0x94, 0xc0, 0xf3, 0xc7, 0x50, 0xff, 0x28, 0x15, 0x46, + 0x08, 0xd1, 0x03, 0x98, 0x00, 0x27, 0x40, 0x02, 0x0c, 0xbf, 0x4f, 0xf0, + 0x01, 0x08, 0x4f, 0xf0, 0x02, 0x08, 0x13, 0xe0, 0x01, 0x28, 0x07, 0xda, + 0x03, 0xa8, 0x07, 0xf0, 0xfd, 0xfe, 0x01, 0x28, 0x02, 0xdb, 0x00, 0x27, + 0xb8, 0x46, 0x09, 0xe0, 0x03, 0x99, 0x21, 0xf0, 0xff, 0x41, 0x41, 0xf0, + 0x7c, 0x51, 0x03, 0x91, 0xa0, 0xf1, 0x7e, 0x07, 0x4f, 0xf0, 0xff, 0x38, + 0x00, 0x21, 0x01, 0xa8, 0x07, 0xf0, 0xfd, 0xfe, 0x06, 0x46, 0x0d, 0xb1, + 0x00, 0x20, 0x28, 0x80, 0x26, 0xb9, 0x20, 0x46, 0x00, 0x21, 0xff, 0xf7, + 0x91, 0xfe, 0x12, 0xd0, 0xb8, 0xf1, 0x00, 0x0f, 0x12, 0xd5, 0x3f, 0xb2, + 0x01, 0x2f, 0x14, 0xd1, 0x03, 0x98, 0x4f, 0xf0, 0x7c, 0x51, 0xff, 0xf7, + 0x85, 0xfe, 0x06, 0xd0, 0x01, 0x2e, 0x0c, 0xd1, 0x4f, 0xf0, 0x3f, 0x41, + 0xff, 0xf7, 0x7e, 0xfe, 0x2e, 0xd1, 0x4f, 0xf0, 0x7e, 0x50, 0x0d, 0xe1, + 0xb8, 0xf1, 0x02, 0x0f, 0x03, 0xd1, 0x03, 0x98, 0x08, 0xe1, 0x01, 0x2e, + 0x53, 0xdb, 0x02, 0x2e, 0x08, 0xbf, 0x20, 0x46, 0x00, 0xf0, 0x02, 0x81, + 0xb8, 0xf1, 0x01, 0x0f, 0x1a, 0xd1, 0x03, 0x98, 0x00, 0x28, 0x02, 0xd4, + 0x00, 0x2c, 0x43, 0xd5, 0x2f, 0xe0, 0x00, 0x2c, 0x09, 0xd4, 0x00, 0x2e, + 0x3e, 0xd1, 0x4f, 0xf0, 0xff, 0x31, 0x01, 0xa8, 0x07, 0xf0, 0xbf, 0xfe, + 0x00, 0x28, 0x37, 0xd5, 0x34, 0xe0, 0x16, 0xbb, 0x4f, 0xf0, 0xff, 0x31, + 0x01, 0xa8, 0x07, 0xf0, 0xb6, 0xfe, 0x00, 0x28, 0x1b, 0xd5, 0x17, 0xe0, + 0x01, 0x2e, 0x08, 0xd1, 0x00, 0x2c, 0x3f, 0xb2, 0x02, 0xd4, 0x01, 0x2f, + 0x26, 0xda, 0x12, 0xe0, 0x01, 0x2f, 0x10, 0xda, 0x22, 0xe0, 0x00, 0x2c, + 0x0f, 0xd4, 0x66, 0xb9, 0x4f, 0xf0, 0xff, 0x31, 0x01, 0xa8, 0x07, 0xf0, + 0xa0, 0xfe, 0x00, 0x28, 0x44, 0xbf, 0x03, 0x98, 0x00, 0x28, 0x02, 0xd5, + 0x4f, 0xf0, 0x00, 0x40, 0xc8, 0xe0, 0x00, 0x20, 0xc6, 0xe0, 0x07, 0xf0, + 0xbb, 0xfe, 0x22, 0x21, 0x01, 0x60, 0x5e, 0xb9, 0x4f, 0xf0, 0xff, 0x31, + 0x01, 0xa8, 0x07, 0xf0, 0x8c, 0xfe, 0x00, 0x28, 0x44, 0xbf, 0x03, 0x98, + 0x00, 0x28, 0x01, 0xd5, 0x4f, 0x48, 0xb5, 0xe0, 0x4f, 0xf0, 0xff, 0x40, + 0xb2, 0xe0, 0x03, 0x98, 0x00, 0x28, 0x48, 0xbf, 0x00, 0x2e, 0x06, 0xd5, + 0x07, 0xf0, 0xa2, 0xfe, 0x21, 0x21, 0x01, 0x60, 0x6f, 0xf0, 0x00, 0x40, + 0xa6, 0xe0, 0x00, 0x21, 0xff, 0xf7, 0x38, 0xff, 0x38, 0xbf, 0x00, 0x26, + 0x08, 0xd3, 0x80, 0xf0, 0x00, 0x40, 0x03, 0x90, 0x4f, 0xf0, 0xff, 0x31, + 0x01, 0xa8, 0x07, 0xf0, 0x68, 0xfe, 0x06, 0x46, 0x03, 0x98, 0x40, 0x49, + 0xff, 0xf7, 0x0e, 0xfe, 0x06, 0xd2, 0x01, 0x46, 0x4f, 0xf0, 0x80, 0x40, + 0xff, 0xf7, 0x1a, 0xfe, 0x03, 0x90, 0x7f, 0x1e, 0x03, 0x99, 0x3b, 0x48, + 0xff, 0xf7, 0x78, 0xfd, 0x83, 0x46, 0x03, 0x99, 0x4f, 0xf0, 0x7e, 0x50, + 0xff, 0xf7, 0x72, 0xfd, 0x01, 0x46, 0x58, 0x46, 0xff, 0xf7, 0x7c, 0xfc, + 0x80, 0x46, 0x41, 0x46, 0xff, 0xf7, 0x06, 0xfe, 0x82, 0x46, 0xcd, 0xf8, + 0x0c, 0xb0, 0x06, 0xf0, 0xcb, 0xff, 0x51, 0x46, 0xff, 0xf7, 0xfe, 0xfd, + 0x03, 0x99, 0xff, 0xf7, 0xeb, 0xfc, 0x41, 0x46, 0xff, 0xf7, 0xf8, 0xfd, + 0x01, 0x46, 0x03, 0x98, 0xff, 0xf7, 0x58, 0xfd, 0x80, 0x46, 0x38, 0xb2, + 0xff, 0xf7, 0x48, 0xfc, 0x07, 0x46, 0x40, 0x46, 0x27, 0x49, 0xff, 0xf7, + 0x5d, 0xfc, 0x39, 0x46, 0xff, 0xf7, 0x4c, 0xfd, 0x01, 0x90, 0x21, 0x46, + 0xff, 0xf7, 0xe4, 0xfd, 0x00, 0x90, 0x4f, 0xf0, 0x47, 0x41, 0xff, 0xf7, + 0xcd, 0xfd, 0x43, 0xd3, 0x20, 0x49, 0xff, 0xf7, 0xe3, 0xfe, 0x41, 0xd9, + 0x00, 0x21, 0xff, 0xf7, 0xc5, 0xfd, 0x01, 0x46, 0x34, 0xbf, 0x4f, 0xf0, + 0x3f, 0x40, 0x4f, 0xf0, 0x7c, 0x50, 0xff, 0xf7, 0x33, 0xfd, 0xff, 0xf7, + 0x39, 0xfe, 0x82, 0x46, 0x38, 0x46, 0x21, 0x46, 0xff, 0xf7, 0xc8, 0xfd, + 0x07, 0x46, 0x50, 0x46, 0xff, 0xf7, 0x1c, 0xfc, 0x01, 0x46, 0x38, 0x46, + 0xff, 0xf7, 0xb0, 0xfc, 0x10, 0x49, 0xff, 0xf7, 0xbd, 0xfd, 0x07, 0x46, + 0x40, 0x46, 0x21, 0x46, 0xff, 0xf7, 0xb8, 0xfd, 0x39, 0x46, 0xff, 0xf7, + 0x19, 0xfd, 0x00, 0x90, 0x1d, 0xb1, 0xa5, 0xf8, 0x00, 0xa0, 0x4f, 0xf0, + 0x00, 0x0a, 0x52, 0x46, 0x4f, 0xf0, 0x7e, 0x51, 0x68, 0x46, 0x07, 0xf0, + 0x19, 0xfe, 0x68, 0xb1, 0x01, 0x28, 0x0d, 0xd0, 0x13, 0xe0, 0x00, 0xbf, + 0x00, 0x00, 0x80, 0xff, 0xf3, 0x04, 0x35, 0x3f, 0x00, 0x00, 0x80, 0xbf, + 0x18, 0x72, 0x31, 0x3f, 0x01, 0x00, 0x00, 0x47, 0x00, 0x20, 0x01, 0xe0, + 0x4f, 0xf0, 0xff, 0x40, 0x00, 0x90, 0x07, 0xf0, 0xfd, 0xfd, 0x22, 0x21, + 0x01, 0x60, 0x00, 0x2e, 0x00, 0x98, 0x18, 0xbf, 0x80, 0xf0, 0x00, 0x40, + 0x04, 0xb0, 0xbd, 0xe8, 0xf0, 0x8d, 0x00, 0x22, 0xa0, 0xe6, 0x00, 0x00, + 0xd2, 0xb2, 0x20, 0x3a, 0x22, 0xbf, 0x00, 0xfa, 0x02, 0xf1, 0x00, 0x20, + 0x70, 0x47, 0x52, 0x42, 0xd0, 0x41, 0xd2, 0xf1, 0x20, 0x02, 0x91, 0x40, + 0x41, 0x40, 0xd0, 0x40, 0x90, 0x40, 0x41, 0x40, 0x70, 0x47, 0x00, 0x00, + 0x38, 0xb5, 0x05, 0x46, 0x0d, 0x48, 0x0c, 0x46, 0x41, 0x78, 0x21, 0x70, + 0x6a, 0x46, 0x00, 0x78, 0x60, 0x70, 0xa1, 0x1d, 0x28, 0x46, 0x00, 0xf0, + 0x89, 0xf8, 0x0f, 0xf2, 0x50, 0x10, 0x30, 0xf8, 0x25, 0x10, 0x01, 0xf1, + 0x8c, 0x41, 0x00, 0xeb, 0x85, 0x00, 0x09, 0x78, 0xe1, 0x70, 0x40, 0x88, + 0x00, 0xf1, 0x8c, 0x40, 0x00, 0x78, 0x20, 0x71, 0x31, 0xbd, 0x00, 0x00, + 0x6d, 0x09, 0x00, 0x46, 0x38, 0xb5, 0x0d, 0x46, 0x2a, 0x79, 0xe9, 0x78, + 0x04, 0x46, 0x00, 0xf0, 0x47, 0xf8, 0xe9, 0x88, 0x20, 0x46, 0x00, 0xf0, + 0x59, 0xf8, 0x29, 0x78, 0x40, 0xf6, 0x6e, 0x10, 0xfb, 0xf7, 0x86, 0xfe, + 0x69, 0x78, 0xbd, 0xe8, 0x34, 0x40, 0x40, 0xf6, 0x6d, 0x10, 0xfb, 0xf7, + 0x7f, 0xbe, 0x70, 0xb5, 0x55, 0x1c, 0x0e, 0x46, 0x03, 0x2e, 0x04, 0x46, + 0x1d, 0xd0, 0x10, 0x78, 0x00, 0xf0, 0x9f, 0x00, 0x10, 0x70, 0x02, 0x2e, + 0x28, 0x78, 0x00, 0xf0, 0xe0, 0x00, 0x28, 0x70, 0x08, 0xd1, 0x90, 0x78, + 0x13, 0x78, 0x43, 0xea, 0x40, 0x13, 0x13, 0x70, 0x2b, 0x78, 0x43, 0xea, + 0x40, 0x10, 0x28, 0x70, 0x00, 0x2c, 0x10, 0x78, 0x07, 0xbf, 0x00, 0xf0, + 0xfc, 0x00, 0x08, 0x43, 0x00, 0xf0, 0xf3, 0x00, 0x40, 0xea, 0x81, 0x00, + 0x10, 0x70, 0x40, 0xf6, 0x6e, 0x10, 0x11, 0x78, 0xfb, 0xf7, 0x56, 0xfe, + 0x29, 0x78, 0x40, 0xf6, 0x6d, 0x10, 0xfb, 0xf7, 0x51, 0xfe, 0x02, 0x2e, + 0x05, 0xd1, 0x20, 0x46, 0xbd, 0xe8, 0x70, 0x40, 0x00, 0x22, 0x00, 0x21, + 0x00, 0xe0, 0x70, 0xbd, 0x70, 0xb5, 0x39, 0x2a, 0x0f, 0xf2, 0x88, 0x06, + 0x04, 0x46, 0xac, 0xbf, 0x42, 0xf0, 0x40, 0x05, 0x02, 0xf0, 0xbf, 0x05, + 0x36, 0xf8, 0x24, 0x00, 0xfb, 0xf7, 0x3a, 0xfe, 0x29, 0x46, 0x06, 0xeb, + 0x84, 0x00, 0xbd, 0xe8, 0x70, 0x40, 0x40, 0x88, 0xfb, 0xf7, 0x32, 0xbe, + 0x70, 0xb5, 0x04, 0x46, 0x0f, 0xf2, 0x64, 0x06, 0x06, 0xeb, 0x84, 0x00, + 0x0d, 0x46, 0x40, 0x88, 0x29, 0x0a, 0xfb, 0xf7, 0x27, 0xfe, 0x36, 0xf8, + 0x24, 0x00, 0xe9, 0xb2, 0xbd, 0xe8, 0x70, 0x40, 0xfb, 0xf7, 0x20, 0xbe, + 0x2d, 0xe9, 0xf0, 0x41, 0x06, 0x46, 0x0f, 0xf2, 0x48, 0x08, 0x08, 0xeb, + 0x86, 0x00, 0x0c, 0x46, 0x47, 0x88, 0x15, 0x46, 0x00, 0x21, 0x38, 0x46, + 0xfb, 0xf7, 0x12, 0xfe, 0x07, 0xf1, 0x8c, 0x40, 0x00, 0x78, 0x38, 0xf8, + 0x26, 0x10, 0x01, 0xf1, 0x8c, 0x41, 0x09, 0x78, 0x41, 0xea, 0x00, 0x20, + 0x81, 0x0a, 0x80, 0x05, 0x29, 0x70, 0x80, 0x0d, 0x20, 0x80, 0xbd, 0xe8, + 0xf0, 0x81, 0x00, 0x00, 0x67, 0x09, 0x68, 0x09, 0x6a, 0x09, 0x6b, 0x09, + 0x60, 0x09, 0x61, 0x09, 0x62, 0x09, 0x63, 0x09, 0x40, 0x09, 0x41, 0x09, + 0x42, 0x09, 0x43, 0x09, 0x13, 0xf0, 0x00, 0x4c, 0x03, 0xd5, 0x5b, 0x42, + 0x52, 0x42, 0x63, 0xf1, 0x00, 0x03, 0x9c, 0xea, 0x21, 0x0c, 0x00, 0xf0, + 0x17, 0x80, 0x10, 0xb5, 0x64, 0x46, 0x03, 0xd3, 0x49, 0x42, 0x40, 0x42, + 0x61, 0xf1, 0x00, 0x01, 0x00, 0xf0, 0x0e, 0xf8, 0x64, 0x00, 0x04, 0xd3, + 0x49, 0x42, 0x40, 0x42, 0x61, 0xf1, 0x00, 0x01, 0x24, 0x42, 0x03, 0xd5, + 0x5b, 0x42, 0x52, 0x42, 0x63, 0xf1, 0x00, 0x03, 0x10, 0xbd, 0x00, 0x00, + 0x1b, 0x42, 0x13, 0xd1, 0x09, 0x42, 0x36, 0xd1, 0x2a, 0xb1, 0x84, 0x46, + 0xb0, 0xfb, 0xf2, 0xf0, 0x02, 0xfb, 0x10, 0xc2, 0x70, 0x47, 0x07, 0xf0, + 0xff, 0xbd, 0xfc, 0xd3, 0x00, 0x22, 0x00, 0x23, 0x70, 0x47, 0x0b, 0x00, + 0x02, 0x00, 0x00, 0x21, 0x00, 0x20, 0x70, 0x47, 0x90, 0x42, 0x71, 0xeb, + 0x03, 0x0c, 0xf6, 0xd3, 0x70, 0xb5, 0xb1, 0xfa, 0x81, 0xf4, 0xb3, 0xfa, + 0x83, 0xf5, 0x2c, 0x1b, 0xa3, 0x40, 0xc4, 0xf1, 0x20, 0x05, 0x32, 0xfa, + 0x05, 0xf6, 0x33, 0x43, 0xa2, 0x40, 0x5f, 0xf0, 0x00, 0x46, 0xe6, 0x40, + 0x02, 0xe0, 0x5b, 0x08, 0x5f, 0xea, 0x32, 0x02, 0x84, 0x1a, 0x71, 0xeb, + 0x03, 0x05, 0x24, 0xbf, 0x20, 0x46, 0x29, 0x46, 0x76, 0x41, 0xf4, 0xd3, + 0x02, 0x00, 0x0b, 0x00, 0x30, 0x00, 0x00, 0x21, 0x70, 0xbd, 0x01, 0x2a, + 0xcf, 0xd9, 0x70, 0xb5, 0x14, 0x0c, 0x20, 0xd0, 0xb1, 0xfa, 0x81, 0xf4, + 0xb2, 0xfa, 0x82, 0xf5, 0xc4, 0xf1, 0x20, 0x04, 0x64, 0x19, 0xb4, 0xf1, + 0x20, 0x06, 0xd6, 0xd3, 0xb2, 0x40, 0x5f, 0xf0, 0x00, 0x44, 0xf4, 0x40, + 0x00, 0x25, 0x02, 0xe0, 0x52, 0x08, 0x5f, 0xea, 0x33, 0x03, 0xc6, 0x1a, + 0x71, 0xeb, 0x02, 0x0e, 0x24, 0xbf, 0x30, 0x46, 0x71, 0x46, 0x64, 0x41, + 0x6d, 0x41, 0xf3, 0xd3, 0x02, 0x00, 0x0b, 0x00, 0x20, 0x00, 0x29, 0x00, + 0x70, 0xbd, 0x0c, 0x46, 0xb1, 0xfb, 0xf2, 0xf1, 0x02, 0xfb, 0x11, 0x45, + 0x2d, 0x04, 0x45, 0xea, 0x10, 0x45, 0xb5, 0xfb, 0xf2, 0xf4, 0x02, 0xfb, + 0x14, 0x55, 0x80, 0xb2, 0x40, 0xea, 0x05, 0x45, 0xb5, 0xfb, 0xf2, 0xf0, + 0x02, 0xfb, 0x10, 0x52, 0x40, 0xea, 0x04, 0x40, 0x70, 0xbd, 0x00, 0x00, + 0x10, 0xb5, 0xda, 0x48, 0x01, 0x1d, 0x00, 0x22, 0x00, 0x23, 0x0c, 0xc1, + 0x00, 0x21, 0x00, 0x24, 0x1e, 0xc0, 0x10, 0xbd, 0x2d, 0xe9, 0xf0, 0x43, + 0xd5, 0x48, 0x87, 0xb0, 0x80, 0x7a, 0x00, 0xf0, 0x03, 0x08, 0x40, 0x46, + 0xfb, 0xf7, 0xb0, 0xfd, 0x00, 0x24, 0x08, 0xb9, 0x02, 0x20, 0x55, 0xe0, + 0x00, 0x26, 0xdf, 0xf8, 0x38, 0x93, 0xcf, 0x4d, 0x28, 0xfa, 0x06, 0xf0, + 0xc0, 0x07, 0x49, 0xd5, 0x00, 0x27, 0x28, 0x78, 0x01, 0x21, 0xb9, 0x40, + 0x08, 0x42, 0x3f, 0xd0, 0x00, 0x21, 0x00, 0x20, 0xfb, 0xf7, 0x85, 0xff, + 0x01, 0x2f, 0x06, 0xd1, 0x03, 0xa9, 0x30, 0x46, 0xfe, 0xf7, 0x26, 0xfd, + 0x05, 0xf1, 0x18, 0x01, 0x11, 0xe0, 0x68, 0x46, 0xfd, 0xf7, 0x27, 0xfe, + 0x01, 0xa8, 0xfe, 0xf7, 0xce, 0xf9, 0x01, 0x21, 0xf0, 0xb2, 0xfe, 0xf7, + 0xcb, 0xf8, 0xfe, 0xf7, 0x06, 0xf9, 0xb0, 0x1c, 0x28, 0x21, 0x80, 0xb2, + 0xfd, 0xf7, 0x2c, 0xfe, 0x29, 0x1d, 0x09, 0xf1, 0x04, 0x00, 0x00, 0xeb, + 0x86, 0x00, 0x00, 0xeb, 0x47, 0x02, 0x30, 0x46, 0x00, 0xf0, 0x6e, 0xf8, + 0x04, 0x46, 0x40, 0x1e, 0x80, 0x41, 0x09, 0xeb, 0x46, 0x01, 0xc0, 0x0f, + 0x78, 0x54, 0x01, 0x2f, 0x04, 0xd1, 0x03, 0xa9, 0x30, 0x46, 0xfe, 0xf7, + 0x11, 0xfd, 0x05, 0xe0, 0x68, 0x46, 0xfd, 0xf7, 0x05, 0xfe, 0x01, 0xa8, + 0xfe, 0xf7, 0xb2, 0xf9, 0x00, 0x20, 0xfb, 0xf7, 0xa7, 0xff, 0x14, 0xb9, + 0x7f, 0x1c, 0x02, 0x2f, 0xb7, 0xd3, 0x14, 0xb9, 0x76, 0x1c, 0x02, 0x2e, + 0xae, 0xd3, 0x20, 0x46, 0x07, 0xb0, 0xbd, 0xe8, 0xf0, 0x83, 0xa2, 0x4a, + 0x02, 0xeb, 0x41, 0x01, 0x40, 0x5c, 0x70, 0x47, 0x9f, 0x4a, 0x02, 0xeb, + 0x81, 0x01, 0x01, 0xeb, 0x40, 0x00, 0x00, 0x1d, 0x70, 0x47, 0x80, 0xb5, + 0xfe, 0xf7, 0x4f, 0xfa, 0xfe, 0xf7, 0x69, 0xfa, 0x02, 0x28, 0x01, 0xd1, + 0x03, 0x20, 0x02, 0xbd, 0x01, 0x28, 0x0c, 0xbf, 0x04, 0x20, 0x00, 0x20, + 0x02, 0xbd, 0xf0, 0xb5, 0x05, 0x46, 0x0c, 0x46, 0x96, 0x48, 0x00, 0xeb, + 0xc4, 0x02, 0xd2, 0xe9, 0x00, 0x01, 0x95, 0x4a, 0x02, 0xeb, 0xc4, 0x06, + 0xd6, 0xe9, 0x00, 0x23, 0x80, 0x18, 0x59, 0x41, 0x2a, 0x46, 0x07, 0xf0, + 0xf9, 0xfc, 0xa0, 0xfb, 0x00, 0x67, 0x00, 0xfb, 0x01, 0x77, 0x01, 0xfb, + 0x00, 0x77, 0x8e, 0x48, 0x00, 0xeb, 0xc4, 0x02, 0xd2, 0xe9, 0x00, 0x01, + 0x8c, 0x4a, 0x02, 0xeb, 0xc4, 0x04, 0xd4, 0xe9, 0x00, 0x23, 0x80, 0x1a, + 0x99, 0x41, 0x2a, 0x46, 0x07, 0xf0, 0xe4, 0xfc, 0xa0, 0xfb, 0x00, 0x23, + 0x00, 0xfb, 0x01, 0x33, 0x01, 0xfb, 0x00, 0x33, 0xb0, 0x18, 0x47, 0xeb, + 0x03, 0x01, 0xf0, 0xbd, 0x2d, 0xe9, 0xf5, 0x4f, 0x0e, 0x46, 0x81, 0xb0, + 0xb6, 0xf9, 0x08, 0x10, 0xb6, 0xf9, 0x06, 0x00, 0xfe, 0xf7, 0xd0, 0xfc, + 0x31, 0x69, 0xf0, 0x68, 0xfe, 0xf7, 0xd4, 0xfc, 0x01, 0x98, 0xfe, 0xf7, + 0xd5, 0xfc, 0x4f, 0xf0, 0x00, 0x0a, 0xd0, 0x46, 0xf0, 0x78, 0x00, 0x27, + 0xc1, 0x46, 0x18, 0xb1, 0xfe, 0xf7, 0x81, 0xfa, 0xc3, 0x46, 0x04, 0xe0, + 0x08, 0x20, 0xfe, 0xf7, 0x6f, 0xfa, 0x4f, 0xf0, 0x08, 0x0b, 0xb6, 0xf9, + 0x06, 0x00, 0x00, 0x28, 0x48, 0xbf, 0x40, 0x42, 0xb6, 0xf9, 0x08, 0x40, + 0x00, 0x2c, 0x48, 0xbf, 0x64, 0x42, 0x84, 0x42, 0x38, 0xbf, 0x04, 0x46, + 0x20, 0x46, 0x00, 0xf0, 0xb7, 0xfb, 0x11, 0x28, 0x04, 0xd2, 0x20, 0x46, + 0x00, 0xf0, 0xb2, 0xfb, 0x11, 0x30, 0x00, 0xe0, 0x22, 0x20, 0xb1, 0x78, + 0x08, 0x18, 0x1d, 0x28, 0x26, 0xbf, 0x1c, 0x38, 0x00, 0x90, 0xcd, 0xf8, + 0x00, 0x80, 0x34, 0x78, 0x10, 0xe0, 0x00, 0x25, 0x00, 0x98, 0x29, 0x46, + 0xff, 0xf7, 0x87, 0xff, 0x89, 0x45, 0x05, 0xdc, 0x01, 0xdb, 0x80, 0x45, + 0x02, 0xd2, 0x2f, 0x19, 0x80, 0x46, 0x89, 0x46, 0x6d, 0x1c, 0x03, 0x2d, + 0xf0, 0xd3, 0xe4, 0x1c, 0x70, 0x78, 0x80, 0x1e, 0xa0, 0x42, 0x08, 0xd3, + 0x01, 0x98, 0x21, 0x04, 0x00, 0xf0, 0x43, 0xf8, 0xff, 0xf7, 0x63, 0xff, + 0x5f, 0xea, 0x00, 0x0a, 0xe1, 0xd0, 0x00, 0xf0, 0x36, 0xf8, 0xf0, 0x78, + 0x00, 0x28, 0x2b, 0xd1, 0x02, 0x99, 0x09, 0x78, 0x01, 0x98, 0x49, 0x1e, + 0x09, 0x04, 0x00, 0xf0, 0x32, 0xf8, 0x00, 0x24, 0x01, 0xe0, 0x08, 0x2c, + 0x1b, 0xd0, 0x20, 0x46, 0xfe, 0xf7, 0x1a, 0xfa, 0xff, 0xf7, 0x4b, 0xff, + 0x5f, 0xea, 0x00, 0x0a, 0x16, 0xd1, 0x00, 0x25, 0x00, 0x98, 0x29, 0x46, + 0xff, 0xf7, 0x51, 0xff, 0x89, 0x45, 0x09, 0xdc, 0x01, 0xdb, 0x80, 0x45, + 0x06, 0xd2, 0x02, 0x9a, 0x12, 0x78, 0xaa, 0x18, 0x57, 0x1e, 0xa3, 0x46, + 0x80, 0x46, 0x89, 0x46, 0x6d, 0x1c, 0x03, 0x2d, 0xec, 0xd3, 0x64, 0x1c, + 0x10, 0x2c, 0xde, 0xd3, 0x00, 0xf0, 0x07, 0xf8, 0xfe, 0xf7, 0x5f, 0xfc, + 0xfe, 0xf7, 0x05, 0xfa, 0x50, 0x46, 0xbd, 0xe8, 0xfe, 0x8f, 0x02, 0x98, + 0x07, 0x70, 0x02, 0x98, 0x80, 0xf8, 0x01, 0xb0, 0x70, 0x47, 0x01, 0xf4, + 0xfe, 0x01, 0x41, 0xea, 0x80, 0x70, 0xb1, 0x78, 0xc9, 0x05, 0x01, 0xf0, + 0x7e, 0x51, 0x08, 0x43, 0x31, 0x79, 0xc9, 0x03, 0x01, 0xf4, 0x00, 0x41, + 0x08, 0x43, 0x40, 0xf0, 0x00, 0x40, 0x40, 0xf4, 0x80, 0x40, 0xfe, 0xf7, + 0xb8, 0xb9, 0x70, 0xb5, 0x04, 0x9c, 0x0e, 0x46, 0x15, 0x46, 0x19, 0x46, + 0x22, 0x46, 0xff, 0xf7, 0x45, 0xff, 0xc8, 0xb9, 0x21, 0x78, 0x71, 0x18, + 0x21, 0x70, 0xad, 0xb1, 0xea, 0x10, 0x05, 0xeb, 0x12, 0x72, 0x12, 0x11, + 0xc9, 0xb2, 0x51, 0x18, 0x63, 0x78, 0xa5, 0xeb, 0x02, 0x12, 0xd2, 0x18, + 0x12, 0xb2, 0x00, 0x2a, 0x02, 0xd5, 0x49, 0x1e, 0x10, 0x32, 0x03, 0xe0, + 0x10, 0x2a, 0xa4, 0xbf, 0x49, 0x1c, 0x10, 0x3a, 0x21, 0x70, 0x62, 0x70, + 0x70, 0xbd, 0x10, 0xb5, 0x00, 0x22, 0x17, 0x4b, 0x44, 0x24, 0x00, 0xf0, + 0x31, 0xf8, 0xdc, 0x63, 0x01, 0x24, 0xa3, 0xf8, 0x40, 0x40, 0x94, 0x24, + 0x13, 0x4b, 0x00, 0xf0, 0x29, 0xf8, 0x9c, 0x61, 0x01, 0x24, 0x9c, 0x83, + 0x58, 0xb1, 0x11, 0x4b, 0x54, 0x24, 0x00, 0xf0, 0x21, 0xf8, 0x9c, 0x64, + 0x01, 0xeb, 0x82, 0x04, 0xa4, 0x68, 0xdc, 0x64, 0x01, 0x24, 0xa3, 0xf8, + 0x50, 0x40, 0x52, 0x1c, 0x02, 0x2a, 0xe0, 0xd3, 0x10, 0xbd, 0x00, 0x00, + 0x78, 0xb8, 0x00, 0x20, 0x78, 0x29, 0x00, 0x20, 0x20, 0x29, 0x00, 0x20, + 0x60, 0x01, 0x00, 0x45, 0xa8, 0x01, 0x00, 0x45, 0x90, 0x01, 0x00, 0x45, + 0x78, 0x01, 0x00, 0x45, 0xa8, 0xef, 0x00, 0x20, 0x74, 0x27, 0x00, 0x20, + 0x94, 0xed, 0x00, 0x20, 0x04, 0xfb, 0x02, 0x33, 0x51, 0xf8, 0x22, 0x40, + 0x70, 0x47, 0x01, 0xb4, 0xbd, 0xf8, 0x02, 0x00, 0x5a, 0x28, 0x03, 0xdb, + 0xbd, 0xf8, 0x00, 0x00, 0x10, 0x28, 0x01, 0xdb, 0x00, 0x20, 0x00, 0xe0, + 0x01, 0x20, 0x01, 0xb0, 0x70, 0x47, 0xfe, 0xb5, 0x04, 0x46, 0x0d, 0x46, + 0x00, 0x26, 0x55, 0xf8, 0x26, 0x00, 0x00, 0x90, 0xff, 0xf7, 0xe9, 0xff, + 0x07, 0x46, 0x34, 0xb1, 0x05, 0xeb, 0x86, 0x00, 0x80, 0x68, 0x00, 0x90, + 0xff, 0xf7, 0xe1, 0xff, 0x00, 0xe0, 0x01, 0x20, 0x17, 0xb1, 0x10, 0xb1, + 0x01, 0x20, 0x00, 0xe0, 0x00, 0x20, 0x01, 0xa9, 0xc0, 0xb2, 0x41, 0xf8, + 0x26, 0x00, 0x76, 0x1c, 0x02, 0x2e, 0xe4, 0xd3, 0x01, 0x98, 0x00, 0x28, + 0x1e, 0xbf, 0x02, 0x98, 0x00, 0x28, 0x01, 0x20, 0xc0, 0xb2, 0xfe, 0xbd, + 0x35, 0x49, 0x00, 0x20, 0x08, 0x80, 0x70, 0x47, 0x07, 0xf0, 0x9d, 0xbb, + 0x07, 0xf0, 0x9c, 0xbb, 0x07, 0xf0, 0x9b, 0xbb, 0x07, 0xf0, 0x9b, 0xbb, + 0x4f, 0xf0, 0x80, 0x73, 0x42, 0xf8, 0x04, 0x39, 0x10, 0x60, 0x10, 0x1f, + 0x2d, 0x4a, 0x40, 0xf8, 0x04, 0x29, 0x4f, 0xf0, 0x12, 0x32, 0x40, 0xf8, + 0x04, 0x29, 0x4f, 0xf0, 0x03, 0x32, 0x40, 0xf8, 0x04, 0x29, 0x4f, 0xf0, + 0x02, 0x32, 0x40, 0xf8, 0x04, 0x29, 0x4f, 0xf0, 0x01, 0x32, 0x40, 0xf8, + 0x04, 0x29, 0x40, 0xf8, 0x04, 0x19, 0x4f, 0xf0, 0x11, 0x31, 0x40, 0xf8, + 0x04, 0x19, 0x4f, 0xf0, 0x10, 0x31, 0x40, 0xf8, 0x04, 0x19, 0x4f, 0xf0, + 0x09, 0x31, 0x40, 0xf8, 0x04, 0x19, 0x4f, 0xf0, 0x08, 0x31, 0x40, 0xf8, + 0x04, 0x19, 0x4f, 0xf0, 0x07, 0x31, 0x40, 0xf8, 0x04, 0x19, 0x4f, 0xf0, + 0x06, 0x31, 0x40, 0xf8, 0x04, 0x19, 0x4f, 0xf0, 0x05, 0x31, 0x40, 0xf8, + 0x04, 0x19, 0x4f, 0xf0, 0x04, 0x31, 0x01, 0x60, 0x70, 0x47, 0x07, 0xf0, + 0x5f, 0xbb, 0x07, 0xf0, 0x64, 0xbb, 0x80, 0xb5, 0x07, 0xf0, 0x62, 0xfb, + 0x0e, 0x48, 0x01, 0x88, 0x49, 0x1c, 0x01, 0x80, 0x89, 0xb2, 0x05, 0x29, + 0x05, 0xd3, 0x00, 0x21, 0x01, 0x80, 0xbd, 0xe8, 0x01, 0x40, 0xfb, 0xf7, + 0xbf, 0xb9, 0x01, 0xbd, 0x80, 0xb5, 0x00, 0xf0, 0x13, 0xf8, 0x08, 0x49, + 0x0a, 0x78, 0x52, 0x1c, 0x0a, 0x70, 0x80, 0xf3, 0x11, 0x88, 0xfa, 0xf7, + 0xcd, 0xf9, 0xbd, 0xe8, 0x01, 0x40, 0xfa, 0xf7, 0x67, 0xb9, 0x00, 0x00, + 0x9c, 0xf3, 0x00, 0x20, 0xbd, 0x2a, 0x00, 0x01, 0x20, 0xbd, 0x00, 0x20, + 0xef, 0xf3, 0x11, 0x80, 0x60, 0x21, 0x81, 0xf3, 0x11, 0x88, 0x70, 0x47, + 0x80, 0xf3, 0x11, 0x88, 0x70, 0x47, 0x1b, 0x48, 0xff, 0x21, 0x01, 0x70, + 0x00, 0x20, 0x80, 0xf3, 0x09, 0x88, 0x19, 0x48, 0x01, 0x21, 0x01, 0x70, + 0x18, 0x48, 0x19, 0x49, 0x01, 0x60, 0x62, 0xb6, 0xfe, 0xe7, 0x16, 0x48, + 0x16, 0x49, 0x01, 0x60, 0x70, 0x47, 0x14, 0x48, 0x14, 0x49, 0x01, 0x60, + 0x70, 0x47, 0x72, 0xb6, 0xef, 0xf3, 0x09, 0x80, 0x28, 0xb1, 0x20, 0x38, + 0x80, 0xe8, 0xf0, 0x0f, 0x10, 0x49, 0x09, 0x68, 0x08, 0x60, 0x00, 0xb5, + 0x0f, 0x48, 0x80, 0x47, 0x5d, 0xf8, 0x04, 0xeb, 0x0e, 0x48, 0x0f, 0x49, + 0x0a, 0x78, 0x02, 0x70, 0x0a, 0x48, 0x0e, 0x49, 0x0a, 0x68, 0x02, 0x60, + 0x10, 0x68, 0x90, 0xe8, 0xf0, 0x0f, 0x20, 0x30, 0x80, 0xf3, 0x09, 0x88, + 0x4e, 0xf0, 0x04, 0x0e, 0x62, 0xb6, 0x70, 0x47, 0x22, 0xed, 0x00, 0xe0, + 0x25, 0xbd, 0x00, 0x20, 0x04, 0xed, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x10, + 0x40, 0xbd, 0x00, 0x20, 0x03, 0x7a, 0x00, 0x01, 0x22, 0xbd, 0x00, 0x20, + 0x23, 0xbd, 0x00, 0x20, 0x48, 0xbd, 0x00, 0x20, 0x00, 0x22, 0x07, 0xf0, + 0xeb, 0xba, 0x00, 0x00, 0x62, 0xf3, 0x0f, 0x22, 0x62, 0xf3, 0x1f, 0x42, + 0x40, 0x18, 0x10, 0xf0, 0x03, 0x03, 0x08, 0xd0, 0xc9, 0x1a, 0x1f, 0xd3, + 0xdb, 0x07, 0x48, 0xbf, 0x00, 0xf8, 0x01, 0x2d, 0x28, 0xbf, 0x20, 0xf8, + 0x02, 0x2d, 0x13, 0x00, 0x30, 0xb4, 0x14, 0x46, 0x15, 0x46, 0x10, 0x39, + 0x28, 0xbf, 0x20, 0xe9, 0x3c, 0x00, 0xfa, 0xd8, 0x49, 0x07, 0x28, 0xbf, + 0x20, 0xe9, 0x0c, 0x00, 0x48, 0xbf, 0x40, 0xf8, 0x04, 0x2d, 0x89, 0x00, + 0x28, 0xbf, 0x20, 0xf8, 0x02, 0x2d, 0x48, 0xbf, 0x00, 0xf8, 0x01, 0x2d, + 0x30, 0xbc, 0x70, 0x47, 0xc9, 0x18, 0x18, 0xbf, 0x00, 0xf8, 0x01, 0x2d, + 0xcb, 0x07, 0x28, 0xbf, 0x00, 0xf8, 0x01, 0x2d, 0x70, 0x47, 0x00, 0x00, + 0x58, 0xb5, 0x04, 0x46, 0x03, 0x2c, 0x16, 0xda, 0x04, 0xf0, 0x00, 0xff, + 0xbb, 0x4a, 0xbc, 0x4e, 0x12, 0x68, 0x09, 0x07, 0x41, 0xea, 0x10, 0x11, + 0x00, 0x07, 0x00, 0x23, 0xff, 0xf7, 0x78, 0xfc, 0x06, 0xeb, 0xc4, 0x02, + 0xc2, 0xe9, 0x00, 0x01, 0x20, 0x46, 0x04, 0xf0, 0xef, 0xfe, 0x06, 0xeb, + 0xc4, 0x02, 0xc2, 0xe9, 0x06, 0x01, 0x51, 0xbd, 0x7c, 0xb5, 0xb2, 0x49, + 0x0f, 0xf2, 0x28, 0x34, 0x09, 0x78, 0x01, 0xf0, 0x03, 0x02, 0x89, 0x08, + 0x01, 0xf0, 0x01, 0x03, 0x60, 0xcc, 0x69, 0x46, 0x01, 0x2a, 0x60, 0xc1, + 0x4f, 0xf4, 0x7a, 0x71, 0xa1, 0xfb, 0x00, 0x01, 0x04, 0xd1, 0x1b, 0xb1, + 0x49, 0x00, 0x41, 0xea, 0xd0, 0x71, 0x40, 0x00, 0x6c, 0x46, 0x04, 0xeb, + 0x83, 0x03, 0xd2, 0x5c, 0x02, 0xb0, 0xbd, 0xe8, 0x70, 0x40, 0x00, 0x23, + 0xff, 0xf7, 0x4a, 0xbc, 0xa2, 0x49, 0x09, 0x78, 0x49, 0x07, 0x46, 0xbf, + 0x05, 0x21, 0xb0, 0xfb, 0xf1, 0xf0, 0x80, 0x08, 0x70, 0x47, 0x9f, 0x49, + 0x09, 0x78, 0xc9, 0x07, 0x9e, 0x49, 0x48, 0xbf, 0x40, 0x08, 0x09, 0x78, + 0xc1, 0xf3, 0x41, 0x01, 0xc8, 0x40, 0x70, 0x47, 0x10, 0xb5, 0x95, 0x48, + 0x95, 0x4c, 0x40, 0x68, 0xff, 0xf7, 0xc4, 0xff, 0x20, 0x63, 0xff, 0xf7, + 0xe3, 0xff, 0x60, 0x63, 0xff, 0xf7, 0xe9, 0xff, 0xa0, 0x63, 0x95, 0x49, + 0xb0, 0xfb, 0xf1, 0xf0, 0x40, 0x1c, 0xe0, 0x63, 0x4f, 0xf4, 0x7a, 0x71, + 0xa0, 0x6b, 0xb0, 0xfb, 0xf1, 0xf0, 0x20, 0x64, 0x10, 0xbd, 0x4b, 0x01, + 0x19, 0x18, 0x8f, 0x48, 0x20, 0x22, 0x18, 0x18, 0x02, 0xf0, 0x10, 0xb8, + 0xf8, 0xb5, 0x8d, 0x4d, 0x8d, 0x4a, 0x29, 0x68, 0x51, 0x18, 0x00, 0x20, + 0x8c, 0x4a, 0x91, 0x42, 0x0c, 0xd2, 0x69, 0x68, 0x8b, 0x4a, 0x51, 0x18, + 0x8b, 0x4a, 0x91, 0x42, 0x06, 0xd2, 0x29, 0x7a, 0x04, 0x29, 0x03, 0xda, + 0x69, 0x89, 0xb1, 0xf5, 0x00, 0x7f, 0x00, 0xd3, 0x01, 0x20, 0xae, 0x7a, + 0x86, 0x49, 0x87, 0x4a, 0x87, 0x4b, 0x88, 0x4c, 0x03, 0x27, 0x3e, 0x42, + 0x0c, 0xd0, 0x2e, 0x7c, 0x03, 0x2e, 0x07, 0xda, 0x6e, 0x69, 0xa6, 0x19, + 0x9e, 0x42, 0x03, 0xd2, 0x6e, 0x6a, 0x00, 0xf0, 0x69, 0xf8, 0x02, 0xe0, + 0x01, 0x26, 0x00, 0xe0, 0x00, 0x26, 0x30, 0x43, 0xae, 0x7a, 0x0c, 0x27, + 0x3e, 0x42, 0x09, 0xd0, 0xee, 0x6a, 0xa6, 0x19, 0x9e, 0x42, 0x03, 0xd2, + 0xae, 0x6b, 0x00, 0xf0, 0x59, 0xf8, 0x02, 0xe0, 0x01, 0x26, 0x00, 0xe0, + 0x00, 0x26, 0x30, 0x43, 0xae, 0x7a, 0x30, 0x27, 0x3e, 0x42, 0x0b, 0xd0, + 0x2e, 0x6c, 0xa6, 0x19, 0x9e, 0x42, 0x05, 0xd2, 0xee, 0x6c, 0x73, 0x4f, + 0xbe, 0x42, 0xb6, 0x41, 0xf6, 0x0f, 0x02, 0xe0, 0x01, 0x26, 0x00, 0xe0, + 0x00, 0x26, 0x30, 0x43, 0x6e, 0x89, 0x4f, 0xf4, 0xe0, 0x77, 0x3e, 0x42, + 0x0c, 0xd0, 0x6e, 0x6d, 0xa4, 0x19, 0x9c, 0x42, 0x06, 0xd2, 0x2b, 0x6e, + 0xd2, 0x18, 0x8a, 0x42, 0x89, 0x41, 0xc9, 0x43, 0xc9, 0x0f, 0x02, 0xe0, + 0x01, 0x21, 0x00, 0xe0, 0x00, 0x21, 0x51, 0xea, 0x00, 0x04, 0x06, 0xd0, + 0x04, 0x22, 0x00, 0x23, 0x00, 0x21, 0x04, 0x20, 0x00, 0xf0, 0xe4, 0xf9, + 0x22, 0xe0, 0x4f, 0x4e, 0x64, 0x22, 0x29, 0x46, 0x30, 0x46, 0x01, 0xf0, + 0x9d, 0xff, 0x70, 0x89, 0xc0, 0xf3, 0x81, 0x00, 0x10, 0xb1, 0x00, 0x21, + 0x00, 0xf0, 0x1e, 0xf8, 0x70, 0x89, 0xc0, 0xf3, 0x01, 0x10, 0x10, 0xb1, + 0x01, 0x21, 0x00, 0xf0, 0x17, 0xf8, 0x70, 0x89, 0xc0, 0xf3, 0x82, 0x10, + 0x10, 0xb1, 0x02, 0x21, 0x00, 0xf0, 0x10, 0xf8, 0xb0, 0x7a, 0x03, 0x21, + 0x08, 0x42, 0x1c, 0xbf, 0x05, 0xf1, 0x64, 0x00, 0xff, 0xf7, 0x69, 0xff, + 0x20, 0x46, 0xf2, 0xbd, 0x96, 0x19, 0x8e, 0x42, 0xb6, 0x41, 0xf6, 0x43, + 0xf6, 0x0f, 0x70, 0x47, 0x05, 0xf1, 0x64, 0x00, 0x5d, 0xe7, 0x80, 0xb5, + 0x00, 0xf0, 0x43, 0xf8, 0x0e, 0xd0, 0x00, 0xf0, 0x35, 0xf8, 0x00, 0x21, + 0x40, 0xf2, 0x09, 0x20, 0xfb, 0xf7, 0x42, 0xf9, 0x00, 0xf0, 0x33, 0xf8, + 0x00, 0x22, 0x03, 0x21, 0x40, 0xf2, 0x0a, 0x20, 0xfb, 0xf7, 0x44, 0xf9, + 0xf8, 0x20, 0x00, 0xf0, 0x35, 0xf8, 0xbd, 0xe8, 0x02, 0x40, 0x0e, 0x20, + 0x00, 0xf0, 0xa5, 0xb8, 0x80, 0xb5, 0x05, 0x21, 0x4f, 0xf4, 0xd8, 0x70, + 0xfb, 0xf7, 0x2c, 0xf9, 0x00, 0x21, 0x4f, 0xf4, 0x82, 0x70, 0xfb, 0xf7, + 0x27, 0xf9, 0x00, 0xf0, 0x1e, 0xf8, 0x10, 0xd0, 0xff, 0x21, 0x40, 0xf2, + 0x09, 0x20, 0xfb, 0xf7, 0x1f, 0xf9, 0x00, 0xf0, 0x0b, 0xf8, 0x00, 0xf0, + 0x0e, 0xf8, 0xbd, 0xe8, 0x08, 0x40, 0x03, 0x22, 0x03, 0x21, 0x40, 0xf2, + 0x0a, 0x20, 0xfb, 0xf7, 0x1d, 0xb9, 0x01, 0xbd, 0xff, 0x21, 0x40, 0xf6, + 0x89, 0x50, 0xfb, 0xf7, 0x0d, 0xb9, 0x03, 0x22, 0x03, 0x21, 0x40, 0xf6, + 0x8a, 0x50, 0xfb, 0xf7, 0x11, 0xb9, 0x15, 0x48, 0x80, 0x7a, 0x03, 0x21, + 0x08, 0x42, 0x70, 0x47, 0x01, 0x07, 0x0a, 0xd5, 0x11, 0x49, 0x49, 0x89, + 0x01, 0xf0, 0x03, 0x02, 0x89, 0x08, 0x89, 0x01, 0x41, 0xea, 0x02, 0x11, + 0x41, 0xf0, 0x0f, 0x01, 0x08, 0x40, 0x01, 0x46, 0x4f, 0xf4, 0xd8, 0x70, + 0xfb, 0xf7, 0xf0, 0xb8, 0x00, 0x28, 0x14, 0xbf, 0x02, 0x22, 0x00, 0x22, + 0x02, 0x21, 0x4f, 0xf4, 0xd8, 0x70, 0xfb, 0xf7, 0xf1, 0xb8, 0x38, 0xb9, + 0x16, 0x49, 0x4f, 0xf0, 0x00, 0x40, 0x08, 0x60, 0x00, 0xbf, 0x00, 0xbf, + 0x00, 0xbf, 0x00, 0xbf, 0x70, 0x47, 0x00, 0x00, 0x78, 0x29, 0x00, 0x20, + 0x00, 0xf2, 0x00, 0x20, 0x19, 0x01, 0x00, 0x46, 0x02, 0x01, 0x00, 0x46, + 0x18, 0x01, 0x00, 0x46, 0x08, 0x0d, 0x00, 0x46, 0x40, 0x42, 0x0f, 0x00, + 0x00, 0x02, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0xc0, 0x87, 0x82, 0xfe, + 0xc1, 0x57, 0x95, 0x11, 0x20, 0xf9, 0xa5, 0xff, 0x21, 0x79, 0x61, 0x00, + 0x81, 0x77, 0x8e, 0x06, 0x00, 0xd3, 0xce, 0xfe, 0x01, 0x70, 0x28, 0x12, + 0x00, 0xa0, 0x15, 0xff, 0x00, 0x2d, 0x31, 0x01, 0x04, 0xed, 0x00, 0xe0, + 0x10, 0xb5, 0x04, 0x46, 0x00, 0xf0, 0x07, 0xf8, 0x01, 0x21, 0x81, 0x40, + 0x49, 0x1e, 0x21, 0x42, 0x18, 0xbf, 0x40, 0x1c, 0x10, 0xbd, 0xb0, 0xfa, + 0x80, 0xf0, 0xc0, 0xf1, 0x1f, 0x00, 0x70, 0x47, 0x04, 0x06, 0x08, 0x0c, + 0x05, 0x0f, 0x0a, 0x0f, 0x01, 0x21, 0x00, 0xf0, 0x1f, 0x02, 0x91, 0x40, + 0x11, 0x4a, 0x04, 0xe0, 0x01, 0x21, 0x00, 0xf0, 0x1f, 0x02, 0x91, 0x40, + 0x0f, 0x4a, 0x40, 0x09, 0x42, 0xf8, 0x20, 0x10, 0x70, 0x47, 0x01, 0x21, + 0x00, 0xf0, 0x1f, 0x02, 0x91, 0x40, 0x0c, 0x4a, 0xf5, 0xe7, 0x01, 0x21, + 0x00, 0xf0, 0x1f, 0x02, 0x91, 0x40, 0x0a, 0x4a, 0xef, 0xe7, 0x09, 0x01, + 0x00, 0x28, 0x06, 0xd5, 0x08, 0x4a, 0x00, 0xf0, 0x0f, 0x00, 0x80, 0x18, + 0x00, 0xf8, 0x04, 0x1c, 0x70, 0x47, 0x06, 0x4a, 0x81, 0x54, 0x70, 0x47, + 0x80, 0xe2, 0x00, 0xe0, 0x00, 0xe1, 0x00, 0xe0, 0x80, 0xe1, 0x00, 0xe0, + 0x00, 0xe2, 0x00, 0xe0, 0x18, 0xed, 0x00, 0xe0, 0x00, 0xe4, 0x00, 0xe0, + 0x42, 0x48, 0x00, 0xf1, 0x08, 0x01, 0x01, 0x60, 0x00, 0x21, 0xc1, 0x80, + 0x04, 0x21, 0x81, 0x80, 0x00, 0x21, 0x3f, 0x48, 0x81, 0x60, 0x6f, 0xf0, + 0x7f, 0x41, 0x01, 0x60, 0x15, 0x21, 0x81, 0x60, 0x70, 0x47, 0xef, 0xf3, + 0x11, 0x80, 0x60, 0x21, 0x81, 0xf3, 0x11, 0x88, 0x70, 0x47, 0x37, 0x49, + 0x0a, 0x68, 0x10, 0x60, 0x01, 0xf5, 0x80, 0x50, 0x00, 0x1d, 0x82, 0x42, + 0x2c, 0xbf, 0x01, 0xf1, 0x08, 0x00, 0x10, 0x1d, 0x08, 0x60, 0xc8, 0x88, + 0xb0, 0xf5, 0x80, 0x6f, 0xbc, 0xbf, 0x40, 0x1c, 0xc8, 0x80, 0x70, 0x47, + 0x38, 0xb5, 0x04, 0x46, 0xff, 0xf7, 0xe3, 0xff, 0x05, 0x46, 0x00, 0xf0, + 0x11, 0xf8, 0x85, 0xf3, 0x11, 0x88, 0x31, 0xbd, 0x70, 0xb5, 0x04, 0x46, + 0x0d, 0x46, 0xff, 0xf7, 0xd8, 0xff, 0x06, 0x46, 0x00, 0xf0, 0x06, 0xf8, + 0x28, 0x46, 0xff, 0xf7, 0xd8, 0xff, 0x86, 0xf3, 0x11, 0x88, 0x70, 0xbd, + 0x23, 0x48, 0x01, 0x68, 0x00, 0x22, 0x42, 0x60, 0x15, 0x22, 0x42, 0x60, + 0x44, 0xea, 0xc1, 0x10, 0xcb, 0xe7, 0x10, 0xb5, 0x1f, 0x4a, 0x04, 0x46, + 0xd2, 0xe9, 0x02, 0x01, 0x22, 0x46, 0xfb, 0xf7, 0x21, 0xfa, 0xc0, 0x07, + 0x04, 0xd5, 0x44, 0xf0, 0x00, 0x40, 0xbd, 0xe8, 0x10, 0x40, 0xcf, 0xe7, + 0x10, 0xbd, 0x38, 0xb5, 0x00, 0xf0, 0x1f, 0xf8, 0xc0, 0x07, 0x08, 0xd5, + 0x05, 0xf0, 0x01, 0x00, 0x44, 0xea, 0x80, 0x10, 0xbd, 0xe8, 0x32, 0x40, + 0x40, 0xf0, 0x00, 0x40, 0xc0, 0xe7, 0x31, 0xbd, 0x38, 0xb5, 0x00, 0xf0, + 0x10, 0xf8, 0xc0, 0x07, 0x0c, 0xd5, 0x68, 0x0e, 0x00, 0xf0, 0x40, 0x00, + 0x04, 0xf0, 0x3f, 0x02, 0x69, 0x00, 0x10, 0x43, 0xbd, 0xe8, 0x34, 0x40, + 0x49, 0x08, 0x40, 0xf0, 0x00, 0x40, 0xb7, 0xe7, 0x31, 0xbd, 0x07, 0x4a, + 0x04, 0x46, 0x0d, 0x46, 0xd2, 0xe9, 0x02, 0x01, 0x22, 0x46, 0xfb, 0xf7, + 0xef, 0xb9, 0x00, 0x00, 0xb8, 0x82, 0x00, 0x20, 0x00, 0x00, 0x30, 0x59, + 0x04, 0x00, 0x30, 0x59, 0x88, 0x02, 0x00, 0x20, 0x10, 0xb5, 0x04, 0x46, + 0x00, 0xf0, 0x07, 0xf8, 0x20, 0x46, 0x07, 0xf0, 0x5b, 0xf8, 0xbd, 0xe8, + 0x10, 0x40, 0x07, 0xf0, 0x4b, 0xb8, 0x10, 0xb5, 0x30, 0x48, 0x00, 0x21, + 0x00, 0x22, 0x00, 0x23, 0x00, 0x24, 0x1e, 0xc0, 0x10, 0xbd, 0x10, 0xb5, + 0x00, 0xf0, 0x05, 0xf8, 0x23, 0xea, 0x00, 0x00, 0x42, 0xf8, 0x21, 0x00, + 0x10, 0xbd, 0x29, 0x4a, 0x01, 0x09, 0x52, 0xf8, 0x21, 0x30, 0x01, 0x24, + 0x40, 0x00, 0x04, 0xfa, 0x00, 0xf0, 0x70, 0x47, 0x30, 0xb5, 0x02, 0x09, + 0x23, 0x4b, 0x53, 0xf8, 0x22, 0x40, 0x40, 0x00, 0x40, 0x1c, 0x07, 0x25, + 0x85, 0x40, 0xac, 0x43, 0x43, 0xf8, 0x22, 0x40, 0x01, 0xf0, 0x07, 0x01, + 0x53, 0xf8, 0x22, 0x40, 0x01, 0xfa, 0x00, 0xf0, 0x20, 0x43, 0x43, 0xf8, + 0x22, 0x00, 0x30, 0xbd, 0x19, 0x4a, 0x03, 0x09, 0x52, 0xf8, 0x23, 0x20, + 0x43, 0x00, 0x5b, 0x1c, 0xda, 0x40, 0x02, 0xf0, 0x07, 0x02, 0x8a, 0x42, + 0x38, 0xbf, 0xff, 0xf7, 0xdd, 0xbf, 0x70, 0x47, 0xf0, 0xb5, 0xef, 0xf3, + 0x10, 0x84, 0x72, 0xb6, 0x11, 0x4d, 0xd5, 0xe9, 0x00, 0x67, 0x26, 0xea, + 0x02, 0x02, 0x27, 0xea, 0x03, 0x03, 0x10, 0x43, 0x19, 0x43, 0xc5, 0xe9, + 0x00, 0x01, 0x84, 0xf3, 0x10, 0x88, 0xf0, 0xbd, 0xd0, 0xb5, 0x04, 0x46, + 0xef, 0xf3, 0x10, 0x80, 0x72, 0xb6, 0x08, 0x49, 0xd1, 0xe9, 0x00, 0x67, + 0x80, 0xf3, 0x10, 0x88, 0x26, 0xea, 0x02, 0x00, 0x27, 0xea, 0x03, 0x01, + 0x22, 0x46, 0xbd, 0xe8, 0xd0, 0x40, 0xfb, 0xf7, 0x79, 0xb9, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x49, 0x10, 0x00, 0x00, 0x49, 0x3c, 0x48, 0x01, 0x74, + 0xc9, 0xb2, 0x03, 0x29, 0x9c, 0xbf, 0x00, 0x20, 0xff, 0xf7, 0x7f, 0xbe, + 0x70, 0x47, 0x30, 0xb5, 0x37, 0x4d, 0x85, 0xb0, 0x04, 0x46, 0x55, 0xf8, + 0x24, 0x10, 0xa1, 0xb9, 0x03, 0xa9, 0x02, 0x91, 0x00, 0x90, 0x00, 0x21, + 0x33, 0x48, 0x34, 0x4b, 0x01, 0x91, 0x01, 0x22, 0x50, 0xf8, 0x24, 0x00, + 0xfa, 0xf7, 0xe8, 0xfc, 0x45, 0xf8, 0x24, 0x00, 0x9d, 0xf8, 0x0c, 0x10, + 0x48, 0x1e, 0x80, 0x41, 0xc0, 0x0f, 0xff, 0xf7, 0x62, 0xfe, 0x05, 0xb0, + 0x30, 0xbd, 0x38, 0xb5, 0x28, 0x4d, 0x04, 0x46, 0x55, 0xf8, 0x24, 0x00, + 0x20, 0xb1, 0x69, 0x46, 0xfa, 0xf7, 0x12, 0xfd, 0x00, 0xf0, 0x1b, 0xf8, + 0x00, 0x20, 0x45, 0xf8, 0x24, 0x00, 0x31, 0xbd, 0x38, 0xb5, 0x00, 0xf0, + 0x3b, 0xf8, 0x11, 0xd1, 0x1f, 0x4d, 0x55, 0xf8, 0x24, 0x00, 0x68, 0xb1, + 0x69, 0x46, 0xfa, 0xf7, 0x5d, 0xfd, 0x01, 0x28, 0x08, 0xd1, 0x00, 0xf0, + 0x08, 0xf8, 0x55, 0xf8, 0x24, 0x00, 0x69, 0x46, 0xfa, 0xf7, 0x74, 0xfd, + 0x00, 0xf0, 0x01, 0xf8, 0x31, 0xbd, 0x9d, 0xf8, 0x00, 0x10, 0x48, 0x1e, + 0x80, 0x41, 0xc0, 0x0f, 0xff, 0xf7, 0x33, 0xbe, 0x38, 0xb5, 0x00, 0xf0, + 0x1d, 0xf8, 0x1a, 0xd1, 0x10, 0x4d, 0x55, 0xf8, 0x24, 0x00, 0xb0, 0xb1, + 0x69, 0x46, 0xfa, 0xf7, 0x3f, 0xfd, 0x03, 0x28, 0x11, 0xd1, 0xff, 0xf7, + 0xea, 0xff, 0x55, 0xf8, 0x24, 0x00, 0x69, 0x46, 0xfa, 0xf7, 0x00, 0xfd, + 0xff, 0xf7, 0xe3, 0xff, 0x55, 0xf8, 0x24, 0x00, 0x6b, 0x46, 0x00, 0x22, + 0x00, 0x21, 0xfa, 0xf7, 0x79, 0xfd, 0xff, 0xf7, 0xda, 0xff, 0x31, 0xbd, + 0x04, 0x46, 0x03, 0x48, 0x00, 0x7c, 0x01, 0x28, 0x70, 0x47, 0x00, 0x00, + 0x08, 0x1f, 0x00, 0x20, 0x1c, 0x1f, 0x00, 0x20, 0x45, 0x81, 0x00, 0x01, + 0x00, 0x20, 0x00, 0xe0, 0x01, 0x20, 0x38, 0xb5, 0xff, 0xf7, 0xee, 0xff, + 0x0b, 0xd1, 0x00, 0x25, 0x00, 0x2c, 0xe8, 0xb2, 0x02, 0xd1, 0xff, 0xf7, + 0x7c, 0xff, 0x01, 0xe0, 0xff, 0xf7, 0x97, 0xff, 0x6d, 0x1c, 0x04, 0x2d, + 0xf4, 0xd3, 0x31, 0xbd, 0xef, 0xf3, 0x11, 0x80, 0x60, 0x21, 0x81, 0xf3, + 0x11, 0x88, 0x70, 0x47, 0x30, 0xb5, 0x00, 0xf0, 0x11, 0xf8, 0x23, 0x43, + 0x13, 0x60, 0x01, 0xeb, 0x40, 0x00, 0x01, 0x22, 0x42, 0x70, 0x30, 0xbd, + 0x30, 0xb5, 0x00, 0xf0, 0x07, 0xf8, 0xa3, 0x43, 0x13, 0x60, 0x01, 0xeb, + 0x40, 0x00, 0x00, 0x22, 0x42, 0x70, 0x30, 0xbd, 0xdf, 0xf8, 0xb0, 0x2c, + 0xdf, 0xf8, 0xd4, 0x1d, 0x13, 0x68, 0x11, 0xf9, 0x10, 0x50, 0x01, 0x24, + 0xac, 0x40, 0x70, 0x47, 0xdf, 0xf8, 0xa0, 0x0c, 0xc0, 0x6c, 0x70, 0x47, + 0xdf, 0xf8, 0x9c, 0x1c, 0xdf, 0xf8, 0x94, 0x0c, 0x89, 0x6b, 0xc0, 0x6c, + 0xdf, 0xf8, 0x94, 0x2c, 0xb1, 0xfb, 0xf2, 0xf1, 0x48, 0x43, 0xdf, 0xf8, + 0x68, 0x1d, 0x48, 0x60, 0x70, 0x47, 0x80, 0xb5, 0xdf, 0xf8, 0x3c, 0x0d, + 0x00, 0x21, 0x41, 0x71, 0x84, 0x30, 0xfb, 0xf7, 0xb1, 0xf9, 0x06, 0xf0, + 0xea, 0xf9, 0xbd, 0xe8, 0x01, 0x40, 0x06, 0xf0, 0x1a, 0xb9, 0xdf, 0xf8, + 0xc8, 0x1d, 0x02, 0x20, 0x08, 0x60, 0x70, 0x47, 0xdf, 0xf8, 0x18, 0x0d, + 0x41, 0x79, 0xd0, 0xf8, 0x80, 0x00, 0x00, 0x29, 0x18, 0xbf, 0x40, 0xf0, + 0x00, 0x40, 0x70, 0x47, 0xdf, 0xf8, 0x04, 0x0d, 0x01, 0x79, 0x00, 0x29, + 0x0e, 0xbf, 0x00, 0x20, 0xd0, 0xf8, 0x80, 0x00, 0xc0, 0xf3, 0x02, 0x10, + 0x70, 0x47, 0x10, 0xb5, 0xdf, 0xf8, 0x28, 0x4c, 0xa1, 0x7c, 0x4f, 0xf4, + 0x17, 0x60, 0xfa, 0xf7, 0x73, 0xfe, 0xe1, 0x7c, 0xbd, 0xe8, 0x10, 0x40, + 0x40, 0xf6, 0x71, 0x10, 0xfa, 0xf7, 0x6c, 0xbe, 0x2d, 0xe9, 0xf0, 0x47, + 0x06, 0x21, 0x31, 0x20, 0xff, 0xf7, 0xdf, 0xfd, 0x31, 0x20, 0xff, 0xf7, + 0xc1, 0xfd, 0x31, 0x20, 0xff, 0xf7, 0xc4, 0xfd, 0xff, 0xf7, 0xac, 0xff, + 0xdf, 0xf8, 0xb4, 0x4c, 0xdf, 0xf8, 0xd0, 0x5c, 0xdf, 0xf8, 0xd0, 0x1c, + 0xdf, 0xf8, 0xe4, 0x9b, 0x00, 0x20, 0x60, 0x71, 0x68, 0x68, 0x08, 0x60, + 0x06, 0x21, 0x10, 0x20, 0xff, 0xf7, 0xc7, 0xfd, 0x02, 0x21, 0x0c, 0x20, + 0xff, 0xf7, 0xc3, 0xfd, 0x02, 0x21, 0x0a, 0x20, 0xff, 0xf7, 0xbf, 0xfd, + 0x02, 0x21, 0x1d, 0x20, 0xff, 0xf7, 0xbb, 0xfd, 0x02, 0x21, 0x0d, 0x20, + 0xff, 0xf7, 0xb7, 0xfd, 0x02, 0x21, 0x0b, 0x20, 0xff, 0xf7, 0xb3, 0xfd, + 0x02, 0x21, 0x1e, 0x20, 0xff, 0xf7, 0xaf, 0xfd, 0x02, 0x21, 0x1f, 0x20, + 0xff, 0xf7, 0xab, 0xfd, 0xdf, 0xf8, 0xc4, 0x0d, 0x40, 0x89, 0xc0, 0xf3, + 0x81, 0x01, 0x89, 0xf8, 0x04, 0x10, 0x01, 0x23, 0x00, 0xf0, 0x03, 0x01, + 0x89, 0xf8, 0x05, 0x10, 0x00, 0x21, 0x03, 0xfa, 0x01, 0xf8, 0x08, 0xea, + 0x00, 0x06, 0x0f, 0x1d, 0x8a, 0x1c, 0x16, 0xf0, 0x03, 0x0f, 0x03, 0xfa, + 0x07, 0xf7, 0x03, 0xfa, 0x02, 0xf2, 0x03, 0xfa, 0x01, 0xfe, 0x0d, 0xd1, + 0x2e, 0x78, 0x42, 0xea, 0x0e, 0x0a, 0x47, 0xea, 0x0a, 0x0a, 0x4a, 0xea, + 0x06, 0x06, 0x2e, 0x70, 0x4e, 0xf0, 0x04, 0x0a, 0x6e, 0x78, 0x4a, 0xea, + 0x06, 0x06, 0x6e, 0x70, 0x08, 0xea, 0x90, 0x0a, 0x8e, 0x1d, 0x1a, 0xf0, + 0x03, 0x0f, 0x03, 0xfa, 0x06, 0xf6, 0x0b, 0xd1, 0x42, 0xea, 0x0e, 0x02, + 0x94, 0xf8, 0x06, 0xa0, 0x17, 0x43, 0x37, 0x43, 0x47, 0xea, 0x0a, 0x07, + 0xa7, 0x71, 0x4a, 0x19, 0x7f, 0x27, 0x97, 0x70, 0x08, 0xea, 0x10, 0x17, + 0x17, 0xf0, 0x03, 0x0f, 0x02, 0xd1, 0xe7, 0x79, 0x37, 0x43, 0xe7, 0x71, + 0x49, 0x1c, 0x02, 0x29, 0xc3, 0xdb, 0xc0, 0xf3, 0x82, 0x10, 0x20, 0xb9, + 0xe0, 0x79, 0x40, 0xf0, 0x30, 0x00, 0xe0, 0x71, 0x15, 0xe0, 0x80, 0x22, + 0x80, 0x21, 0x4f, 0xf4, 0x02, 0x60, 0xfa, 0xf7, 0xe5, 0xfd, 0xc0, 0x22, + 0xc0, 0x21, 0x40, 0xf6, 0x1f, 0x00, 0xfa, 0xf7, 0xdf, 0xfd, 0x3f, 0x21, + 0x40, 0xf6, 0x8c, 0x50, 0xfa, 0xf7, 0xd0, 0xfd, 0x03, 0x21, 0x4f, 0xf4, + 0x03, 0x70, 0xfa, 0xf7, 0xcb, 0xfd, 0xc0, 0x22, 0xc0, 0x21, 0x40, 0xf6, + 0x14, 0x00, 0xfa, 0xf7, 0xcf, 0xfd, 0xc0, 0x22, 0xc0, 0x21, 0x40, 0xf6, + 0x12, 0x00, 0xfa, 0xf7, 0xc9, 0xfd, 0xc0, 0x22, 0xc0, 0x21, 0x40, 0xf6, + 0x13, 0x00, 0xfa, 0xf7, 0xc3, 0xfd, 0xc0, 0x22, 0xc0, 0x21, 0x40, 0xf2, + 0x42, 0x50, 0xfa, 0xf7, 0xbd, 0xfd, 0xc0, 0x22, 0xc0, 0x21, 0x40, 0xf2, + 0x43, 0x50, 0xfa, 0xf7, 0xb7, 0xfd, 0x00, 0x22, 0xc0, 0x21, 0x40, 0xf2, + 0xe4, 0x60, 0xfa, 0xf7, 0xb1, 0xfd, 0x99, 0xf8, 0x04, 0x00, 0x99, 0xf8, + 0x05, 0x10, 0x40, 0xea, 0x81, 0x00, 0xc4, 0xf8, 0x80, 0x00, 0x06, 0xf0, + 0x2b, 0xf8, 0xbd, 0xe8, 0xf0, 0x47, 0x05, 0xf0, 0x6b, 0xbe, 0x80, 0xb5, + 0x4f, 0xf0, 0x92, 0x41, 0x00, 0x20, 0x08, 0x60, 0x04, 0x21, 0x01, 0x20, + 0xff, 0xf7, 0x09, 0xfd, 0x01, 0x20, 0xff, 0xf7, 0xf1, 0xfc, 0x00, 0x20, + 0x02, 0xbd, 0xf8, 0xb5, 0x0a, 0x20, 0xff, 0xf7, 0xe5, 0xfc, 0x1d, 0x20, + 0xff, 0xf7, 0xe2, 0xfc, 0x0c, 0x20, 0xff, 0xf7, 0xdf, 0xfc, 0xdf, 0xf8, + 0x78, 0x3c, 0xdf, 0xf8, 0x78, 0x5c, 0xdf, 0xf8, 0x30, 0x2a, 0xdf, 0xf8, + 0xf0, 0x4a, 0x00, 0x20, 0x98, 0x60, 0x18, 0x60, 0x28, 0x60, 0x4f, 0xf4, + 0x00, 0x21, 0x90, 0x78, 0x70, 0xb9, 0x00, 0xf0, 0xfd, 0xf9, 0x10, 0x79, + 0xc2, 0x07, 0x4c, 0xbf, 0x80, 0x22, 0x00, 0x22, 0xa2, 0x65, 0x80, 0x07, + 0x58, 0xbf, 0x00, 0x21, 0x21, 0x66, 0x03, 0x20, 0x20, 0x72, 0x45, 0xe0, + 0x03, 0xf1, 0x40, 0x00, 0x60, 0x62, 0x03, 0xf1, 0x3c, 0x00, 0xa0, 0x62, + 0x05, 0xf1, 0x40, 0x00, 0x20, 0x63, 0x05, 0xf1, 0x3c, 0x00, 0x60, 0x63, + 0x80, 0x20, 0xd8, 0x63, 0xe9, 0x63, 0x98, 0x6c, 0x40, 0xf0, 0x80, 0x00, + 0x98, 0x64, 0xd8, 0x6c, 0x40, 0xf0, 0x80, 0x00, 0xd8, 0x64, 0xa8, 0x6c, + 0x40, 0xf4, 0x00, 0x20, 0xa8, 0x64, 0xe8, 0x6c, 0x40, 0xf4, 0x00, 0x20, + 0xe8, 0x64, 0xdf, 0xf8, 0xe8, 0x0b, 0x46, 0x89, 0xc6, 0xf3, 0x81, 0x07, + 0x03, 0x2f, 0x04, 0xbf, 0x12, 0x78, 0x00, 0x2a, 0x40, 0xf2, 0x05, 0x10, + 0x05, 0xd1, 0x80, 0x21, 0x99, 0x60, 0x08, 0x22, 0x04, 0x21, 0x21, 0x72, + 0x11, 0xe0, 0x00, 0x22, 0x22, 0x72, 0xc6, 0xf3, 0x80, 0x02, 0x1a, 0xb1, + 0x80, 0x22, 0x1a, 0x60, 0x01, 0x22, 0x22, 0x72, 0xb2, 0x08, 0x92, 0x07, + 0x04, 0xd5, 0x29, 0x60, 0x21, 0x7a, 0x41, 0xf0, 0x02, 0x01, 0x21, 0x72, + 0x00, 0x22, 0x08, 0x21, 0xfa, 0xf7, 0x26, 0xfd, 0x00, 0xf0, 0xc3, 0xf9, + 0x05, 0xf0, 0xeb, 0xff, 0xd4, 0xf8, 0x80, 0x00, 0x80, 0x08, 0x80, 0x00, + 0xc4, 0xf8, 0x80, 0x00, 0x0a, 0x20, 0xff, 0xf7, 0x82, 0xfc, 0x1d, 0x20, + 0xff, 0xf7, 0x7f, 0xfc, 0xbd, 0xe8, 0xf2, 0x40, 0x0c, 0x20, 0xff, 0xf7, + 0x7a, 0xbc, 0xf8, 0xb5, 0x0d, 0x20, 0xff, 0xf7, 0x61, 0xfc, 0x0b, 0x20, + 0xff, 0xf7, 0x5e, 0xfc, 0x1e, 0x20, 0xff, 0xf7, 0x5b, 0xfc, 0xdf, 0xf8, + 0xf8, 0x5b, 0xdf, 0xf8, 0xf8, 0x6b, 0xdf, 0xf8, 0x28, 0x39, 0xdf, 0xf8, + 0xdc, 0x1c, 0xdf, 0xf8, 0xe4, 0x49, 0x00, 0x20, 0xa8, 0x60, 0x28, 0x60, + 0x30, 0x60, 0x4f, 0xf4, 0x80, 0x12, 0x98, 0x78, 0x70, 0xb9, 0x00, 0xf0, + 0x6a, 0xf9, 0x58, 0x79, 0xc3, 0x07, 0x4c, 0xbf, 0x40, 0x23, 0x00, 0x23, + 0xa3, 0x64, 0x80, 0x07, 0x58, 0xbf, 0x00, 0x22, 0x22, 0x65, 0x03, 0x20, + 0x08, 0x70, 0x43, 0xe0, 0x05, 0xf1, 0x3c, 0x00, 0xe0, 0x60, 0x05, 0xf1, + 0x38, 0x00, 0x20, 0x61, 0x06, 0xf1, 0x3c, 0x00, 0xa0, 0x61, 0x06, 0xf1, + 0x38, 0x00, 0xe0, 0x61, 0x40, 0x20, 0xa8, 0x63, 0xb2, 0x63, 0x68, 0x6c, + 0x40, 0xf0, 0x40, 0x00, 0x68, 0x64, 0xa8, 0x6c, 0x40, 0xf0, 0x40, 0x00, + 0xa8, 0x64, 0x70, 0x6c, 0x40, 0xf4, 0x80, 0x10, 0x70, 0x64, 0xb0, 0x6c, + 0x40, 0xf4, 0x80, 0x10, 0xb0, 0x64, 0xdf, 0xf8, 0xdc, 0x0a, 0x47, 0x89, + 0x07, 0xf0, 0x03, 0x0c, 0xbc, 0xf1, 0x03, 0x0f, 0x04, 0xbf, 0x5b, 0x78, + 0x00, 0x2b, 0x40, 0xf2, 0x05, 0x10, 0x04, 0xd1, 0x40, 0x22, 0xaa, 0x60, + 0x04, 0x22, 0x0a, 0x70, 0x0f, 0xe0, 0x00, 0x23, 0x0b, 0x70, 0xfb, 0x07, + 0x03, 0xd5, 0x40, 0x23, 0x2b, 0x60, 0x01, 0x23, 0x0b, 0x70, 0xbb, 0x07, + 0x04, 0xd5, 0x32, 0x60, 0x0a, 0x78, 0x42, 0xf0, 0x02, 0x02, 0x0a, 0x70, + 0x00, 0x22, 0x04, 0x21, 0xfa, 0xf7, 0xa2, 0xfc, 0x00, 0xf0, 0x6f, 0xf9, + 0xff, 0xf7, 0x19, 0xfe, 0xd4, 0xf8, 0x80, 0x00, 0x20, 0xf0, 0x0c, 0x00, + 0xc4, 0xf8, 0x80, 0x00, 0x0b, 0x20, 0xff, 0xf7, 0xfe, 0xfb, 0x1e, 0x20, + 0xff, 0xf7, 0xfb, 0xfb, 0xbd, 0xe8, 0xf2, 0x40, 0x0d, 0x20, 0xff, 0xf7, + 0xf6, 0xbb, 0x2d, 0xe9, 0xf8, 0x43, 0xdf, 0xf8, 0x38, 0x58, 0xdf, 0xf8, + 0xf0, 0x6b, 0xe8, 0x78, 0xdf, 0xf8, 0xf0, 0x48, 0x98, 0xb9, 0x00, 0xf0, + 0x12, 0xf9, 0x30, 0x60, 0x10, 0x20, 0x60, 0x64, 0xa9, 0x79, 0x48, 0x08, + 0x40, 0x00, 0x01, 0xf0, 0x01, 0x02, 0x89, 0x08, 0x00, 0xf0, 0x02, 0x00, + 0x89, 0x00, 0x10, 0x43, 0x01, 0xf0, 0x04, 0x01, 0x08, 0x43, 0xa0, 0x66, + 0x37, 0xe0, 0x00, 0x20, 0x01, 0xf0, 0x88, 0xfb, 0x80, 0x46, 0x01, 0x20, + 0x01, 0xf0, 0x84, 0xfb, 0x07, 0x46, 0x02, 0x20, 0x01, 0xf0, 0x80, 0xfb, + 0x81, 0x46, 0x03, 0x20, 0x01, 0xf0, 0x7c, 0xfb, 0xa8, 0xf1, 0x04, 0x01, + 0x04, 0x2f, 0x21, 0x67, 0x0a, 0xd2, 0x07, 0xf1, 0x0a, 0x02, 0x62, 0x67, + 0x0a, 0x30, 0xe0, 0x67, 0x09, 0xf1, 0x0a, 0x02, 0xa2, 0x67, 0xdf, 0xf8, + 0x88, 0x0b, 0x0c, 0xe0, 0x10, 0x2f, 0x09, 0xd2, 0x3a, 0x1f, 0x62, 0x67, + 0x00, 0x1f, 0xe0, 0x67, 0xa9, 0xf1, 0x04, 0x02, 0xa2, 0x67, 0x06, 0xf1, + 0x38, 0x00, 0x00, 0xe0, 0x00, 0x20, 0xe0, 0x63, 0x01, 0x20, 0x88, 0x40, + 0x06, 0xf1, 0x34, 0x01, 0x21, 0x64, 0x60, 0x64, 0x70, 0x63, 0x30, 0x60, + 0x31, 0x6c, 0x08, 0x43, 0x30, 0x64, 0x00, 0x22, 0x03, 0x21, 0x40, 0xf2, + 0x05, 0x10, 0xfa, 0xf7, 0x31, 0xfc, 0x00, 0x21, 0x4f, 0xf4, 0x82, 0x70, + 0xfa, 0xf7, 0x22, 0xfc, 0xdf, 0xf8, 0xb4, 0x0b, 0x00, 0x78, 0x60, 0x70, + 0x29, 0x7e, 0xc9, 0x07, 0x48, 0xbf, 0x40, 0xf0, 0xc0, 0x00, 0x20, 0x70, + 0x00, 0xf0, 0x10, 0xf9, 0x05, 0xf0, 0x58, 0xfd, 0xd4, 0xf8, 0x80, 0x00, + 0xdf, 0xf8, 0x98, 0x1b, 0x20, 0xf0, 0x70, 0x00, 0xc4, 0xf8, 0x80, 0x00, + 0x00, 0x20, 0x08, 0x70, 0x1f, 0x20, 0xbd, 0xe8, 0xf2, 0x43, 0xff, 0xf7, + 0x78, 0xbb, 0xdf, 0xf8, 0x84, 0x0b, 0x01, 0x79, 0x01, 0x29, 0x0c, 0xbf, + 0x02, 0x21, 0x00, 0x21, 0x01, 0x71, 0x00, 0x20, 0x70, 0x47, 0x10, 0xb5, + 0xdf, 0xf8, 0xec, 0x47, 0x20, 0x79, 0x02, 0x28, 0x6d, 0xd1, 0xdf, 0xf8, + 0x68, 0x0b, 0x01, 0x68, 0x21, 0xf0, 0xc0, 0x01, 0x01, 0x60, 0x41, 0x68, + 0x21, 0xf0, 0xc0, 0x01, 0x41, 0x60, 0xdf, 0xf8, 0x58, 0x0b, 0x01, 0x68, + 0x21, 0xf4, 0xc0, 0x11, 0x01, 0x60, 0x41, 0x68, 0x21, 0xf4, 0xc0, 0x11, + 0x41, 0x60, 0xdf, 0xf8, 0xf8, 0x16, 0xc9, 0x78, 0x01, 0x29, 0x05, 0xd1, + 0x01, 0x68, 0x23, 0x6f, 0x01, 0x22, 0x9a, 0x40, 0x91, 0x43, 0x01, 0x60, + 0x05, 0xf0, 0x07, 0xff, 0x00, 0xf0, 0x60, 0xf8, 0x00, 0x20, 0xa0, 0x65, + 0x20, 0x66, 0x0c, 0x20, 0xff, 0xf7, 0x3f, 0xfb, 0x0a, 0x20, 0xff, 0xf7, + 0x3c, 0xfb, 0x1d, 0x20, 0xff, 0xf7, 0x39, 0xfb, 0x00, 0xf0, 0x45, 0xf8, + 0x00, 0x20, 0xa0, 0x64, 0x20, 0x65, 0x0d, 0x20, 0xff, 0xf7, 0x31, 0xfb, + 0x0b, 0x20, 0xff, 0xf7, 0x2e, 0xfb, 0x1e, 0x20, 0xff, 0xf7, 0x2b, 0xfb, + 0x00, 0xf0, 0x51, 0xf8, 0xa0, 0x66, 0x1f, 0x20, 0xff, 0xf7, 0x25, 0xfb, + 0xdf, 0xf8, 0xd8, 0x1a, 0x01, 0x20, 0x08, 0x70, 0x10, 0x20, 0xff, 0xf7, + 0x18, 0xfb, 0x0a, 0x20, 0xff, 0xf7, 0x15, 0xfb, 0x1d, 0x20, 0xff, 0xf7, + 0x12, 0xfb, 0x0c, 0x20, 0xff, 0xf7, 0x0f, 0xfb, 0x0b, 0x20, 0xff, 0xf7, + 0x0c, 0xfb, 0x1e, 0x20, 0xff, 0xf7, 0x09, 0xfb, 0x0d, 0x20, 0xff, 0xf7, + 0x06, 0xfb, 0x1f, 0x20, 0xff, 0xf7, 0x03, 0xfb, 0x06, 0xf0, 0x7b, 0xfc, + 0x00, 0x20, 0xff, 0xf7, 0xa1, 0xfa, 0xff, 0xf7, 0x5d, 0xfa, 0x07, 0x22, + 0x04, 0xf1, 0x8c, 0x01, 0x0f, 0xf6, 0xfc, 0x20, 0xfa, 0xf7, 0xa6, 0xfb, + 0x04, 0xe0, 0x00, 0x20, 0xff, 0xf7, 0x94, 0xfa, 0xff, 0xf7, 0x50, 0xfa, + 0x00, 0x20, 0x20, 0x71, 0x10, 0xbd, 0x04, 0xf1, 0x48, 0x00, 0xe0, 0x60, + 0x04, 0xf1, 0x4c, 0x00, 0x20, 0x61, 0x04, 0xf1, 0x50, 0x00, 0xa0, 0x61, + 0x04, 0xf1, 0x54, 0x00, 0xe0, 0x61, 0x70, 0x47, 0x04, 0xf1, 0x58, 0x00, + 0x60, 0x62, 0x04, 0xf1, 0x5c, 0x00, 0xa0, 0x62, 0x04, 0xf1, 0x60, 0x00, + 0x20, 0x63, 0x04, 0xf1, 0x64, 0x00, 0x60, 0x63, 0x70, 0x47, 0x04, 0xf1, + 0x68, 0x00, 0xe0, 0x63, 0x04, 0xf1, 0x6c, 0x00, 0x20, 0x64, 0x00, 0x20, + 0x60, 0x67, 0x01, 0x20, 0xa0, 0x67, 0x02, 0x20, 0xe0, 0x67, 0x00, 0x20, + 0x70, 0x47, 0x38, 0xb5, 0xdf, 0xf8, 0xe0, 0x45, 0xdf, 0xf8, 0xa0, 0x16, + 0x20, 0x7b, 0x89, 0x79, 0xdf, 0xf8, 0xb8, 0x56, 0x20, 0xea, 0x01, 0x01, + 0x40, 0xf6, 0x84, 0x50, 0xfa, 0xf7, 0x48, 0xfb, 0x60, 0x7b, 0xa9, 0x78, + 0x20, 0xea, 0x01, 0x01, 0x40, 0xf6, 0x85, 0x50, 0xfa, 0xf7, 0x40, 0xfb, + 0xa0, 0x7b, 0xe9, 0x78, 0x20, 0xea, 0x01, 0x01, 0x40, 0xf6, 0x86, 0x50, + 0xfa, 0xf7, 0x38, 0xfb, 0x00, 0x21, 0x4f, 0xf4, 0x01, 0x70, 0xfa, 0xf7, + 0x33, 0xfb, 0x00, 0x21, 0x40, 0xf2, 0x05, 0x20, 0xfa, 0xf7, 0x2e, 0xfb, + 0xbd, 0xe8, 0x34, 0x40, 0x00, 0x21, 0x40, 0xf2, 0x06, 0x20, 0xfa, 0xf7, + 0x27, 0xbb, 0x38, 0xb5, 0xdf, 0xf8, 0x64, 0x46, 0xdf, 0xf8, 0xcc, 0x59, + 0x21, 0x78, 0x28, 0x7c, 0x20, 0xea, 0x01, 0x01, 0x40, 0xf6, 0x89, 0x50, + 0xfa, 0xf7, 0x1a, 0xfb, 0x68, 0x7c, 0x61, 0x78, 0x20, 0xea, 0x01, 0x01, + 0x40, 0xf6, 0x8a, 0x50, 0xfa, 0xf7, 0x12, 0xfb, 0x00, 0x21, 0x40, 0xf2, + 0x09, 0x20, 0xfa, 0xf7, 0x0d, 0xfb, 0xbd, 0xe8, 0x34, 0x40, 0x00, 0x21, + 0x40, 0xf2, 0x0a, 0x20, 0xfa, 0xf7, 0x06, 0xbb, 0x80, 0xb5, 0xdf, 0xf8, + 0x04, 0x16, 0xdf, 0xf8, 0x3c, 0x05, 0xc9, 0x79, 0x40, 0x69, 0xc9, 0x43, + 0x01, 0x40, 0xc9, 0xb2, 0x40, 0xf6, 0x87, 0x50, 0xfa, 0xf7, 0xf8, 0xfa, + 0xbd, 0xe8, 0x04, 0x40, 0x00, 0x21, 0x40, 0xf2, 0x07, 0x20, 0xfa, 0xf7, + 0xf1, 0xba, 0xf8, 0xb5, 0x00, 0x24, 0x0f, 0xf6, 0x18, 0x25, 0x0f, 0xf6, + 0x10, 0x26, 0xa0, 0x5d, 0xfb, 0xf7, 0x36, 0xfe, 0x30, 0xb1, 0x20, 0x46, + 0x01, 0xf0, 0x6d, 0xfd, 0x10, 0xb9, 0x20, 0x46, 0x05, 0xf0, 0xb3, 0xf9, + 0x60, 0x5d, 0xfb, 0xf7, 0x2b, 0xfe, 0x10, 0xb1, 0x20, 0x46, 0xfd, 0xf7, + 0x62, 0xfe, 0x64, 0x1c, 0x02, 0x2c, 0xea, 0xd3, 0x04, 0xf0, 0xa1, 0xfa, + 0x08, 0xb1, 0x04, 0xf0, 0xa2, 0xfa, 0xdf, 0xf8, 0xd8, 0x44, 0xe0, 0x78, + 0x01, 0x28, 0x43, 0xd1, 0x00, 0x20, 0x01, 0xf0, 0xef, 0xf9, 0x00, 0x1f, + 0x0c, 0x28, 0x3b, 0xd2, 0x01, 0x20, 0x01, 0xf0, 0xe9, 0xf9, 0x05, 0x46, + 0x02, 0x20, 0x01, 0xf0, 0xe5, 0xf9, 0x06, 0x46, 0x03, 0x20, 0x01, 0xf0, + 0xe1, 0xf9, 0x04, 0x2d, 0xb8, 0xbf, 0x00, 0x21, 0x07, 0xdb, 0x10, 0x2d, + 0xb8, 0xbf, 0x01, 0x21, 0x03, 0xdb, 0x13, 0x2d, 0xb4, 0xbf, 0x02, 0x21, + 0x03, 0x21, 0x04, 0x2e, 0xb8, 0xbf, 0x00, 0x22, 0x07, 0xdb, 0x10, 0x2e, + 0xb8, 0xbf, 0x01, 0x22, 0x03, 0xdb, 0x13, 0x2e, 0xb4, 0xbf, 0x02, 0x22, + 0x03, 0x22, 0x04, 0x28, 0xb8, 0xbf, 0x00, 0x23, 0x07, 0xdb, 0x10, 0x28, + 0xb8, 0xbf, 0x01, 0x23, 0x03, 0xdb, 0x13, 0x28, 0xb4, 0xbf, 0x02, 0x23, + 0x03, 0x23, 0x03, 0x29, 0x0a, 0xd2, 0x91, 0x42, 0x08, 0xbf, 0x99, 0x42, + 0x06, 0xd1, 0x02, 0x29, 0x06, 0xd1, 0x10, 0x2d, 0x04, 0xbf, 0x11, 0x2e, + 0x12, 0x28, 0x01, 0xd0, 0x04, 0x20, 0xf2, 0xbd, 0xef, 0xf3, 0x10, 0x86, + 0x72, 0xb6, 0xdf, 0xf8, 0x04, 0x55, 0x0f, 0xf6, 0xec, 0x00, 0x07, 0x22, + 0x05, 0xf1, 0x8c, 0x01, 0xfa, 0xf7, 0xad, 0xfa, 0xff, 0xf7, 0xef, 0xfc, + 0xff, 0xf7, 0x71, 0xfd, 0xff, 0xf7, 0xf3, 0xfd, 0x21, 0x7a, 0x4f, 0xf4, + 0xdb, 0x70, 0xfa, 0xf7, 0x71, 0xfa, 0x61, 0x7a, 0x40, 0xf2, 0xb7, 0x10, + 0xfa, 0xf7, 0x6c, 0xfa, 0x08, 0x20, 0xff, 0xf7, 0x67, 0xf9, 0x40, 0xf2, + 0x2f, 0x47, 0x80, 0x22, 0x80, 0x21, 0x38, 0x46, 0xfa, 0xf7, 0x6c, 0xfa, + 0x00, 0x22, 0x80, 0x21, 0x38, 0x46, 0xfa, 0xf7, 0x67, 0xfa, 0xa0, 0x78, + 0x01, 0x28, 0x18, 0xbf, 0x00, 0x20, 0xff, 0xf7, 0x67, 0xf9, 0xff, 0xf7, + 0xa3, 0xfb, 0x01, 0x20, 0x28, 0x71, 0x86, 0xf3, 0x10, 0x88, 0x10, 0x20, + 0xff, 0xf7, 0xb2, 0xf9, 0x28, 0x7a, 0x41, 0x07, 0x48, 0xbf, 0x0c, 0x20, + 0x08, 0xd4, 0xc0, 0x07, 0x44, 0xbf, 0x0a, 0x20, 0xff, 0xf7, 0xa8, 0xf9, + 0x28, 0x7a, 0x80, 0x07, 0x02, 0xd5, 0x1d, 0x20, 0xff, 0xf7, 0xa2, 0xf9, + 0xdf, 0xf8, 0x68, 0x47, 0x20, 0x78, 0x41, 0x07, 0x48, 0xbf, 0x0d, 0x20, + 0x08, 0xd4, 0xc0, 0x07, 0x44, 0xbf, 0x0b, 0x20, 0xff, 0xf7, 0x96, 0xf9, + 0x20, 0x78, 0x80, 0x07, 0x02, 0xd5, 0x1e, 0x20, 0xff, 0xf7, 0x90, 0xf9, + 0x1f, 0x20, 0xff, 0xf7, 0x8d, 0xf9, 0x06, 0xf0, 0xc5, 0xfa, 0x00, 0x20, + 0xf2, 0xbd, 0x2d, 0xe9, 0xf0, 0x41, 0x4f, 0xf0, 0x92, 0x45, 0xdf, 0xf8, + 0x3c, 0x64, 0x28, 0x68, 0x69, 0x68, 0x6f, 0x68, 0x4f, 0xea, 0x11, 0x28, + 0x31, 0x79, 0x00, 0x24, 0x01, 0x29, 0x04, 0xbf, 0x00, 0xf0, 0x3f, 0x00, + 0x0a, 0x28, 0x63, 0xd1, 0x00, 0x21, 0xff, 0xf7, 0x53, 0xfa, 0xff, 0xb2, + 0x61, 0x2f, 0xdf, 0xf8, 0xa0, 0x07, 0x40, 0xd0, 0x64, 0x2f, 0x04, 0xbf, + 0x80, 0x78, 0x00, 0x28, 0x56, 0xd1, 0xd6, 0xf8, 0x80, 0x00, 0x08, 0xf0, + 0x0f, 0x08, 0x88, 0xea, 0x00, 0x07, 0xf8, 0x07, 0x0b, 0xd5, 0x71, 0x6a, + 0x08, 0xf0, 0x01, 0x00, 0xc0, 0x01, 0x08, 0x60, 0x01, 0x24, 0xb1, 0x6a, + 0xf0, 0x6a, 0x08, 0x60, 0x0a, 0x20, 0xff, 0xf7, 0x64, 0xf9, 0xb8, 0x07, + 0x0b, 0xd5, 0x31, 0x6b, 0x08, 0xf0, 0x02, 0x00, 0x80, 0x04, 0x08, 0x60, + 0x01, 0x24, 0x71, 0x6b, 0xb0, 0x6b, 0x08, 0x60, 0x1d, 0x20, 0xff, 0xf7, + 0x56, 0xf9, 0x78, 0x07, 0x0b, 0xd5, 0xf1, 0x68, 0x08, 0xf0, 0x04, 0x00, + 0x00, 0x01, 0x08, 0x60, 0x01, 0x24, 0x31, 0x69, 0x70, 0x69, 0x08, 0x60, + 0x0b, 0x20, 0xff, 0xf7, 0x48, 0xf9, 0x38, 0x07, 0x1c, 0xd5, 0xb1, 0x69, + 0x08, 0xf0, 0x08, 0x00, 0x40, 0x04, 0x08, 0x60, 0xf1, 0x69, 0x30, 0x6a, + 0x08, 0x60, 0x1e, 0x20, 0x0f, 0xe0, 0xc0, 0x78, 0xc0, 0xb9, 0xf1, 0x6b, + 0x08, 0xf0, 0x07, 0x00, 0x08, 0x60, 0x04, 0x28, 0x32, 0x6c, 0x71, 0x6c, + 0x11, 0x60, 0x04, 0xbf, 0xc8, 0xf3, 0x01, 0x10, 0x00, 0xf0, 0xf3, 0xfa, + 0x1f, 0x20, 0xff, 0xf7, 0x2a, 0xf9, 0x00, 0xe0, 0x5c, 0xb1, 0x00, 0x20, + 0x28, 0x60, 0x0a, 0x20, 0xbd, 0xe8, 0xf0, 0x41, 0xfb, 0xf7, 0x1b, 0xbc, + 0xbd, 0xe8, 0xf0, 0x41, 0x0f, 0x20, 0xff, 0xf7, 0x1c, 0xb9, 0xbd, 0xe8, + 0xf0, 0x81, 0x10, 0xb5, 0x05, 0xf0, 0xe8, 0xfc, 0x05, 0xf0, 0x1c, 0xfc, + 0xd8, 0x4c, 0x00, 0x20, 0xa0, 0x60, 0x02, 0x20, 0xe0, 0x60, 0x31, 0x20, + 0xff, 0xf7, 0xf8, 0xf8, 0xcb, 0x48, 0x01, 0x21, 0x41, 0x71, 0x84, 0x30, + 0xd1, 0x49, 0x49, 0x68, 0x21, 0x60, 0x70, 0x21, 0xa1, 0x60, 0xbd, 0xe8, + 0x10, 0x40, 0xfa, 0xf7, 0xa3, 0xbc, 0x70, 0xb5, 0x00, 0xf0, 0x8c, 0xf8, + 0x10, 0xd5, 0x30, 0x78, 0x40, 0xf0, 0x40, 0x00, 0x30, 0x70, 0x04, 0x20, + 0xff, 0xf7, 0xae, 0xfa, 0xd5, 0xf8, 0x80, 0x00, 0x40, 0xf0, 0x01, 0x00, + 0xc5, 0xf8, 0x80, 0x00, 0x00, 0x20, 0xc0, 0x46, 0xc0, 0x46, 0x0f, 0xe0, + 0x00, 0x20, 0xc0, 0x46, 0xc0, 0x46, 0x30, 0x78, 0x00, 0xf0, 0xbf, 0x00, + 0x30, 0x70, 0x04, 0x20, 0xff, 0xf7, 0xa4, 0xfa, 0xd5, 0xf8, 0x80, 0x00, + 0x40, 0x08, 0x40, 0x00, 0xc5, 0xf8, 0x80, 0x00, 0x62, 0xe0, 0x70, 0xb5, + 0xb1, 0x4c, 0xdf, 0xf8, 0x54, 0x56, 0x61, 0x6b, 0xdf, 0xf8, 0x50, 0x66, + 0x4f, 0xf4, 0x00, 0x20, 0x08, 0x60, 0x4f, 0xf6, 0xfe, 0x60, 0x28, 0x60, + 0x20, 0x6b, 0x00, 0x68, 0x00, 0x03, 0x10, 0xd5, 0x30, 0x78, 0x40, 0xf0, + 0x80, 0x00, 0x30, 0x70, 0x05, 0x20, 0xff, 0xf7, 0x7b, 0xfa, 0xd4, 0xf8, + 0x80, 0x00, 0x40, 0xf0, 0x02, 0x00, 0xc4, 0xf8, 0x80, 0x00, 0x01, 0x20, + 0xc0, 0x46, 0xc0, 0x46, 0x0f, 0xe0, 0x01, 0x20, 0xc0, 0x46, 0xc0, 0x46, + 0x30, 0x78, 0x00, 0xf0, 0x7f, 0x00, 0x30, 0x70, 0x05, 0x20, 0xff, 0xf7, + 0x71, 0xfa, 0xd4, 0xf8, 0x80, 0x00, 0x20, 0xf0, 0x02, 0x00, 0xc4, 0xf8, + 0x80, 0x00, 0x10, 0x20, 0xff, 0xf7, 0xa5, 0xf8, 0x00, 0x20, 0x28, 0x60, + 0x70, 0xbd, 0x70, 0xb5, 0x00, 0xf0, 0x2e, 0xf8, 0x13, 0xd5, 0x30, 0x78, + 0x40, 0xf0, 0xc0, 0x00, 0x30, 0x70, 0x04, 0x20, 0xff, 0xf7, 0x50, 0xfa, + 0x05, 0x20, 0xff, 0xf7, 0x4d, 0xfa, 0xd5, 0xf8, 0x80, 0x00, 0x40, 0xf0, + 0x03, 0x00, 0xc5, 0xf8, 0x80, 0x00, 0x02, 0x20, 0xc0, 0x46, 0xc0, 0x46, + 0x12, 0xe0, 0x02, 0x20, 0xc0, 0x46, 0xc0, 0x46, 0x30, 0x78, 0x00, 0xf0, + 0x3f, 0x00, 0x30, 0x70, 0x04, 0x20, 0xff, 0xf7, 0x43, 0xfa, 0x05, 0x20, + 0xff, 0xf7, 0x40, 0xfa, 0xd5, 0xf8, 0x80, 0x00, 0x80, 0x08, 0x80, 0x00, + 0xc5, 0xf8, 0x80, 0x00, 0x10, 0x20, 0xff, 0xf7, 0x74, 0xf8, 0x00, 0x20, + 0x20, 0x60, 0x70, 0xbd, 0xdf, 0xf8, 0x84, 0x45, 0x7c, 0x4d, 0xdf, 0xf8, + 0x84, 0x65, 0x4f, 0xf6, 0xfe, 0x60, 0x20, 0x60, 0x80, 0x20, 0xa9, 0x6a, + 0x08, 0x60, 0x68, 0x6a, 0x00, 0x68, 0x00, 0x06, 0x70, 0x47, 0x38, 0xb5, + 0x00, 0xf0, 0x75, 0xf8, 0x0c, 0xd5, 0x41, 0xf0, 0x10, 0x01, 0x01, 0x70, + 0x06, 0x20, 0xff, 0xf7, 0x11, 0xfa, 0xd5, 0xf8, 0x80, 0x00, 0x40, 0xf0, + 0x04, 0x00, 0x00, 0xf0, 0x3f, 0xf8, 0x0b, 0xe0, 0x01, 0xf0, 0xef, 0x01, + 0x01, 0x70, 0x06, 0x20, 0xff, 0xf7, 0x0e, 0xfa, 0xd5, 0xf8, 0x80, 0x00, + 0x20, 0xf0, 0x04, 0x00, 0xc5, 0xf8, 0x80, 0x00, 0x2a, 0xe0, 0x38, 0xb5, + 0xdf, 0xf8, 0x28, 0x45, 0x65, 0x4d, 0x4f, 0xf6, 0xfe, 0x60, 0x20, 0x60, + 0x4f, 0xf4, 0x80, 0x10, 0xe9, 0x69, 0x08, 0x60, 0xa9, 0x69, 0xdf, 0xf8, + 0x18, 0x05, 0x09, 0x68, 0xc9, 0x02, 0x01, 0x78, 0x0c, 0xd5, 0x41, 0xf0, + 0x20, 0x01, 0x01, 0x70, 0x07, 0x20, 0xff, 0xf7, 0xe5, 0xf9, 0xd5, 0xf8, + 0x80, 0x00, 0x40, 0xf0, 0x08, 0x00, 0x00, 0xf0, 0x13, 0xf8, 0x0b, 0xe0, + 0x01, 0xf0, 0xdf, 0x01, 0x01, 0x70, 0x07, 0x20, 0xff, 0xf7, 0xe2, 0xf9, + 0xd5, 0xf8, 0x80, 0x00, 0x20, 0xf0, 0x08, 0x00, 0xc5, 0xf8, 0x80, 0x00, + 0x10, 0x20, 0xff, 0xf7, 0x16, 0xf8, 0x00, 0x20, 0x20, 0x60, 0x31, 0xbd, + 0xc5, 0xf8, 0x80, 0x00, 0x0e, 0x20, 0xff, 0xf7, 0x0e, 0xb8, 0x38, 0xb5, + 0x00, 0xf0, 0x21, 0xf8, 0x0f, 0xd5, 0x41, 0xf0, 0x30, 0x01, 0x01, 0x70, + 0x06, 0x20, 0xff, 0xf7, 0xbd, 0xf9, 0x07, 0x20, 0xff, 0xf7, 0xba, 0xf9, + 0xd5, 0xf8, 0x80, 0x00, 0x40, 0xf0, 0x0c, 0x00, 0xff, 0xf7, 0xe8, 0xff, + 0x0e, 0xe0, 0x01, 0xf0, 0xcf, 0x01, 0x01, 0x70, 0x06, 0x20, 0xff, 0xf7, + 0xb7, 0xf9, 0x07, 0x20, 0xff, 0xf7, 0xb4, 0xf9, 0xd5, 0xf8, 0x80, 0x00, + 0x20, 0xf0, 0x0c, 0x00, 0xc5, 0xf8, 0x80, 0x00, 0xd0, 0xe7, 0xdf, 0xf8, + 0x78, 0x44, 0x39, 0x4d, 0x4f, 0xf6, 0xfe, 0x60, 0x20, 0x60, 0x40, 0x20, + 0x29, 0x69, 0x08, 0x60, 0xe9, 0x68, 0xdf, 0xf8, 0x68, 0x04, 0x09, 0x68, + 0x49, 0x06, 0x01, 0x78, 0x70, 0x47, 0x00, 0x00, 0x18, 0x00, 0x00, 0x49, + 0x4c, 0x1f, 0x00, 0x20, 0x00, 0xf2, 0x00, 0x20, 0x40, 0x42, 0x0f, 0x00, + 0xf8, 0xb5, 0x2d, 0x48, 0x02, 0x6c, 0x41, 0x6c, 0x11, 0x60, 0xd0, 0xf8, + 0x80, 0x10, 0xc1, 0xf3, 0x02, 0x14, 0xc1, 0x6b, 0x91, 0xb1, 0x09, 0x68, + 0x42, 0x6f, 0x21, 0xfa, 0x02, 0xf3, 0x82, 0x6f, 0x21, 0xfa, 0x02, 0xf5, + 0x05, 0xf0, 0x01, 0x02, 0x5b, 0x08, 0xc3, 0x6f, 0x52, 0x41, 0xd9, 0x40, + 0x01, 0xf0, 0x01, 0x01, 0x42, 0xea, 0x81, 0x05, 0xed, 0xb2, 0x04, 0xe0, + 0xdf, 0xf8, 0x10, 0x14, 0x09, 0x78, 0x01, 0xf0, 0x07, 0x05, 0xac, 0x42, + 0x35, 0xd0, 0xd0, 0xf8, 0x80, 0x10, 0xdf, 0xf8, 0xf8, 0x63, 0x21, 0xf0, + 0x70, 0x01, 0x41, 0xea, 0x05, 0x11, 0xc0, 0xf8, 0x80, 0x10, 0x10, 0x20, + 0xfe, 0xf7, 0x9f, 0xff, 0x4f, 0xf6, 0xfe, 0x60, 0x30, 0x60, 0xdf, 0xf8, + 0xd8, 0x03, 0x00, 0x7e, 0xc0, 0x07, 0x03, 0xd5, 0xdf, 0xf8, 0xb8, 0x03, + 0x00, 0xf0, 0x83, 0xf8, 0xdf, 0xf8, 0xd4, 0x73, 0x0f, 0xf2, 0x50, 0x41, + 0x38, 0x78, 0x00, 0xf0, 0xef, 0x00, 0x38, 0x70, 0x20, 0x46, 0x51, 0xf8, + 0x24, 0x10, 0x88, 0x47, 0x0f, 0xf2, 0x1c, 0x41, 0x51, 0xf8, 0x25, 0x10, + 0x28, 0x46, 0x88, 0x47, 0x38, 0x78, 0x40, 0xf0, 0x10, 0x00, 0x38, 0x70, + 0x00, 0x20, 0x30, 0x60, 0x1c, 0x20, 0xbd, 0xe8, 0xf2, 0x40, 0xfe, 0xf7, + 0x76, 0xbf, 0xf1, 0xbd, 0xd0, 0x1f, 0x00, 0x20, 0xdf, 0xf8, 0x98, 0x03, + 0xdf, 0xf8, 0x98, 0x23, 0x01, 0x78, 0x92, 0xf8, 0x6b, 0x20, 0x01, 0xf0, + 0xe0, 0x01, 0x11, 0x43, 0x41, 0xf0, 0x20, 0x01, 0x01, 0x70, 0x70, 0x47, + 0x30, 0xf3, 0x00, 0x20, 0x00, 0x00, 0x20, 0x59, 0xdf, 0xf8, 0x7c, 0x13, + 0x00, 0x20, 0x08, 0x70, 0xdf, 0xf8, 0x78, 0x13, 0x08, 0x80, 0x70, 0x47, + 0x70, 0x47, 0x10, 0xb5, 0x00, 0xf0, 0x2b, 0xf8, 0x00, 0xf0, 0x65, 0xf8, + 0xa4, 0x7c, 0x00, 0xf0, 0x69, 0xf8, 0x49, 0x7d, 0x81, 0x70, 0x01, 0x21, + 0x11, 0x70, 0xd4, 0x4a, 0x41, 0x79, 0x00, 0xf0, 0x54, 0xf8, 0x41, 0x71, + 0x01, 0x20, 0x11, 0xe0, 0xb4, 0x28, 0x00, 0x20, 0x10, 0xb5, 0x00, 0xf0, + 0x16, 0xf8, 0x00, 0xf0, 0x75, 0xf8, 0xa4, 0x7c, 0x23, 0x43, 0x03, 0x70, + 0x09, 0x78, 0x89, 0x18, 0x49, 0x7d, 0x81, 0x70, 0x01, 0x20, 0x00, 0xf0, + 0x68, 0xf8, 0x05, 0x20, 0x05, 0xf0, 0x67, 0xf9, 0x00, 0xf0, 0x1d, 0xf9, + 0x08, 0x20, 0xbd, 0xe8, 0x10, 0x40, 0xff, 0xf7, 0xe3, 0xb8, 0xc6, 0x48, + 0xc6, 0x4a, 0x01, 0x79, 0x01, 0xf0, 0x7f, 0x01, 0x01, 0x71, 0x70, 0x47, + 0x0c, 0x00, 0x00, 0x59, 0x80, 0xb5, 0x00, 0xe0, 0x80, 0xb5, 0x05, 0xf0, + 0x85, 0xf9, 0xc1, 0x48, 0x81, 0x78, 0x41, 0xf0, 0x80, 0x01, 0x81, 0x70, + 0x00, 0xf0, 0x05, 0xf8, 0x08, 0x20, 0xbd, 0xe8, 0x02, 0x40, 0xff, 0xf7, + 0xd3, 0xb8, 0x01, 0x78, 0x41, 0xf0, 0xc0, 0x01, 0x01, 0x70, 0x70, 0x47, + 0x10, 0xb5, 0x00, 0xf0, 0x49, 0xf8, 0x00, 0xf0, 0x18, 0xf8, 0x24, 0x7e, + 0x00, 0xf0, 0x1c, 0xf8, 0xc9, 0x7e, 0x81, 0x70, 0x02, 0x21, 0x11, 0x70, + 0xad, 0x4a, 0x01, 0x79, 0x00, 0xf0, 0x07, 0xf8, 0x01, 0x71, 0x02, 0x20, + 0x05, 0xf0, 0x2d, 0xf9, 0x00, 0xf0, 0x42, 0xf8, 0xc5, 0xe7, 0x92, 0xf8, + 0x43, 0x20, 0x01, 0xf0, 0xc0, 0x01, 0x11, 0x43, 0x70, 0x47, 0xab, 0x49, + 0x03, 0x78, 0x0c, 0x78, 0xa4, 0x18, 0x03, 0xf0, 0xc0, 0x03, 0x70, 0x47, + 0x23, 0x43, 0x03, 0x70, 0x09, 0x78, 0x89, 0x18, 0xa0, 0x4a, 0x70, 0x47, + 0x10, 0xb5, 0x00, 0xf0, 0x1f, 0xf8, 0x00, 0xf0, 0x13, 0xf8, 0x24, 0x7e, + 0x23, 0x43, 0x03, 0x70, 0x09, 0x78, 0x89, 0x18, 0xc9, 0x7e, 0x81, 0x70, + 0x02, 0x20, 0x00, 0xf0, 0x06, 0xf8, 0x06, 0x20, 0x05, 0xf0, 0x05, 0xf9, + 0x00, 0xf0, 0x1a, 0xf8, 0x9d, 0xe7, 0x95, 0x49, 0x08, 0x70, 0x55, 0xe7, + 0x99, 0x49, 0x03, 0x78, 0x0c, 0x78, 0xa4, 0x18, 0x03, 0xf0, 0xc0, 0x03, + 0x70, 0x47, 0x00, 0x00, 0x78, 0x29, 0x00, 0x20, 0x95, 0x48, 0x91, 0x4a, + 0xc1, 0x78, 0x01, 0xf0, 0xbf, 0x01, 0xc1, 0x70, 0x70, 0x47, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x50, 0x04, 0x00, 0x00, 0x58, 0x7c, 0x48, 0x01, 0x78, + 0x01, 0xf0, 0x3f, 0x01, 0x01, 0x70, 0x09, 0x20, 0x70, 0x47, 0x80, 0xb5, + 0x05, 0xf0, 0x12, 0xf9, 0x00, 0xf0, 0x07, 0xf8, 0x91, 0xe7, 0x80, 0xb5, + 0x05, 0xf0, 0x0c, 0xf9, 0x00, 0xf0, 0x01, 0xf8, 0x8b, 0xe7, 0x87, 0x48, + 0x41, 0x78, 0x41, 0xf0, 0x40, 0x01, 0x41, 0x70, 0x01, 0x78, 0x41, 0xf0, + 0xc0, 0x01, 0x01, 0x70, 0x09, 0x20, 0x70, 0x47, 0x10, 0xb5, 0x79, 0x49, + 0x7a, 0x4a, 0x00, 0x20, 0x08, 0x70, 0x7a, 0x49, 0x7b, 0x48, 0x13, 0x78, + 0x00, 0xf0, 0x1c, 0xf8, 0xa4, 0x7c, 0x23, 0x43, 0x13, 0x70, 0x93, 0x78, + 0x00, 0xf0, 0x16, 0xf8, 0x64, 0x7d, 0x23, 0x43, 0x93, 0x70, 0x53, 0x78, + 0x00, 0xf0, 0x10, 0xf8, 0x24, 0x7e, 0x23, 0x43, 0x53, 0x70, 0xd3, 0x78, + 0x00, 0x78, 0x40, 0x18, 0x03, 0xf0, 0xc0, 0x03, 0xc0, 0x7e, 0x18, 0x43, + 0xd0, 0x70, 0x10, 0xbd, 0x08, 0x00, 0x00, 0x50, 0x08, 0x00, 0x00, 0x58, + 0x04, 0x78, 0x64, 0x18, 0x03, 0xf0, 0xc0, 0x03, 0x70, 0x47, 0x80, 0xb5, + 0x05, 0xf0, 0xd0, 0xf8, 0x6b, 0x48, 0xff, 0xf7, 0x54, 0xff, 0x41, 0x78, + 0x41, 0xf0, 0xc0, 0x01, 0x41, 0x70, 0x63, 0x49, 0x8a, 0x78, 0x42, 0xf0, + 0xc0, 0x02, 0x8a, 0x70, 0x0a, 0x78, 0x42, 0xf0, 0xc0, 0x02, 0x0a, 0x70, + 0x4a, 0x78, 0x42, 0xf0, 0xc0, 0x02, 0x4a, 0x70, 0x81, 0x79, 0x01, 0xf0, + 0xcc, 0x01, 0x81, 0x71, 0x60, 0x48, 0x61, 0x49, 0x0a, 0x78, 0x03, 0x78, + 0x1a, 0x40, 0x83, 0x78, 0x1a, 0x43, 0x0a, 0x70, 0x4a, 0x78, 0x43, 0x78, + 0x1a, 0x40, 0xc3, 0x78, 0x1a, 0x43, 0x4a, 0x70, 0x01, 0x21, 0x41, 0x60, + 0x81, 0x60, 0x00, 0x20, 0x42, 0x49, 0x08, 0x70, 0x01, 0xbd, 0x08, 0xb1, + 0x57, 0x49, 0x08, 0x70, 0x70, 0x47, 0x56, 0x48, 0x00, 0x78, 0x70, 0x47, + 0x80, 0xb5, 0x55, 0x48, 0x53, 0x4a, 0x81, 0x79, 0x46, 0x4b, 0x01, 0xf0, + 0x7f, 0x01, 0x81, 0x71, 0x41, 0x79, 0x01, 0xf0, 0x3f, 0x01, 0x41, 0x71, + 0x12, 0x78, 0x0f, 0xf2, 0xa4, 0x11, 0x51, 0x5c, 0x4e, 0x4a, 0x11, 0x70, + 0x04, 0x22, 0x1a, 0x70, 0x01, 0x70, 0xff, 0xf7, 0xa9, 0xfe, 0x04, 0x20, + 0x05, 0xf0, 0x4f, 0xf8, 0x00, 0xf0, 0x05, 0xf8, 0x0a, 0x20, 0xbd, 0xe8, + 0x02, 0x40, 0xfe, 0xf7, 0xcb, 0xbf, 0x2c, 0x48, 0x01, 0x78, 0x01, 0xf0, + 0x3f, 0x01, 0x01, 0x70, 0x70, 0x47, 0x80, 0xb5, 0x05, 0xf0, 0x72, 0xf8, + 0x40, 0x48, 0x00, 0x21, 0x01, 0x70, 0x81, 0x79, 0x41, 0xf0, 0x80, 0x01, + 0x81, 0x71, 0x41, 0x79, 0x41, 0xf0, 0xc0, 0x01, 0x41, 0x71, 0x0a, 0x20, + 0xe7, 0xe6, 0x00, 0x00, 0x64, 0xf3, 0x00, 0x20, 0x0c, 0x00, 0x00, 0x58, + 0x44, 0x00, 0x00, 0x50, 0x2d, 0xe9, 0xf0, 0x47, 0x04, 0x46, 0x91, 0x46, + 0x9a, 0x46, 0xfe, 0xf7, 0xa1, 0xff, 0x1c, 0x4f, 0x80, 0x46, 0x38, 0x79, + 0x01, 0x28, 0x25, 0xd1, 0x02, 0x2c, 0x21, 0xd1, 0xfe, 0xf7, 0x98, 0xff, + 0x30, 0x4e, 0x31, 0x49, 0x35, 0x68, 0x04, 0x46, 0x4f, 0xf0, 0x00, 0x40, + 0x08, 0x60, 0xd7, 0xf8, 0x80, 0x00, 0xc0, 0xf3, 0x02, 0x10, 0x03, 0x28, + 0x18, 0xbf, 0x04, 0x28, 0x09, 0xd0, 0x05, 0x28, 0x18, 0xbf, 0x06, 0x28, + 0x05, 0xd0, 0x02, 0x22, 0x48, 0x46, 0x51, 0x46, 0x03, 0xf0, 0xc4, 0xfc, + 0x00, 0xe0, 0x05, 0x20, 0x05, 0xf0, 0x00, 0x41, 0x31, 0x60, 0x84, 0xf3, + 0x11, 0x88, 0x06, 0xe0, 0x05, 0x20, 0x04, 0xe0, 0x22, 0x46, 0x48, 0x46, + 0x51, 0x46, 0x03, 0xf0, 0xb5, 0xfc, 0x88, 0xf3, 0x11, 0x88, 0xc0, 0xb2, + 0xbd, 0xe8, 0xf0, 0x87, 0x41, 0x0c, 0x00, 0x46, 0x65, 0x2c, 0x00, 0x20, + 0xd0, 0x1f, 0x00, 0x20, 0x4c, 0x00, 0x00, 0x50, 0x4c, 0x00, 0x00, 0x58, + 0x4c, 0x1f, 0x00, 0x20, 0x48, 0x00, 0x00, 0x50, 0xb0, 0x01, 0x00, 0x46, + 0x28, 0x0b, 0x00, 0x46, 0x42, 0x06, 0x00, 0x46, 0x15, 0x08, 0x00, 0x46, + 0x68, 0xee, 0x00, 0x20, 0x04, 0x01, 0x00, 0x46, 0xfe, 0x01, 0x00, 0x41, + 0x10, 0x08, 0x00, 0x46, 0x4c, 0x29, 0x00, 0x20, 0x12, 0x08, 0x00, 0x46, + 0x6c, 0x29, 0x00, 0x20, 0x6d, 0x29, 0x00, 0x20, 0x11, 0x08, 0x00, 0x46, + 0x13, 0x08, 0x00, 0x46, 0x42, 0x05, 0x00, 0x46, 0xec, 0x2b, 0x00, 0x20, + 0x02, 0x0b, 0x00, 0x46, 0x64, 0x2c, 0x00, 0x20, 0x1a, 0x08, 0x00, 0x46, + 0x0c, 0x02, 0x00, 0x46, 0x00, 0xe1, 0x00, 0xe0, 0x80, 0xe1, 0x00, 0xe0, + 0x04, 0x02, 0x84, 0x0d, 0x05, 0x02, 0x85, 0x0d, 0x06, 0x02, 0x86, 0x0d, + 0x41, 0x0c, 0x00, 0x00, 0x45, 0x90, 0x00, 0x01, 0x57, 0x90, 0x00, 0x01, + 0xf1, 0x90, 0x00, 0x01, 0xdd, 0x91, 0x00, 0x01, 0xa1, 0x92, 0x00, 0x01, + 0x81, 0x90, 0x00, 0x01, 0x45, 0x91, 0x00, 0x01, 0x45, 0x90, 0x00, 0x01, + 0x55, 0x90, 0x00, 0x01, 0xc5, 0x90, 0x00, 0x01, 0xaf, 0x91, 0x00, 0x01, + 0x33, 0x92, 0x00, 0x01, 0xef, 0x92, 0x00, 0x01, 0xc9, 0x90, 0x00, 0x01, + 0xbb, 0x91, 0x00, 0x01, 0x55, 0x90, 0x00, 0x01, 0x08, 0x09, 0x00, 0x00, + 0x0c, 0x0d, 0x00, 0x00, 0x00, 0x03, 0x0c, 0x30, 0x0f, 0xf2, 0x2c, 0x02, + 0x00, 0xf0, 0x1f, 0x00, 0x80, 0x5c, 0x08, 0xb9, 0x03, 0x20, 0x70, 0x47, + 0x01, 0x22, 0x02, 0xfa, 0x01, 0xf1, 0x08, 0x42, 0x14, 0xbf, 0x00, 0x20, + 0x02, 0x20, 0x70, 0x47, 0x0f, 0xf2, 0x1c, 0x02, 0x06, 0x23, 0x03, 0xfb, + 0x00, 0x20, 0x08, 0x5c, 0x70, 0x47, 0x00, 0x00, 0x0c, 0x18, 0x1c, 0x1c, + 0x18, 0x3e, 0x3e, 0x18, 0x00, 0x3e, 0x1c, 0x3e, 0x3e, 0x0c, 0x00, 0x00, + 0x02, 0x00, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x80, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x02, 0x02, 0x00, 0x80, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x80, 0xb5, 0x08, 0x46, + 0x6b, 0x46, 0x40, 0x68, 0x01, 0x22, 0x08, 0x21, 0xf8, 0xf7, 0x44, 0xff, + 0x00, 0xf0, 0x01, 0xf8, 0x01, 0xbd, 0x9d, 0xf8, 0x00, 0x10, 0x48, 0x1e, + 0x80, 0x41, 0xc0, 0x0f, 0xfe, 0xf7, 0x9d, 0xbc, 0x70, 0xb5, 0x82, 0xb0, + 0x0d, 0xf1, 0x01, 0x00, 0xfa, 0xf7, 0x47, 0xfa, 0x01, 0x24, 0x67, 0x4d, + 0x58, 0x20, 0x00, 0xfb, 0x04, 0x56, 0x33, 0x69, 0x18, 0x00, 0x03, 0xd0, + 0x70, 0x6a, 0x00, 0x22, 0x00, 0x21, 0x98, 0x47, 0x69, 0x46, 0x00, 0x20, + 0xf8, 0xf7, 0x73, 0xfe, 0x70, 0x60, 0xff, 0xf7, 0xe0, 0xff, 0x64, 0x1c, + 0x11, 0x2c, 0xeb, 0xd3, 0x05, 0xf0, 0x46, 0xff, 0x0d, 0xf1, 0x01, 0x00, + 0x00, 0xf0, 0xe0, 0xfa, 0x73, 0xbd, 0xf8, 0xb5, 0xfe, 0xf7, 0x70, 0xfe, + 0x00, 0x24, 0x57, 0x4d, 0x57, 0x4e, 0xe0, 0xb2, 0xfb, 0xf7, 0xae, 0xf8, + 0x60, 0xb1, 0xa0, 0x5d, 0x58, 0x21, 0x01, 0xfb, 0x00, 0x57, 0x00, 0xf0, + 0x25, 0xf8, 0x3b, 0x69, 0x18, 0x00, 0x03, 0xd0, 0x78, 0x6a, 0x00, 0x22, + 0x02, 0x21, 0x98, 0x47, 0x64, 0x1c, 0x10, 0x2c, 0xeb, 0xd3, 0xf1, 0xbd, + 0x10, 0xb5, 0x4b, 0x4c, 0x82, 0xb0, 0x60, 0x62, 0x60, 0x68, 0x20, 0xb9, + 0x69, 0x46, 0xf8, 0xf7, 0x42, 0xfe, 0x60, 0x60, 0x03, 0xe0, 0x00, 0xf0, + 0x98, 0xf8, 0xff, 0xf7, 0xac, 0xff, 0x00, 0x20, 0x00, 0xf0, 0x08, 0xf8, + 0x23, 0x69, 0x18, 0x00, 0x03, 0xd0, 0x60, 0x6a, 0x00, 0x22, 0x02, 0x21, + 0x98, 0x47, 0x13, 0xbd, 0x30, 0xb5, 0x04, 0x46, 0x3d, 0x48, 0x58, 0x21, + 0x87, 0xb0, 0x01, 0xfb, 0x04, 0x05, 0xfb, 0xf7, 0x37, 0xf8, 0xc4, 0xb1, + 0x3b, 0x48, 0x20, 0x5c, 0xfb, 0xf7, 0x74, 0xf8, 0x00, 0x28, 0x36, 0xd0, + 0x20, 0x46, 0xfa, 0xf7, 0xfd, 0xfd, 0x05, 0xa9, 0x02, 0x91, 0x00, 0x95, + 0x00, 0x21, 0x01, 0x91, 0x01, 0x46, 0x35, 0x4b, 0x01, 0x22, 0x00, 0x20, + 0xf9, 0xf7, 0xa4, 0xfa, 0xa8, 0x62, 0x9d, 0xf8, 0x14, 0x10, 0xff, 0xf7, + 0x80, 0xff, 0xeb, 0x6b, 0xa8, 0x6c, 0xe9, 0x6c, 0x01, 0x90, 0x03, 0x22, + 0x04, 0x92, 0x02, 0x91, 0x9a, 0xb2, 0x00, 0x92, 0x00, 0xeb, 0x81, 0x00, + 0x03, 0x94, 0x02, 0x1f, 0x69, 0x6a, 0x68, 0x6c, 0xdb, 0xb2, 0xf9, 0xf7, + 0x6c, 0xf9, 0x8d, 0xf8, 0x14, 0x00, 0x00, 0xf0, 0x4d, 0xf8, 0xe8, 0x6b, + 0x29, 0x6c, 0x05, 0xaa, 0xc0, 0xb2, 0xf9, 0xf7, 0x19, 0xfa, 0x9d, 0xf8, + 0x14, 0x10, 0xff, 0xf7, 0x60, 0xff, 0x29, 0x46, 0x20, 0x46, 0xf9, 0xf7, + 0x23, 0xff, 0x00, 0x20, 0x07, 0xb0, 0x30, 0xbd, 0x38, 0xb5, 0x05, 0x46, + 0x18, 0x48, 0x58, 0x21, 0x01, 0xfb, 0x05, 0x04, 0xfa, 0xf7, 0xee, 0xff, + 0x25, 0xb1, 0x17, 0x48, 0x28, 0x5c, 0xfb, 0xf7, 0x2b, 0xf8, 0xf8, 0xb1, + 0x28, 0x46, 0xfa, 0xf7, 0x99, 0xf8, 0xa0, 0x6a, 0x68, 0xb1, 0x6b, 0x46, + 0x00, 0x22, 0x00, 0x21, 0xf9, 0xf7, 0x46, 0xfb, 0xa0, 0x6a, 0x0d, 0xf1, + 0x01, 0x01, 0xf9, 0xf7, 0x99, 0xfa, 0x9d, 0xf8, 0x01, 0x10, 0xff, 0xf7, + 0x38, 0xff, 0x60, 0x68, 0x00, 0xf0, 0x1d, 0xf8, 0xff, 0xf7, 0x31, 0xff, + 0xe0, 0x6b, 0xc0, 0xb2, 0xf9, 0xf7, 0x74, 0xf9, 0x8d, 0xf8, 0x00, 0x00, + 0x00, 0xf0, 0x0e, 0xf8, 0x9d, 0xf8, 0x00, 0x00, 0x00, 0xb1, 0x02, 0x20, + 0x32, 0xbd, 0x00, 0x00, 0xd8, 0x20, 0x00, 0x20, 0xc8, 0x20, 0x00, 0x20, + 0xf4, 0x1e, 0x00, 0x20, 0xf5, 0x94, 0x00, 0x01, 0x40, 0x1e, 0x80, 0x41, + 0xc0, 0x0f, 0xfe, 0xf7, 0xba, 0xbb, 0x6b, 0x46, 0x00, 0x22, 0x4f, 0xf6, + 0xff, 0x71, 0xf8, 0xf7, 0x51, 0xbe, 0x00, 0x00, 0x2c, 0x21, 0xfe, 0xf7, + 0x05, 0xba, 0x00, 0x00, 0x2d, 0xe9, 0xf0, 0x41, 0x88, 0x46, 0x04, 0x46, + 0x00, 0x25, 0xc9, 0xb2, 0x48, 0x09, 0x05, 0x28, 0x01, 0xf0, 0x1f, 0x01, + 0x49, 0xda, 0x0f, 0xf2, 0xac, 0x03, 0x03, 0xeb, 0xc0, 0x02, 0x57, 0x68, + 0x00, 0x2f, 0x42, 0xd0, 0x13, 0xf8, 0x30, 0x30, 0x99, 0x42, 0x3e, 0xda, + 0x23, 0x4b, 0x53, 0xf8, 0x20, 0x60, 0x01, 0x27, 0x07, 0xfa, 0x01, 0xfe, + 0x0e, 0xea, 0x06, 0x06, 0xd3, 0xf8, 0x14, 0xe0, 0x9b, 0x69, 0x07, 0xfa, + 0x00, 0xf0, 0x00, 0xea, 0x0e, 0x00, 0x30, 0x43, 0x43, 0xea, 0x00, 0x07, + 0x50, 0x68, 0x00, 0xeb, 0xc1, 0x06, 0xfb, 0xf7, 0xc2, 0xf9, 0x04, 0x28, + 0x03, 0xd1, 0xf0, 0x88, 0x80, 0xf0, 0x01, 0x00, 0x07, 0x43, 0x00, 0x2c, + 0x1c, 0xbf, 0x00, 0x2f, 0x06, 0x25, 0x1d, 0xd1, 0x30, 0x68, 0xb1, 0x88, + 0x00, 0x28, 0x18, 0xbf, 0x00, 0x29, 0x14, 0xd0, 0x4f, 0xea, 0x08, 0x23, + 0x4f, 0xea, 0x18, 0x62, 0x02, 0xeb, 0x13, 0x46, 0xb1, 0x42, 0x0a, 0xdb, + 0x00, 0xeb, 0x13, 0x40, 0x0b, 0x4b, 0x00, 0x2c, 0x12, 0xbf, 0x19, 0x46, + 0x01, 0x46, 0x18, 0x46, 0x00, 0xf0, 0x6e, 0xfa, 0x04, 0xe0, 0x07, 0x25, + 0x02, 0xe0, 0x05, 0x25, 0x00, 0xe0, 0x04, 0x25, 0x28, 0x46, 0xbd, 0xe8, + 0xf0, 0x81, 0x02, 0x49, 0x00, 0xf0, 0x01, 0x00, 0x88, 0x61, 0x70, 0x47, + 0x14, 0x27, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x13, 0x00, 0x00, 0x00, + 0x00, 0x68, 0x01, 0x01, 0x08, 0x00, 0x00, 0x00, 0x68, 0x6f, 0x01, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x38, 0x76, 0x01, 0x01, + 0x10, 0xb5, 0x01, 0x21, 0x15, 0x20, 0xfe, 0xf7, 0x08, 0xfc, 0x00, 0xf0, + 0x4d, 0xf8, 0x84, 0x4c, 0xf9, 0xf7, 0x47, 0xfc, 0x21, 0x7a, 0x4f, 0xf4, + 0xdb, 0x70, 0xf9, 0xf7, 0x11, 0xfc, 0x61, 0x7a, 0x80, 0x4c, 0x40, 0xf2, + 0xb7, 0x10, 0xf9, 0xf7, 0x0b, 0xfc, 0xfe, 0xf7, 0xbc, 0xfa, 0x00, 0x22, + 0x03, 0x21, 0x40, 0xf2, 0x33, 0x40, 0xf9, 0xf7, 0x0d, 0xfc, 0x00, 0x22, + 0x01, 0x21, 0x40, 0xf2, 0x4c, 0x40, 0xf9, 0xf7, 0x07, 0xfc, 0x00, 0x22, + 0x0f, 0x21, 0x40, 0xf2, 0x2e, 0x40, 0xf9, 0xf7, 0x01, 0xfc, 0x00, 0x22, + 0x03, 0x21, 0x4f, 0xf4, 0x89, 0x60, 0xf9, 0xf7, 0xfb, 0xfb, 0x21, 0x78, + 0x40, 0xf2, 0x35, 0x40, 0xf9, 0xf7, 0xec, 0xfb, 0x61, 0x7d, 0x40, 0xf2, + 0x36, 0x40, 0xf9, 0xf7, 0xe7, 0xfb, 0xff, 0xf7, 0x8e, 0xf8, 0xff, 0xf7, + 0xbc, 0xf8, 0xff, 0xf7, 0xdb, 0xf8, 0xbd, 0xe8, 0x10, 0x40, 0x04, 0x20, + 0xfc, 0xf7, 0xc2, 0xbf, 0x80, 0xb5, 0x04, 0x20, 0xfd, 0xf7, 0x00, 0xf8, + 0x00, 0xf0, 0x0a, 0xf8, 0xf9, 0xf7, 0xf2, 0xfb, 0xfe, 0xf7, 0xa0, 0xfa, + 0xbd, 0xe8, 0x04, 0x40, 0x00, 0x21, 0x15, 0x20, 0xfe, 0xf7, 0xb9, 0xbb, + 0x09, 0x22, 0x5f, 0x49, 0x0f, 0xf2, 0x78, 0x20, 0x70, 0x47, 0x2d, 0xe9, + 0xf1, 0x4f, 0xdf, 0xf8, 0x74, 0xa1, 0x5d, 0x4e, 0x5d, 0x4f, 0x82, 0xb0, + 0x9a, 0xf8, 0x00, 0x00, 0x00, 0x90, 0x00, 0x24, 0x74, 0x60, 0xb4, 0x81, + 0x03, 0x21, 0xb8, 0x7a, 0x08, 0x42, 0x06, 0xd0, 0x01, 0x20, 0x03, 0xf0, + 0x5f, 0xf8, 0x00, 0x29, 0x08, 0xbf, 0x00, 0x28, 0x15, 0xd0, 0x78, 0x89, + 0xc0, 0xf3, 0x81, 0x00, 0x30, 0xb1, 0x00, 0x20, 0x03, 0xf0, 0x54, 0xf8, + 0x00, 0x29, 0x08, 0xbf, 0x00, 0x28, 0x0a, 0xd0, 0x78, 0x89, 0xc0, 0xf3, + 0x82, 0x10, 0x40, 0xb1, 0x02, 0x20, 0x03, 0xf0, 0x49, 0xf8, 0x00, 0x29, + 0x08, 0xbf, 0x00, 0x28, 0x01, 0xd1, 0x05, 0x24, 0x53, 0xe0, 0x00, 0x98, + 0x20, 0x28, 0x4f, 0xd2, 0x01, 0x20, 0xff, 0xf7, 0x54, 0xff, 0x34, 0x61, + 0x00, 0x27, 0xdf, 0xf8, 0x14, 0x81, 0xdf, 0xf8, 0x14, 0x91, 0x00, 0xe0, + 0x7f, 0x1c, 0x00, 0x98, 0x87, 0x42, 0x3d, 0xd2, 0x07, 0xeb, 0x0a, 0x00, + 0x0c, 0x21, 0x40, 0x78, 0x00, 0xf0, 0x1f, 0x05, 0x0f, 0xf2, 0x00, 0x10, + 0x01, 0xfb, 0x05, 0x0b, 0xdb, 0xf8, 0x04, 0x00, 0x00, 0x28, 0xed, 0xd0, + 0x02, 0x98, 0xe8, 0x40, 0xc0, 0x07, 0xe9, 0xd5, 0x29, 0x46, 0x16, 0x20, + 0xfe, 0xf7, 0x6c, 0xfb, 0x49, 0x46, 0x04, 0x20, 0xfc, 0xf7, 0x5e, 0xff, + 0x9b, 0xf8, 0x08, 0x00, 0xfe, 0xf7, 0x66, 0xfa, 0xdb, 0xf8, 0x04, 0x20, + 0x41, 0x46, 0x00, 0x20, 0x90, 0x47, 0x04, 0x46, 0x04, 0x20, 0xfc, 0xf7, + 0x77, 0xff, 0xe4, 0xb2, 0x1c, 0xb1, 0x35, 0x73, 0x74, 0x73, 0x07, 0x24, + 0x10, 0xe0, 0x01, 0x21, 0x72, 0x68, 0xa9, 0x40, 0x0a, 0x43, 0x72, 0x60, + 0x32, 0x68, 0x11, 0x43, 0x31, 0x60, 0x31, 0x69, 0x49, 0x44, 0x08, 0x1a, + 0x30, 0x61, 0xfa, 0xf7, 0x20, 0xfe, 0x00, 0x28, 0xbe, 0xd0, 0x06, 0x24, + 0x00, 0x20, 0xff, 0xf7, 0x08, 0xff, 0x00, 0xe0, 0x04, 0x24, 0x20, 0x46, + 0xbd, 0xe8, 0xfe, 0x8f, 0x1f, 0x49, 0x01, 0x20, 0x08, 0x70, 0x70, 0x47, + 0xf8, 0xb5, 0x04, 0x46, 0x0d, 0x46, 0x16, 0x46, 0x19, 0x46, 0x00, 0x20, + 0xfc, 0xf7, 0xcc, 0xff, 0x00, 0x27, 0xfa, 0xf7, 0x06, 0xfe, 0x08, 0xb1, + 0x02, 0x27, 0x0d, 0xe0, 0x04, 0xf1, 0x8c, 0x40, 0x05, 0xea, 0x06, 0x01, + 0x00, 0x78, 0x28, 0x40, 0x88, 0x42, 0x05, 0xd0, 0x00, 0x20, 0xfc, 0xf7, + 0xd3, 0xff, 0x00, 0x28, 0xed, 0xd0, 0x01, 0x27, 0x00, 0x20, 0xfc, 0xf7, + 0x45, 0xff, 0x38, 0x46, 0xf2, 0xbd, 0x09, 0x48, 0x81, 0x68, 0x00, 0x68, + 0x08, 0x40, 0x88, 0x42, 0x0c, 0xbf, 0x01, 0x20, 0x00, 0x20, 0x70, 0x47, + 0x00, 0x00, 0x00, 0x00, 0x4c, 0x1f, 0x00, 0x20, 0x31, 0x04, 0x00, 0x46, + 0xfc, 0xf2, 0x00, 0x20, 0xd4, 0x28, 0x00, 0x20, 0xe8, 0xf2, 0x00, 0x20, + 0x78, 0x29, 0x00, 0x20, 0x60, 0xb5, 0x00, 0x20, 0xc0, 0xe1, 0xe4, 0x00, + 0x9e, 0xf3, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0xed, 0x52, 0x01, 0x01, + 0x05, 0x00, 0x00, 0x00, 0x91, 0x55, 0x01, 0x01, 0x93, 0x55, 0x01, 0x01, + 0x05, 0x00, 0x00, 0x00, 0x7d, 0x69, 0x01, 0x01, 0x7f, 0x69, 0x01, 0x01, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x38, 0x01, 0x01, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x64, 0x01, 0x01, + 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf5, 0x76, 0x01, 0x01, + 0x38, 0x00, 0x00, 0x00, 0x11, 0x31, 0x01, 0x01, 0x13, 0x31, 0x01, 0x01, + 0xc8, 0x00, 0x00, 0x00, 0x6d, 0x75, 0x00, 0x01, 0x81, 0x75, 0x00, 0x01, + 0x38, 0x00, 0x00, 0x00, 0x5d, 0x17, 0x00, 0x01, 0xc9, 0x13, 0x00, 0x01, + 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x15, 0x00, 0x01, + 0x38, 0x00, 0x00, 0x00, 0xb7, 0x58, 0x01, 0x01, 0xf7, 0x58, 0x01, 0x01, + 0x38, 0x00, 0x00, 0x00, 0x95, 0x5b, 0x01, 0x01, 0x8b, 0x5c, 0x01, 0x01, + 0x38, 0x00, 0x00, 0x00, 0x91, 0x5d, 0x01, 0x01, 0xd5, 0x5d, 0x01, 0x01, + 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xf9, 0x5c, 0x01, 0x01, 0xa5, 0x5d, 0x01, 0x01, + 0xc8, 0x00, 0x00, 0x00, 0xd9, 0xdb, 0x00, 0x01, 0x31, 0xdc, 0x00, 0x01, + 0xf8, 0x00, 0x00, 0x00, 0xbd, 0xa5, 0x00, 0x01, 0x1d, 0xa6, 0x00, 0x01, + 0x38, 0x00, 0x00, 0x00, 0xe5, 0x60, 0x00, 0x01, 0x15, 0x61, 0x00, 0x01, + 0x38, 0x00, 0x00, 0x00, 0x4b, 0x34, 0x00, 0x01, 0x4d, 0x34, 0x00, 0x01, + 0x38, 0x00, 0x00, 0x00, 0x2e, 0x04, 0x33, 0x04, 0x35, 0x04, 0x36, 0x04, + 0x48, 0x04, 0x4c, 0x04, 0x5b, 0x04, 0x5c, 0x04, 0x5d, 0x04, 0x00, 0x00, + 0x30, 0xb5, 0x04, 0x46, 0x4a, 0x4d, 0x87, 0xb0, 0x08, 0x21, 0x28, 0x1d, + 0xf8, 0xf7, 0x0f, 0xfd, 0x28, 0x60, 0x00, 0xb1, 0x01, 0x20, 0xfe, 0xf7, + 0x8e, 0xf9, 0x03, 0x21, 0x04, 0x91, 0x00, 0xf0, 0x24, 0xf8, 0x05, 0xaa, + 0x0f, 0xf2, 0x10, 0x11, 0x16, 0x20, 0xf8, 0xf7, 0x97, 0xff, 0x00, 0x20, + 0x12, 0xe0, 0x30, 0xb5, 0x87, 0xb0, 0x03, 0x21, 0x04, 0x91, 0x04, 0x46, + 0x00, 0xf0, 0x15, 0xf8, 0x00, 0xf0, 0x0d, 0xf8, 0x05, 0xaa, 0x0f, 0xf2, + 0x00, 0x11, 0x16, 0x20, 0xf8, 0xf7, 0x86, 0xff, 0x00, 0x2d, 0x0c, 0xbf, + 0x00, 0x20, 0x02, 0x20, 0x20, 0x70, 0x07, 0xb0, 0x30, 0xbd, 0x05, 0x46, + 0x40, 0x1e, 0x80, 0x41, 0xc0, 0x0f, 0xfe, 0xf7, 0x66, 0xb9, 0x00, 0x21, + 0x03, 0x91, 0x4f, 0xf4, 0x20, 0x71, 0x02, 0x91, 0x16, 0x21, 0x2f, 0x48, + 0x01, 0x90, 0x00, 0x91, 0x00, 0xf6, 0xfc, 0x12, 0x16, 0x23, 0x00, 0x21, + 0x0f, 0xf2, 0x39, 0x00, 0xf8, 0xf7, 0xb1, 0xbe, 0x38, 0xb5, 0x04, 0x46, + 0x00, 0x20, 0xfe, 0xf7, 0x1d, 0xfb, 0x03, 0x20, 0xfe, 0xf7, 0x1a, 0xfb, + 0x24, 0x48, 0x00, 0x68, 0xf8, 0xf7, 0x00, 0xfd, 0xff, 0xf7, 0xdc, 0xff, + 0x16, 0x20, 0xf8, 0xf7, 0xe7, 0xfe, 0xff, 0xf7, 0xd6, 0xff, 0x00, 0x2d, + 0x0c, 0xbf, 0x00, 0x20, 0x02, 0x20, 0x20, 0x70, 0x31, 0xbd, 0x00, 0x00, + 0x38, 0xb5, 0x1b, 0x4c, 0x23, 0xe0, 0xfe, 0xf7, 0x36, 0xf9, 0x00, 0x20, + 0xfe, 0xf7, 0xe2, 0xfa, 0x00, 0x20, 0xf9, 0xf7, 0x7f, 0xfe, 0x01, 0x28, + 0x19, 0xd0, 0x29, 0x0e, 0x0c, 0x20, 0xfe, 0xf7, 0x0d, 0xfa, 0x01, 0x21, + 0x0b, 0x20, 0xfe, 0xf7, 0xfa, 0xf9, 0x00, 0x20, 0xf9, 0xf7, 0x87, 0xfd, + 0x01, 0x00, 0x0c, 0xd0, 0x48, 0x68, 0xc9, 0x68, 0x88, 0x47, 0x00, 0x21, + 0x0b, 0x20, 0xfe, 0xf7, 0xee, 0xf9, 0x00, 0x20, 0xf9, 0xf7, 0xe0, 0xfd, + 0x00, 0x20, 0xfe, 0xf7, 0xe1, 0xfa, 0x00, 0x20, 0xfe, 0xf7, 0xde, 0xfa, + 0x20, 0x68, 0x6a, 0x46, 0x00, 0x21, 0xf8, 0xf7, 0xd2, 0xfc, 0x00, 0x68, + 0x05, 0x04, 0xc0, 0xb2, 0x07, 0x28, 0x0c, 0xbf, 0x01, 0x20, 0x00, 0x20, + 0xcb, 0xe7, 0x00, 0x00, 0x88, 0xf2, 0x00, 0x20, 0x68, 0x2c, 0x00, 0x20, + 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x61, 0x73, 0x6b, + 0x00, 0x00, 0x00, 0x00, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, + 0x54, 0x73, 0x6b, 0x00, 0x62, 0xb3, 0x8b, 0x07, 0x08, 0xd0, 0x52, 0x1e, + 0x11, 0xf8, 0x01, 0x3b, 0x00, 0xf8, 0x01, 0x3b, 0x00, 0xf0, 0x24, 0x80, + 0x8b, 0x07, 0xf6, 0xd1, 0x83, 0x07, 0x40, 0xf0, 0x20, 0x80, 0x00, 0xbf, + 0x10, 0x3a, 0x07, 0xd3, 0x30, 0xb4, 0xb1, 0xe8, 0x38, 0x10, 0x10, 0x3a, + 0xa0, 0xe8, 0x38, 0x10, 0xf9, 0xd2, 0x30, 0xbc, 0x53, 0x07, 0x24, 0xbf, + 0xb1, 0xe8, 0x08, 0x10, 0xa0, 0xe8, 0x08, 0x10, 0x44, 0xbf, 0x51, 0xf8, + 0x04, 0x3b, 0x40, 0xf8, 0x04, 0x3b, 0xd2, 0x07, 0x24, 0xbf, 0x31, 0xf8, + 0x02, 0x2b, 0x20, 0xf8, 0x02, 0x2b, 0x44, 0xbf, 0x0b, 0x78, 0x03, 0x70, + 0x70, 0x47, 0x08, 0x3a, 0x07, 0xd3, 0xb1, 0xe8, 0x08, 0x10, 0x08, 0x3a, + 0x40, 0xf8, 0x04, 0x3b, 0x40, 0xf8, 0x04, 0xcb, 0xf7, 0xd2, 0x53, 0x07, + 0xe4, 0xe7, 0x00, 0x00, 0x80, 0xb5, 0x30, 0x48, 0x4f, 0xf0, 0x80, 0x71, + 0x01, 0x63, 0xc2, 0x6b, 0x42, 0xf0, 0x80, 0x72, 0xc2, 0x63, 0x01, 0x60, + 0x20, 0x20, 0x01, 0x21, 0xfe, 0xf7, 0x07, 0xf9, 0x20, 0x20, 0xfe, 0xf7, + 0xe9, 0xf8, 0xbd, 0xe8, 0x02, 0x40, 0x20, 0x20, 0xfe, 0xf7, 0xea, 0xb8, + 0x2d, 0xe9, 0xf0, 0x41, 0x82, 0xb0, 0x00, 0x24, 0x00, 0x25, 0x24, 0x4e, + 0x06, 0xeb, 0xc5, 0x07, 0xd7, 0xf8, 0x08, 0x80, 0x0e, 0xe0, 0x30, 0x68, + 0x64, 0x1c, 0x84, 0x42, 0x05, 0xd3, 0x71, 0x68, 0xb0, 0x69, 0x6a, 0x46, + 0xf8, 0xf7, 0x68, 0xfd, 0x00, 0x24, 0x40, 0x46, 0x00, 0xf0, 0x0a, 0xf8, + 0x08, 0xf1, 0x04, 0x08, 0xf8, 0x68, 0x80, 0x45, 0xed, 0xd3, 0x6d, 0x1c, + 0x02, 0x2d, 0xe5, 0xd3, 0xbd, 0xe8, 0xf3, 0x81, 0x80, 0xb5, 0x72, 0xb6, + 0x15, 0x48, 0x16, 0x49, 0x01, 0x60, 0x00, 0x21, 0x01, 0x60, 0x62, 0xb6, + 0x00, 0x22, 0xf0, 0x21, 0x40, 0xf6, 0x59, 0x40, 0xf9, 0xf7, 0x60, 0xf9, + 0xbd, 0xe8, 0x08, 0x40, 0x00, 0x22, 0xf0, 0x21, 0x40, 0xf6, 0x51, 0x40, + 0xf9, 0xf7, 0x58, 0xb9, 0x80, 0xb5, 0xff, 0xf7, 0xaf, 0xff, 0x00, 0x22, + 0x02, 0x21, 0x4f, 0xf4, 0x45, 0x60, 0xf9, 0xf7, 0x4f, 0xf9, 0x00, 0x20, + 0xf8, 0xf7, 0x10, 0xfd, 0x04, 0x49, 0x88, 0x61, 0x01, 0xbd, 0x03, 0x48, + 0x80, 0x69, 0xf8, 0xf7, 0x8d, 0xbd, 0x00, 0x00, 0x10, 0x00, 0x00, 0x58, + 0x30, 0x1f, 0x00, 0x20, 0x48, 0x00, 0x00, 0x50, 0x00, 0x00, 0xab, 0xab, + 0x00, 0x20, 0xfe, 0xf7, 0x48, 0xb8, 0x00, 0x00, 0x0f, 0x28, 0xb4, 0xbf, + 0x01, 0x20, 0x00, 0x20, 0x70, 0x47, 0x70, 0xb5, 0x00, 0xf0, 0x12, 0xf8, + 0x2c, 0x43, 0x1c, 0x60, 0x02, 0xeb, 0x40, 0x00, 0x01, 0x23, 0x07, 0xe0, + 0x70, 0xb5, 0x00, 0xf0, 0x09, 0xf8, 0xac, 0x43, 0x1c, 0x60, 0x02, 0xeb, + 0x40, 0x00, 0x00, 0x23, 0x43, 0x70, 0x81, 0xf3, 0x10, 0x88, 0x70, 0xbd, + 0xef, 0xf3, 0x10, 0x81, 0x72, 0xb6, 0x1d, 0x4b, 0x1d, 0x4a, 0x1c, 0x68, + 0x12, 0xf9, 0x10, 0x60, 0x01, 0x25, 0xb5, 0x40, 0x70, 0x47, 0x0f, 0xf2, + 0x78, 0x02, 0x19, 0x49, 0x82, 0x5c, 0x52, 0xb9, 0x11, 0xf8, 0x10, 0x00, + 0x17, 0x49, 0xc2, 0x08, 0x00, 0xf0, 0x07, 0x00, 0x51, 0x5c, 0xc1, 0x40, + 0x01, 0xf0, 0x01, 0x00, 0x70, 0x47, 0x01, 0xeb, 0x40, 0x00, 0x40, 0x78, + 0x70, 0x47, 0x38, 0xb5, 0x0f, 0x4b, 0x03, 0xeb, 0x40, 0x03, 0xef, 0xf3, + 0x10, 0x84, 0x72, 0xb6, 0x0f, 0xf2, 0x40, 0x05, 0x45, 0x5d, 0x01, 0x2d, + 0x0a, 0xd1, 0x02, 0xb9, 0x13, 0x21, 0x19, 0x70, 0x59, 0x78, 0x11, 0xb1, + 0xff, 0xf7, 0xb9, 0xff, 0x03, 0xe0, 0xff, 0xf7, 0xbf, 0xff, 0x00, 0xe0, + 0x19, 0x70, 0x84, 0xf3, 0x10, 0x88, 0x31, 0xbd, 0x02, 0x49, 0x11, 0xf8, + 0x10, 0x00, 0x70, 0x47, 0x18, 0x00, 0x00, 0x49, 0xb4, 0x28, 0x00, 0x20, + 0x26, 0x0b, 0x00, 0x46, 0x0f, 0xf2, 0x04, 0x01, 0x40, 0x5c, 0x70, 0x47, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x00, 0xef, 0xf3, 0x11, 0x80, 0x60, 0x21, 0x81, 0xf3, + 0x11, 0x88, 0x70, 0x47, 0xdf, 0xf8, 0x9c, 0x06, 0x00, 0x78, 0x00, 0xf0, + 0x02, 0x00, 0x70, 0x47, 0x38, 0xb5, 0x04, 0x46, 0x0d, 0x46, 0xff, 0xf7, + 0xef, 0xff, 0x00, 0x22, 0x00, 0x23, 0xc5, 0xe9, 0x02, 0x23, 0xc5, 0xe9, + 0x04, 0x23, 0xc5, 0xe9, 0x06, 0x23, 0x00, 0x21, 0xca, 0x00, 0xdf, 0xf8, + 0x78, 0x56, 0xab, 0x50, 0x49, 0x1c, 0xdf, 0xf8, 0x74, 0x56, 0xab, 0x50, + 0x16, 0x29, 0xf5, 0xd3, 0xa1, 0x00, 0xdf, 0xf8, 0x6c, 0x26, 0x41, 0xf0, + 0x01, 0x01, 0x11, 0x60, 0x16, 0xe0, 0x38, 0xb5, 0x04, 0x46, 0x0d, 0x46, + 0xff, 0xf7, 0xd0, 0xff, 0xdf, 0xf8, 0x58, 0x26, 0x24, 0xb9, 0xdf, 0xf8, + 0x58, 0x36, 0x1c, 0x68, 0x12, 0x78, 0x03, 0xe0, 0xdf, 0xf8, 0x50, 0x36, + 0x1c, 0x68, 0x52, 0x78, 0x24, 0xf0, 0x02, 0x04, 0x44, 0xea, 0x45, 0x01, + 0x11, 0x43, 0x19, 0x60, 0x80, 0xf3, 0x11, 0x88, 0x31, 0xbd, 0x7f, 0xb5, + 0x0a, 0xb1, 0x00, 0xf5, 0x80, 0x70, 0x40, 0xf2, 0xfc, 0x72, 0x02, 0xea, + 0x80, 0x00, 0x40, 0xf0, 0x02, 0x00, 0x00, 0x22, 0x03, 0xeb, 0x82, 0x05, + 0x33, 0xf8, 0x22, 0x60, 0xb5, 0xf9, 0x02, 0x50, 0x46, 0xea, 0x05, 0x45, + 0x4d, 0xf8, 0x22, 0x50, 0x52, 0x1c, 0x04, 0x2a, 0xf2, 0xdb, 0x03, 0x9a, + 0x02, 0x9b, 0x01, 0x9c, 0x00, 0x29, 0x0c, 0xbf, 0xdf, 0xf8, 0x00, 0x16, + 0xdf, 0xf8, 0x00, 0x16, 0x00, 0x9d, 0x4d, 0x60, 0x8c, 0x60, 0xcb, 0x60, + 0x0a, 0x61, 0x08, 0x60, 0x7f, 0xbd, 0x7f, 0xb5, 0x04, 0x46, 0x68, 0x46, + 0x10, 0x21, 0xfd, 0xf7, 0xbf, 0xfd, 0x4f, 0xf4, 0x00, 0x50, 0xad, 0xf8, + 0x00, 0x00, 0x00, 0x25, 0x00, 0x26, 0x86, 0xf0, 0x01, 0x01, 0xc9, 0xb2, + 0xe0, 0xb2, 0xff, 0xf7, 0xac, 0xff, 0x6b, 0x46, 0x32, 0x46, 0x21, 0x46, + 0x28, 0x46, 0xff, 0xf7, 0xc0, 0xff, 0x76, 0x1c, 0x02, 0x2e, 0xf0, 0xd3, + 0x6d, 0x1c, 0xff, 0x2d, 0xec, 0xd9, 0x7f, 0xbd, 0xc0, 0x0b, 0x00, 0x21, + 0x00, 0xfa, 0x01, 0xf2, 0x12, 0x05, 0x03, 0xd4, 0x49, 0x1c, 0xc9, 0xb2, + 0x07, 0x29, 0xf7, 0xdb, 0xc1, 0xf1, 0x07, 0x01, 0xc9, 0xb2, 0x00, 0x29, + 0x14, 0xbf, 0x4a, 0x1e, 0x00, 0x22, 0xd0, 0x40, 0x00, 0xf0, 0x1f, 0x00, + 0x40, 0xea, 0x41, 0x10, 0x70, 0x47, 0x41, 0x09, 0x05, 0xd0, 0x00, 0xf0, + 0x1f, 0x00, 0x40, 0xf0, 0x20, 0x00, 0x4a, 0x1e, 0x90, 0x40, 0x02, 0x29, + 0x04, 0xdb, 0x01, 0x22, 0x89, 0x1e, 0x02, 0xfa, 0x01, 0xf1, 0x08, 0x43, + 0x70, 0x47, 0x10, 0xb5, 0x02, 0x46, 0x0b, 0x46, 0x14, 0x68, 0x18, 0x46, + 0x21, 0x46, 0xfc, 0xf7, 0xb5, 0xfe, 0x38, 0xbf, 0x1c, 0x46, 0x83, 0xf0, + 0x00, 0x43, 0x20, 0x46, 0x19, 0x46, 0xfc, 0xf7, 0xad, 0xfe, 0x38, 0xbf, + 0x1c, 0x46, 0x14, 0x60, 0x10, 0xbd, 0x2d, 0xe9, 0xf7, 0x4f, 0x8e, 0xb0, + 0x9a, 0x46, 0x1a, 0x9c, 0xdf, 0xf8, 0x34, 0xb5, 0x00, 0x26, 0x4f, 0xf0, + 0x8c, 0x48, 0x0d, 0xf1, 0x14, 0x09, 0xf0, 0xb2, 0xff, 0xf7, 0xcd, 0xff, + 0x80, 0x03, 0x01, 0xf0, 0x2d, 0xf8, 0x01, 0x46, 0x0e, 0x9a, 0x00, 0x94, + 0x53, 0x46, 0x05, 0xa8, 0x01, 0xf0, 0x92, 0xfb, 0x00, 0x25, 0x59, 0xf8, + 0x35, 0x00, 0x41, 0x46, 0xfc, 0xf7, 0x9c, 0xfe, 0x49, 0xf8, 0x35, 0x00, + 0x41, 0x46, 0x05, 0xa8, 0x00, 0xeb, 0xc5, 0x07, 0x78, 0x68, 0xfc, 0xf7, + 0x93, 0xfe, 0x78, 0x60, 0x59, 0x46, 0x38, 0x46, 0xff, 0xf7, 0xbf, 0xff, + 0x59, 0x46, 0x38, 0x1d, 0xff, 0xf7, 0xbb, 0xff, 0x59, 0xf8, 0x35, 0x00, + 0xfc, 0xf7, 0xf2, 0xfe, 0x01, 0xa9, 0x21, 0xf8, 0x25, 0x00, 0x78, 0x68, + 0xfc, 0xf7, 0xec, 0xfe, 0x01, 0xa9, 0x01, 0xeb, 0x85, 0x01, 0x6d, 0x1c, + 0x04, 0x2d, 0x48, 0x80, 0xd7, 0xd3, 0x10, 0x9a, 0x0f, 0x99, 0x01, 0xab, + 0x30, 0x46, 0xff, 0xf7, 0x36, 0xff, 0x76, 0x1c, 0xff, 0x2e, 0xc0, 0xd9, + 0x11, 0xb0, 0xbd, 0xe8, 0xf0, 0x8f, 0x10, 0xb5, 0x04, 0x00, 0x0c, 0xbf, + 0xdf, 0xf8, 0xa0, 0x24, 0xdf, 0xf8, 0xa0, 0x24, 0xc8, 0xb2, 0x10, 0x60, + 0x08, 0x1d, 0xdf, 0xf8, 0x9c, 0x14, 0xdf, 0xf8, 0x9c, 0x24, 0x89, 0x6b, + 0x52, 0x69, 0xa1, 0xfb, 0x00, 0x01, 0x00, 0x23, 0xfd, 0xf7, 0xc8, 0xf9, + 0xdf, 0xf8, 0x8c, 0x14, 0x40, 0x1c, 0x41, 0xf8, 0x24, 0x00, 0x10, 0xbd, + 0xf8, 0xb5, 0x00, 0x88, 0x00, 0x0a, 0x0c, 0x46, 0x80, 0xf0, 0x02, 0x00, + 0x59, 0x00, 0xc0, 0x00, 0x01, 0xf0, 0x02, 0x01, 0x00, 0xf0, 0x18, 0x00, + 0x08, 0x43, 0x15, 0x46, 0x40, 0xf0, 0x01, 0x07, 0xff, 0xf7, 0xbe, 0xfe, + 0x06, 0x46, 0x29, 0x46, 0x20, 0x46, 0xff, 0xf7, 0xce, 0xff, 0xdf, 0xf8, + 0x2c, 0x04, 0x1c, 0xb9, 0x00, 0x78, 0xdf, 0xf8, 0x28, 0x14, 0x02, 0xe0, + 0x40, 0x78, 0xdf, 0xf8, 0x24, 0x14, 0x38, 0x43, 0x08, 0x60, 0x86, 0xf3, + 0x11, 0x88, 0xf1, 0xbd, 0xf8, 0xb5, 0x07, 0x00, 0x0c, 0x46, 0x1a, 0xbf, + 0x00, 0x20, 0xdf, 0xf8, 0x30, 0x14, 0xdf, 0xf8, 0x30, 0x14, 0x15, 0x46, + 0x08, 0x60, 0x1e, 0x46, 0xdf, 0xf8, 0x1c, 0x04, 0x50, 0xf8, 0x27, 0x00, + 0xfc, 0xf7, 0x91, 0xfb, 0xc7, 0xb1, 0x00, 0x20, 0xb0, 0x42, 0x2e, 0xda, + 0x41, 0x42, 0xc9, 0x00, 0xdf, 0xf8, 0x10, 0x24, 0x00, 0xf0, 0x31, 0xf8, + 0xdf, 0xf8, 0x0c, 0x24, 0x52, 0x58, 0xd2, 0x08, 0x5a, 0x80, 0xdf, 0xf8, + 0x08, 0x24, 0x52, 0x58, 0xd2, 0x08, 0x25, 0xf8, 0x20, 0x20, 0xdf, 0xf8, + 0x00, 0x24, 0x00, 0xf0, 0x1b, 0xf8, 0xe7, 0xe7, 0x00, 0x20, 0x14, 0xe0, + 0x41, 0x42, 0xc9, 0x00, 0xdf, 0xf8, 0xf0, 0x23, 0x00, 0xf0, 0x19, 0xf8, + 0xdf, 0xf8, 0xec, 0x23, 0x52, 0x58, 0xd2, 0x08, 0x5a, 0x80, 0xdf, 0xf8, + 0xe8, 0x23, 0x52, 0x58, 0xd2, 0x08, 0x25, 0xf8, 0x20, 0x20, 0xdf, 0xf8, + 0xe0, 0x23, 0x00, 0xf0, 0x03, 0xf8, 0xb0, 0x42, 0xe8, 0xdb, 0xf1, 0xbd, + 0x51, 0x58, 0x05, 0xeb, 0x80, 0x02, 0xc9, 0x08, 0x51, 0x80, 0x40, 0x1c, + 0x70, 0x47, 0x52, 0x58, 0xd2, 0x08, 0x24, 0xf8, 0x20, 0x20, 0x04, 0xeb, + 0x80, 0x03, 0x70, 0x47, 0xf8, 0xb5, 0x06, 0x46, 0x0c, 0x46, 0x15, 0x46, + 0x1f, 0x46, 0xff, 0xf7, 0x4f, 0xfe, 0x00, 0x21, 0xca, 0x00, 0x56, 0xf8, + 0x31, 0x30, 0xdf, 0xf8, 0x44, 0xc3, 0x4c, 0xf8, 0x02, 0x30, 0x06, 0xeb, + 0xc1, 0x03, 0xdf, 0xf8, 0x3c, 0xc3, 0x5b, 0x68, 0x4c, 0xf8, 0x02, 0x30, + 0x49, 0x1c, 0x15, 0x29, 0xee, 0xd3, 0xdf, 0xf8, 0x88, 0x13, 0x0c, 0x60, + 0x4d, 0x60, 0x3f, 0x06, 0x06, 0x99, 0x3a, 0x0d, 0x02, 0xf0, 0xf0, 0x02, + 0x42, 0xea, 0x81, 0x01, 0xc6, 0x4a, 0x41, 0xf0, 0x03, 0x01, 0x11, 0x60, + 0x80, 0xf3, 0x11, 0x88, 0xf1, 0xbd, 0x38, 0xb5, 0x04, 0x46, 0x00, 0x21, + 0x00, 0x20, 0xf9, 0xf7, 0x3e, 0xf9, 0x20, 0x69, 0x04, 0xf1, 0xbc, 0x01, + 0x00, 0xf0, 0x21, 0xf8, 0x05, 0x00, 0x07, 0xd1, 0x21, 0x68, 0x20, 0x69, + 0x00, 0xf0, 0x76, 0xf8, 0x20, 0x69, 0x00, 0xf0, 0x58, 0xf8, 0x05, 0x46, + 0x20, 0x69, 0xfc, 0xf7, 0xe9, 0xf9, 0x28, 0x46, 0x32, 0xbd, 0x10, 0xb5, + 0x04, 0x46, 0xf9, 0xf7, 0x15, 0xfc, 0x03, 0x28, 0x06, 0xd1, 0x04, 0xf0, + 0x1b, 0xf9, 0x00, 0x21, 0x04, 0xf1, 0xbc, 0x00, 0xfb, 0xf7, 0x15, 0xf9, + 0xbd, 0xe8, 0x10, 0x40, 0x00, 0x20, 0xf9, 0xf7, 0x75, 0xb9, 0x2d, 0xe9, + 0xf0, 0x41, 0x04, 0x46, 0x88, 0x46, 0xf9, 0xf7, 0x01, 0xfc, 0x00, 0x26, + 0x03, 0x28, 0x25, 0xd1, 0xe0, 0xb2, 0xf9, 0xf7, 0x35, 0xfc, 0x05, 0x46, + 0x40, 0x46, 0xfb, 0xf7, 0xee, 0xf8, 0x00, 0x2d, 0x48, 0xbf, 0x14, 0x26, + 0x20, 0xd4, 0x28, 0x46, 0xfb, 0xf7, 0x0f, 0xf9, 0xfb, 0xf7, 0x41, 0xf9, + 0xfb, 0xf7, 0x2c, 0xf9, 0x01, 0x2d, 0x0c, 0xd1, 0x03, 0x27, 0x02, 0x20, + 0x04, 0xf0, 0x98, 0xf8, 0xb3, 0x48, 0xb0, 0xf8, 0x54, 0x10, 0x20, 0x46, + 0xfa, 0xf7, 0xc3, 0xfb, 0x60, 0xb1, 0x13, 0x26, 0x0a, 0xe0, 0x02, 0x27, + 0x00, 0x2d, 0xf0, 0xd1, 0x01, 0x20, 0xef, 0xe7, 0xf9, 0xf7, 0xd6, 0xfb, + 0x02, 0x28, 0x0c, 0xbf, 0x03, 0x27, 0x02, 0x27, 0xf8, 0xb2, 0xfa, 0xf7, + 0xd9, 0xf9, 0x18, 0xb9, 0xf9, 0xf7, 0x4b, 0xfc, 0x00, 0xb9, 0x0c, 0x26, + 0x30, 0x46, 0xbd, 0xe8, 0xf0, 0x81, 0x38, 0xb5, 0x04, 0x46, 0x01, 0x20, + 0xa0, 0x40, 0xf8, 0xf7, 0xe7, 0xfe, 0x00, 0x25, 0x08, 0xb9, 0x02, 0x25, + 0x0a, 0xe0, 0x04, 0x20, 0xf8, 0xf7, 0xd2, 0xfe, 0x08, 0xb9, 0x01, 0x25, + 0x04, 0xe0, 0xe0, 0xb2, 0xfb, 0xf7, 0x5d, 0xfa, 0x00, 0xb1, 0x11, 0x25, + 0xfa, 0xf7, 0x41, 0xf9, 0x00, 0xb1, 0x00, 0x25, 0x28, 0x46, 0x32, 0xbd, + 0x10, 0xb5, 0x0c, 0x46, 0x21, 0x78, 0x09, 0x04, 0x01, 0xf4, 0xfe, 0x01, + 0x41, 0xea, 0x80, 0x70, 0x40, 0xf0, 0x00, 0x40, 0x40, 0xf4, 0x80, 0x40, + 0xfb, 0xf7, 0x27, 0xfc, 0x60, 0x78, 0xbd, 0xe8, 0x10, 0x40, 0xfb, 0xf7, + 0x45, 0xbc, 0x38, 0xb5, 0x04, 0x46, 0xf7, 0xf7, 0xf1, 0xfc, 0x20, 0x68, + 0xc0, 0x78, 0x80, 0xf0, 0x01, 0x05, 0xa0, 0x68, 0x20, 0x30, 0x2a, 0x46, + 0x01, 0x79, 0x00, 0x91, 0x03, 0x68, 0x21, 0x69, 0x04, 0xf1, 0x14, 0x00, + 0xff, 0xf7, 0x45, 0xfe, 0x20, 0x68, 0x02, 0x78, 0x21, 0x69, 0xa0, 0x68, + 0x2b, 0x46, 0xff, 0xf7, 0xa7, 0xfe, 0x20, 0x68, 0xc5, 0x70, 0xbd, 0xe8, + 0x31, 0x40, 0xf7, 0xf7, 0xea, 0xbc, 0x2d, 0xe9, 0xf8, 0x43, 0x80, 0x46, + 0x4f, 0xf4, 0xd4, 0x70, 0x00, 0xfb, 0x08, 0xf5, 0x7a, 0x4e, 0xdf, 0xf8, + 0xec, 0x91, 0xaf, 0x19, 0xf8, 0x78, 0x80, 0xf0, 0x01, 0x04, 0x09, 0xf1, + 0x20, 0x00, 0x22, 0x46, 0x01, 0x79, 0x03, 0x68, 0x00, 0x91, 0x07, 0xf1, + 0x28, 0x00, 0x41, 0x46, 0xff, 0xf7, 0x1f, 0xfe, 0xaa, 0x5d, 0x23, 0x46, + 0x41, 0x46, 0x48, 0x46, 0xff, 0xf7, 0x82, 0xfe, 0xfc, 0x70, 0xbd, 0xe8, + 0xf1, 0x83, 0x10, 0xb5, 0xcb, 0x07, 0x55, 0x4a, 0x0d, 0xd5, 0x55, 0x4b, + 0x28, 0xb1, 0x04, 0x24, 0x14, 0x70, 0x1c, 0x68, 0x44, 0xf0, 0x04, 0x04, + 0x04, 0xe0, 0x00, 0x24, 0x14, 0x70, 0x1c, 0x68, 0x24, 0xf0, 0x04, 0x04, + 0x1c, 0x60, 0x89, 0x07, 0x0c, 0xd5, 0x4e, 0x49, 0x28, 0xb1, 0x04, 0x20, + 0x50, 0x70, 0x08, 0x68, 0x40, 0xf0, 0x04, 0x00, 0x03, 0xe0, 0x50, 0x70, + 0x08, 0x68, 0x20, 0xf0, 0x04, 0x00, 0x08, 0x60, 0x10, 0xbd, 0xf8, 0xb5, + 0x04, 0x46, 0x0d, 0x46, 0x16, 0x46, 0x1f, 0x46, 0x21, 0x46, 0x30, 0x46, + 0xff, 0xf7, 0x30, 0xfd, 0x20, 0x88, 0x00, 0x90, 0x4f, 0xf4, 0xd4, 0x71, + 0x20, 0x46, 0xfd, 0xf7, 0x4f, 0xfb, 0xbd, 0xf8, 0x00, 0x00, 0x20, 0x80, + 0x4f, 0xf2, 0xff, 0x71, 0x38, 0x88, 0x08, 0x40, 0xa0, 0x80, 0x04, 0xf5, + 0xce, 0x70, 0x39, 0x6a, 0x01, 0x60, 0x97, 0xf8, 0x24, 0x10, 0x01, 0x71, + 0x30, 0x46, 0xff, 0xf7, 0x78, 0xfd, 0x00, 0x20, 0xe0, 0x70, 0x00, 0x21, + 0xf0, 0xb2, 0xff, 0xf7, 0x30, 0xfd, 0x00, 0x20, 0x28, 0x85, 0x68, 0x85, + 0xf1, 0xbd, 0x46, 0x49, 0x4f, 0xf4, 0xd4, 0x72, 0x02, 0xfb, 0x00, 0x10, + 0x90, 0xf8, 0xa1, 0x01, 0x00, 0xb1, 0x01, 0x20, 0x70, 0x47, 0x41, 0x4a, + 0x4f, 0xf4, 0xd4, 0x73, 0x03, 0xfb, 0x00, 0x20, 0x80, 0xf8, 0xa1, 0x11, + 0x70, 0x47, 0x3d, 0x49, 0x4f, 0xf4, 0xd4, 0x72, 0x02, 0xfb, 0x00, 0x11, + 0x01, 0xf1, 0xe0, 0x00, 0x28, 0x31, 0xb8, 0x22, 0xff, 0xf7, 0xe0, 0xbb, + 0x70, 0xb5, 0x04, 0x46, 0x0d, 0x46, 0x36, 0x48, 0x4f, 0xf4, 0xd4, 0x71, + 0x01, 0xfb, 0x04, 0x06, 0x00, 0x20, 0x86, 0xf8, 0xa1, 0x01, 0x28, 0x07, + 0x03, 0xd5, 0x31, 0x46, 0x20, 0x46, 0xff, 0xf7, 0xdf, 0xfc, 0x68, 0x07, + 0x04, 0xd5, 0xb8, 0x21, 0x06, 0xf1, 0x28, 0x00, 0xf8, 0xf7, 0x52, 0xfd, + 0xe8, 0x07, 0x08, 0xd5, 0x2c, 0x48, 0x2b, 0x4b, 0x94, 0x21, 0x01, 0xfb, + 0x04, 0x01, 0x22, 0x46, 0x30, 0x46, 0xff, 0xf7, 0x94, 0xff, 0xa8, 0x07, + 0x0a, 0xd5, 0x06, 0xf1, 0x28, 0x00, 0x06, 0xf1, 0xe0, 0x01, 0xb8, 0x22, + 0xff, 0xf7, 0xb4, 0xfb, 0x20, 0x46, 0xbd, 0xe8, 0x70, 0x40, 0x42, 0xe7, + 0x70, 0xbd, 0x1f, 0x49, 0x4f, 0xf4, 0xd4, 0x72, 0x02, 0xfb, 0x00, 0x10, + 0x80, 0x78, 0x70, 0x47, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x46, + 0x08, 0x00, 0x60, 0x59, 0x0c, 0x00, 0x60, 0x59, 0x00, 0x00, 0x60, 0x59, + 0x98, 0xf3, 0x00, 0x20, 0x00, 0x00, 0x40, 0x59, 0x00, 0x00, 0x50, 0x59, + 0x04, 0x00, 0x40, 0x59, 0x04, 0x00, 0x50, 0x59, 0x00, 0xfc, 0x7f, 0x46, + 0x18, 0x00, 0x40, 0x59, 0x18, 0x00, 0x50, 0x59, 0x00, 0xf2, 0x00, 0x20, + 0x78, 0x29, 0x00, 0x20, 0x38, 0xf3, 0x00, 0x20, 0x1c, 0x00, 0x50, 0x59, + 0x1c, 0x00, 0x40, 0x59, 0x4c, 0x00, 0x50, 0x59, 0x50, 0x00, 0x50, 0x59, + 0x8c, 0x00, 0x50, 0x59, 0x90, 0x00, 0x50, 0x59, 0x4c, 0x00, 0x40, 0x59, + 0x50, 0x00, 0x40, 0x59, 0x8c, 0x00, 0x40, 0x59, 0x90, 0x00, 0x40, 0x59, + 0xb0, 0x00, 0x60, 0x59, 0x4c, 0x1f, 0x00, 0x20, 0x10, 0xb2, 0x00, 0x20, + 0x30, 0x27, 0x00, 0x20, 0x74, 0x27, 0x00, 0x20, 0x2d, 0xe9, 0xf8, 0x43, + 0xdf, 0xf8, 0x88, 0x8a, 0x88, 0x21, 0x40, 0x46, 0xfd, 0xf7, 0x98, 0xfa, + 0x00, 0x25, 0x0f, 0xf6, 0x4d, 0x29, 0xdf, 0xf8, 0x7c, 0x7a, 0xd4, 0x20, + 0x00, 0xfb, 0x05, 0xf4, 0x44, 0x20, 0xe5, 0x53, 0x00, 0xfb, 0x05, 0x86, + 0x6f, 0xf0, 0xc7, 0x00, 0x70, 0x61, 0xf8, 0xf7, 0xa1, 0xfa, 0x70, 0x63, + 0x00, 0x21, 0xdf, 0xf8, 0x60, 0x0a, 0x28, 0x18, 0x4b, 0x46, 0x81, 0x70, + 0x01, 0x71, 0x01, 0x22, 0xe9, 0xb2, 0x02, 0x20, 0xf8, 0xf7, 0x38, 0xfe, + 0xe0, 0x19, 0x00, 0xf0, 0xb7, 0xfc, 0x6d, 0x1c, 0x02, 0x2d, 0xe0, 0xd3, + 0xbd, 0xe8, 0xf1, 0x43, 0xf8, 0xf7, 0xdc, 0xbe, 0x2d, 0xe9, 0xf0, 0x43, + 0xdf, 0xf8, 0x34, 0x0a, 0xdf, 0xf8, 0x24, 0x9a, 0xdf, 0xf8, 0x30, 0x7a, + 0x89, 0xb0, 0x80, 0x7a, 0x00, 0xf0, 0x03, 0x08, 0xff, 0xf7, 0xc2, 0xff, + 0x00, 0x24, 0x00, 0x25, 0x28, 0xfa, 0x05, 0xf0, 0xc0, 0x07, 0x3d, 0xd5, + 0xdf, 0xf8, 0x08, 0x0a, 0x01, 0x95, 0xd4, 0x21, 0x01, 0xfb, 0x05, 0x00, + 0xdf, 0xf8, 0x0c, 0x1a, 0x02, 0x91, 0x03, 0x97, 0x44, 0x21, 0x01, 0xfb, + 0x05, 0x91, 0x04, 0x91, 0x08, 0x90, 0x00, 0xf1, 0xd0, 0x06, 0x05, 0x80, + 0x00, 0x21, 0x31, 0x70, 0x71, 0x70, 0x00, 0xf0, 0x85, 0xfc, 0x01, 0xa8, + 0x00, 0xf0, 0x89, 0xfc, 0x04, 0x00, 0x09, 0xd1, 0x02, 0x98, 0x00, 0x96, + 0xb0, 0xf9, 0x02, 0x20, 0x01, 0x88, 0x03, 0x1d, 0x01, 0x98, 0xfd, 0xf7, + 0xde, 0xf8, 0x04, 0x46, 0x01, 0xa8, 0x00, 0xf0, 0xad, 0xfc, 0x14, 0xb9, + 0x30, 0x78, 0x5a, 0x28, 0x05, 0xda, 0x04, 0x98, 0x3c, 0x30, 0x00, 0x21, + 0xc1, 0x80, 0x81, 0x80, 0x0d, 0xe0, 0x04, 0x98, 0x3c, 0x30, 0x01, 0x21, + 0xc1, 0x80, 0x81, 0x80, 0x08, 0x99, 0x11, 0xf8, 0xd0, 0x2f, 0x42, 0x80, + 0x49, 0x78, 0x01, 0x80, 0x6d, 0x1c, 0x02, 0x2d, 0xba, 0xd3, 0x20, 0x46, + 0x09, 0xb0, 0xbd, 0xe8, 0xf0, 0x83, 0x00, 0x00, 0x2d, 0xe9, 0xf1, 0x4f, + 0xa0, 0xb0, 0xf8, 0xf7, 0x02, 0xfe, 0x02, 0x90, 0x3a, 0x21, 0x20, 0x98, + 0xdf, 0xf8, 0x70, 0x69, 0xdf, 0xf8, 0x7c, 0x49, 0x04, 0x90, 0x44, 0x22, + 0x06, 0xf1, 0x10, 0x00, 0x05, 0x90, 0x4f, 0xf4, 0x84, 0x58, 0x20, 0x98, + 0x01, 0xfb, 0x00, 0xf5, 0x28, 0x19, 0x06, 0x90, 0x20, 0x99, 0xdf, 0xf8, + 0x48, 0x09, 0x02, 0xfb, 0x01, 0x00, 0x07, 0x90, 0xd4, 0x22, 0x20, 0x99, + 0xdf, 0xf8, 0x3c, 0x09, 0x02, 0xfb, 0x01, 0x00, 0x0b, 0x90, 0x0f, 0x90, + 0xf7, 0xf7, 0x20, 0xfb, 0x28, 0x19, 0xdf, 0xf8, 0x38, 0x19, 0x3a, 0x22, + 0xff, 0xf7, 0xa2, 0xfa, 0x07, 0x98, 0x0b, 0x99, 0xc0, 0x8f, 0x81, 0xf8, + 0xd0, 0x00, 0x07, 0x98, 0x0b, 0x99, 0x80, 0x8f, 0x81, 0xf8, 0xd1, 0x00, + 0xf7, 0xf7, 0x23, 0xfb, 0x06, 0x98, 0x20, 0x99, 0x30, 0xf9, 0x11, 0x00, + 0x03, 0x90, 0x07, 0x98, 0x41, 0x6b, 0x81, 0x63, 0xf8, 0xf7, 0xec, 0xf9, + 0x07, 0x9d, 0x68, 0x63, 0x28, 0x6b, 0x40, 0x1c, 0x28, 0x63, 0x20, 0x98, + 0x06, 0xeb, 0x80, 0x00, 0x11, 0x90, 0x03, 0x98, 0xfc, 0xf7, 0x6e, 0xf9, + 0xdf, 0xf8, 0xf4, 0x18, 0xfc, 0xf7, 0x84, 0xf9, 0xdf, 0xf8, 0xf0, 0x18, + 0xfc, 0xf7, 0x80, 0xf9, 0x00, 0xf0, 0xc9, 0xfa, 0x11, 0x99, 0x88, 0x60, + 0x03, 0x98, 0x68, 0x61, 0x02, 0x98, 0x68, 0x62, 0xb5, 0xf8, 0x40, 0x00, + 0x30, 0xb9, 0x0f, 0x98, 0x00, 0xf0, 0xf0, 0xfb, 0x49, 0xf2, 0x80, 0x28, + 0x06, 0x25, 0xab, 0xe2, 0x00, 0x20, 0x0e, 0x90, 0x00, 0x90, 0x0d, 0x90, + 0x0c, 0x90, 0x10, 0x90, 0x04, 0xa8, 0x00, 0xf0, 0xea, 0xfb, 0x05, 0x00, + 0x1d, 0xd1, 0x0b, 0x98, 0x90, 0xf8, 0xd0, 0x10, 0x04, 0x98, 0xff, 0xf7, + 0x7e, 0xfc, 0xef, 0xf3, 0x11, 0x8b, 0x60, 0x20, 0x80, 0xf3, 0x11, 0x88, + 0x20, 0x98, 0xf8, 0xf7, 0x15, 0xfe, 0x20, 0x98, 0x80, 0x19, 0x01, 0x90, + 0x00, 0x20, 0x01, 0x99, 0x08, 0x71, 0x00, 0xf0, 0x9f, 0xfa, 0x00, 0x8c, + 0x48, 0xb9, 0x01, 0x99, 0x88, 0x70, 0x8b, 0xf3, 0x11, 0x88, 0x00, 0x27, + 0x84, 0xe0, 0x04, 0xa8, 0x00, 0xf0, 0xfa, 0xfb, 0x7e, 0xe2, 0x20, 0x98, + 0x00, 0x21, 0xf8, 0xf7, 0xf0, 0xfd, 0x00, 0x28, 0xef, 0xd0, 0x01, 0x20, + 0xed, 0xe7, 0x00, 0x26, 0x12, 0xaa, 0x12, 0xa8, 0x32, 0xf9, 0x26, 0x20, + 0x00, 0xeb, 0x86, 0x0a, 0xd3, 0x17, 0xa2, 0xfb, 0x02, 0x49, 0xba, 0xf9, + 0x02, 0x00, 0x02, 0xfb, 0x03, 0x99, 0x03, 0xfb, 0x02, 0x99, 0xc1, 0x17, + 0xa0, 0xfb, 0x00, 0x23, 0x00, 0xfb, 0x01, 0x33, 0x01, 0xfb, 0x00, 0x33, + 0x49, 0x46, 0xa0, 0x18, 0x59, 0x41, 0xfc, 0xf7, 0xd1, 0xf8, 0x0e, 0x99, + 0xfc, 0xf7, 0x0c, 0xfa, 0x0e, 0x90, 0x19, 0xa8, 0x00, 0xeb, 0x86, 0x0b, + 0x30, 0xf9, 0x26, 0x00, 0xc1, 0x17, 0xa0, 0xfb, 0x00, 0x23, 0xbb, 0xf9, + 0x02, 0x40, 0x00, 0xfb, 0x01, 0x33, 0x01, 0xfb, 0x00, 0x33, 0x4f, 0xea, + 0xe4, 0x79, 0xa4, 0xfb, 0x04, 0x01, 0x04, 0xfb, 0x09, 0x11, 0x09, 0xfb, + 0x04, 0x11, 0x10, 0x18, 0x59, 0x41, 0xfc, 0xf7, 0xb3, 0xf8, 0x00, 0x99, + 0xfc, 0xf7, 0xee, 0xf9, 0x00, 0x90, 0x19, 0xa8, 0xbb, 0xf9, 0x02, 0x40, + 0x30, 0xf9, 0x26, 0xb0, 0xba, 0xf9, 0x02, 0x20, 0x12, 0xa8, 0x4f, 0xea, + 0xe4, 0x79, 0x30, 0xf9, 0x26, 0xc0, 0xa2, 0xfb, 0x04, 0x01, 0xd3, 0x17, + 0x02, 0xfb, 0x09, 0x11, 0x03, 0xfb, 0x04, 0x11, 0xcc, 0xfb, 0x0b, 0x01, + 0xfc, 0xf7, 0x98, 0xf8, 0x0d, 0x99, 0xfc, 0xf7, 0xd3, 0xf9, 0x0d, 0x90, + 0x22, 0x46, 0x12, 0xa8, 0x4b, 0x46, 0x30, 0xf9, 0x26, 0x00, 0xa0, 0xfb, + 0x02, 0x49, 0xc1, 0x17, 0x00, 0xfb, 0x03, 0x99, 0x19, 0xa8, 0x01, 0xfb, + 0x02, 0x99, 0x30, 0xf9, 0x26, 0x00, 0xba, 0xf9, 0x02, 0x10, 0x81, 0xfb, + 0x00, 0x01, 0x20, 0x1a, 0x69, 0xeb, 0x01, 0x01, 0xfc, 0xf7, 0x7c, 0xf8, + 0x0c, 0x99, 0xfc, 0xf7, 0xb7, 0xf9, 0x76, 0x1c, 0x07, 0x2e, 0x0c, 0x90, + 0x88, 0xd3, 0x7f, 0x1c, 0x00, 0xf0, 0x10, 0xfa, 0x00, 0x8b, 0x87, 0x42, + 0x19, 0xd2, 0x0f, 0x98, 0x00, 0x88, 0x07, 0x23, 0x12, 0xaa, 0x19, 0xa9, + 0xff, 0xf7, 0x16, 0xfc, 0xf9, 0xf7, 0x57, 0xfe, 0x00, 0x28, 0x3f, 0xf4, + 0x76, 0xaf, 0x07, 0x99, 0x04, 0x20, 0x08, 0x60, 0x7f, 0x1e, 0x04, 0xa8, + 0x00, 0xf0, 0x60, 0xfb, 0x04, 0xa8, 0x00, 0xf0, 0x2a, 0xfb, 0x05, 0x00, + 0xe1, 0xd0, 0x01, 0x20, 0x10, 0x90, 0x04, 0xa8, 0x00, 0xf0, 0x56, 0xfb, + 0x10, 0x98, 0x00, 0x28, 0x02, 0xbf, 0x01, 0x98, 0x00, 0x79, 0x00, 0x28, + 0x05, 0xd1, 0x01, 0x98, 0x80, 0x78, 0x18, 0xb1, 0x0f, 0x25, 0x49, 0xf2, + 0x80, 0x28, 0xcd, 0xe1, 0x06, 0x98, 0x20, 0x99, 0xdf, 0xf8, 0x04, 0xb7, + 0x00, 0xeb, 0x41, 0x07, 0x38, 0x8b, 0xc0, 0xeb, 0xc0, 0x00, 0xfc, 0xf7, + 0x6b, 0xf8, 0x04, 0x46, 0x00, 0x98, 0x21, 0x46, 0xfc, 0xf7, 0x80, 0xf8, + 0xfc, 0xf7, 0xb2, 0xf9, 0x00, 0xf0, 0xc3, 0xf9, 0x06, 0x46, 0x0e, 0x98, + 0x21, 0x46, 0xfc, 0xf7, 0x77, 0xf8, 0xfc, 0xf7, 0xa9, 0xf9, 0x00, 0xf0, + 0xba, 0xf9, 0x81, 0x46, 0x07, 0x9c, 0x01, 0x21, 0x30, 0x46, 0x03, 0xf0, + 0x05, 0xfb, 0x00, 0xf0, 0xe3, 0xfa, 0x00, 0xf0, 0xb8, 0xf9, 0xfc, 0xf7, + 0x61, 0xfa, 0xa0, 0x62, 0x01, 0x21, 0x48, 0x46, 0x03, 0xf0, 0xfa, 0xfa, + 0x00, 0xf0, 0xd8, 0xfa, 0x00, 0xf0, 0xad, 0xf9, 0xfc, 0xf7, 0x56, 0xfa, + 0xe0, 0x62, 0x01, 0x98, 0x80, 0x78, 0x10, 0xb1, 0x49, 0xf2, 0x80, 0x28, + 0x29, 0xe0, 0xf8, 0x8e, 0xfc, 0xf7, 0x42, 0xf8, 0x4f, 0xf0, 0x5e, 0x5a, + 0x00, 0xf0, 0xc3, 0xfa, 0x01, 0x46, 0x30, 0x46, 0xfc, 0xf7, 0xc6, 0xf9, + 0x04, 0xd2, 0x02, 0x98, 0x60, 0x62, 0x49, 0xf2, 0xb2, 0x28, 0x12, 0x25, + 0xb8, 0x8b, 0xfc, 0xf7, 0x31, 0xf8, 0x00, 0xf0, 0xb4, 0xfa, 0x01, 0x46, + 0x48, 0x46, 0xfc, 0xf7, 0xb7, 0xf9, 0x10, 0xd2, 0x02, 0x98, 0x60, 0x62, + 0x49, 0xf2, 0xb2, 0x28, 0x13, 0x25, 0x66, 0x6a, 0x48, 0xf4, 0x02, 0x40, + 0x40, 0xf0, 0xe4, 0x08, 0x01, 0x98, 0x80, 0x78, 0x00, 0x28, 0x00, 0xf0, + 0x27, 0x81, 0x0f, 0x25, 0x66, 0xe1, 0x00, 0x2d, 0xf1, 0xd1, 0x01, 0x98, + 0x04, 0x78, 0xb8, 0x8a, 0xfc, 0xf7, 0x12, 0xf8, 0xdf, 0xf8, 0x30, 0x16, + 0xfc, 0xf7, 0x1e, 0xf8, 0x31, 0x46, 0xfc, 0xf7, 0x97, 0xf9, 0x4f, 0xf0, + 0x00, 0x0a, 0x38, 0xbf, 0x00, 0x20, 0x0b, 0xd3, 0x38, 0x8a, 0xfc, 0xf7, + 0x03, 0xf8, 0xdf, 0xf8, 0x14, 0x16, 0xfc, 0xf7, 0x0f, 0xf8, 0x31, 0x46, + 0xfc, 0xf7, 0x88, 0xf9, 0x16, 0xd2, 0x01, 0x20, 0x04, 0x2c, 0x13, 0xd8, + 0xdf, 0xe8, 0x04, 0xf0, 0x03, 0x0c, 0x05, 0x03, 0x03, 0x00, 0x20, 0xb9, + 0x07, 0xe0, 0x10, 0xb9, 0x4f, 0xf0, 0x04, 0x0a, 0x08, 0xe0, 0x4f, 0xf0, + 0x02, 0x0a, 0x05, 0xe0, 0x10, 0xb9, 0x4f, 0xf0, 0x01, 0x0a, 0x01, 0xe0, + 0x4f, 0xf0, 0x03, 0x0a, 0x01, 0x98, 0x80, 0xf8, 0x00, 0xa0, 0xf7, 0xf7, + 0x5f, 0xf9, 0x01, 0x98, 0x04, 0x78, 0x54, 0xb9, 0x07, 0x9c, 0x00, 0x20, + 0xa0, 0x61, 0xe0, 0x61, 0x20, 0x62, 0x48, 0xf4, 0x02, 0x48, 0xf7, 0xf7, + 0x68, 0xf9, 0x0b, 0x25, 0x1e, 0xe1, 0x48, 0x46, 0x31, 0x46, 0xfb, 0xf7, + 0xdd, 0xff, 0x81, 0x46, 0x0d, 0x98, 0x00, 0x99, 0xfb, 0xf7, 0xd8, 0xff, + 0x4f, 0xf0, 0x8c, 0x47, 0x39, 0x46, 0xfc, 0xf7, 0x61, 0xf9, 0x00, 0xf0, + 0x18, 0xf9, 0x82, 0x46, 0x0c, 0x98, 0x00, 0x99, 0xfb, 0xf7, 0xcc, 0xff, + 0x39, 0x46, 0xfc, 0xf7, 0x57, 0xf9, 0x00, 0xf0, 0x0e, 0xf9, 0x07, 0x46, + 0x50, 0x46, 0x00, 0xf0, 0x38, 0xfa, 0x00, 0x90, 0x39, 0x46, 0x38, 0x46, + 0xfc, 0xf7, 0x4c, 0xf9, 0x00, 0x99, 0xfc, 0xf7, 0xad, 0xf8, 0xfc, 0xf7, + 0xed, 0xf8, 0x01, 0x2c, 0x1c, 0xbf, 0x03, 0x2c, 0x81, 0x46, 0x07, 0x9c, + 0x01, 0x21, 0x48, 0x46, 0x03, 0xf0, 0x48, 0xfa, 0x00, 0xf0, 0x26, 0xfa, + 0x00, 0xf0, 0xfb, 0xf8, 0xfc, 0xf7, 0xa4, 0xf9, 0xa0, 0x61, 0x51, 0x46, + 0xdf, 0xf8, 0x34, 0x05, 0xfc, 0xf7, 0x32, 0xf9, 0xfc, 0xf7, 0x9c, 0xf9, + 0xe0, 0x61, 0x39, 0x46, 0xdf, 0xf8, 0x24, 0x05, 0xfc, 0xf7, 0x2a, 0xf9, + 0xfc, 0xf7, 0x94, 0xf9, 0x20, 0x62, 0xf7, 0xf7, 0x1c, 0xf9, 0x00, 0xf0, + 0xe7, 0xf8, 0x81, 0x8c, 0x61, 0xb1, 0x07, 0x99, 0x03, 0x9a, 0x89, 0x69, + 0x00, 0x8d, 0x89, 0x1a, 0x48, 0xbf, 0x49, 0x42, 0x88, 0x42, 0x03, 0xda, + 0x48, 0xf4, 0x02, 0x48, 0x10, 0x25, 0xc3, 0xe0, 0x02, 0xa8, 0x00, 0x88, + 0xfb, 0xf7, 0x72, 0xff, 0x04, 0x46, 0xdf, 0xf8, 0xf4, 0x04, 0x21, 0x46, + 0xfc, 0xf7, 0x0a, 0xf9, 0xdf, 0xf8, 0xec, 0x14, 0xfb, 0xf7, 0x78, 0xff, + 0x00, 0xf0, 0xc1, 0xf8, 0x01, 0x46, 0x0f, 0x98, 0x33, 0x46, 0x4a, 0x46, + 0x00, 0xf0, 0xc7, 0xf8, 0x07, 0x46, 0xfc, 0xf7, 0x67, 0xf9, 0x10, 0xf1, + 0x01, 0x0f, 0x18, 0xbf, 0x10, 0xf1, 0x02, 0x0f, 0x49, 0xf2, 0xcb, 0x21, + 0x05, 0xd0, 0x10, 0xf1, 0x03, 0x0f, 0x18, 0xbf, 0x10, 0xf1, 0x04, 0x0f, + 0x05, 0xd1, 0x07, 0x9a, 0x02, 0x98, 0x50, 0x62, 0x88, 0x46, 0x07, 0x25, + 0x96, 0xe0, 0x06, 0x98, 0x20, 0x9a, 0x00, 0xeb, 0x42, 0x06, 0xb0, 0x88, + 0x28, 0xb9, 0x07, 0x9a, 0x02, 0x98, 0x50, 0x62, 0x88, 0x46, 0x09, 0x25, + 0x8a, 0xe0, 0xb0, 0x89, 0xfb, 0xf7, 0x3a, 0xff, 0xdf, 0xf8, 0x8c, 0x14, + 0xfc, 0xf7, 0xd4, 0xf8, 0x11, 0x99, 0x89, 0x68, 0x81, 0x46, 0x38, 0x46, + 0xfb, 0xf7, 0x40, 0xff, 0x01, 0x21, 0x03, 0xf0, 0xd5, 0xf9, 0x00, 0xf0, + 0xb3, 0xf9, 0x00, 0x90, 0x00, 0xf0, 0xb3, 0xf9, 0x00, 0xf0, 0xae, 0xf9, + 0x21, 0x46, 0xfc, 0xf7, 0x25, 0xf8, 0x82, 0x46, 0x11, 0xe0, 0x4f, 0xf0, + 0x7c, 0x50, 0x00, 0xf0, 0xa8, 0xf9, 0x81, 0x46, 0x00, 0x98, 0x00, 0xf0, + 0xa4, 0xf9, 0x00, 0xf0, 0x9f, 0xf9, 0x21, 0x46, 0xfc, 0xf7, 0x16, 0xf8, + 0x07, 0x99, 0x82, 0x46, 0x08, 0x20, 0x08, 0x60, 0x50, 0x46, 0xfc, 0xf7, + 0x17, 0xf9, 0x07, 0xb2, 0xb7, 0xf5, 0x52, 0x7f, 0xe7, 0xd2, 0x30, 0x89, + 0xfb, 0xf7, 0x06, 0xff, 0x00, 0xf0, 0x8c, 0xf9, 0x06, 0x46, 0x38, 0x46, + 0xfb, 0xf7, 0xf6, 0xfe, 0x01, 0x46, 0x30, 0x46, 0xfc, 0xf7, 0xa2, 0xf9, + 0x9c, 0xbf, 0xb2, 0x46, 0x0a, 0x25, 0x50, 0x46, 0xfc, 0xf7, 0x00, 0xf9, + 0x06, 0x46, 0xcf, 0xe6, 0x06, 0x98, 0x20, 0x99, 0x00, 0xeb, 0x41, 0x02, + 0xd1, 0x8d, 0x53, 0x8e, 0x5a, 0x18, 0xcb, 0x1a, 0xb6, 0xb2, 0xb2, 0x42, + 0xb4, 0xbf, 0x4f, 0xf0, 0x01, 0x0c, 0x4f, 0xf0, 0x00, 0x0c, 0x9e, 0x42, + 0xb4, 0xbf, 0x4f, 0xf0, 0x01, 0x0b, 0x4f, 0xf0, 0x00, 0x0b, 0x5b, 0xea, + 0x0c, 0x04, 0x13, 0xd0, 0x20, 0x9d, 0x28, 0x18, 0x90, 0xf8, 0x2c, 0x00, + 0x10, 0xb1, 0x02, 0x28, 0x02, 0xd0, 0x07, 0xe0, 0x0e, 0x46, 0x07, 0xe0, + 0xbc, 0xf1, 0x00, 0x0f, 0x0c, 0xbf, 0x1e, 0x46, 0x16, 0x46, 0x01, 0xe0, + 0x07, 0x98, 0x46, 0x6a, 0x11, 0x25, 0x01, 0xe0, 0x49, 0xf6, 0xe4, 0x28, + 0x20, 0x98, 0x0f, 0xf2, 0xc4, 0x34, 0x4f, 0xea, 0x40, 0x0b, 0x30, 0x04, + 0x01, 0x0e, 0x34, 0xf8, 0x1b, 0x00, 0xf8, 0xf7, 0x9b, 0xf9, 0x04, 0xeb, + 0x4b, 0x00, 0xf1, 0xb2, 0x40, 0x88, 0xf8, 0xf7, 0x95, 0xf9, 0x07, 0x98, + 0xb6, 0xb2, 0x46, 0x62, 0x42, 0x46, 0x07, 0x98, 0x29, 0x46, 0x03, 0xf0, + 0x15, 0xf9, 0x28, 0x46, 0x21, 0xb0, 0xbd, 0xe8, 0xf0, 0x8f, 0x4f, 0xf0, + 0x64, 0x51, 0xfc, 0xf7, 0x43, 0xb8, 0x01, 0x46, 0xd9, 0x48, 0xfc, 0xf7, + 0xb6, 0xba, 0xd2, 0x49, 0xfc, 0xf7, 0x3c, 0xb8, 0x06, 0x98, 0x20, 0x99, + 0x00, 0xeb, 0x41, 0x00, 0x70, 0x47, 0x2d, 0xe9, 0xf6, 0x4f, 0x04, 0x46, + 0x1d, 0x46, 0x87, 0xb0, 0x28, 0x46, 0x00, 0x21, 0xfc, 0xf7, 0x1c, 0xf8, + 0x04, 0xd2, 0x20, 0x46, 0x00, 0xf0, 0x1a, 0xf9, 0xce, 0x48, 0x07, 0xe1, + 0x60, 0x88, 0x10, 0x28, 0x1d, 0xda, 0x0c, 0x22, 0x07, 0x99, 0x02, 0xfb, + 0x00, 0x40, 0x01, 0x61, 0x60, 0x88, 0x08, 0x99, 0x02, 0xfb, 0x00, 0x40, + 0x41, 0x61, 0x29, 0x46, 0x60, 0x88, 0x02, 0xfb, 0x00, 0x40, 0x85, 0x61, + 0xa0, 0x68, 0xfc, 0xf7, 0x01, 0xf8, 0x38, 0xbf, 0xa5, 0x60, 0x03, 0xd3, + 0x00, 0xf0, 0xf1, 0xf8, 0x38, 0xbf, 0xe5, 0x60, 0x60, 0x88, 0x40, 0x1c, + 0x60, 0x80, 0x08, 0x98, 0xe6, 0xe0, 0x8b, 0x46, 0x00, 0x26, 0x8a, 0x46, + 0x88, 0x46, 0x89, 0x46, 0x02, 0x91, 0x06, 0x91, 0x05, 0x91, 0xad, 0xf8, + 0x10, 0x10, 0x00, 0x27, 0x0c, 0x20, 0x00, 0xfb, 0x07, 0x40, 0x03, 0x90, + 0x59, 0x46, 0x00, 0x69, 0x01, 0x90, 0x7f, 0x1c, 0xfb, 0xf7, 0x56, 0xff, + 0x83, 0x46, 0x03, 0x98, 0x40, 0x69, 0x00, 0x90, 0x31, 0x46, 0xfb, 0xf7, + 0x4f, 0xff, 0x06, 0x46, 0x01, 0x98, 0x00, 0x99, 0xfb, 0xf7, 0xe6, 0xff, + 0x49, 0x46, 0xfb, 0xf7, 0x47, 0xff, 0x81, 0x46, 0x01, 0x98, 0x01, 0x46, + 0xfb, 0xf7, 0xde, 0xff, 0x51, 0x46, 0xfb, 0xf7, 0x3f, 0xff, 0x82, 0x46, + 0x00, 0x98, 0x01, 0x46, 0xfb, 0xf7, 0xd6, 0xff, 0x41, 0x46, 0xfb, 0xf7, + 0x37, 0xff, 0x10, 0x2f, 0x80, 0x46, 0xd3, 0xd3, 0x4f, 0xf0, 0x83, 0x40, + 0x00, 0xf0, 0xb3, 0xf8, 0x07, 0x46, 0x58, 0x46, 0x00, 0xf0, 0xb2, 0xf8, + 0x01, 0x46, 0x38, 0x46, 0xfb, 0xf7, 0xb4, 0xfe, 0x07, 0x46, 0x4f, 0xf0, + 0x83, 0x40, 0x41, 0x46, 0xfb, 0xf7, 0xbe, 0xff, 0x80, 0x46, 0x30, 0x46, + 0x31, 0x46, 0xfb, 0xf7, 0xb9, 0xff, 0x01, 0x46, 0x40, 0x46, 0xfb, 0xf7, + 0xa5, 0xfe, 0x80, 0x46, 0x4f, 0xf0, 0x83, 0x40, 0x00, 0xf0, 0x9d, 0xf8, + 0x81, 0x46, 0x58, 0x46, 0x31, 0x46, 0xfb, 0xf7, 0xab, 0xff, 0x01, 0x46, + 0x48, 0x46, 0xfb, 0xf7, 0x97, 0xfe, 0x81, 0x46, 0x8d, 0x49, 0x38, 0x46, + 0xfc, 0xf7, 0xaa, 0xf8, 0x21, 0xd8, 0x40, 0x46, 0xfc, 0xf7, 0xa6, 0xf8, + 0x1d, 0xd8, 0x01, 0x20, 0xad, 0xf8, 0x10, 0x00, 0x41, 0x46, 0x38, 0x46, + 0xfb, 0xf7, 0x96, 0xff, 0xfb, 0xf7, 0x3a, 0xff, 0x01, 0x46, 0x48, 0x46, + 0xfb, 0xf7, 0x02, 0xfe, 0x05, 0x90, 0x39, 0x46, 0x48, 0x46, 0xfb, 0xf7, + 0xfd, 0xfd, 0x02, 0x90, 0x00, 0xf0, 0x72, 0xf8, 0x01, 0x46, 0x30, 0x46, + 0xfb, 0xf7, 0x74, 0xfe, 0x4f, 0xf0, 0x76, 0x51, 0xfb, 0xf7, 0x80, 0xff, + 0x06, 0x90, 0x29, 0x46, 0xe0, 0x68, 0xfb, 0xf7, 0x69, 0xff, 0x03, 0xd2, + 0xa1, 0x68, 0x00, 0xf0, 0x5b, 0xf8, 0x26, 0xd3, 0xbd, 0xf8, 0x10, 0x00, + 0x20, 0xb1, 0x05, 0x98, 0x74, 0x49, 0xfb, 0xf7, 0x5d, 0xff, 0x01, 0xd2, + 0x73, 0x4a, 0x1d, 0xe0, 0x02, 0x99, 0x07, 0x98, 0xfb, 0xf7, 0x68, 0xff, + 0x06, 0x99, 0xfb, 0xf7, 0xc9, 0xfe, 0x08, 0x99, 0x06, 0x46, 0xfb, 0xf7, + 0x51, 0xfe, 0x00, 0x21, 0xfb, 0xf7, 0x4c, 0xff, 0x03, 0xd2, 0x08, 0x98, + 0x31, 0x46, 0xfb, 0xf7, 0x49, 0xfe, 0x08, 0x99, 0xfb, 0xf7, 0xc8, 0xfd, + 0x68, 0x49, 0xfc, 0xf7, 0x5b, 0xf8, 0x98, 0xbf, 0x4f, 0xf0, 0x40, 0x42, + 0x00, 0xd9, 0x08, 0x9a, 0xa0, 0x88, 0x0c, 0x21, 0x01, 0xfb, 0x00, 0x40, + 0x07, 0x99, 0x01, 0x61, 0x0c, 0x21, 0xa0, 0x88, 0x01, 0xfb, 0x00, 0x40, + 0x08, 0x99, 0x41, 0x61, 0x0c, 0x21, 0xa0, 0x88, 0x01, 0xfb, 0x00, 0x40, + 0x00, 0x23, 0x85, 0x61, 0xa0, 0x88, 0x40, 0x1c, 0xc1, 0x10, 0x00, 0xeb, + 0x11, 0x71, 0x09, 0x11, 0xa0, 0xeb, 0x01, 0x10, 0xa0, 0x80, 0x0c, 0x20, + 0x00, 0xfb, 0x03, 0x40, 0x85, 0x69, 0xa0, 0x68, 0x29, 0x46, 0xfb, 0xf7, + 0x19, 0xff, 0x38, 0xbf, 0xa5, 0x60, 0x03, 0xd3, 0x00, 0xf0, 0x09, 0xf8, + 0x38, 0xbf, 0xe5, 0x60, 0x5b, 0x1c, 0x10, 0x2b, 0xed, 0xd3, 0x10, 0x46, + 0x09, 0xb0, 0xbd, 0xe8, 0xf0, 0x8f, 0xe1, 0x68, 0x28, 0x46, 0xfb, 0xf7, + 0x07, 0xbf, 0x51, 0x46, 0xfb, 0xf7, 0x16, 0xbf, 0x59, 0x46, 0xfb, 0xf7, + 0x13, 0xbf, 0x49, 0x46, 0xfb, 0xf7, 0x10, 0xbf, 0x00, 0x21, 0x41, 0x80, + 0x81, 0x80, 0x81, 0x60, 0x44, 0x49, 0xc1, 0x60, 0x70, 0x47, 0x38, 0xb5, + 0x04, 0x46, 0x00, 0x21, 0x00, 0x20, 0xf8, 0xf7, 0x9a, 0xfa, 0x20, 0x68, + 0x04, 0xf1, 0x10, 0x01, 0xff, 0xf7, 0x7d, 0xf9, 0x05, 0x00, 0x09, 0xd1, + 0xe0, 0x69, 0x00, 0xf1, 0xd0, 0x01, 0x20, 0x68, 0xff, 0xf7, 0xd0, 0xf9, + 0x20, 0x68, 0xff, 0xf7, 0xb2, 0xf9, 0x05, 0x46, 0x01, 0x2d, 0x0b, 0xd0, + 0x02, 0x2d, 0x0b, 0xd0, 0x0c, 0x2d, 0x0b, 0xd0, 0x11, 0x2d, 0x0b, 0xd0, + 0x13, 0x2d, 0x0b, 0xd0, 0x14, 0x2d, 0x08, 0xbf, 0x0d, 0x25, 0x08, 0xe0, + 0x02, 0x25, 0x06, 0xe0, 0x01, 0x25, 0x04, 0xe0, 0x0e, 0x25, 0x02, 0xe0, + 0x03, 0x25, 0x00, 0xe0, 0x0c, 0x25, 0x20, 0x68, 0xfb, 0xf7, 0x2c, 0xfb, + 0x28, 0x46, 0x32, 0xbd, 0x10, 0xb5, 0x04, 0x46, 0xf8, 0xf7, 0x58, 0xfd, + 0x03, 0x28, 0x06, 0xd1, 0x03, 0xf0, 0x5e, 0xfa, 0x00, 0x21, 0x04, 0xf1, + 0x10, 0x00, 0xfa, 0xf7, 0x58, 0xfa, 0xbd, 0xe8, 0x10, 0x40, 0x00, 0x20, + 0xf8, 0xf7, 0xb8, 0xba, 0x11, 0x4a, 0x22, 0xf8, 0x10, 0x10, 0x70, 0x47, + 0x10, 0xb5, 0x04, 0x46, 0x0e, 0x49, 0x01, 0xeb, 0x44, 0x01, 0x09, 0x8c, + 0x29, 0xb1, 0x01, 0x21, 0xf8, 0xf7, 0xdb, 0xf9, 0x10, 0xb1, 0x01, 0x20, + 0x00, 0xe0, 0x00, 0x20, 0x06, 0x49, 0x61, 0x18, 0x88, 0x70, 0x8a, 0x78, + 0x50, 0x1e, 0x80, 0x41, 0xc0, 0x0f, 0x08, 0x71, 0x10, 0xbd, 0x00, 0x00, + 0xa8, 0xef, 0x00, 0x20, 0xcc, 0xe6, 0x00, 0x20, 0xb0, 0x26, 0x00, 0x20, + 0x78, 0x29, 0x00, 0x20, 0xd8, 0x26, 0x00, 0x20, 0xc0, 0x26, 0x00, 0x20, + 0xd4, 0xac, 0x00, 0x20, 0x00, 0x00, 0xc8, 0x42, 0x00, 0x00, 0xa0, 0x41, + 0x00, 0x00, 0x7a, 0x44, 0xcd, 0xcc, 0x4c, 0x3d, 0x00, 0x00, 0xa0, 0xc1, + 0x0a, 0xd7, 0x23, 0x3c, 0x00, 0x00, 0x20, 0x41, 0x00, 0x00, 0x80, 0xc0, + 0x70, 0x12, 0x83, 0x3a, 0xcd, 0xcc, 0xcc, 0x3d, 0x00, 0x00, 0x40, 0xc0, + 0xce, 0xcc, 0x4c, 0x3d, 0xec, 0x78, 0xad, 0x60, 0x61, 0x09, 0x60, 0x09, + 0x63, 0x09, 0x62, 0x09, 0x01, 0x22, 0x41, 0x1c, 0x03, 0xe0, 0x0a, 0x46, + 0xb0, 0xfb, 0xf2, 0xf1, 0x89, 0x18, 0x49, 0x08, 0x8a, 0x1a, 0x48, 0xbf, + 0x52, 0x42, 0x02, 0x2a, 0xf5, 0xda, 0x01, 0xfb, 0x01, 0xf2, 0x90, 0x42, + 0x38, 0xbf, 0x49, 0x1e, 0xf9, 0xd3, 0x08, 0x46, 0x70, 0x47, 0x30, 0xb5, + 0x4f, 0xf4, 0x80, 0x53, 0x03, 0x60, 0x41, 0x60, 0x02, 0x23, 0x00, 0xeb, + 0x83, 0x05, 0x01, 0xfb, 0x02, 0xf4, 0x55, 0xf8, 0x04, 0x5c, 0x6c, 0x43, + 0x64, 0x0b, 0x40, 0xf8, 0x23, 0x40, 0x5b, 0x1c, 0x08, 0x2b, 0xf2, 0xdb, + 0x30, 0xbd, 0x2d, 0xe9, 0xf0, 0x41, 0x06, 0x9e, 0x00, 0x24, 0x00, 0x25, + 0x26, 0xfa, 0x05, 0xfe, 0x5f, 0xea, 0xce, 0x7e, 0x4f, 0xea, 0xd5, 0x0c, + 0x05, 0xf0, 0x07, 0x07, 0x49, 0xd5, 0xbc, 0xf1, 0x03, 0x0f, 0x01, 0xeb, + 0x87, 0x07, 0x11, 0xd0, 0xbc, 0xf1, 0x01, 0x0f, 0x05, 0xd1, 0x3f, 0x6a, + 0xb2, 0xf9, 0x00, 0xc0, 0xb2, 0xf9, 0x02, 0xe0, 0x1f, 0xe0, 0x3f, 0x68, + 0xbc, 0xf1, 0x02, 0x0f, 0xf6, 0xd1, 0xb2, 0xf9, 0x04, 0xc0, 0xb2, 0xf9, + 0x06, 0xe0, 0x16, 0xe0, 0x93, 0xb1, 0x5f, 0xea, 0x83, 0x7c, 0x4c, 0xbf, + 0x3f, 0x6c, 0x3f, 0x6a, 0x5f, 0xea, 0xc3, 0x7c, 0xe8, 0xd5, 0xb2, 0xf8, + 0x00, 0xc0, 0xb2, 0xf8, 0x04, 0xe0, 0xb2, 0xf8, 0x06, 0x80, 0xf4, 0x44, + 0xb2, 0xf8, 0x02, 0xe0, 0xc6, 0x44, 0x02, 0xe0, 0x00, 0x27, 0xbe, 0x46, + 0xbc, 0x46, 0x0f, 0xfa, 0x8c, 0xfc, 0x07, 0xfb, 0x0c, 0xfc, 0x4f, 0xea, + 0x6c, 0x28, 0x0c, 0xeb, 0x98, 0x5c, 0x4f, 0xea, 0xac, 0x2c, 0x40, 0xf8, + 0x34, 0xc0, 0x0f, 0xfa, 0x8e, 0xfe, 0x07, 0xfb, 0x0e, 0xf7, 0x4f, 0xea, + 0x67, 0x2c, 0x07, 0xeb, 0x9c, 0x57, 0x00, 0xeb, 0xc4, 0x0c, 0x64, 0x1c, + 0xbf, 0x12, 0x15, 0x2c, 0xcc, 0xf8, 0x04, 0x70, 0x02, 0xd2, 0x6d, 0x1c, + 0x20, 0x2d, 0xa9, 0xd3, 0xbd, 0xe8, 0xf0, 0x81, 0x2d, 0xe9, 0xf0, 0x43, + 0x00, 0x24, 0x61, 0xe0, 0x00, 0x26, 0x00, 0xeb, 0x44, 0x05, 0xa8, 0x27, + 0x07, 0xfb, 0x04, 0x27, 0x07, 0xeb, 0xc6, 0x07, 0x57, 0xf8, 0xa8, 0xef, + 0x95, 0xf9, 0x01, 0x80, 0xd7, 0xf8, 0x04, 0x90, 0x10, 0xf9, 0x14, 0xc0, + 0x09, 0xfb, 0x08, 0xf8, 0x0e, 0xfb, 0x0c, 0x8c, 0x52, 0xf8, 0x36, 0xe0, + 0x4f, 0xea, 0x6c, 0x18, 0x0c, 0xeb, 0x98, 0x6c, 0x0e, 0xeb, 0xac, 0x1c, + 0x42, 0xf8, 0x36, 0xc0, 0xd7, 0xf8, 0x04, 0xe0, 0x10, 0xf9, 0x14, 0xc0, + 0x3f, 0x68, 0x0e, 0xfb, 0x0c, 0xfc, 0x95, 0xf9, 0x01, 0xe0, 0x07, 0xfb, + 0x1e, 0xc7, 0x02, 0xeb, 0xc6, 0x0c, 0x4f, 0xea, 0x67, 0x18, 0xdc, 0xf8, + 0x04, 0xe0, 0x07, 0xeb, 0x98, 0x67, 0x76, 0x1c, 0x0e, 0xeb, 0xa7, 0x17, + 0x15, 0x2e, 0xcc, 0xf8, 0x04, 0x70, 0xca, 0xd3, 0x03, 0xeb, 0xc4, 0x06, + 0x95, 0xf9, 0x01, 0xe0, 0xd6, 0xf8, 0x0c, 0x80, 0x10, 0xf9, 0x14, 0x70, + 0xd6, 0xf8, 0x08, 0xc0, 0x08, 0xfb, 0x0e, 0xfe, 0x0c, 0xfb, 0x07, 0xe7, + 0xd3, 0xf8, 0x00, 0xc0, 0x4f, 0xea, 0x67, 0x1e, 0x07, 0xeb, 0x9e, 0x67, + 0x0c, 0xeb, 0xa7, 0x17, 0x1f, 0x60, 0xd6, 0xf8, 0x0c, 0xc0, 0x10, 0xf9, + 0x14, 0x70, 0x95, 0xf9, 0x01, 0x50, 0xb6, 0x68, 0x0c, 0xfb, 0x07, 0xf7, + 0x06, 0xfb, 0x15, 0x75, 0x5e, 0x68, 0x6f, 0x11, 0x05, 0xeb, 0x97, 0x65, + 0x06, 0xeb, 0xa5, 0x15, 0x5d, 0x60, 0x64, 0x1c, 0x8c, 0x42, 0x9b, 0xd3, + 0xbd, 0xe8, 0xf0, 0x83, 0x2d, 0xe9, 0xf0, 0x4f, 0x04, 0x46, 0xad, 0xf2, + 0x5c, 0x4d, 0xa0, 0x68, 0x00, 0x88, 0xc0, 0xf3, 0x01, 0x1a, 0x20, 0x68, + 0x0f, 0x46, 0x81, 0x88, 0x08, 0x0a, 0x00, 0xf0, 0x03, 0x00, 0x8d, 0xf8, + 0x04, 0x00, 0x90, 0x46, 0x01, 0xf0, 0x0f, 0x00, 0x8d, 0xf8, 0x05, 0x00, + 0x00, 0x25, 0x08, 0xeb, 0x85, 0x00, 0xb0, 0xf9, 0x02, 0x00, 0x38, 0xf9, + 0x25, 0x10, 0x00, 0xf0, 0x63, 0xfb, 0xa1, 0x68, 0x91, 0xf8, 0x24, 0x20, + 0x01, 0x46, 0xde, 0xa8, 0x00, 0xeb, 0x45, 0x10, 0xff, 0xf7, 0xfd, 0xfe, + 0x6d, 0x1c, 0x07, 0x2d, 0xeb, 0xd3, 0x00, 0x20, 0x02, 0xae, 0x37, 0xf9, + 0x20, 0x10, 0x46, 0xf8, 0x30, 0x10, 0x02, 0xaa, 0x07, 0xeb, 0x80, 0x01, + 0x02, 0xeb, 0xc0, 0x02, 0xb1, 0xf9, 0x02, 0x10, 0x51, 0x60, 0x40, 0x1c, + 0x05, 0x28, 0xf0, 0xd3, 0x00, 0x27, 0xa8, 0x25, 0x02, 0xe0, 0x00, 0xf0, + 0x29, 0xf8, 0x7f, 0x1c, 0x57, 0x45, 0xfa, 0xd3, 0x05, 0x2f, 0x1f, 0xd2, + 0x00, 0xf0, 0x22, 0xf8, 0xa7, 0xeb, 0x0a, 0x0b, 0x0c, 0xa8, 0x05, 0xfb, + 0x0b, 0x09, 0x02, 0xa8, 0x00, 0xeb, 0xcb, 0x03, 0xa0, 0x68, 0x4a, 0x46, + 0x51, 0x46, 0x0e, 0x30, 0xff, 0xf7, 0x40, 0xff, 0x20, 0x69, 0x9d, 0xf8, + 0x05, 0x30, 0xc0, 0xb2, 0x00, 0x90, 0x06, 0xeb, 0xcb, 0x02, 0x7f, 0x1c, + 0xd2, 0xe9, 0x00, 0x01, 0x0a, 0x46, 0x01, 0x46, 0x48, 0x46, 0xfe, 0xf7, + 0x4f, 0xff, 0xdd, 0xe7, 0x0d, 0xf2, 0x5c, 0x4d, 0xbd, 0xe8, 0xf0, 0x8f, + 0xa0, 0x68, 0x00, 0x6a, 0x9d, 0xf8, 0x04, 0x30, 0x00, 0x90, 0x08, 0xeb, + 0x87, 0x02, 0xde, 0xa8, 0x00, 0xeb, 0x47, 0x11, 0x0c, 0xa8, 0x05, 0xfb, + 0x07, 0x00, 0xc0, 0xe6, 0x2d, 0xe9, 0xf6, 0x4f, 0xdf, 0xb0, 0x04, 0x46, + 0x01, 0x20, 0xa2, 0x68, 0xd2, 0x7e, 0x00, 0x21, 0xfb, 0xf7, 0x84, 0xff, + 0x04, 0xf0, 0x74, 0xf8, 0xcd, 0xe9, 0x0e, 0x01, 0x20, 0x69, 0x00, 0x28, + 0x14, 0xbf, 0xdf, 0xf8, 0x6c, 0x0b, 0xdf, 0xf8, 0x6c, 0x0b, 0x04, 0x90, + 0x00, 0x20, 0x02, 0x90, 0x5f, 0x98, 0x02, 0x99, 0xa8, 0x22, 0x02, 0xfb, + 0x01, 0x00, 0x00, 0x27, 0x03, 0x90, 0x04, 0x98, 0x02, 0x99, 0x00, 0xeb, + 0xc1, 0x00, 0x00, 0xeb, 0x07, 0x22, 0x00, 0xf0, 0xc5, 0xf9, 0x04, 0x46, + 0x88, 0x46, 0x5f, 0x98, 0xa8, 0x21, 0x01, 0xfb, 0x07, 0x00, 0x06, 0x90, + 0x5f, 0x98, 0x02, 0x99, 0x00, 0xeb, 0xc7, 0x00, 0x07, 0x90, 0x5f, 0x98, + 0x00, 0xeb, 0xc1, 0x00, 0x05, 0x90, 0x02, 0x98, 0xb8, 0x42, 0x37, 0xd1, + 0x38, 0xb1, 0xdd, 0xe9, 0x0e, 0x01, 0x22, 0x46, 0x43, 0x46, 0x04, 0xf0, + 0x5f, 0xf8, 0x04, 0x46, 0x88, 0x46, 0x00, 0x25, 0x21, 0xe0, 0xa8, 0x20, + 0x00, 0xfb, 0x05, 0xf2, 0x05, 0x98, 0x13, 0x18, 0xd3, 0xe9, 0x00, 0x01, + 0x07, 0x9b, 0xd6, 0x18, 0xd6, 0xe9, 0x00, 0x23, 0x04, 0xf0, 0xc2, 0xf8, + 0x06, 0x46, 0x03, 0x98, 0x00, 0xeb, 0xc5, 0x02, 0x89, 0x46, 0xd2, 0xe9, + 0x00, 0x01, 0x06, 0x9a, 0x02, 0xeb, 0xc5, 0x0c, 0x6d, 0x1c, 0xdc, 0xe9, + 0x00, 0x23, 0x04, 0xf0, 0xb3, 0xf8, 0x00, 0xf0, 0x7f, 0xf9, 0x00, 0xf0, + 0x6c, 0xf9, 0x04, 0x46, 0x88, 0x46, 0xbd, 0x42, 0xdb, 0xdb, 0x20, 0x46, + 0x41, 0x46, 0x04, 0xf0, 0x79, 0xf9, 0x03, 0x9a, 0x02, 0x9b, 0x02, 0xeb, + 0xc3, 0x02, 0x5c, 0xe0, 0x04, 0x98, 0x02, 0x99, 0x00, 0xeb, 0x01, 0x20, + 0x00, 0xeb, 0xc7, 0x02, 0x00, 0x25, 0x00, 0xf0, 0x71, 0xf9, 0x40, 0xe0, + 0x06, 0x98, 0x00, 0xeb, 0xc5, 0x02, 0xd2, 0xe9, 0x00, 0x01, 0xcd, 0xe9, + 0x0c, 0x01, 0x00, 0xf0, 0x46, 0xf9, 0xcd, 0xe9, 0x0a, 0x01, 0xa8, 0x20, + 0x00, 0xfb, 0x05, 0xf2, 0x07, 0x98, 0x13, 0x18, 0x6d, 0x1c, 0xd3, 0xe9, + 0x00, 0x01, 0xcd, 0xe9, 0x08, 0x01, 0x05, 0x98, 0x10, 0x18, 0xd0, 0xe9, + 0x00, 0xab, 0xdd, 0xe9, 0x08, 0x01, 0x00, 0xf0, 0x28, 0xf9, 0xcd, 0xe9, + 0x00, 0x01, 0xdd, 0xe9, 0x0a, 0x23, 0xdd, 0xe9, 0x0c, 0x01, 0x04, 0xf0, + 0x73, 0xf8, 0xdd, 0xe9, 0x00, 0x23, 0x03, 0xf0, 0xfb, 0xff, 0x00, 0xf0, + 0x2a, 0xf9, 0x04, 0x46, 0x88, 0x46, 0xdd, 0xe9, 0x0c, 0x01, 0x00, 0xf0, + 0x14, 0xf9, 0x82, 0x46, 0x8b, 0x46, 0xdd, 0xe9, 0x0a, 0x23, 0xdd, 0xe9, + 0x08, 0x01, 0x04, 0xf0, 0x5f, 0xf8, 0x02, 0x46, 0x0b, 0x46, 0x50, 0x46, + 0x59, 0x46, 0x04, 0xf0, 0xa3, 0xf9, 0x00, 0xf0, 0x25, 0xf9, 0x06, 0x46, + 0x89, 0x46, 0xbd, 0x42, 0xba, 0xdb, 0x06, 0x9a, 0x00, 0xf0, 0x37, 0xf9, + 0x00, 0xf0, 0x20, 0xf9, 0x05, 0x9a, 0xa8, 0x23, 0x03, 0xfb, 0x07, 0x22, + 0x00, 0xf0, 0x0e, 0xf9, 0x03, 0x9a, 0x02, 0xeb, 0xc7, 0x02, 0xc2, 0xe9, + 0x00, 0x01, 0x02, 0x98, 0x7f, 0x1c, 0xb8, 0x42, 0xbf, 0xf6, 0x49, 0xaf, + 0x40, 0x1c, 0x15, 0x28, 0x02, 0x90, 0xff, 0xf6, 0x3d, 0xaf, 0x00, 0x27, + 0x04, 0x98, 0x00, 0xeb, 0x07, 0x22, 0x7d, 0x1e, 0xd2, 0xe9, 0x2a, 0x01, + 0x03, 0xf0, 0x8e, 0xff, 0x04, 0x46, 0x04, 0x98, 0x00, 0xeb, 0xc7, 0x00, + 0x00, 0xf5, 0xa8, 0x52, 0x88, 0x46, 0x00, 0xf0, 0xff, 0xf8, 0x06, 0x46, + 0x89, 0x46, 0x5f, 0x98, 0xa8, 0x21, 0x01, 0xfb, 0x07, 0x00, 0x03, 0x90, + 0x3d, 0xe0, 0x00, 0xf0, 0xd4, 0xf8, 0xcd, 0xe9, 0x06, 0x01, 0x00, 0xf0, + 0xf5, 0xf8, 0x00, 0xeb, 0x05, 0x10, 0x02, 0x90, 0x5b, 0x46, 0x0a, 0xa8, + 0x00, 0xeb, 0x05, 0x12, 0xd2, 0xe9, 0x00, 0x01, 0x52, 0x46, 0x04, 0xf0, + 0x0d, 0xf8, 0xcd, 0xe9, 0x00, 0x01, 0xdd, 0xf8, 0x08, 0xc0, 0xdd, 0xe9, + 0x06, 0x23, 0xdc, 0xe9, 0x02, 0x01, 0x04, 0xf0, 0x03, 0xf8, 0xdd, 0xe9, + 0x00, 0x23, 0x03, 0xf0, 0x8b, 0xff, 0x00, 0xf0, 0xba, 0xf8, 0x04, 0x46, + 0x0a, 0xa8, 0x00, 0xeb, 0x05, 0x1c, 0x88, 0x46, 0xdd, 0xe9, 0x06, 0x23, + 0xdc, 0xe9, 0x00, 0x01, 0x03, 0xf0, 0xf2, 0xff, 0xdd, 0xf8, 0x08, 0xc0, + 0xcd, 0xe9, 0x00, 0x01, 0xdc, 0xe9, 0x02, 0x23, 0x50, 0x46, 0x59, 0x46, + 0x03, 0xf0, 0xe8, 0xff, 0x00, 0xf0, 0x97, 0xf8, 0x00, 0xf0, 0xb2, 0xf8, + 0x06, 0x46, 0x89, 0x46, 0x6d, 0x1e, 0x00, 0x2d, 0xbf, 0xd5, 0x00, 0xf0, + 0xc3, 0xf8, 0x00, 0xf0, 0xad, 0xf8, 0x00, 0xf0, 0x9c, 0xf8, 0x0a, 0xaa, + 0x02, 0xeb, 0x07, 0x12, 0x7f, 0x1c, 0xc2, 0xe9, 0x02, 0x01, 0x15, 0x2f, + 0x98, 0xdb, 0x14, 0x27, 0x0a, 0xa8, 0x00, 0xeb, 0x07, 0x10, 0xa8, 0x21, + 0xd0, 0xe9, 0x00, 0x48, 0x0a, 0xa8, 0x00, 0xeb, 0x07, 0x10, 0x04, 0x90, + 0xd0, 0xe9, 0x02, 0x69, 0x5f, 0x98, 0x01, 0xfb, 0x07, 0x00, 0x7d, 0x1c, + 0x03, 0x90, 0x41, 0xe0, 0x00, 0xf0, 0x73, 0xf8, 0xcd, 0xe9, 0x08, 0x01, + 0x00, 0xf0, 0x94, 0xf8, 0x00, 0xeb, 0x05, 0x13, 0xd3, 0xe9, 0x00, 0x01, + 0xcd, 0xe9, 0x06, 0x01, 0x5b, 0x46, 0x0a, 0xa8, 0x00, 0xeb, 0x05, 0x10, + 0x02, 0x90, 0x02, 0x46, 0x6d, 0x1c, 0xd2, 0xe9, 0x02, 0x01, 0x52, 0x46, + 0x03, 0xf0, 0xa6, 0xff, 0xcd, 0xe9, 0x00, 0x01, 0xdd, 0xe9, 0x08, 0x23, + 0xdd, 0xe9, 0x06, 0x01, 0x03, 0xf0, 0x9e, 0xff, 0x00, 0xf0, 0x4d, 0xf8, + 0x22, 0x46, 0x43, 0x46, 0x03, 0xf0, 0x24, 0xff, 0x04, 0x46, 0x88, 0x46, + 0xdd, 0xe9, 0x06, 0x01, 0x00, 0xf0, 0x3f, 0xf8, 0xdd, 0xf8, 0x08, 0xc0, + 0x82, 0x46, 0x8b, 0x46, 0xdd, 0xe9, 0x08, 0x23, 0xdc, 0xe9, 0x02, 0x01, + 0x03, 0xf0, 0x88, 0xff, 0x52, 0x46, 0x5b, 0x46, 0x03, 0xf0, 0x10, 0xff, + 0x02, 0x46, 0x0b, 0x46, 0x30, 0x46, 0x49, 0x46, 0x04, 0xf0, 0xc8, 0xf8, + 0x06, 0x46, 0x89, 0x46, 0x15, 0x2d, 0xbb, 0xdb, 0x00, 0xf0, 0x5e, 0xf8, + 0x00, 0xf0, 0x48, 0xf8, 0x00, 0xf0, 0x37, 0xf8, 0x04, 0x9a, 0x7f, 0x1e, + 0xc2, 0xe9, 0x02, 0x01, 0x9e, 0xd5, 0x00, 0x24, 0x0a, 0xa8, 0x00, 0xeb, + 0x04, 0x12, 0xd2, 0xe9, 0x00, 0x01, 0x04, 0xf0, 0x71, 0xf9, 0x60, 0x99, + 0x41, 0xf8, 0x34, 0x00, 0x0a, 0xa8, 0x00, 0xeb, 0x04, 0x12, 0xd2, 0xe9, + 0x02, 0x01, 0x04, 0xf0, 0x67, 0xf9, 0x60, 0x99, 0x01, 0xeb, 0xc4, 0x01, + 0x64, 0x1c, 0x15, 0x2c, 0x48, 0x60, 0xe7, 0xdb, 0x61, 0xb0, 0xbd, 0xe8, + 0xf0, 0x8f, 0x52, 0x46, 0x5b, 0x46, 0x03, 0xf0, 0x4f, 0xbf, 0x02, 0x46, + 0x0b, 0x46, 0xdd, 0xe9, 0x00, 0x01, 0x04, 0xf0, 0x93, 0xb8, 0x03, 0x98, + 0x00, 0xeb, 0xc5, 0x02, 0xd2, 0xe9, 0x00, 0x01, 0x70, 0x47, 0x02, 0x46, + 0x0b, 0x46, 0x20, 0x46, 0x41, 0x46, 0x04, 0xf0, 0x87, 0xb8, 0x0a, 0xaa, + 0x02, 0xeb, 0x07, 0x12, 0x4b, 0x46, 0xc2, 0xe9, 0x00, 0x01, 0x32, 0x46, + 0x28, 0x46, 0x59, 0x46, 0x03, 0xf0, 0x32, 0xbf, 0x32, 0x46, 0x4b, 0x46, + 0x03, 0xf0, 0xba, 0xbe, 0x05, 0x46, 0x8b, 0x46, 0x22, 0x46, 0x43, 0x46, + 0x03, 0xf0, 0x28, 0xbf, 0xd2, 0xe9, 0x00, 0x01, 0x03, 0xf0, 0x82, 0xbe, + 0x5f, 0x98, 0x00, 0xeb, 0xc7, 0x00, 0xa8, 0x21, 0x01, 0xfb, 0x05, 0x00, + 0xd0, 0xe9, 0x00, 0xab, 0x0a, 0xa8, 0x70, 0x47, 0x03, 0x9a, 0xdf, 0xf8, + 0xa0, 0x17, 0x02, 0xeb, 0xc7, 0x0c, 0x00, 0x20, 0xdc, 0xe9, 0x00, 0x23, + 0x04, 0xf0, 0x62, 0xb9, 0x2d, 0xe9, 0xf0, 0x4f, 0x89, 0xb0, 0x90, 0x46, + 0x04, 0x46, 0x12, 0x9a, 0x9b, 0x46, 0x68, 0x46, 0xff, 0xf7, 0x9f, 0xfc, + 0x00, 0x20, 0x00, 0x21, 0x44, 0xf8, 0x30, 0x10, 0x04, 0xeb, 0xc0, 0x02, + 0x40, 0x1c, 0x04, 0x28, 0x51, 0x60, 0xf7, 0xd3, 0x00, 0x27, 0x00, 0x25, + 0x4f, 0xf0, 0x6a, 0x59, 0x2b, 0xfa, 0x05, 0xf0, 0xc0, 0x07, 0x27, 0xd5, + 0x05, 0xf0, 0x07, 0x00, 0x5d, 0xf8, 0x20, 0x00, 0xfb, 0xf7, 0x46, 0xf9, + 0x82, 0x46, 0x58, 0xf8, 0x37, 0x00, 0x51, 0x46, 0xfb, 0xf7, 0xe8, 0xfa, + 0x49, 0x46, 0xfb, 0xf7, 0xe5, 0xfa, 0xee, 0x08, 0x54, 0xf8, 0x36, 0x10, + 0xfb, 0xf7, 0x44, 0xfa, 0x51, 0x46, 0x44, 0xf8, 0x36, 0x00, 0x04, 0xeb, + 0xc6, 0x06, 0x08, 0xeb, 0xc7, 0x00, 0x7f, 0x1c, 0x40, 0x68, 0xfb, 0xf7, + 0xd5, 0xfa, 0x49, 0x46, 0xfb, 0xf7, 0xd2, 0xfa, 0x71, 0x68, 0xfb, 0xf7, + 0x33, 0xfa, 0x15, 0x2f, 0x70, 0x60, 0x02, 0xd2, 0x6d, 0x1c, 0x20, 0x2d, + 0xd0, 0xd3, 0x09, 0xb0, 0xbd, 0xe8, 0xf0, 0x8f, 0x2d, 0xe9, 0xf0, 0x4f, + 0x0d, 0x46, 0x9d, 0xb0, 0x82, 0x46, 0xa8, 0x68, 0x00, 0x88, 0x00, 0x0a, + 0x00, 0xf0, 0x03, 0x04, 0x00, 0x26, 0x0a, 0xeb, 0x86, 0x00, 0xb0, 0xf9, + 0x02, 0x00, 0x3a, 0xf9, 0x26, 0x10, 0x00, 0xf0, 0xa9, 0xf8, 0xa9, 0x68, + 0x20, 0x31, 0x0a, 0x79, 0x00, 0x92, 0x05, 0xf1, 0x14, 0x02, 0x0b, 0x68, + 0x01, 0x46, 0x04, 0xa8, 0x00, 0xeb, 0x46, 0x10, 0xff, 0xf7, 0x96, 0xff, + 0x76, 0x1c, 0x03, 0x2e, 0xe7, 0xd3, 0xa0, 0x07, 0x4c, 0xbf, 0x40, 0x27, + 0x20, 0x27, 0xba, 0xf9, 0x06, 0x00, 0xfb, 0xf7, 0xf3, 0xf8, 0x04, 0xae, + 0x05, 0x46, 0x71, 0x68, 0xf0, 0x6a, 0xfb, 0xf7, 0xf9, 0xf9, 0x83, 0x46, + 0xba, 0xf9, 0x02, 0x00, 0xfb, 0xf7, 0xe8, 0xf8, 0x03, 0x90, 0xba, 0xf9, + 0x04, 0x00, 0xfb, 0xf7, 0xe3, 0xf8, 0x80, 0x46, 0x04, 0x99, 0xb0, 0x6a, + 0xfb, 0xf7, 0xea, 0xf9, 0x81, 0x46, 0xba, 0xf9, 0x00, 0x00, 0xfb, 0xf7, + 0xd9, 0xf8, 0x82, 0x46, 0x04, 0xa8, 0x3f, 0x18, 0x49, 0x46, 0xb8, 0x69, + 0xfb, 0xf7, 0xde, 0xf9, 0x51, 0x46, 0xfb, 0xf7, 0x77, 0xfa, 0x00, 0x90, + 0x41, 0x46, 0x30, 0x69, 0xfb, 0xf7, 0x72, 0xfa, 0x00, 0x99, 0xfb, 0xf7, + 0xd3, 0xf9, 0x01, 0x90, 0x59, 0x46, 0xf8, 0x69, 0xfb, 0xf7, 0xce, 0xf9, + 0x03, 0x99, 0xfb, 0xf7, 0x67, 0xfa, 0x00, 0x90, 0x29, 0x46, 0x70, 0x69, + 0xfb, 0xf7, 0x62, 0xfa, 0x00, 0x99, 0xfb, 0xf7, 0xc3, 0xf9, 0x01, 0x46, + 0x01, 0x98, 0xfb, 0xf7, 0x4b, 0xf9, 0xfb, 0xf7, 0xc5, 0xfa, 0xad, 0xf8, + 0x08, 0x00, 0x49, 0x46, 0xb8, 0x69, 0xfb, 0xf7, 0xb7, 0xf9, 0x03, 0x99, + 0xfb, 0xf7, 0x50, 0xfa, 0x81, 0x46, 0x30, 0x69, 0x00, 0xf0, 0x98, 0xf8, + 0x49, 0x46, 0xfb, 0xf7, 0xad, 0xf9, 0x81, 0x46, 0xf8, 0x69, 0x59, 0x46, + 0xfb, 0xf7, 0xa8, 0xf9, 0x51, 0x46, 0xfb, 0xf7, 0x41, 0xfa, 0x83, 0x46, + 0x70, 0x69, 0x00, 0xf0, 0x15, 0xff, 0x59, 0x46, 0xfb, 0xf7, 0x9e, 0xf9, + 0x49, 0x46, 0xfb, 0xf7, 0x9b, 0xf9, 0xfb, 0xf7, 0xa1, 0xfa, 0x06, 0x46, + 0xe0, 0x07, 0xad, 0xf8, 0x0a, 0x60, 0x21, 0xd5, 0xbd, 0xf8, 0x08, 0x40, + 0xb8, 0x69, 0x00, 0xf0, 0x03, 0xff, 0x83, 0x46, 0xf8, 0x69, 0x00, 0xf0, + 0x73, 0xf8, 0x01, 0x46, 0x58, 0x46, 0xfb, 0xf7, 0x13, 0xf9, 0xfb, 0xf7, + 0x8d, 0xfa, 0x00, 0x19, 0xad, 0xf8, 0x08, 0x00, 0x29, 0x46, 0xb8, 0x69, + 0xfb, 0xf7, 0x1a, 0xfa, 0x04, 0x46, 0xf8, 0x69, 0x00, 0xf0, 0xee, 0xfe, + 0x21, 0x46, 0xfb, 0xf7, 0x77, 0xf9, 0xfb, 0xf7, 0x7d, 0xfa, 0x80, 0x19, + 0xad, 0xf8, 0x0a, 0x00, 0x02, 0x98, 0x1d, 0xb0, 0xbd, 0xe8, 0xf0, 0x8f, + 0x40, 0x43, 0x01, 0xfb, 0x01, 0x00, 0x00, 0xeb, 0xd0, 0x70, 0x40, 0x10, + 0xff, 0xf7, 0x86, 0xbb, 0x01, 0xb4, 0xbd, 0xf9, 0x02, 0x00, 0xbd, 0xf9, + 0x00, 0x10, 0x40, 0x43, 0x01, 0xfb, 0x01, 0x00, 0x01, 0xb0, 0x70, 0x47, + 0x49, 0x43, 0x00, 0xfb, 0x00, 0x10, 0x70, 0x47, 0x38, 0xb5, 0x0d, 0x46, + 0x01, 0x46, 0xfb, 0xf7, 0xef, 0xf9, 0x04, 0x46, 0x28, 0x46, 0x00, 0xf0, + 0x37, 0xf8, 0x21, 0x46, 0xbd, 0xe8, 0x34, 0x40, 0xfb, 0xf7, 0x4a, 0xb9, + 0x2d, 0xe9, 0xf9, 0x42, 0x82, 0xb0, 0x0c, 0x46, 0xbd, 0xf9, 0x0a, 0x00, + 0x15, 0x46, 0xfb, 0xf7, 0x35, 0xf8, 0x07, 0x46, 0xbd, 0xf9, 0x08, 0x00, + 0xfb, 0xf7, 0x30, 0xf8, 0x06, 0x46, 0x20, 0x46, 0x31, 0x46, 0xfb, 0xf7, + 0xd3, 0xf9, 0x81, 0x46, 0x38, 0x46, 0x00, 0xf0, 0x1b, 0xf8, 0x01, 0x46, + 0x48, 0x46, 0xfb, 0xf7, 0xbb, 0xf8, 0xfb, 0xf7, 0x35, 0xfa, 0xad, 0xf8, + 0x00, 0x00, 0x39, 0x46, 0x20, 0x46, 0xfb, 0xf7, 0xc3, 0xf9, 0x04, 0x46, + 0x30, 0x46, 0x00, 0xf0, 0x0b, 0xf8, 0x21, 0x46, 0xfb, 0xf7, 0x20, 0xf9, + 0xfb, 0xf7, 0x26, 0xfa, 0xad, 0xf8, 0x02, 0x00, 0x00, 0x98, 0x04, 0xb0, + 0xbd, 0xe8, 0xf0, 0x82, 0x29, 0x46, 0xfb, 0xf7, 0xb1, 0xb9, 0x0e, 0xb4, + 0x2d, 0xe9, 0xf0, 0x4a, 0x84, 0xb0, 0x81, 0x46, 0x0f, 0x98, 0x00, 0x28, + 0x14, 0xbf, 0x4f, 0xf0, 0xff, 0x37, 0x01, 0x27, 0xdd, 0xe9, 0x0d, 0x45, + 0x93, 0x46, 0x20, 0x46, 0xfb, 0xf7, 0xa0, 0xf9, 0x00, 0x90, 0x38, 0x46, + 0xfa, 0xf7, 0xf4, 0xff, 0x59, 0x46, 0xfb, 0xf7, 0x99, 0xf9, 0xff, 0xf7, + 0xe3, 0xff, 0x01, 0x46, 0x00, 0x98, 0xfb, 0xf7, 0x83, 0xf8, 0x06, 0x46, + 0x20, 0x46, 0x59, 0x46, 0xfb, 0xf7, 0x8e, 0xf9, 0x04, 0x46, 0x38, 0x46, + 0xfa, 0xf7, 0xe2, 0xff, 0x0b, 0x99, 0xfb, 0xf7, 0x87, 0xf9, 0xff, 0xf7, + 0xd1, 0xff, 0x21, 0x46, 0xfb, 0xf7, 0xe6, 0xf8, 0xc9, 0xe9, 0x00, 0x60, + 0x04, 0xb0, 0xbd, 0xe8, 0xf0, 0x0a, 0x5d, 0xf8, 0x10, 0xfb, 0xfe, 0xb5, + 0x06, 0x46, 0x10, 0x46, 0x19, 0x46, 0xfa, 0xf7, 0x9b, 0xff, 0x07, 0x46, + 0xdd, 0xe9, 0x08, 0x01, 0xfa, 0xf7, 0x96, 0xff, 0x39, 0x46, 0xfa, 0xf7, + 0xdf, 0xff, 0x05, 0x46, 0xdd, 0xe9, 0x0a, 0x01, 0xfa, 0xf7, 0x8e, 0xff, + 0x39, 0x46, 0xfa, 0xf7, 0xd7, 0xff, 0x07, 0x46, 0x28, 0x46, 0x39, 0x46, + 0xff, 0xf7, 0x6c, 0xff, 0x04, 0x46, 0x29, 0x46, 0xdf, 0xf8, 0x88, 0x0d, + 0xfb, 0xf7, 0x5a, 0xf9, 0x21, 0x46, 0xfa, 0xf7, 0xc9, 0xff, 0x04, 0x46, + 0x28, 0x46, 0x39, 0x46, 0xff, 0xf7, 0x5e, 0xff, 0x05, 0x46, 0xdf, 0xf8, + 0x74, 0x0d, 0x39, 0x46, 0xfb, 0xf7, 0x4c, 0xf9, 0x29, 0x46, 0xfa, 0xf7, + 0xbb, 0xff, 0xc6, 0xe9, 0x00, 0x40, 0xfe, 0xbd, 0x2d, 0xe9, 0xf0, 0x4f, + 0x07, 0x46, 0x8f, 0xb0, 0x38, 0x68, 0x00, 0x22, 0xc0, 0xe9, 0x06, 0x22, + 0xc0, 0xe9, 0x04, 0x22, 0xc0, 0xe9, 0x02, 0x22, 0x00, 0x24, 0x0d, 0xf1, + 0x04, 0x0a, 0x0d, 0xf1, 0x20, 0x09, 0x38, 0x69, 0x07, 0x23, 0x01, 0xaa, + 0x08, 0xa9, 0xfe, 0xf7, 0x03, 0xfb, 0xf8, 0xf7, 0x44, 0xfd, 0x48, 0xb1, + 0x38, 0x46, 0xfe, 0xf7, 0x96, 0xfb, 0x38, 0x46, 0xfe, 0xf7, 0x79, 0xfb, + 0x64, 0x1e, 0x00, 0x28, 0x40, 0xd0, 0x56, 0xe0, 0x00, 0x25, 0x01, 0xa8, + 0x00, 0xeb, 0x85, 0x06, 0xd7, 0xf8, 0x00, 0xc0, 0xb6, 0xf9, 0x02, 0xb0, + 0x08, 0xa8, 0x00, 0xeb, 0x85, 0x08, 0xdc, 0xe9, 0x02, 0x01, 0x02, 0x46, + 0x0b, 0x46, 0xb8, 0xf9, 0x02, 0xe0, 0x39, 0xf9, 0x25, 0x00, 0x3a, 0xf9, + 0x25, 0x10, 0x0b, 0xfb, 0x0e, 0xfe, 0x01, 0xfb, 0x00, 0xe0, 0xc1, 0x17, + 0x10, 0x18, 0x59, 0x41, 0xcc, 0xe9, 0x02, 0x01, 0x39, 0xf9, 0x25, 0x20, + 0xb6, 0xf9, 0x02, 0x30, 0x3a, 0xf9, 0x25, 0x60, 0x5a, 0x43, 0xdc, 0xe9, + 0x04, 0x01, 0xb8, 0xf9, 0x02, 0x30, 0x06, 0xfb, 0x13, 0x22, 0x80, 0x18, + 0x41, 0xeb, 0xe2, 0x71, 0xcc, 0xe9, 0x04, 0x01, 0x59, 0xf8, 0x25, 0x00, + 0x00, 0x90, 0xff, 0xf7, 0xeb, 0xfe, 0x3e, 0x68, 0x00, 0x21, 0xd6, 0xe9, + 0x06, 0x23, 0x10, 0x18, 0x59, 0x41, 0xc6, 0xe9, 0x06, 0x01, 0x6d, 0x1c, + 0x07, 0x2d, 0xc0, 0xdb, 0x64, 0x1c, 0x80, 0x2c, 0xa9, 0xdb, 0x3a, 0x68, + 0xb8, 0x68, 0x80, 0x8b, 0xd2, 0xe9, 0x06, 0x45, 0xa0, 0xfb, 0x00, 0x23, + 0x4f, 0xf4, 0x60, 0x70, 0xa0, 0xfb, 0x02, 0x68, 0x00, 0xfb, 0x03, 0x88, + 0x45, 0x45, 0x03, 0xd8, 0x2c, 0xbf, 0xb4, 0x42, 0x07, 0x20, 0x00, 0xd3, + 0x00, 0x20, 0x0f, 0xb0, 0xbd, 0xe8, 0xf0, 0x8f, 0x2d, 0xe9, 0xf1, 0x4f, + 0xad, 0xf5, 0x06, 0x7d, 0x84, 0x68, 0x00, 0x68, 0x03, 0x90, 0x20, 0x21, + 0x7e, 0xa8, 0xfb, 0xf7, 0x6d, 0xff, 0x66, 0xa8, 0x60, 0x21, 0xfb, 0xf7, + 0x69, 0xff, 0x3c, 0xa8, 0xa8, 0x21, 0xfb, 0xf7, 0x65, 0xff, 0x12, 0xa8, + 0xa8, 0x21, 0xfb, 0xf7, 0x61, 0xff, 0x07, 0xa8, 0x00, 0x21, 0x00, 0x22, + 0x06, 0xc0, 0x03, 0x98, 0xd4, 0x30, 0x02, 0x90, 0x00, 0x68, 0xfb, 0xf7, + 0x87, 0xf8, 0x05, 0xd1, 0x02, 0x98, 0x40, 0x68, 0xfb, 0xf7, 0x82, 0xf8, + 0x00, 0xf0, 0xf2, 0x80, 0x03, 0x9a, 0x0d, 0xf5, 0xfc, 0x7a, 0xd2, 0xe9, + 0x08, 0x01, 0xff, 0xf7, 0xa5, 0xfe, 0x02, 0x9a, 0x09, 0x90, 0xd2, 0xe9, + 0x00, 0x01, 0xff, 0xf7, 0x9f, 0xfe, 0x04, 0x90, 0x01, 0x20, 0x01, 0x90, + 0x02, 0x98, 0xd0, 0xe9, 0x00, 0x9b, 0x03, 0x98, 0xcd, 0xf8, 0x00, 0xb0, + 0x4b, 0x46, 0xd0, 0xe9, 0x08, 0x9b, 0x49, 0x46, 0x5a, 0x46, 0x05, 0xa8, + 0xff, 0xf7, 0xd1, 0xfe, 0x05, 0x98, 0x04, 0x99, 0xfa, 0xf7, 0xf0, 0xfe, + 0x05, 0x90, 0x4f, 0xf0, 0x8c, 0x49, 0x06, 0x98, 0x04, 0x99, 0xfa, 0xf7, + 0xe9, 0xfe, 0x02, 0x99, 0x06, 0x90, 0x09, 0x89, 0x34, 0xf8, 0x0c, 0x2f, + 0x8d, 0x1a, 0x49, 0x46, 0xfb, 0xf7, 0x6e, 0xf8, 0xfb, 0xf7, 0xd8, 0xf8, + 0xad, 0xf8, 0x06, 0x00, 0x49, 0x46, 0x05, 0x98, 0xfb, 0xf7, 0x66, 0xf8, + 0xfb, 0xf7, 0xd0, 0xf8, 0xad, 0xf8, 0x04, 0x00, 0x0d, 0xf1, 0x48, 0x0b, + 0x0b, 0xe0, 0x00, 0xbf, 0x00, 0x98, 0x41, 0x1e, 0x00, 0x28, 0x00, 0x91, + 0xf9, 0xd1, 0x08, 0xf1, 0x01, 0x08, 0xb8, 0xf1, 0x04, 0x0f, 0x6f, 0xd3, + 0x6d, 0x1c, 0x02, 0x99, 0x09, 0x89, 0xe8, 0xb2, 0x88, 0x42, 0x80, 0xf0, + 0x9f, 0x80, 0xfe, 0xf7, 0x6c, 0xf9, 0x80, 0x03, 0xff, 0xf7, 0xcc, 0xf9, + 0x01, 0x46, 0x20, 0x7e, 0x00, 0x90, 0x00, 0x27, 0x03, 0x98, 0x63, 0x69, + 0x00, 0xf1, 0x28, 0x02, 0x0a, 0xa8, 0xff, 0xf7, 0x2d, 0xfd, 0x0a, 0xa8, + 0x49, 0x46, 0x50, 0xf8, 0x37, 0x00, 0xfb, 0xf7, 0x37, 0xf8, 0xfb, 0xf7, + 0xa1, 0xf8, 0x4a, 0xf8, 0x37, 0x00, 0x49, 0x46, 0x0a, 0xa8, 0x00, 0xeb, + 0xc7, 0x00, 0x40, 0x68, 0xfb, 0xf7, 0x2c, 0xf8, 0xfb, 0xf7, 0x96, 0xf8, + 0x7e, 0xa9, 0x01, 0xeb, 0xc7, 0x01, 0x7f, 0x1c, 0x04, 0x2f, 0x48, 0x60, + 0xe5, 0xdb, 0xe8, 0xb2, 0xfe, 0xf7, 0x41, 0xf9, 0xfa, 0xf7, 0x80, 0xfe, + 0x4f, 0xf0, 0x8d, 0x41, 0xfb, 0xf7, 0x1a, 0xf8, 0x09, 0x99, 0xfb, 0xf7, + 0x17, 0xf8, 0x04, 0x99, 0xfa, 0xf7, 0x86, 0xfe, 0x01, 0xf0, 0x12, 0xff, + 0xff, 0xf7, 0x94, 0xf9, 0x07, 0x46, 0xbd, 0xf8, 0x04, 0x00, 0xad, 0xf8, + 0x1c, 0x00, 0x00, 0x26, 0xbd, 0xf8, 0x06, 0x00, 0xad, 0xf8, 0x1e, 0x00, + 0xbd, 0xf8, 0x04, 0x00, 0xad, 0xf8, 0x20, 0x00, 0xbd, 0xf8, 0x06, 0x00, + 0xad, 0xf8, 0x22, 0x00, 0x22, 0x7e, 0x66, 0xa8, 0x39, 0x46, 0x00, 0xeb, + 0x46, 0x10, 0xff, 0xf7, 0x90, 0xf9, 0x76, 0x1c, 0x03, 0x2e, 0xf5, 0xdb, + 0x07, 0xaa, 0x86, 0x98, 0x80, 0x68, 0x00, 0x6a, 0x00, 0x90, 0x66, 0xa9, + 0x03, 0x98, 0x80, 0x88, 0x00, 0x0a, 0x00, 0xf0, 0x03, 0x03, 0x3c, 0xa8, + 0xff, 0xf7, 0x93, 0xf9, 0x00, 0x26, 0xb0, 0x46, 0x00, 0x27, 0x00, 0x20, + 0x4b, 0xf8, 0x37, 0x00, 0x12, 0xa9, 0x01, 0xeb, 0xc7, 0x01, 0x7f, 0x1c, + 0x15, 0x2f, 0x48, 0x60, 0xf6, 0xdb, 0x61, 0x69, 0x00, 0xeb, 0xc8, 0x02, + 0xd1, 0x40, 0xc9, 0x07, 0x0f, 0xd5, 0x3c, 0xa9, 0x12, 0xaa, 0x51, 0xf8, + 0x36, 0x10, 0x4b, 0xf8, 0x36, 0x10, 0x02, 0xeb, 0xc6, 0x02, 0x3c, 0xa9, + 0x01, 0xeb, 0xc6, 0x01, 0x76, 0x1c, 0x49, 0x68, 0x51, 0x60, 0x15, 0x2e, + 0x02, 0xd2, 0x40, 0x1c, 0x08, 0x28, 0xe6, 0xd3, 0x86, 0x98, 0x00, 0x69, + 0xc0, 0xb2, 0x00, 0x90, 0x0a, 0xeb, 0xc8, 0x02, 0x00, 0x23, 0xd2, 0xe9, + 0x00, 0x01, 0x0a, 0x46, 0x01, 0x46, 0x12, 0xa8, 0xfe, 0xf7, 0xda, 0xf9, + 0x4f, 0xf4, 0xc8, 0x70, 0x00, 0x90, 0x4f, 0xe7, 0x0d, 0xf5, 0x07, 0x7d, + 0xbd, 0xe8, 0xf0, 0x8f, 0x70, 0xb5, 0x82, 0xb0, 0x04, 0x46, 0x00, 0x25, + 0x00, 0x26, 0x54, 0xf8, 0x26, 0x00, 0x00, 0x90, 0x76, 0x1c, 0xff, 0xf7, + 0x9d, 0xfd, 0x45, 0x19, 0x07, 0x2e, 0xf6, 0xd3, 0x28, 0x46, 0x76, 0xbd, + 0x70, 0xb5, 0x82, 0xb0, 0x04, 0x46, 0x00, 0x25, 0x00, 0x26, 0x54, 0xf8, + 0x26, 0x00, 0x00, 0x90, 0xff, 0xf7, 0x8e, 0xfd, 0x85, 0x42, 0x38, 0xbf, + 0x05, 0x46, 0x76, 0x1c, 0x07, 0x2e, 0xf4, 0xd3, 0x28, 0x46, 0x76, 0xbd, + 0x38, 0xb5, 0x00, 0x24, 0x02, 0xfb, 0x02, 0xf5, 0x11, 0xb9, 0xff, 0xf7, + 0xe7, 0xff, 0x03, 0xe0, 0xff, 0xf7, 0xd4, 0xff, 0xc5, 0xeb, 0xc5, 0x05, + 0xa8, 0x42, 0x28, 0xbf, 0x01, 0x24, 0x20, 0x46, 0x32, 0xbd, 0xc9, 0xb2, + 0x51, 0xb1, 0x15, 0x29, 0x08, 0xda, 0xc0, 0x68, 0x00, 0xeb, 0x81, 0x01, + 0x0a, 0x6c, 0x52, 0x1c, 0x0a, 0x64, 0x01, 0x6c, 0x49, 0x1c, 0x01, 0x64, + 0x70, 0x47, 0x03, 0x68, 0x00, 0xf1, 0x08, 0x01, 0x03, 0xf1, 0x14, 0x02, + 0x18, 0x46, 0xff, 0xf7, 0x4d, 0xba, 0x10, 0xb5, 0x82, 0xb0, 0x04, 0x46, + 0x6a, 0x46, 0x00, 0x21, 0x00, 0x20, 0xf7, 0xf7, 0xa2, 0xfc, 0x00, 0x98, + 0xdf, 0xf8, 0x84, 0x29, 0x04, 0x60, 0x00, 0x21, 0x00, 0x20, 0xf7, 0xf7, + 0x26, 0xfd, 0x00, 0x20, 0xf7, 0xf7, 0xdf, 0xfc, 0x13, 0xbd, 0x00, 0x00, + 0x00, 0x20, 0x70, 0x59, 0x00, 0x00, 0x70, 0x59, 0x00, 0x00, 0xf0, 0x3f, + 0x2d, 0xe9, 0xf0, 0x4f, 0x04, 0x46, 0xd3, 0xb0, 0xa3, 0x68, 0x08, 0x93, + 0x20, 0x68, 0x08, 0x9a, 0x05, 0x90, 0xe1, 0x68, 0x06, 0x91, 0x00, 0x21, + 0x10, 0x91, 0x0f, 0x91, 0x0e, 0x91, 0x08, 0x99, 0x24, 0x31, 0x04, 0x91, + 0x05, 0x99, 0x01, 0xf5, 0xcc, 0x71, 0x09, 0x91, 0x05, 0x99, 0x12, 0x88, + 0x89, 0x88, 0x22, 0xf4, 0x00, 0x62, 0x91, 0x42, 0x0b, 0xd1, 0x09, 0x99, + 0x08, 0x9a, 0x49, 0x68, 0x12, 0x6a, 0x91, 0x42, 0x05, 0xd1, 0x09, 0x99, + 0x04, 0x9a, 0x09, 0x7a, 0x12, 0x78, 0x91, 0x42, 0x03, 0xd0, 0x22, 0x69, + 0x06, 0x99, 0xfe, 0xf7, 0x6a, 0xfa, 0x05, 0x98, 0x08, 0x30, 0x07, 0x90, + 0xd0, 0xe9, 0x04, 0x23, 0x00, 0x2b, 0x08, 0xbf, 0x00, 0x2a, 0x0b, 0xd0, + 0xd0, 0xe9, 0x00, 0x23, 0x00, 0x2b, 0x08, 0xbf, 0x00, 0x2a, 0x0c, 0xd1, + 0xd0, 0xe9, 0x02, 0x23, 0x00, 0x2b, 0x08, 0xbf, 0x00, 0x2a, 0x06, 0xd1, + 0x20, 0x46, 0xff, 0xf7, 0xbb, 0xfd, 0x5f, 0xea, 0x00, 0x09, 0x40, 0xf0, + 0xbe, 0x82, 0x00, 0x20, 0x0b, 0x90, 0x6a, 0x46, 0x07, 0x98, 0x0a, 0xc8, + 0x0a, 0xc2, 0x0a, 0xc8, 0x0a, 0xc2, 0x07, 0x98, 0x00, 0x25, 0xd0, 0xe9, + 0x04, 0x23, 0x0c, 0xa8, 0xff, 0xf7, 0x73, 0xfd, 0xdd, 0xe9, 0x0c, 0x01, + 0x05, 0x9a, 0xc2, 0xe9, 0x08, 0x01, 0x00, 0x20, 0xcd, 0xe9, 0x18, 0x00, + 0xcd, 0xe9, 0x0c, 0x00, 0x04, 0x9a, 0x08, 0x98, 0x04, 0x99, 0x04, 0x9b, + 0x40, 0x88, 0x92, 0x89, 0x49, 0x8a, 0xdb, 0x89, 0x03, 0x90, 0x12, 0x18, + 0x64, 0x31, 0x9a, 0x18, 0x51, 0x43, 0x64, 0x22, 0xb1, 0xfb, 0xf2, 0xf1, + 0x01, 0x20, 0x14, 0x91, 0x01, 0x90, 0x0d, 0xe0, 0x02, 0x28, 0x03, 0xd1, + 0x04, 0x99, 0x03, 0x98, 0x89, 0x89, 0x04, 0xe0, 0x03, 0x28, 0x05, 0xd1, + 0x04, 0x99, 0x03, 0x98, 0xc9, 0x89, 0x08, 0x18, 0x80, 0xb2, 0x03, 0x90, + 0x01, 0x20, 0xad, 0xf8, 0x00, 0x00, 0x00, 0xf0, 0xa1, 0xfb, 0x0a, 0x90, + 0x00, 0x20, 0x02, 0x90, 0x76, 0xe0, 0xdd, 0xe9, 0x18, 0x01, 0x0b, 0x46, + 0x00, 0x21, 0xc0, 0x19, 0x59, 0x41, 0xcd, 0xe9, 0x18, 0x01, 0xdd, 0xe9, + 0x0c, 0x23, 0x00, 0x21, 0x12, 0xeb, 0x0b, 0x00, 0x59, 0x41, 0xcd, 0xe9, + 0x0c, 0x01, 0x05, 0x98, 0x00, 0x79, 0x00, 0xf0, 0x0f, 0x00, 0x01, 0x21, + 0x08, 0x30, 0x01, 0xfa, 0x00, 0xf0, 0xc1, 0x17, 0xcd, 0xe9, 0x16, 0x01, + 0x07, 0x98, 0xd0, 0xe9, 0x00, 0x79, 0x00, 0xf0, 0x6b, 0xfb, 0x38, 0x1a, + 0x69, 0xeb, 0x01, 0x01, 0x07, 0x9a, 0x10, 0xeb, 0x0a, 0x00, 0x41, 0xeb, + 0xea, 0x71, 0xc2, 0xe9, 0x00, 0x01, 0x07, 0x98, 0xd0, 0xe9, 0x02, 0x79, + 0x00, 0xf0, 0x5c, 0xfb, 0x3a, 0x1a, 0x15, 0x98, 0x69, 0xeb, 0x01, 0x03, + 0xc1, 0x17, 0x10, 0x18, 0x07, 0x9a, 0x59, 0x41, 0xc2, 0xe9, 0x02, 0x01, + 0x07, 0x98, 0xd0, 0xe9, 0x04, 0x79, 0x00, 0xf0, 0x4d, 0xfb, 0x38, 0x1a, + 0x69, 0xeb, 0x01, 0x01, 0x00, 0x23, 0x07, 0x9a, 0x10, 0xeb, 0x0b, 0x00, + 0x59, 0x41, 0xc2, 0xe9, 0x04, 0x01, 0x1a, 0xa8, 0x50, 0xf8, 0x26, 0x00, + 0x15, 0x90, 0x05, 0x98, 0xd0, 0xe9, 0x08, 0x23, 0x11, 0x46, 0x15, 0x98, + 0x1a, 0x46, 0xff, 0xf7, 0x7f, 0xfc, 0x1a, 0xa9, 0x41, 0xf8, 0x26, 0x00, + 0x1a, 0xa8, 0x21, 0xa9, 0x30, 0xf9, 0x26, 0x00, 0x31, 0xf9, 0x26, 0x10, + 0x40, 0x1a, 0x11, 0x90, 0x13, 0x98, 0xb8, 0xf9, 0x02, 0x10, 0xb0, 0xf9, + 0x02, 0x00, 0x00, 0xf0, 0x14, 0xfb, 0x08, 0x99, 0x49, 0x89, 0x49, 0x43, + 0x81, 0x42, 0x02, 0xd2, 0x0e, 0x98, 0x40, 0x1c, 0x0e, 0x90, 0x76, 0x1c, + 0x07, 0x2e, 0x62, 0xd3, 0x1a, 0xaa, 0x21, 0xa9, 0x20, 0x46, 0xff, 0xf7, + 0xb7, 0xf8, 0x6d, 0x1c, 0x03, 0x98, 0x85, 0x42, 0x80, 0xf0, 0x90, 0x80, + 0x00, 0xf0, 0x28, 0xfb, 0x06, 0x99, 0x0a, 0x98, 0x08, 0x62, 0x6e, 0x1e, + 0xf8, 0xf7, 0x4d, 0xfa, 0x88, 0xb1, 0x00, 0xf0, 0x0e, 0xfb, 0x20, 0x46, + 0xfe, 0xf7, 0x83, 0xf8, 0x5f, 0xea, 0x00, 0x09, 0x35, 0x46, 0x07, 0xd1, + 0x08, 0x99, 0x05, 0x98, 0x09, 0x88, 0x80, 0x88, 0x21, 0xf4, 0x00, 0x61, + 0x88, 0x42, 0xe0, 0xd0, 0xe3, 0xe1, 0x01, 0x98, 0x01, 0x28, 0x31, 0xd0, + 0x0a, 0x98, 0xfa, 0xf7, 0x89, 0xfe, 0x00, 0xf0, 0xf9, 0xfa, 0x40, 0xbb, + 0x02, 0x98, 0x45, 0x1c, 0x01, 0x98, 0x03, 0x28, 0x1b, 0xd1, 0x04, 0x99, + 0xbd, 0xf8, 0x00, 0x00, 0x09, 0x8a, 0x88, 0x42, 0x03, 0xd2, 0x40, 0x1c, + 0xad, 0xf8, 0x00, 0x00, 0x12, 0xe0, 0x04, 0x98, 0xc0, 0x88, 0xfa, 0xf7, + 0x69, 0xfc, 0x00, 0xf0, 0xd4, 0xfa, 0x00, 0xf0, 0xcf, 0xfa, 0x00, 0xf0, + 0xf3, 0xfa, 0x01, 0x46, 0x0a, 0x98, 0xfa, 0xf7, 0xfd, 0xfd, 0x0a, 0x90, + 0x01, 0x20, 0xad, 0xf8, 0x00, 0x00, 0x02, 0x95, 0x02, 0x98, 0x14, 0x99, + 0x88, 0x42, 0x80, 0xf0, 0xdc, 0x81, 0x35, 0x46, 0xad, 0xe7, 0x00, 0xf0, + 0xd3, 0xfa, 0x0a, 0x90, 0x21, 0xa8, 0xff, 0xf7, 0x51, 0xfe, 0x0b, 0x99, + 0x81, 0x42, 0x38, 0xbf, 0x01, 0x46, 0x0b, 0x91, 0x00, 0x26, 0x21, 0xa8, + 0x00, 0xf0, 0xa9, 0xfa, 0x83, 0x46, 0x1a, 0xa8, 0x00, 0xf0, 0xa5, 0xfa, + 0x07, 0x46, 0x1a, 0xa8, 0x00, 0xeb, 0x86, 0x01, 0x13, 0x91, 0x1a, 0xaa, + 0xb1, 0xf9, 0x02, 0x00, 0x32, 0xf9, 0x26, 0x20, 0x21, 0xa9, 0x01, 0xeb, + 0x86, 0x08, 0xb8, 0xf9, 0x02, 0x30, 0x31, 0xf9, 0x26, 0x10, 0x43, 0x43, + 0x02, 0xfb, 0x01, 0x3a, 0x21, 0xa9, 0x1a, 0xaa, 0x31, 0xf9, 0x26, 0x10, + 0x32, 0xf9, 0x26, 0x20, 0x48, 0x43, 0xb8, 0xf9, 0x02, 0x10, 0x02, 0xfb, + 0x11, 0x01, 0x08, 0x98, 0x15, 0x91, 0x00, 0x89, 0x40, 0x43, 0x58, 0x45, + 0x03, 0xd2, 0x10, 0x98, 0x40, 0x1c, 0x10, 0x90, 0x69, 0xe7, 0xb8, 0x42, + 0xbf, 0xf4, 0xf9, 0xae, 0x0f, 0x98, 0x40, 0x1c, 0x0f, 0x90, 0x62, 0xe7, + 0x01, 0x98, 0x40, 0x1c, 0xc0, 0xb2, 0x04, 0x28, 0x01, 0x90, 0xff, 0xf6, + 0xd7, 0xae, 0x00, 0xf0, 0x80, 0xfa, 0x03, 0xa8, 0x00, 0x21, 0x00, 0x88, + 0xcd, 0xe9, 0x00, 0x01, 0x07, 0x26, 0x04, 0x98, 0x80, 0x7e, 0x00, 0x28, + 0x60, 0xd0, 0x04, 0x98, 0xc0, 0x8b, 0xfa, 0xf7, 0xf9, 0xfb, 0x00, 0xf0, + 0x64, 0xfa, 0xdf, 0xf8, 0x04, 0x16, 0xfa, 0xf7, 0x03, 0xfc, 0x00, 0xf0, + 0x81, 0xfa, 0x05, 0x46, 0x04, 0x98, 0x82, 0x8b, 0xdd, 0xe9, 0x00, 0x01, + 0xa2, 0xfb, 0x00, 0x79, 0x02, 0xfb, 0x01, 0x99, 0xa2, 0xfb, 0x07, 0x01, + 0x02, 0xfb, 0x09, 0x11, 0xa6, 0xfb, 0x00, 0x79, 0x06, 0xfb, 0x01, 0x99, + 0x38, 0x46, 0x49, 0x46, 0xfa, 0xf7, 0xae, 0xfb, 0xff, 0xf7, 0xc4, 0xfb, + 0x03, 0xf0, 0xf4, 0xfc, 0x02, 0x46, 0x20, 0x69, 0x0b, 0x46, 0x01, 0x28, + 0x0c, 0xbf, 0x02, 0x21, 0x01, 0x21, 0x00, 0x25, 0xef, 0xf3, 0x11, 0x8a, + 0x60, 0x20, 0x80, 0xf3, 0x11, 0x88, 0x09, 0x98, 0xc0, 0x7a, 0x38, 0xbb, + 0x09, 0x98, 0x80, 0x7a, 0x80, 0xb1, 0xdd, 0xe9, 0x0c, 0x70, 0x83, 0x42, + 0x08, 0xd8, 0x28, 0xbf, 0xba, 0x42, 0x05, 0xd2, 0x09, 0x9a, 0x95, 0x72, + 0x01, 0x20, 0xfe, 0xf7, 0x86, 0xf8, 0x17, 0xe0, 0x00, 0x20, 0xfe, 0xf7, + 0x82, 0xf8, 0x12, 0xe0, 0xdd, 0xe9, 0x0c, 0x23, 0x4b, 0x45, 0x0f, 0xd8, + 0x28, 0xbf, 0xba, 0x42, 0x0c, 0xd2, 0x09, 0x9a, 0x01, 0x20, 0x90, 0x72, + 0x00, 0x20, 0xfe, 0xf7, 0x74, 0xf8, 0xa0, 0x68, 0x90, 0xf8, 0x3f, 0x10, + 0x20, 0x69, 0xfe, 0xf7, 0xd9, 0xf8, 0x0f, 0x25, 0x8a, 0xf3, 0x11, 0x88, + 0x00, 0x2d, 0x72, 0xd1, 0x08, 0x98, 0x80, 0x8b, 0xdd, 0xe9, 0x00, 0x23, + 0xa0, 0xfb, 0x02, 0x79, 0x00, 0xfb, 0x03, 0x99, 0xa0, 0xfb, 0x07, 0x23, + 0x00, 0xfb, 0x09, 0x33, 0xa6, 0xfb, 0x02, 0x01, 0x06, 0xfb, 0x03, 0x11, + 0xdd, 0xe9, 0x0c, 0x23, 0x8b, 0x42, 0x07, 0xd8, 0x28, 0xbf, 0x82, 0x42, + 0x04, 0xd2, 0x21, 0x68, 0x00, 0xf0, 0x09, 0xfa, 0x07, 0x20, 0xdb, 0xe1, + 0x10, 0x9a, 0x02, 0x2a, 0x07, 0xd3, 0xa3, 0x68, 0x22, 0x69, 0x06, 0x99, + 0x05, 0x98, 0xfe, 0xf7, 0x66, 0xf8, 0x08, 0x20, 0xd0, 0xe1, 0xdd, 0xe9, + 0x18, 0x23, 0x8b, 0x42, 0x03, 0xd8, 0x2c, 0xbf, 0x82, 0x42, 0x05, 0x20, + 0xf6, 0xd3, 0x0f, 0x98, 0x04, 0x28, 0x03, 0xd3, 0x00, 0xf0, 0xee, 0xf9, + 0x06, 0x20, 0xc1, 0xe1, 0x0e, 0x98, 0x03, 0x28, 0x03, 0xd3, 0x00, 0xf0, + 0xe7, 0xf9, 0x0a, 0x20, 0xba, 0xe1, 0xdd, 0xe9, 0x0c, 0x01, 0xdd, 0xe9, + 0x00, 0x23, 0xfb, 0xf7, 0x67, 0xf8, 0xfa, 0xf7, 0x29, 0xfb, 0xfa, 0xf7, + 0x99, 0xfc, 0x01, 0xf0, 0xf1, 0xfb, 0x07, 0x90, 0x11, 0x25, 0x0f, 0xf2, + 0x80, 0x56, 0x0f, 0xf2, 0xd4, 0x47, 0x28, 0xa8, 0x39, 0x46, 0xa8, 0x22, + 0xfd, 0xf7, 0x60, 0xfc, 0xd6, 0xe9, 0x00, 0x01, 0x28, 0xab, 0x01, 0x22, + 0x43, 0xf8, 0x35, 0x20, 0x00, 0x23, 0x22, 0x69, 0xd2, 0xb2, 0x00, 0x92, + 0x6d, 0x1c, 0x0a, 0x46, 0x01, 0x46, 0x28, 0xa8, 0xfd, 0xf7, 0xfe, 0xfe, + 0x15, 0x2d, 0xe8, 0xd3, 0x20, 0x46, 0xff, 0xf7, 0x09, 0xfc, 0x20, 0x46, + 0xff, 0xf7, 0x6d, 0xfd, 0x20, 0x46, 0xfd, 0xf7, 0x1e, 0xff, 0x05, 0x00, + 0x03, 0xd0, 0x00, 0xf0, 0xa2, 0xf9, 0x28, 0x46, 0x82, 0xe1, 0x00, 0x20, + 0xcd, 0xe9, 0x0c, 0x00, 0x03, 0x90, 0x00, 0x27, 0x00, 0xf0, 0xa2, 0xf9, + 0x80, 0x46, 0x02, 0x97, 0xbb, 0x46, 0xba, 0x46, 0x01, 0x25, 0x00, 0x26, + 0x63, 0xe0, 0x80, 0x88, 0xfa, 0xf7, 0x16, 0xfb, 0x80, 0x46, 0x4f, 0xf0, + 0x00, 0x09, 0x1a, 0xa8, 0x50, 0xf8, 0x29, 0x00, 0x05, 0x9a, 0x00, 0x90, + 0xd2, 0xe9, 0x08, 0x01, 0x0a, 0x46, 0x01, 0x46, 0x00, 0x98, 0xff, 0xf7, + 0xbf, 0xfa, 0x1a, 0xa9, 0x41, 0xf8, 0x29, 0x00, 0x09, 0xf1, 0x01, 0x09, + 0xb9, 0xf1, 0x03, 0x0f, 0xeb, 0xd3, 0x21, 0x46, 0x1a, 0xa8, 0xff, 0xf7, + 0xd3, 0xf9, 0x00, 0x90, 0xbd, 0xf9, 0x00, 0x10, 0xbd, 0xf9, 0x84, 0x00, + 0x40, 0x1a, 0x11, 0x90, 0xbd, 0xf9, 0x02, 0x10, 0xbd, 0xf9, 0x86, 0x00, + 0x00, 0xf0, 0x4d, 0xf9, 0xfa, 0xf7, 0xec, 0xfa, 0x03, 0x99, 0xfa, 0xf7, + 0xeb, 0xfb, 0x03, 0x90, 0x1a, 0x98, 0xff, 0xf7, 0x81, 0xfa, 0xfa, 0xf7, + 0xe3, 0xfa, 0x59, 0x46, 0xfa, 0xf7, 0xe2, 0xfb, 0x83, 0x46, 0x00, 0x98, + 0xff, 0xf7, 0x78, 0xfa, 0xfa, 0xf7, 0xda, 0xfa, 0x51, 0x46, 0xfa, 0xf7, + 0xd9, 0xfb, 0x82, 0x46, 0x21, 0x98, 0xff, 0xf7, 0x6f, 0xfa, 0xfd, 0xf7, + 0x79, 0xfd, 0x5f, 0xfa, 0x80, 0xf9, 0xdd, 0xe9, 0x11, 0x01, 0xff, 0xf7, + 0x71, 0xfa, 0x04, 0x99, 0x49, 0x88, 0x49, 0x43, 0x88, 0x42, 0x3c, 0xbf, + 0x4f, 0x45, 0x4f, 0x46, 0xdd, 0xe9, 0x0c, 0x01, 0xcd, 0xe9, 0x00, 0x01, + 0x21, 0x98, 0xff, 0xf7, 0x59, 0xfa, 0xdd, 0xe9, 0x00, 0x23, 0x00, 0x21, + 0x10, 0x18, 0x59, 0x41, 0xcd, 0xe9, 0x0c, 0x01, 0x76, 0x1c, 0x08, 0x98, + 0xc0, 0x88, 0x86, 0x42, 0x3d, 0xda, 0x00, 0xf0, 0x39, 0xf9, 0xf8, 0xf7, + 0x62, 0xf8, 0xa6, 0xf1, 0x01, 0x09, 0x60, 0xb1, 0x00, 0xf0, 0x21, 0xf9, + 0x20, 0x46, 0xfd, 0xf7, 0x96, 0xfe, 0x4e, 0x46, 0x5f, 0xea, 0x00, 0x09, + 0xea, 0xd0, 0x00, 0xf0, 0x18, 0xf9, 0x48, 0x46, 0xf8, 0xe0, 0x40, 0x46, + 0xfa, 0xf7, 0xa4, 0xfc, 0x00, 0xf0, 0x14, 0xf9, 0x00, 0x28, 0x04, 0x98, + 0x7f, 0xf4, 0x7b, 0xaf, 0x00, 0x8a, 0xad, 0xb2, 0x85, 0x42, 0x38, 0xbf, + 0x6d, 0x1c, 0x10, 0xd3, 0x04, 0x98, 0xc0, 0x88, 0xfa, 0xf7, 0x8a, 0xfa, + 0x00, 0xf0, 0xf5, 0xf8, 0x00, 0xf0, 0xf0, 0xf8, 0x00, 0xf0, 0x14, 0xf9, + 0x00, 0xf0, 0xf8, 0xf8, 0x80, 0x46, 0x02, 0x98, 0x40, 0x1c, 0x01, 0x25, + 0x02, 0x90, 0x02, 0x98, 0x14, 0x99, 0x88, 0x42, 0x03, 0xd3, 0x00, 0xf0, + 0xf0, 0xf8, 0x0d, 0x20, 0xd0, 0xe0, 0x4e, 0x46, 0xbc, 0xe7, 0x00, 0xf0, + 0xea, 0xf8, 0xdd, 0xe9, 0x0c, 0x01, 0x40, 0x1c, 0x41, 0xf1, 0x00, 0x01, + 0xfa, 0xf7, 0x3c, 0xfa, 0x01, 0x46, 0x03, 0x98, 0xfa, 0xf7, 0x76, 0xfa, + 0xfa, 0xf7, 0xa8, 0xfb, 0xb8, 0x49, 0xfa, 0xf7, 0xff, 0xfb, 0x01, 0xf0, + 0xfd, 0xfa, 0x06, 0x99, 0xc8, 0x60, 0x09, 0x98, 0x06, 0x99, 0x00, 0x68, + 0x48, 0x62, 0x06, 0x98, 0xc6, 0x68, 0x08, 0x98, 0x80, 0x88, 0xb0, 0x42, + 0x02, 0xd2, 0x00, 0xf0, 0xd7, 0xf8, 0x33, 0xe0, 0x04, 0x98, 0xb0, 0xf8, + 0x0a, 0x80, 0xb8, 0xf1, 0x00, 0x0f, 0x2f, 0xd0, 0x00, 0x89, 0xfa, 0xf7, + 0x47, 0xfa, 0x00, 0xf0, 0xb2, 0xf8, 0x00, 0xf0, 0xad, 0xf8, 0x00, 0xf0, + 0xd1, 0xf8, 0x05, 0x46, 0x40, 0x46, 0xfa, 0xf7, 0x3d, 0xfa, 0x00, 0xf0, + 0xa8, 0xf8, 0x80, 0x46, 0x30, 0x46, 0xfa, 0xf7, 0x37, 0xfa, 0x06, 0x46, + 0x09, 0x98, 0x00, 0x68, 0xff, 0xf7, 0x1c, 0xfa, 0x81, 0x46, 0x4f, 0xf0, + 0x7e, 0x50, 0x29, 0x46, 0xfa, 0xf7, 0xba, 0xfa, 0x31, 0x46, 0xfa, 0xf7, + 0xc7, 0xfb, 0x49, 0x46, 0xfa, 0xf7, 0x28, 0xfb, 0x01, 0x46, 0x09, 0x98, + 0x01, 0x60, 0x40, 0x46, 0xfa, 0xf7, 0xbe, 0xfb, 0x31, 0x46, 0xfa, 0xf7, + 0xa9, 0xfb, 0x01, 0xd2, 0x09, 0x20, 0x75, 0xe0, 0xa0, 0x68, 0x90, 0xf8, + 0x3a, 0x00, 0xa0, 0xb3, 0x01, 0x21, 0x58, 0x46, 0x01, 0xf0, 0xba, 0xfc, + 0x90, 0x49, 0xfa, 0xf7, 0xad, 0xfb, 0x06, 0x46, 0x01, 0x21, 0x50, 0x46, + 0x01, 0xf0, 0xb2, 0xfc, 0x8c, 0x49, 0xfa, 0xf7, 0xa5, 0xfb, 0x80, 0x46, + 0x30, 0x46, 0x41, 0x46, 0xfa, 0xf7, 0x90, 0xfa, 0x00, 0x21, 0xfa, 0xf7, + 0x8b, 0xfb, 0x05, 0x46, 0x04, 0xd2, 0x40, 0x46, 0x31, 0x46, 0xfa, 0xf7, + 0x87, 0xfa, 0x05, 0x46, 0x84, 0x48, 0xff, 0xf7, 0xdf, 0xf9, 0x05, 0x46, + 0x01, 0xf0, 0x90, 0xfa, 0xe1, 0x68, 0x08, 0x63, 0xa6, 0x68, 0xb0, 0x8f, + 0xfa, 0xf7, 0xec, 0xf9, 0x29, 0x46, 0xfa, 0xf7, 0x75, 0xfb, 0x06, 0xd2, + 0x96, 0xf8, 0x3b, 0x10, 0x20, 0x69, 0xfd, 0xf7, 0x1b, 0xff, 0x0e, 0x20, + 0x3c, 0xe0, 0x20, 0x46, 0xfd, 0xf7, 0x69, 0xfe, 0x0b, 0x98, 0xfe, 0xf7, + 0xfd, 0xfc, 0x06, 0x99, 0x08, 0x85, 0x06, 0x98, 0x06, 0x99, 0x40, 0x8d, + 0x09, 0x8d, 0x88, 0x42, 0x38, 0xbf, 0x08, 0x46, 0x06, 0x99, 0x48, 0x85, + 0xa0, 0x68, 0x00, 0x88, 0x40, 0x05, 0x26, 0xd5, 0x05, 0x98, 0x08, 0x9a, + 0x50, 0xf8, 0xd0, 0x1f, 0x92, 0x7e, 0x51, 0x43, 0x64, 0x22, 0x91, 0xfb, + 0xf2, 0xf1, 0x07, 0x9a, 0x91, 0x42, 0x1a, 0xd2, 0x81, 0x89, 0x02, 0x60, + 0xb9, 0x42, 0x38, 0xbf, 0x87, 0x81, 0x05, 0x98, 0x00, 0x25, 0xd0, 0xe9, + 0x08, 0x23, 0xd4, 0x30, 0xc0, 0xe9, 0x00, 0x23, 0x04, 0xeb, 0xc5, 0x00, + 0x00, 0xf1, 0x14, 0x02, 0xd2, 0xe9, 0x00, 0x01, 0x05, 0x9a, 0x02, 0xeb, + 0xc5, 0x02, 0x28, 0x32, 0x6d, 0x1c, 0xc2, 0xe9, 0x00, 0x01, 0x15, 0x2d, + 0xf0, 0xd3, 0x00, 0x20, 0x53, 0xb0, 0xbd, 0xe8, 0xf0, 0x8f, 0x40, 0x1a, + 0x12, 0x90, 0xdd, 0xe9, 0x11, 0x01, 0xff, 0xf7, 0x41, 0xb9, 0x50, 0xf8, + 0x26, 0x00, 0x13, 0x90, 0xff, 0xf7, 0x32, 0xb9, 0x54, 0x49, 0xfa, 0xf7, + 0xa3, 0xb9, 0x52, 0x49, 0xfa, 0xf7, 0xa0, 0xb9, 0xdd, 0xe9, 0x16, 0x23, + 0x38, 0x46, 0x49, 0x46, 0xfa, 0xf7, 0x76, 0xbe, 0x41, 0x46, 0xfa, 0xf7, + 0x25, 0xbb, 0x20, 0x46, 0xfd, 0xf7, 0x8f, 0xbd, 0x02, 0x46, 0x04, 0x98, + 0x81, 0x8a, 0x21, 0xa8, 0xff, 0xf7, 0x94, 0xbb, 0x04, 0x98, 0x80, 0x88, + 0xfa, 0xf7, 0x7a, 0xb9, 0x05, 0x99, 0x20, 0x69, 0xfd, 0xf7, 0x9e, 0xbb, + 0x20, 0x69, 0x07, 0x23, 0x1a, 0xaa, 0x21, 0xa9, 0xfd, 0xf7, 0xe2, 0xbc, + 0x01, 0x46, 0x3f, 0x48, 0xfa, 0xf7, 0x81, 0xbd, 0x80, 0xb5, 0x41, 0x68, + 0x02, 0x68, 0x00, 0x92, 0x0b, 0x1d, 0xb1, 0xf9, 0x02, 0x20, 0x09, 0x88, + 0x00, 0x69, 0xfb, 0xf7, 0x56, 0xf8, 0x02, 0xbd, 0x2d, 0xe9, 0xf8, 0x43, + 0x04, 0x46, 0x25, 0x69, 0x26, 0x68, 0xd4, 0xf8, 0x0c, 0x90, 0x88, 0x46, + 0xfd, 0xf7, 0x78, 0xfb, 0x00, 0x27, 0x08, 0xb9, 0x0b, 0x27, 0x30, 0xe0, + 0x00, 0x2d, 0x14, 0xbf, 0x32, 0x48, 0x33, 0x48, 0x01, 0x21, 0x01, 0x60, + 0x2a, 0x46, 0xa3, 0x68, 0x49, 0x46, 0x30, 0x46, 0xfd, 0xf7, 0x35, 0xfe, + 0xb8, 0xf1, 0x00, 0x0f, 0x86, 0xf8, 0xa1, 0x71, 0x03, 0xd1, 0xe0, 0x68, + 0xf3, 0x78, 0x42, 0x8b, 0x15, 0xe0, 0x20, 0x46, 0xff, 0xf7, 0xce, 0xff, + 0x07, 0x00, 0x03, 0xd1, 0x20, 0x68, 0x01, 0x78, 0x5a, 0x29, 0x04, 0xda, + 0xe1, 0x68, 0x00, 0x20, 0x88, 0x83, 0x03, 0x27, 0x0d, 0xe0, 0xe2, 0x68, + 0x51, 0x83, 0x40, 0x78, 0x10, 0x83, 0x01, 0x20, 0x90, 0x83, 0xf3, 0x78, + 0x32, 0x78, 0xa0, 0x68, 0x29, 0x46, 0xfd, 0xf7, 0x6f, 0xfc, 0x01, 0x20, + 0xb0, 0x70, 0x38, 0x46, 0xbd, 0xe8, 0xf2, 0x83, 0x10, 0xb5, 0x00, 0x21, + 0x1a, 0x4a, 0x20, 0xfa, 0x01, 0xf3, 0xdb, 0x07, 0x06, 0xd5, 0x4f, 0xf4, + 0xd4, 0x74, 0x04, 0xfb, 0x01, 0x24, 0x01, 0x23, 0x84, 0xf8, 0xa3, 0x31, + 0x49, 0x1c, 0x02, 0x29, 0xf1, 0xd3, 0x10, 0xbd, 0x10, 0xb5, 0x00, 0x21, + 0x11, 0x4a, 0x20, 0xfa, 0x01, 0xf3, 0xdb, 0x07, 0x06, 0xd5, 0x4f, 0xf4, + 0xd4, 0x74, 0x04, 0xfb, 0x01, 0x24, 0x00, 0x23, 0x84, 0xf8, 0xa3, 0x31, + 0x49, 0x1c, 0x02, 0x29, 0xf1, 0xd3, 0x10, 0xbd, 0xae, 0x47, 0x81, 0x3f, + 0xae, 0x47, 0x81, 0xbf, 0xcb, 0xbe, 0x00, 0x01, 0x00, 0x00, 0xa0, 0x41, + 0x00, 0x00, 0x7a, 0x44, 0x00, 0x00, 0x20, 0x41, 0x00, 0x00, 0xc8, 0x42, + 0x00, 0x00, 0xa0, 0xc1, 0x00, 0x00, 0x50, 0x59, 0x00, 0x00, 0x40, 0x59, + 0x10, 0xb2, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0xb4, 0x50, 0xf8, 0x04, 0x1b, 0x79, 0xb1, 0x02, 0x68, 0x43, 0x68, + 0x12, 0x18, 0x08, 0x30, 0xdc, 0x07, 0x44, 0xbf, 0xa9, 0xf1, 0x01, 0x04, + 0xe3, 0x18, 0x52, 0xf8, 0x04, 0x4b, 0x43, 0xf8, 0x04, 0x4b, 0x09, 0x1f, + 0xf9, 0xd1, 0xec, 0xe7, 0x10, 0xbc, 0x70, 0x47, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x28, 0x07, 0xda, 0xdf, 0xf8, 0xa0, 0x1c, 0x28, 0x22, 0x02, 0xfb, + 0x00, 0x12, 0xd2, 0xe9, 0x02, 0x01, 0x70, 0x47, 0x00, 0x20, 0x00, 0x21, + 0x70, 0x47, 0xf0, 0xb5, 0xdf, 0xf8, 0x8c, 0x3c, 0x0f, 0xf2, 0x48, 0x05, + 0x1b, 0x68, 0x4f, 0xf4, 0x7a, 0x74, 0x0a, 0x46, 0xb3, 0xfb, 0xf4, 0xf3, + 0x00, 0x21, 0x00, 0x24, 0x42, 0xf2, 0x10, 0x77, 0x15, 0xf8, 0x14, 0x60, + 0x7e, 0x43, 0x9e, 0x42, 0x0d, 0xd3, 0x05, 0xeb, 0x44, 0x04, 0x94, 0xf9, + 0x01, 0x40, 0x00, 0x2c, 0x0a, 0xd4, 0x14, 0x70, 0x03, 0x2c, 0x07, 0xbf, + 0x5a, 0x00, 0x02, 0x60, 0xe3, 0x40, 0x03, 0x60, 0x03, 0xe0, 0x64, 0x1c, + 0x05, 0x2c, 0xe9, 0xd3, 0x04, 0x21, 0x08, 0x46, 0xf0, 0xbd, 0x00, 0x00, + 0x02, 0xff, 0x04, 0x03, 0x08, 0x00, 0x10, 0x01, 0x20, 0x02, 0x00, 0x00, + 0xf8, 0xb5, 0x00, 0x24, 0x00, 0x27, 0x0f, 0xf2, 0xf4, 0x25, 0xdf, 0xf8, + 0x24, 0x6c, 0x28, 0x20, 0x78, 0x43, 0xf9, 0xb2, 0x81, 0x53, 0x80, 0x19, + 0x35, 0xf8, 0x17, 0x20, 0x42, 0x80, 0x01, 0x21, 0x80, 0xf8, 0x27, 0x10, + 0x02, 0xf1, 0x22, 0x00, 0x0e, 0x21, 0x00, 0xf0, 0x70, 0xfb, 0x7f, 0x1c, + 0x04, 0x2f, 0xec, 0xdb, 0xdf, 0xf8, 0xfc, 0x5b, 0x68, 0x89, 0xc0, 0xf3, + 0x81, 0x00, 0x80, 0xb1, 0x00, 0x22, 0x10, 0x21, 0x4f, 0xf4, 0x10, 0x70, + 0xf6, 0xf7, 0xfc, 0xfa, 0x03, 0x22, 0x32, 0x21, 0x00, 0x20, 0x00, 0xf0, + 0x36, 0xfc, 0x04, 0x46, 0x4f, 0xf4, 0x10, 0x70, 0x00, 0xf0, 0x20, 0xfc, + 0xec, 0xb9, 0xa8, 0x7a, 0x03, 0x21, 0x08, 0x42, 0x1a, 0xd0, 0x00, 0x22, + 0x10, 0x21, 0x4f, 0xf4, 0x2c, 0x70, 0xf6, 0xf7, 0xe7, 0xfa, 0x03, 0x22, + 0x32, 0x21, 0x01, 0x20, 0x00, 0xf0, 0x21, 0xfc, 0x04, 0x46, 0x4f, 0xf4, + 0x2c, 0x70, 0x00, 0xf0, 0x0b, 0xfc, 0xa8, 0x69, 0xdf, 0xf8, 0xa8, 0x2b, + 0x40, 0x08, 0x00, 0xf5, 0x43, 0x40, 0x50, 0x30, 0x00, 0x21, 0xc2, 0xe9, + 0x00, 0x01, 0xec, 0xb9, 0x68, 0x89, 0x4f, 0xf4, 0xf8, 0x71, 0x08, 0x42, + 0x18, 0xd0, 0x00, 0x22, 0x10, 0x21, 0x4f, 0xf4, 0x50, 0x70, 0xf6, 0xf7, + 0xc7, 0xfa, 0x03, 0x22, 0x4f, 0xf4, 0xfa, 0x71, 0x02, 0x20, 0x00, 0xf0, + 0x00, 0xfc, 0x04, 0x46, 0x03, 0x22, 0x4f, 0xf4, 0xfa, 0x71, 0x03, 0x20, + 0x00, 0xf0, 0xf9, 0xfb, 0x04, 0xb9, 0x04, 0x46, 0x4f, 0xf4, 0x50, 0x70, + 0x00, 0xf0, 0xe2, 0xfb, 0x20, 0x46, 0xf2, 0xbd, 0x2d, 0xe9, 0xf0, 0x47, + 0x16, 0x46, 0x86, 0xb0, 0x04, 0x46, 0x8a, 0x46, 0x35, 0x88, 0x06, 0xf1, + 0x10, 0x01, 0x02, 0xa8, 0xff, 0xf7, 0x55, 0xff, 0x00, 0x28, 0x42, 0xd1, + 0x30, 0x7c, 0x0f, 0xf6, 0x44, 0x51, 0x00, 0xf0, 0x03, 0x00, 0x80, 0x00, + 0x40, 0xf0, 0x13, 0x00, 0x30, 0x74, 0x00, 0x27, 0x4f, 0xf4, 0x7a, 0x70, + 0x51, 0xf8, 0x27, 0x20, 0xa0, 0xfb, 0x02, 0x89, 0xca, 0x45, 0x05, 0xd3, + 0x01, 0xd8, 0x44, 0x45, 0x02, 0xd3, 0x7f, 0x1c, 0x08, 0x2f, 0xf3, 0xd3, + 0x00, 0x2f, 0x18, 0xbf, 0x08, 0x2f, 0x25, 0xd0, 0xc7, 0xf1, 0x07, 0x07, + 0x02, 0x22, 0xba, 0x40, 0xd3, 0x17, 0xa4, 0xfb, 0x02, 0x89, 0x04, 0xfb, + 0x03, 0x99, 0x0a, 0xfb, 0x02, 0x99, 0xcd, 0xe9, 0x04, 0x89, 0x77, 0x74, + 0x00, 0x27, 0x0f, 0xf6, 0x64, 0x31, 0xdd, 0xe9, 0x04, 0x23, 0xcd, 0xe9, + 0x00, 0x23, 0x51, 0xf8, 0x27, 0x80, 0xa0, 0xfb, 0x08, 0x23, 0xdd, 0xe9, + 0x00, 0x89, 0x99, 0x45, 0x04, 0xd8, 0x2e, 0xbf, 0x90, 0x45, 0x7f, 0x1c, + 0x34, 0x2f, 0xee, 0xd3, 0x78, 0x1c, 0x01, 0xd0, 0x36, 0x28, 0x01, 0xd3, + 0x04, 0x20, 0x8c, 0xe0, 0x00, 0x27, 0x0f, 0xf6, 0xdc, 0x41, 0x7a, 0x5c, + 0x82, 0x42, 0x3c, 0xbf, 0x7f, 0x1c, 0x07, 0x2f, 0xf9, 0xd3, 0xc7, 0xf1, + 0x0d, 0x01, 0x41, 0xf0, 0x40, 0x01, 0xb1, 0x74, 0xa0, 0xf1, 0x1e, 0x01, + 0x05, 0x29, 0x34, 0xbf, 0xc2, 0x22, 0xc1, 0x22, 0xf2, 0x74, 0x08, 0x28, + 0x38, 0xbf, 0x04, 0x22, 0x06, 0xd3, 0x11, 0x28, 0x38, 0xbf, 0x06, 0x22, + 0x02, 0xd3, 0x07, 0x22, 0x1a, 0x28, 0x05, 0xd0, 0x08, 0x29, 0x03, 0xd3, + 0x28, 0x28, 0x01, 0xd0, 0x2c, 0x28, 0x01, 0xd3, 0x03, 0x21, 0x00, 0xe0, + 0x02, 0x21, 0x42, 0xea, 0xc1, 0x01, 0x31, 0x75, 0x0f, 0xf6, 0xa0, 0x21, + 0x41, 0x18, 0x11, 0xf8, 0x01, 0x1c, 0x01, 0xf0, 0x0f, 0x01, 0xc9, 0x00, + 0x71, 0x75, 0x1e, 0x28, 0x38, 0xbf, 0x0c, 0x21, 0x03, 0xd3, 0x23, 0x28, + 0x34, 0xbf, 0x0d, 0x21, 0x0e, 0x21, 0xb1, 0x75, 0xd4, 0x22, 0xdf, 0xf8, + 0x38, 0x1a, 0xdf, 0xf8, 0x38, 0x7a, 0x02, 0xfb, 0x05, 0x11, 0x01, 0xeb, + 0x80, 0x00, 0x00, 0x21, 0x50, 0xf8, 0x04, 0x0c, 0x0f, 0xf6, 0x20, 0x42, + 0xc6, 0xf8, 0x17, 0x00, 0x00, 0x20, 0x12, 0xf8, 0x11, 0x30, 0xa7, 0xfb, + 0x03, 0x89, 0xd1, 0x45, 0x06, 0xd8, 0x28, 0xbf, 0xa0, 0x45, 0x03, 0xd2, + 0x49, 0x1c, 0x04, 0x29, 0xf3, 0xd3, 0x02, 0xe0, 0x02, 0xeb, 0x41, 0x00, + 0x40, 0x78, 0xf0, 0x76, 0x4f, 0xf4, 0x7a, 0x71, 0x02, 0x98, 0x01, 0xfb, + 0x00, 0xf4, 0xdd, 0xe9, 0x04, 0x01, 0x00, 0xf0, 0xe9, 0xfc, 0xdd, 0xe9, + 0x04, 0x23, 0x07, 0x46, 0x04, 0xfb, 0x10, 0x20, 0xdf, 0xf8, 0xe0, 0x19, + 0xa1, 0xfb, 0x00, 0x01, 0x00, 0xf0, 0xde, 0xfc, 0x40, 0x1c, 0x40, 0x08, + 0xdf, 0xf8, 0xd4, 0x19, 0x88, 0x42, 0x06, 0xf1, 0x21, 0x01, 0x04, 0xbf, + 0x00, 0x20, 0x7f, 0x1c, 0x0f, 0x70, 0x3f, 0x04, 0x3a, 0x0e, 0x02, 0xf0, + 0x03, 0x02, 0x4a, 0x70, 0xb0, 0x77, 0x01, 0x0a, 0x00, 0x0c, 0x00, 0xf0, + 0x7f, 0x00, 0x86, 0xf8, 0x20, 0x00, 0xf1, 0x77, 0x00, 0x20, 0x06, 0xb0, + 0xbd, 0xe8, 0xf0, 0x87, 0x70, 0xb5, 0x04, 0x46, 0x0f, 0xf2, 0x50, 0x00, + 0x30, 0xf8, 0x14, 0x60, 0x4f, 0xf4, 0x96, 0x71, 0x02, 0x20, 0xf9, 0xf7, + 0x53, 0xfe, 0x00, 0x25, 0x06, 0xf1, 0x8c, 0x46, 0x30, 0x78, 0xc0, 0x07, + 0x04, 0xd5, 0x02, 0x20, 0xf9, 0xf7, 0x62, 0xfe, 0x00, 0x28, 0xf7, 0xd0, + 0x30, 0x78, 0xc0, 0x07, 0x0d, 0xd4, 0x20, 0x46, 0x00, 0xf0, 0x92, 0xf9, + 0x20, 0xb9, 0x02, 0x20, 0xf9, 0xf7, 0x56, 0xfe, 0x00, 0x28, 0xf6, 0xd0, + 0x20, 0x46, 0x00, 0xf0, 0x89, 0xf9, 0x00, 0xb1, 0x01, 0x25, 0x02, 0x20, + 0xf9, 0xf7, 0xc4, 0xfd, 0x28, 0x46, 0x70, 0xbd, 0x40, 0x02, 0xb0, 0x02, + 0x40, 0x03, 0x40, 0x03, 0x2d, 0xe9, 0xf0, 0x4d, 0x80, 0x46, 0x8a, 0x46, + 0x15, 0x46, 0xdf, 0xf8, 0x20, 0x09, 0xdf, 0xf8, 0x38, 0x29, 0x28, 0x21, + 0x01, 0xfb, 0x05, 0x06, 0x00, 0x20, 0x01, 0x23, 0x9a, 0x45, 0x04, 0xd3, + 0x01, 0xd8, 0x90, 0x45, 0x01, 0xd3, 0x02, 0x20, 0x06, 0xe0, 0x82, 0x45, + 0xdf, 0xf8, 0x1c, 0x29, 0x01, 0xd8, 0x90, 0x45, 0x00, 0xd3, 0x01, 0x20, + 0xdf, 0xf8, 0x14, 0x19, 0xdf, 0xf8, 0xf0, 0x28, 0x47, 0x18, 0x20, 0x31, + 0x05, 0xb3, 0x02, 0x2d, 0x3b, 0xd0, 0x62, 0xd2, 0x93, 0x7a, 0x12, 0x7b, + 0x08, 0x70, 0x02, 0xf0, 0x01, 0x0b, 0x3a, 0x78, 0x03, 0xf0, 0x03, 0x04, + 0x3f, 0x21, 0x4f, 0xf4, 0x01, 0x60, 0xf6, 0xf7, 0x6d, 0xf9, 0xba, 0x79, + 0x3f, 0x21, 0x40, 0xf6, 0x11, 0x00, 0xf6, 0xf7, 0x67, 0xf9, 0xfa, 0x78, + 0x3f, 0x21, 0x40, 0xf6, 0x12, 0x00, 0xf6, 0xf7, 0x61, 0xf9, 0x7a, 0x7a, + 0x3f, 0x21, 0x40, 0xf6, 0x13, 0x00, 0x2f, 0xe0, 0x50, 0x89, 0xc0, 0xf3, + 0x81, 0x04, 0x10, 0x7b, 0x3a, 0x78, 0x00, 0xf0, 0x02, 0x0b, 0x3f, 0x21, + 0x4f, 0xf4, 0xa4, 0x60, 0xf6, 0xf7, 0x50, 0xf9, 0xba, 0x79, 0x3f, 0x21, + 0x40, 0xf2, 0x21, 0x50, 0xf6, 0xf7, 0x4a, 0xf9, 0xfa, 0x78, 0x3f, 0x21, + 0x40, 0xf2, 0x22, 0x50, 0xf6, 0xf7, 0x44, 0xf9, 0x7a, 0x7a, 0x3f, 0x21, + 0x40, 0xf2, 0x23, 0x50, 0x12, 0xe0, 0x52, 0x89, 0x12, 0xf4, 0xf8, 0x72, + 0x14, 0x46, 0x18, 0xbf, 0x01, 0x24, 0x48, 0x70, 0x3f, 0x21, 0x3a, 0x7b, + 0x40, 0xf6, 0x1e, 0x00, 0xf6, 0xf7, 0x32, 0xf9, 0xfa, 0x7b, 0x4f, 0xf0, + 0x00, 0x0b, 0x3f, 0x21, 0x40, 0xf6, 0x1f, 0x00, 0xf6, 0xf7, 0x2a, 0xf9, + 0x00, 0x20, 0xc6, 0xe9, 0x02, 0x00, 0x4f, 0xf0, 0xff, 0x31, 0xdf, 0xf8, + 0x5c, 0x08, 0x18, 0xeb, 0x00, 0x02, 0x4a, 0xeb, 0x01, 0x03, 0x01, 0x21, + 0x8b, 0x42, 0xdf, 0xf8, 0x50, 0x08, 0x04, 0xd3, 0x01, 0xd8, 0x82, 0x42, + 0x01, 0xd3, 0x05, 0x20, 0x4b, 0xe0, 0x0c, 0xb9, 0x05, 0x27, 0x47, 0xe0, + 0x32, 0x46, 0x40, 0x46, 0x51, 0x46, 0xff, 0xf7, 0x5b, 0xfe, 0x07, 0x00, + 0x6e, 0xd1, 0x74, 0x88, 0xbb, 0xf1, 0x00, 0x0f, 0x3f, 0xd0, 0x01, 0x2d, + 0x1a, 0xd1, 0x80, 0x21, 0x40, 0xf2, 0x02, 0x20, 0xf6, 0xf7, 0xf6, 0xf8, + 0x01, 0x21, 0x4f, 0xf4, 0x40, 0x70, 0xf6, 0xf7, 0xf1, 0xf8, 0x10, 0x21, + 0x40, 0xf2, 0xca, 0x20, 0xf6, 0xf7, 0xec, 0xf8, 0xf2, 0x7e, 0x1f, 0x21, + 0x40, 0xf6, 0x15, 0x00, 0xf6, 0xf7, 0xf0, 0xf8, 0x40, 0x46, 0x51, 0x46, + 0x00, 0xf0, 0x52, 0xf8, 0x07, 0x46, 0x14, 0xe0, 0x80, 0x21, 0x4f, 0xf4, + 0x00, 0x70, 0xf6, 0xf7, 0xdb, 0xf8, 0x01, 0x21, 0x4f, 0xf4, 0x24, 0x70, + 0xf6, 0xf7, 0xd6, 0xf8, 0x10, 0x21, 0x40, 0xf2, 0x5a, 0x20, 0xf6, 0xf7, + 0xd1, 0xf8, 0xf2, 0x7e, 0x1f, 0x21, 0x40, 0xf2, 0x25, 0x50, 0xf6, 0xf7, + 0xd5, 0xf8, 0x04, 0xf1, 0x42, 0x00, 0x07, 0x21, 0x00, 0xf0, 0x35, 0xf9, + 0x27, 0xb9, 0xc6, 0xe9, 0x02, 0x8a, 0x28, 0x46, 0xfa, 0xf7, 0x66, 0xfe, + 0x38, 0x46, 0xbd, 0xe8, 0xf0, 0x8d, 0x00, 0x21, 0x30, 0x46, 0x00, 0xf0, + 0xaf, 0xf8, 0x28, 0x46, 0xff, 0xf7, 0xf0, 0xfe, 0x08, 0xb9, 0x07, 0x27, + 0xf2, 0xe7, 0x04, 0xf1, 0x08, 0x00, 0x80, 0xb2, 0x00, 0xf1, 0x8c, 0x40, + 0x00, 0x78, 0x00, 0xf0, 0xfd, 0x00, 0x70, 0x75, 0xe0, 0x1d, 0x80, 0xb2, + 0x00, 0xf1, 0x8c, 0x40, 0x00, 0x78, 0x30, 0x77, 0xa0, 0x1d, 0x80, 0xb2, + 0x00, 0xf1, 0x8c, 0x40, 0x01, 0x2d, 0x00, 0x78, 0x00, 0xf0, 0x7f, 0x00, + 0x70, 0x77, 0xd4, 0xd1, 0x40, 0x46, 0x51, 0x46, 0x00, 0xf0, 0x06, 0xf8, + 0x07, 0x46, 0x00, 0xf0, 0x64, 0xf8, 0xcb, 0xe7, 0x06, 0x27, 0xcf, 0xe7, + 0x2d, 0xe9, 0xf0, 0x42, 0xdf, 0xf8, 0x20, 0x47, 0xdf, 0xf8, 0x44, 0x77, + 0xd4, 0xe9, 0x00, 0x23, 0x00, 0x26, 0x84, 0x18, 0x41, 0xeb, 0x03, 0x09, + 0x01, 0x25, 0xa9, 0x45, 0x05, 0xd3, 0x01, 0xd8, 0xbc, 0x42, 0x02, 0xd3, + 0x84, 0x1a, 0x61, 0xeb, 0x03, 0x09, 0xdf, 0xf8, 0xf4, 0x56, 0x05, 0xf1, + 0x80, 0x07, 0xd7, 0xe9, 0x00, 0x01, 0x89, 0x45, 0x08, 0xbf, 0x84, 0x42, + 0x22, 0xd0, 0xc7, 0xe9, 0x00, 0x66, 0x05, 0xf1, 0x78, 0x02, 0x20, 0x46, + 0x49, 0x46, 0xff, 0xf7, 0xc1, 0xfd, 0x06, 0x00, 0x18, 0xd1, 0x00, 0x21, + 0x05, 0xf1, 0x78, 0x00, 0x00, 0xf0, 0x58, 0xf8, 0x02, 0x20, 0xff, 0xf7, + 0x99, 0xfe, 0x70, 0xb1, 0xdf, 0xf8, 0xec, 0x06, 0x81, 0x78, 0x01, 0xf0, + 0xfd, 0x01, 0x79, 0x73, 0x41, 0x78, 0x39, 0x75, 0x00, 0x78, 0xc7, 0xe9, + 0x00, 0x49, 0x00, 0xf0, 0x7f, 0x00, 0x78, 0x75, 0x00, 0xe0, 0x04, 0x26, + 0x30, 0x46, 0xbd, 0xe8, 0xf0, 0x82, 0xdf, 0xf8, 0x94, 0x06, 0x10, 0xb5, + 0xd0, 0xe9, 0x20, 0x23, 0x00, 0x24, 0x00, 0x2b, 0x08, 0xbf, 0x00, 0x2a, + 0x0b, 0xd0, 0x01, 0x21, 0x78, 0x30, 0x00, 0xf0, 0xaf, 0xf8, 0x04, 0x46, + 0x32, 0x20, 0xf9, 0xf7, 0x7d, 0xfc, 0xdf, 0xf8, 0xa8, 0x16, 0x01, 0x20, + 0x08, 0x60, 0x20, 0x46, 0x10, 0xbd, 0xdf, 0xf8, 0x9c, 0x06, 0x00, 0x68, + 0x70, 0x47, 0x38, 0xb5, 0xdf, 0xf8, 0x58, 0x26, 0x04, 0x20, 0xd2, 0xe9, + 0x16, 0x45, 0x00, 0x2d, 0x08, 0xbf, 0x00, 0x2c, 0x0b, 0xd0, 0x01, 0x21, + 0x02, 0xf1, 0x50, 0x00, 0x00, 0xf0, 0x16, 0xf8, 0x32, 0x20, 0xf9, 0xf7, + 0x61, 0xfc, 0xdf, 0xf8, 0x70, 0x16, 0x00, 0x20, 0x08, 0x60, 0x32, 0xbd, + 0x30, 0xb1, 0x01, 0x28, 0x0c, 0xbf, 0xdf, 0xf8, 0x64, 0x06, 0xdf, 0xf8, + 0x64, 0x06, 0x01, 0xe0, 0xdf, 0xf8, 0x60, 0x06, 0x00, 0x78, 0x00, 0xf0, + 0x01, 0x00, 0x70, 0x47, 0x2d, 0xe9, 0xf0, 0x41, 0x07, 0x46, 0xbc, 0x1c, + 0x88, 0x46, 0x25, 0x88, 0xb5, 0xf5, 0x10, 0x7f, 0x0c, 0xd0, 0xb5, 0xf5, + 0x2c, 0x7f, 0xa1, 0x7b, 0x14, 0xd1, 0x40, 0xf2, 0x32, 0x20, 0xf5, 0xf7, + 0xf9, 0xff, 0x62, 0x7e, 0x1f, 0x21, 0x40, 0xf6, 0x15, 0x00, 0x08, 0xe0, + 0xa1, 0x7b, 0x4f, 0xf4, 0x0c, 0x70, 0xf5, 0xf7, 0xef, 0xff, 0x62, 0x7e, + 0x1f, 0x21, 0x40, 0xf2, 0x25, 0x50, 0xf5, 0xf7, 0xf3, 0xff, 0x03, 0xe0, + 0x40, 0xf2, 0x33, 0x20, 0xf5, 0xf7, 0xe4, 0xff, 0x39, 0x46, 0x00, 0x20, + 0x00, 0xf0, 0xd3, 0xf8, 0x17, 0xf8, 0x22, 0x2f, 0xa8, 0x1c, 0x07, 0x21, + 0x80, 0xb2, 0xf5, 0xf7, 0xe3, 0xff, 0xe1, 0x7f, 0x68, 0x1c, 0x00, 0xf0, + 0x44, 0xf8, 0xe1, 0x7b, 0x05, 0xf1, 0x42, 0x00, 0x00, 0xf0, 0x3f, 0xf8, + 0x78, 0x79, 0x28, 0xb1, 0x4f, 0xf4, 0xfa, 0x60, 0xf9, 0xf7, 0x0e, 0xfc, + 0x00, 0x20, 0x78, 0x71, 0xae, 0x1d, 0xb8, 0xf1, 0x00, 0x0f, 0x05, 0xf1, + 0x08, 0x07, 0x12, 0xd1, 0x80, 0x22, 0x80, 0x21, 0xb0, 0xb2, 0xf5, 0xf7, + 0xc7, 0xff, 0x00, 0x22, 0x80, 0x21, 0xb0, 0xb2, 0xf5, 0xf7, 0xc2, 0xff, + 0x00, 0x22, 0x02, 0x21, 0xb8, 0xb2, 0xf5, 0xf7, 0xbd, 0xff, 0x01, 0x22, + 0x01, 0x21, 0x28, 0x46, 0x18, 0xe0, 0x00, 0xf0, 0x99, 0xf8, 0xf5, 0xf7, + 0xb5, 0xff, 0xe0, 0x7e, 0x40, 0xf0, 0x80, 0x01, 0xb0, 0xb2, 0xf5, 0xf7, + 0xa5, 0xff, 0xa1, 0x7e, 0xe8, 0x1d, 0x00, 0xf0, 0x10, 0xf8, 0x00, 0xf0, + 0x84, 0xf8, 0xb8, 0xb2, 0xf5, 0xf7, 0xa6, 0xff, 0x01, 0x20, 0xf9, 0xf7, + 0xdd, 0xfb, 0x00, 0x22, 0x00, 0xf0, 0x85, 0xf8, 0xf5, 0xf7, 0x9e, 0xff, + 0x00, 0x20, 0xbd, 0xe8, 0xf0, 0x81, 0x80, 0xb2, 0xf5, 0xf7, 0x8e, 0xbf, + 0x2d, 0xe9, 0xf0, 0x41, 0x06, 0x46, 0xb4, 0x1c, 0x88, 0x46, 0x25, 0x88, + 0xb5, 0xf5, 0x10, 0x7f, 0x40, 0xf6, 0x15, 0x07, 0x08, 0xd0, 0xa1, 0x7b, + 0xb5, 0xf5, 0x2c, 0x7f, 0x0c, 0xbf, 0x40, 0xf2, 0x32, 0x20, 0x40, 0xf2, + 0x33, 0x20, 0x09, 0xe0, 0xa1, 0x7b, 0x4f, 0xf4, 0x0c, 0x70, 0xf8, 0xf7, + 0x2a, 0xf9, 0x62, 0x7e, 0x1f, 0x21, 0x40, 0xf2, 0x25, 0x50, 0x04, 0xe0, + 0xf8, 0xf7, 0x23, 0xf9, 0x62, 0x7e, 0x1f, 0x21, 0x38, 0x46, 0xf8, 0xf7, + 0x45, 0xf9, 0x31, 0x46, 0x01, 0x20, 0x00, 0xf0, 0x58, 0xf8, 0x96, 0xf8, + 0x22, 0x20, 0xa8, 0x1c, 0x07, 0x21, 0x80, 0xb2, 0xf8, 0xf7, 0x3a, 0xf9, + 0xe1, 0x7f, 0x68, 0x1c, 0x80, 0xb2, 0xf8, 0xf7, 0x0e, 0xf9, 0xe1, 0x7b, + 0x05, 0xf1, 0x42, 0x00, 0x80, 0xb2, 0xf8, 0xf7, 0x08, 0xf9, 0xaf, 0x1d, + 0xb8, 0xf1, 0x00, 0x0f, 0x05, 0xf1, 0x08, 0x06, 0x12, 0xd1, 0x80, 0x22, + 0x80, 0x21, 0xb8, 0xb2, 0xf8, 0xf7, 0x24, 0xf9, 0x00, 0x22, 0x80, 0x21, + 0xb8, 0xb2, 0xf8, 0xf7, 0x1f, 0xf9, 0x00, 0x22, 0x02, 0x21, 0xb0, 0xb2, + 0xf8, 0xf7, 0x1a, 0xf9, 0x01, 0x22, 0x01, 0x21, 0x28, 0x46, 0x19, 0xe0, + 0x00, 0xf0, 0x24, 0xf8, 0xf8, 0xf7, 0x12, 0xf9, 0xe0, 0x7e, 0x40, 0xf0, + 0x80, 0x01, 0xb8, 0xb2, 0xf8, 0xf7, 0xe5, 0xf8, 0xa1, 0x7e, 0xe8, 0x1d, + 0x80, 0xb2, 0xf8, 0xf7, 0xe0, 0xf8, 0x00, 0xf0, 0x0e, 0xf8, 0xb0, 0xb2, + 0xf8, 0xf7, 0x02, 0xf9, 0x01, 0x20, 0xf9, 0xf7, 0x67, 0xfb, 0x00, 0x22, + 0x00, 0xf0, 0x0f, 0xf8, 0xf8, 0xf7, 0xfa, 0xf8, 0x04, 0x20, 0xbd, 0xe8, + 0xf0, 0x81, 0xe0, 0x7c, 0x00, 0xf0, 0x01, 0x00, 0x40, 0xf0, 0x02, 0x02, + 0x03, 0x21, 0x70, 0x47, 0x05, 0xf1, 0x13, 0x08, 0x80, 0x22, 0x80, 0x21, + 0x1f, 0xfa, 0x88, 0xf0, 0x70, 0x47, 0xb0, 0xb5, 0x88, 0xb0, 0x04, 0x46, + 0x0d, 0x46, 0x68, 0x46, 0x0f, 0xf2, 0x48, 0x61, 0x20, 0x22, 0xfc, 0xf7, + 0x3b, 0xfd, 0xa8, 0x7c, 0x8d, 0xf8, 0x01, 0x00, 0x00, 0x27, 0xe8, 0x7c, + 0x8d, 0xf8, 0x03, 0x00, 0x28, 0x7d, 0x8d, 0xf8, 0x05, 0x00, 0x68, 0x7d, + 0x8d, 0xf8, 0x07, 0x00, 0xa8, 0x7d, 0x8d, 0xf8, 0x0b, 0x00, 0xe8, 0x7d, + 0x8d, 0xf8, 0x0f, 0x00, 0x28, 0x7e, 0x8d, 0xf8, 0x11, 0x00, 0x68, 0x7e, + 0x8d, 0xf8, 0x13, 0x00, 0xa8, 0x7e, 0x8d, 0xf8, 0x15, 0x00, 0xa8, 0x7f, + 0x8d, 0xf8, 0x19, 0x00, 0xe8, 0x7f, 0x8d, 0xf8, 0x1b, 0x00, 0x95, 0xf8, + 0x20, 0x00, 0x8d, 0xf8, 0x1d, 0x00, 0x68, 0x88, 0x1d, 0xf8, 0x17, 0x10, + 0x08, 0x18, 0x69, 0x46, 0x01, 0xeb, 0x47, 0x01, 0x01, 0x2c, 0x49, 0x78, + 0x80, 0xb2, 0x02, 0xd1, 0xf8, 0xf7, 0x85, 0xf8, 0x01, 0xe0, 0xf5, 0xf7, + 0xcd, 0xfe, 0x7f, 0x1c, 0x0f, 0x2f, 0xec, 0xd3, 0x08, 0xb0, 0xb0, 0xbd, + 0x70, 0xb5, 0x04, 0x46, 0x00, 0x25, 0x0f, 0xf2, 0xe4, 0x56, 0x06, 0xeb, + 0x45, 0x00, 0x41, 0x78, 0x16, 0xf8, 0x15, 0x00, 0x00, 0x19, 0xff, 0xf7, + 0x2a, 0xff, 0x6d, 0x1c, 0x14, 0x2d, 0xf4, 0xd3, 0x70, 0xbd, 0x03, 0x46, + 0x06, 0x20, 0x04, 0x2b, 0x00, 0xdb, 0x70, 0x47, 0x10, 0xb5, 0x0f, 0xf2, + 0xe4, 0x54, 0x34, 0xf8, 0x13, 0x40, 0xa1, 0x42, 0x22, 0xbf, 0x0f, 0xf2, + 0xe0, 0x54, 0x34, 0xf8, 0x13, 0x40, 0x8c, 0x42, 0x14, 0xd3, 0x0f, 0xf2, + 0xdc, 0x54, 0x1c, 0x5d, 0xa2, 0x42, 0x22, 0xbf, 0x0f, 0xf2, 0xd4, 0x54, + 0x1c, 0x5d, 0x94, 0x42, 0x0a, 0xd3, 0xcd, 0x48, 0x28, 0x24, 0x04, 0xfb, + 0x03, 0x00, 0x00, 0xf1, 0x24, 0x03, 0x19, 0x80, 0x9a, 0x70, 0xbd, 0xe8, + 0x10, 0x40, 0x0b, 0xe0, 0x10, 0xbd, 0x10, 0xb5, 0xc6, 0x4b, 0x28, 0x24, + 0x04, 0xfb, 0x00, 0x30, 0x30, 0xf8, 0x24, 0x3f, 0x0b, 0x80, 0x80, 0x78, + 0x10, 0x70, 0x10, 0xbd, 0x2d, 0xe9, 0xf0, 0x4f, 0x04, 0x46, 0x89, 0xb0, + 0x20, 0x78, 0x0f, 0xf2, 0x98, 0x58, 0x0f, 0xf2, 0x80, 0x39, 0x07, 0x90, + 0x04, 0xf1, 0x10, 0x01, 0x06, 0xa8, 0xff, 0xf7, 0x2e, 0xfb, 0xc0, 0xb2, + 0x00, 0x25, 0x00, 0x28, 0x55, 0xd1, 0x59, 0xf8, 0x25, 0x00, 0x06, 0x99, + 0xb0, 0xfb, 0xf1, 0xfb, 0x0f, 0xf2, 0x74, 0x40, 0x30, 0xf8, 0x15, 0xa0, + 0x0f, 0xf2, 0x18, 0x30, 0x00, 0x68, 0x03, 0x90, 0x00, 0x27, 0x03, 0xa8, + 0x02, 0x90, 0x08, 0xeb, 0x87, 0x06, 0x04, 0xa8, 0x01, 0x90, 0xcd, 0xf8, + 0x00, 0xa0, 0x72, 0x78, 0x31, 0x78, 0x5b, 0x46, 0x20, 0x46, 0x00, 0xf0, + 0x3d, 0xf8, 0xf1, 0x78, 0x01, 0x29, 0x05, 0xd1, 0xbd, 0xf8, 0x0c, 0x10, + 0xb2, 0x78, 0x91, 0x42, 0x07, 0xd1, 0x09, 0xe0, 0x02, 0x29, 0x02, 0xbf, + 0xbd, 0xf8, 0x0e, 0x10, 0xb2, 0x78, 0x91, 0x42, 0x02, 0xd0, 0x7f, 0x1c, + 0x04, 0x2f, 0xde, 0xd3, 0x10, 0xbb, 0x07, 0x9a, 0xa2, 0x49, 0xd4, 0x23, + 0x03, 0xfb, 0x02, 0x11, 0x9d, 0xf8, 0x15, 0x20, 0x01, 0xeb, 0x85, 0x01, + 0x02, 0xf0, 0x3f, 0x02, 0x0a, 0x70, 0x9d, 0xf8, 0x10, 0x30, 0x9d, 0xf8, + 0x11, 0x20, 0x03, 0xf0, 0x0f, 0x03, 0x43, 0xea, 0x02, 0x12, 0x4a, 0x70, + 0x9d, 0xf8, 0x12, 0x30, 0x9d, 0xf8, 0x13, 0x20, 0x03, 0xf0, 0x0f, 0x03, + 0x43, 0xea, 0x02, 0x12, 0x8a, 0x70, 0x9d, 0xf8, 0x14, 0x20, 0x02, 0xf0, + 0x0f, 0x02, 0xca, 0x70, 0x6d, 0x1c, 0x35, 0x2d, 0xa7, 0xd3, 0x09, 0xb0, + 0xbd, 0xe8, 0xf0, 0x8f, 0x2d, 0xe9, 0xfe, 0x4f, 0x9c, 0xb0, 0x04, 0x46, + 0x04, 0xa8, 0x28, 0x21, 0xfa, 0xf7, 0x7e, 0xfb, 0x12, 0xa8, 0x28, 0x21, + 0xfa, 0xf7, 0x7a, 0xfb, 0x04, 0xf1, 0x24, 0x00, 0x4f, 0xf4, 0x7a, 0x72, + 0x01, 0x88, 0x0f, 0xf2, 0x6c, 0x3b, 0x51, 0x43, 0x93, 0x4a, 0xa2, 0xfb, + 0x01, 0x23, 0x12, 0x0c, 0x42, 0xea, 0x03, 0x42, 0x1b, 0x0c, 0xcd, 0xe9, + 0x00, 0x23, 0x84, 0x78, 0xdd, 0xe9, 0x00, 0x01, 0x00, 0x23, 0x22, 0x46, + 0xfa, 0xf7, 0x22, 0xf8, 0xcd, 0xe9, 0x10, 0x01, 0x4f, 0xf0, 0x00, 0x09, + 0xdd, 0xe9, 0x00, 0x01, 0xa4, 0xfb, 0x00, 0x23, 0x04, 0xfb, 0x01, 0x33, + 0xcd, 0xe9, 0x02, 0x23, 0xdd, 0xe9, 0x02, 0x01, 0x89, 0x00, 0x41, 0xea, + 0x90, 0x71, 0x80, 0x00, 0xcd, 0xe9, 0x0e, 0x01, 0xca, 0x46, 0x3f, 0x27, + 0x0c, 0x97, 0xdd, 0xe9, 0x00, 0x45, 0x1e, 0x9a, 0x28, 0x9b, 0xa2, 0xfb, + 0x04, 0x01, 0x02, 0xfb, 0x05, 0x11, 0x3a, 0x46, 0x5a, 0x43, 0x00, 0xf0, + 0xce, 0xf8, 0xdd, 0xe9, 0x10, 0x45, 0x0a, 0x90, 0x02, 0x46, 0xa2, 0xfb, + 0x04, 0x68, 0x02, 0xfb, 0x05, 0x88, 0xcd, 0xe9, 0x04, 0x68, 0x14, 0x46, + 0x50, 0x08, 0xdd, 0xe9, 0x02, 0x23, 0xa2, 0xfb, 0x04, 0x68, 0x03, 0xfb, + 0x04, 0x88, 0xdd, 0xe9, 0x04, 0x23, 0xb2, 0x1a, 0x68, 0xeb, 0x03, 0x03, + 0xcd, 0xe9, 0x06, 0x23, 0x0b, 0x90, 0xdd, 0xe9, 0x0e, 0x23, 0xa0, 0xfb, + 0x02, 0x45, 0x00, 0xfb, 0x03, 0x55, 0xcd, 0xe9, 0x08, 0x45, 0x00, 0x22, + 0x04, 0xab, 0x0a, 0xac, 0x00, 0x25, 0x0b, 0xeb, 0x05, 0x1e, 0xd3, 0xe9, + 0x00, 0x01, 0xde, 0xe9, 0x02, 0x68, 0x41, 0x45, 0x0c, 0xd3, 0x01, 0xd8, + 0xb0, 0x42, 0x09, 0xd3, 0x0b, 0xeb, 0x05, 0x1c, 0xdc, 0xe9, 0x00, 0x68, + 0x88, 0x45, 0x03, 0xd3, 0x01, 0xd8, 0x86, 0x42, 0x00, 0xd3, 0x52, 0x1c, + 0x08, 0x33, 0x6d, 0x1c, 0x03, 0x2d, 0xe6, 0xd3, 0x00, 0x20, 0x0f, 0xf2, + 0xb0, 0x23, 0x21, 0x68, 0x53, 0xf8, 0x30, 0x30, 0x99, 0x42, 0x21, 0xbf, + 0x0f, 0xf2, 0xa0, 0x23, 0x03, 0xeb, 0xc0, 0x03, 0x5b, 0x68, 0x8b, 0x42, + 0x28, 0xbf, 0x52, 0x1c, 0x24, 0x1d, 0x40, 0x1c, 0x02, 0x28, 0xec, 0xd3, + 0xad, 0xf8, 0x34, 0x20, 0x92, 0xb2, 0xbd, 0xf9, 0x70, 0x10, 0x8a, 0x42, + 0x18, 0xda, 0xbd, 0xf9, 0x74, 0x10, 0x8a, 0x42, 0x07, 0xdb, 0x91, 0x46, + 0x12, 0xa8, 0x04, 0xa9, 0x28, 0x22, 0xfc, 0xf7, 0xa5, 0xfb, 0xad, 0xf8, + 0x6e, 0x90, 0x7f, 0x1e, 0x01, 0x2f, 0x89, 0xda, 0xbd, 0xf9, 0x74, 0x00, + 0x81, 0x45, 0x0d, 0xdb, 0x29, 0x99, 0x12, 0xa8, 0x00, 0xf0, 0x10, 0xf8, + 0x1b, 0x98, 0x04, 0xe0, 0x29, 0x99, 0x04, 0xa8, 0x00, 0xf0, 0x0a, 0xf8, + 0x0d, 0x98, 0x2a, 0x99, 0x08, 0x60, 0x01, 0xe0, 0x4f, 0xf0, 0x05, 0x0a, + 0x50, 0x46, 0x1f, 0xb0, 0xbd, 0xe8, 0xf0, 0x8f, 0x2d, 0xe9, 0xf0, 0x43, + 0x00, 0xf1, 0x18, 0x04, 0x05, 0x46, 0x00, 0x6a, 0x0f, 0xf2, 0x20, 0x29, + 0x48, 0x71, 0xce, 0x1c, 0x88, 0x46, 0x00, 0x27, 0x09, 0xeb, 0xc7, 0x00, + 0x22, 0x68, 0x41, 0x68, 0x91, 0x42, 0x38, 0xbf, 0x0f, 0x20, 0x0d, 0xd3, + 0x59, 0xf8, 0x37, 0x10, 0x91, 0x42, 0x28, 0xbf, 0x00, 0x20, 0x07, 0xd2, + 0x40, 0x68, 0x41, 0x0c, 0xc0, 0x03, 0x00, 0xf0, 0x2e, 0xf8, 0xc0, 0xf5, + 0x04, 0x20, 0xc0, 0x0b, 0x24, 0x1d, 0x7f, 0x1c, 0x02, 0x2f, 0x06, 0xf8, + 0x01, 0x0b, 0xe3, 0xd3, 0x00, 0x24, 0x0f, 0xf2, 0xac, 0x16, 0x06, 0xeb, + 0x04, 0x1e, 0xd5, 0xe9, 0x00, 0x23, 0xde, 0xe9, 0x02, 0x01, 0x8b, 0x42, + 0x03, 0xd8, 0x2c, 0xbf, 0x82, 0x42, 0x0f, 0x20, 0x0c, 0xd3, 0x06, 0xeb, + 0x04, 0x1c, 0xdc, 0xe9, 0x00, 0x01, 0x8b, 0x42, 0x04, 0xd3, 0x01, 0xd8, + 0x82, 0x42, 0x01, 0xd3, 0x00, 0x20, 0x01, 0xe0, 0xf9, 0xf7, 0x3a, 0xff, + 0x08, 0x35, 0x64, 0x1c, 0x03, 0x2c, 0x08, 0xf8, 0x01, 0x0b, 0xe0, 0xd3, + 0xbd, 0xe8, 0xf0, 0x83, 0x22, 0x46, 0x00, 0x23, 0xf9, 0xf7, 0x2e, 0xbf, + 0x68, 0xee, 0x00, 0x20, 0x78, 0x29, 0x00, 0x20, 0x48, 0xf3, 0x00, 0x20, + 0x7c, 0xdf, 0x00, 0x20, 0x80, 0x96, 0x98, 0x00, 0x00, 0xf0, 0xff, 0x00, + 0x00, 0xf8, 0x7f, 0x00, 0x00, 0xf2, 0x05, 0x2a, 0x00, 0x5e, 0xd0, 0xb2, + 0x4c, 0x29, 0x00, 0x20, 0x80, 0x18, 0x42, 0xfd, 0x81, 0xb5, 0xd8, 0x68, + 0x01, 0x9d, 0x96, 0x6b, 0x46, 0x03, 0x00, 0x46, 0x78, 0xf3, 0x00, 0x20, + 0xc7, 0x02, 0x00, 0x46, 0x57, 0x03, 0x00, 0x46, 0x57, 0x02, 0x00, 0x46, + 0x7e, 0x48, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0x0f, + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0e, 0x0d, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0d, 0x0c, 0x0c, 0x0d, 0x0c, 0x0c, + 0x0c, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0c, + 0x0b, 0x0b, 0x0b, 0x0c, 0x0d, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0e, + 0x0e, 0x00, 0x00, 0x00, 0x48, 0x56, 0xc0, 0x00, 0x08, 0xd8, 0xba, 0x00, + 0xd0, 0xab, 0xb5, 0x00, 0xa0, 0xd1, 0xb0, 0x00, 0xc0, 0x3d, 0xac, 0x00, + 0x18, 0xf4, 0xa7, 0x00, 0xf0, 0xe8, 0xa3, 0x00, 0x60, 0x18, 0xa0, 0x00, + 0x50, 0x86, 0x9c, 0x00, 0x20, 0x23, 0x99, 0x00, 0xd8, 0xf5, 0x95, 0x00, + 0x7c, 0xf5, 0x92, 0x00, 0xb4, 0x1f, 0x90, 0x00, 0x28, 0x72, 0x8d, 0x00, + 0xf0, 0xe8, 0x8a, 0x00, 0x7c, 0x82, 0x88, 0x00, 0x48, 0x3b, 0x86, 0x00, + 0xc4, 0x11, 0x84, 0x00, 0x98, 0x03, 0x82, 0x00, 0x6c, 0x0e, 0x80, 0x00, + 0x4c, 0x30, 0x7e, 0x00, 0x0c, 0x68, 0x7c, 0x00, 0xb8, 0xb3, 0x7a, 0x00, + 0xc0, 0x11, 0x79, 0x00, 0xf8, 0x80, 0x77, 0x00, 0xd0, 0xff, 0x75, 0x00, + 0x80, 0x8d, 0x74, 0x00, 0xdc, 0x28, 0x73, 0x00, 0xb8, 0xd0, 0x71, 0x00, + 0xb0, 0x84, 0x70, 0x00, 0xfc, 0x43, 0x6f, 0x00, 0x70, 0x0d, 0x6e, 0x00, + 0x0c, 0xe1, 0x6c, 0x00, 0x08, 0xbe, 0x6b, 0x00, 0x9c, 0xa3, 0x6a, 0x00, + 0xc8, 0x91, 0x69, 0x00, 0x28, 0x88, 0x68, 0x00, 0x58, 0x86, 0x67, 0x00, + 0xf4, 0x8b, 0x66, 0x00, 0x98, 0x98, 0x65, 0x00, 0xa8, 0xac, 0x64, 0x00, + 0xc0, 0xc7, 0x63, 0x00, 0x7c, 0xe9, 0x62, 0x00, 0x78, 0x11, 0x62, 0x00, + 0x18, 0x40, 0x61, 0x00, 0xf8, 0x74, 0x60, 0x00, 0xb4, 0xaf, 0x5f, 0x00, + 0xb0, 0xf0, 0x5e, 0x00, 0x24, 0x37, 0x5e, 0x00, 0x10, 0x83, 0x5d, 0x00, + 0x10, 0xd4, 0x5c, 0x00, 0x24, 0x2a, 0x5c, 0x00, 0x84, 0x84, 0x5b, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x05, 0x09, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x95, 0x8d, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xaf, 0x2b, + 0x78, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xba, 0x82, 0x07, 0x00, 0x00, 0x00, + 0x00, 0x80, 0xf1, 0x42, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x18, 0x2f, 0xf4, + 0x04, 0x00, 0x00, 0x00, 0x1c, 0x02, 0x00, 0x00, 0xdb, 0x21, 0x00, 0x00, + 0xae, 0x00, 0x00, 0x00, 0xe2, 0x0a, 0x00, 0x00, 0x6e, 0x46, 0xb6, 0x3f, + 0xee, 0x39, 0xf8, 0x34, 0xac, 0x30, 0xe2, 0x2c, 0x90, 0x29, 0x9d, 0x26, + 0xff, 0x23, 0xa8, 0x21, 0x8e, 0x1f, 0xa9, 0x1d, 0xf3, 0x1b, 0x65, 0x1a, + 0xfb, 0x18, 0xb0, 0x17, 0xa8, 0x17, 0x83, 0x16, 0x75, 0x15, 0x7c, 0x14, + 0x95, 0x13, 0xbf, 0x12, 0xf8, 0x11, 0x2d, 0x12, 0x77, 0x11, 0xc2, 0x11, + 0x18, 0x11, 0x79, 0x10, 0xe4, 0x0f, 0xa7, 0x13, 0xfd, 0x12, 0x5c, 0x12, + 0xc3, 0x11, 0x33, 0x11, 0x02, 0x0d, 0x60, 0x0d, 0xfa, 0x0c, 0x99, 0x0c, + 0x3c, 0x0c, 0x38, 0x10, 0xc6, 0x0f, 0x58, 0x0f, 0xf0, 0x0e, 0x8d, 0x0f, + 0x27, 0x0f, 0xc6, 0x0e, 0x69, 0x0e, 0x0f, 0x0e, 0xbe, 0x0e, 0x66, 0x0e, + 0x11, 0x0e, 0xc0, 0x0d, 0x72, 0x0d, 0x00, 0x00, 0x1e, 0x0b, 0x50, 0x0a, + 0x78, 0x0a, 0xa0, 0x05, 0xb0, 0xb3, 0x00, 0x00, 0x36, 0x6e, 0x01, 0x00, + 0x6c, 0xdc, 0x02, 0x00, 0xd8, 0xb8, 0x05, 0x00, 0xb0, 0x71, 0x0b, 0x00, + 0x60, 0xe3, 0x16, 0x00, 0xc0, 0xc6, 0x2d, 0x00, 0x20, 0x14, 0x5d, 0x00, + 0x10, 0x17, 0x19, 0x23, 0x27, 0x2b, 0x30, 0x00, 0x0a, 0x00, 0x09, 0x00, + 0x12, 0x00, 0x08, 0x00, 0x15, 0x00, 0x21, 0x00, 0x20, 0x70, 0x0b, 0x00, + 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x0d, 0x84, 0x03, 0x00, 0x04, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x1d, 0x2b, 0x1c, 0x0f, 0x1d, 0x6b, + 0x1d, 0x2a, 0x1c, 0x0f, 0x1d, 0x6a, 0x1d, 0x29, 0x1c, 0x0f, 0x1d, 0x69, + 0x1d, 0x28, 0x1c, 0x00, 0x1d, 0x68, 0x1d, 0x27, 0x1c, 0x00, 0x1d, 0x67, + 0x1d, 0x26, 0x1c, 0x00, 0x1d, 0x66, 0x1d, 0x20, 0x32, 0x00, 0x32, 0x00, + 0xf4, 0x01, 0xf4, 0x01, 0xee, 0x02, 0xee, 0x02, 0xee, 0x02, 0xee, 0x02, + 0x03, 0x03, 0x03, 0x03, 0x0f, 0x0f, 0x0f, 0x0f, 0x05, 0x02, 0x05, 0x01, + 0x04, 0x04, 0x04, 0x01, 0x04, 0x03, 0x03, 0x02, 0x03, 0x02, 0x00, 0x00, + 0x03, 0x49, 0x09, 0x68, 0xc1, 0x40, 0xc8, 0x07, 0x01, 0xd4, 0x01, 0x21, + 0x03, 0xe0, 0x70, 0x47, 0x84, 0xf3, 0x00, 0x20, 0x00, 0x21, 0x40, 0xf6, + 0x01, 0x50, 0xf5, 0xf7, 0x9b, 0xbb, 0x00, 0x00, 0x70, 0xb5, 0x00, 0x20, + 0x0f, 0xf2, 0x74, 0x21, 0x11, 0xf8, 0x10, 0x30, 0x7b, 0x4c, 0x63, 0x43, + 0x7b, 0x4c, 0x24, 0x68, 0xa3, 0x42, 0x24, 0xbf, 0x01, 0xeb, 0x40, 0x02, + 0x52, 0x78, 0x40, 0x1c, 0x04, 0x28, 0xf1, 0xd3, 0xd2, 0xb2, 0x03, 0x21, + 0x4f, 0xf4, 0xbb, 0x70, 0xf5, 0xf7, 0x8c, 0xfb, 0x00, 0x24, 0x0f, 0xf2, + 0x50, 0x25, 0x0f, 0xf2, 0x60, 0x26, 0xa1, 0x5d, 0x35, 0xf8, 0x14, 0x00, + 0xf5, 0xf7, 0x78, 0xfb, 0x64, 0x1c, 0x09, 0x2c, 0xf7, 0xd3, 0x01, 0x20, + 0x70, 0xbd, 0x30, 0xb5, 0x14, 0x46, 0x6c, 0x4a, 0x0f, 0xf2, 0x18, 0x23, + 0x12, 0x78, 0x0f, 0xf2, 0x48, 0x25, 0xe3, 0x5c, 0x02, 0xf0, 0x03, 0x02, + 0x52, 0x5d, 0xd2, 0x18, 0x52, 0xb2, 0x00, 0x2a, 0x02, 0xd4, 0xf9, 0xf7, + 0x99, 0xfc, 0x02, 0xe0, 0x52, 0x42, 0xf5, 0xf7, 0x63, 0xfd, 0x07, 0x2c, + 0x08, 0xbf, 0x03, 0x22, 0x02, 0xd0, 0x08, 0x2c, 0x05, 0xd1, 0x05, 0x22, + 0xbd, 0xe8, 0x30, 0x40, 0x00, 0x23, 0xf9, 0xf7, 0x7f, 0xbd, 0x30, 0xbd, + 0x23, 0x29, 0x05, 0xd3, 0x02, 0xd8, 0xb0, 0xf1, 0xf1, 0x4f, 0x01, 0xd3, + 0x3f, 0x20, 0x0d, 0xe0, 0x40, 0x0b, 0x40, 0xea, 0xc1, 0x40, 0x50, 0x21, + 0x48, 0x43, 0x40, 0xf2, 0xcb, 0x21, 0xb0, 0xfb, 0xf1, 0xf0, 0x00, 0xf5, + 0x80, 0x40, 0xc0, 0x0b, 0x18, 0xbf, 0x40, 0x1e, 0xc0, 0xb2, 0x70, 0x47, + 0xf8, 0xb5, 0x06, 0x46, 0x4d, 0x48, 0x14, 0x46, 0x02, 0x68, 0x1d, 0x46, + 0xa2, 0xfb, 0x04, 0x01, 0x02, 0xfb, 0x05, 0x11, 0x00, 0x0f, 0x40, 0xea, + 0x01, 0x10, 0x09, 0x0f, 0x00, 0xf0, 0x98, 0xf8, 0x07, 0x00, 0x01, 0xd5, + 0x00, 0x20, 0xf2, 0xbd, 0x3a, 0x46, 0x20, 0x46, 0x29, 0x46, 0xff, 0xf7, + 0xac, 0xff, 0x05, 0x2e, 0x04, 0x46, 0x0d, 0x46, 0x03, 0xda, 0x0f, 0xf2, + 0xa8, 0x10, 0x31, 0x5c, 0x09, 0xb9, 0x40, 0x48, 0x01, 0x78, 0x40, 0xf2, + 0x0b, 0x20, 0xf5, 0xf7, 0x11, 0xfb, 0x0f, 0xf2, 0x50, 0x10, 0x39, 0x5c, + 0x40, 0xf2, 0x81, 0x10, 0xf5, 0xf7, 0x0a, 0xfb, 0x20, 0x46, 0x29, 0x46, + 0xff, 0xf7, 0xb6, 0xff, 0x02, 0x46, 0x3f, 0x21, 0x40, 0xf2, 0x77, 0x10, + 0xf5, 0xf7, 0x0a, 0xfb, 0x22, 0x0f, 0x42, 0xea, 0x05, 0x12, 0xd1, 0xb2, + 0x40, 0xf2, 0x75, 0x10, 0xf5, 0xf7, 0xf8, 0xfa, 0x6f, 0xf0, 0x70, 0x40, + 0x20, 0x40, 0x4f, 0xf4, 0xff, 0x12, 0xa2, 0xfb, 0x00, 0x45, 0x24, 0x0f, + 0x44, 0xea, 0x05, 0x14, 0xe1, 0xb2, 0x4f, 0xf4, 0xba, 0x70, 0x2d, 0x0f, + 0xf5, 0xf7, 0xe8, 0xfa, 0x24, 0x0a, 0x44, 0xea, 0x05, 0x64, 0xe1, 0xb2, + 0x40, 0xf2, 0x73, 0x10, 0xf5, 0xf7, 0xe0, 0xfa, 0x21, 0x0a, 0x4f, 0xf4, + 0xb9, 0x70, 0xf5, 0xf7, 0xdb, 0xfa, 0x01, 0x21, 0x40, 0xf2, 0x7f, 0x10, + 0xf5, 0xf7, 0xd6, 0xfa, 0x01, 0x20, 0xf2, 0xbd, 0x10, 0xb5, 0x05, 0x21, + 0x4f, 0xf4, 0xb8, 0x70, 0xf5, 0xf7, 0xce, 0xfa, 0x01, 0x21, 0x4f, 0xf4, + 0xb8, 0x70, 0xf5, 0xf7, 0xc9, 0xfa, 0x1a, 0x49, 0x01, 0x20, 0xf8, 0xf7, + 0x5d, 0xff, 0xf6, 0xf7, 0x98, 0xfd, 0x50, 0xb9, 0x17, 0x48, 0x00, 0x78, + 0x00, 0x06, 0x01, 0xd5, 0x01, 0x24, 0x05, 0xe0, 0x01, 0x20, 0xf8, 0xf7, + 0x69, 0xff, 0x00, 0x28, 0xf1, 0xd0, 0x00, 0x24, 0x01, 0x20, 0xf8, 0xf7, + 0xdb, 0xfe, 0x20, 0x46, 0x10, 0xbd, 0x10, 0xb5, 0x04, 0x46, 0x00, 0x20, + 0x10, 0x2b, 0x0e, 0xd2, 0x1b, 0x07, 0x43, 0xea, 0x12, 0x11, 0x10, 0x07, + 0x06, 0x4a, 0x12, 0x68, 0x00, 0x23, 0xf9, 0xf7, 0xd1, 0xfc, 0x02, 0x46, + 0x20, 0x46, 0xbd, 0xe8, 0x10, 0x40, 0x0b, 0x46, 0x64, 0xe7, 0x10, 0xbd, + 0x80, 0x96, 0x98, 0x00, 0x78, 0x29, 0x00, 0x20, 0x76, 0x01, 0x00, 0x46, + 0x0b, 0x02, 0x00, 0x46, 0x40, 0x42, 0x0f, 0x00, 0x7f, 0x01, 0x00, 0x46, + 0x10, 0xb5, 0x4f, 0xf4, 0x7a, 0x72, 0x00, 0x23, 0xf9, 0xf7, 0xb8, 0xfc, + 0x4f, 0xf0, 0xff, 0x34, 0x00, 0x21, 0x0f, 0xf2, 0x18, 0x02, 0x52, 0xf8, + 0x21, 0x30, 0x83, 0x42, 0x01, 0xd3, 0x0c, 0x46, 0x02, 0xe0, 0x49, 0x1c, + 0x09, 0x29, 0xf6, 0xd3, 0x20, 0x46, 0x10, 0xbd, 0xf4, 0xef, 0x02, 0x00, + 0xe8, 0xdf, 0x05, 0x00, 0xd0, 0xbf, 0x0b, 0x00, 0xa0, 0x7f, 0x17, 0x00, + 0x98, 0x9e, 0x19, 0x00, 0x38, 0x07, 0x20, 0x00, 0x80, 0xb9, 0x2a, 0x00, + 0xe0, 0x7e, 0x46, 0x00, 0x60, 0x56, 0x6c, 0x00, 0x00, 0x01, 0x02, 0x03, + 0x04, 0x14, 0x24, 0x05, 0x05, 0x00, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x03, 0x08, 0x00, + 0x10, 0x01, 0x64, 0x02, 0x7d, 0x01, 0x7e, 0x01, 0x7e, 0x01, 0x7e, 0x01, + 0x79, 0x01, 0x7a, 0x01, 0x7b, 0x01, 0x7c, 0x01, 0x7f, 0x01, 0x00, 0x00, + 0x86, 0x08, 0x01, 0x05, 0xe5, 0x5b, 0x35, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x02, 0xff, 0x00, 0x54, 0x2c, 0x04, 0xf8, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x0d, 0xd2, 0x01, 0x0e, 0x7f, 0x39, 0x0a, 0xd4, 0xd1, 0xf1, + 0x1f, 0x01, 0x04, 0xd4, 0xc0, 0x01, 0x40, 0xf0, 0x00, 0x40, 0xc8, 0x40, + 0x70, 0x47, 0x7f, 0xf0, 0x00, 0x00, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, + 0x03, 0x48, 0x00, 0x78, 0x18, 0xb9, 0x03, 0x48, 0x00, 0x78, 0x00, 0xf0, + 0x07, 0x00, 0x70, 0x47, 0x88, 0x02, 0x00, 0x20, 0x04, 0x00, 0x00, 0x46, + 0x2d, 0xe9, 0xf8, 0x43, 0x88, 0x4c, 0x4f, 0xf4, 0x94, 0x71, 0x04, 0xf1, + 0x44, 0x00, 0xf9, 0xf7, 0x89, 0xff, 0x00, 0x25, 0x85, 0x4e, 0x0f, 0xf2, + 0x2c, 0x28, 0x85, 0x4f, 0x4f, 0xf4, 0xd4, 0x79, 0x84, 0x48, 0x09, 0xfb, + 0x05, 0x00, 0x49, 0x46, 0x88, 0x30, 0xf5, 0xf7, 0xcf, 0xf9, 0x94, 0x20, + 0x00, 0xfb, 0x05, 0x40, 0x4f, 0xf4, 0x7a, 0x71, 0x01, 0x65, 0x79, 0x69, + 0x41, 0x65, 0x39, 0x6c, 0x81, 0x65, 0x00, 0x20, 0x58, 0xf8, 0x25, 0x10, + 0x08, 0x60, 0x04, 0x20, 0xa8, 0x55, 0x6d, 0x1c, 0x02, 0x2d, 0xe5, 0xd3, + 0xbd, 0xe8, 0xf1, 0x83, 0x2d, 0xe9, 0xf8, 0x43, 0x74, 0x48, 0xdf, 0xf8, + 0xc8, 0x81, 0x80, 0x7a, 0x0c, 0x46, 0x00, 0x25, 0x00, 0xf0, 0x03, 0x09, + 0x00, 0x27, 0x29, 0xfa, 0x07, 0xf0, 0xc0, 0x07, 0x35, 0xd5, 0x08, 0xf5, + 0xb6, 0x70, 0x60, 0x60, 0x4f, 0xf4, 0xd4, 0x71, 0x6c, 0x48, 0x27, 0x61, + 0x01, 0xfb, 0x07, 0x00, 0xc4, 0xf8, 0x08, 0x80, 0x88, 0x30, 0x20, 0x60, + 0x94, 0x21, 0x08, 0xf1, 0x44, 0x00, 0x01, 0xfb, 0x07, 0x00, 0xe0, 0x60, + 0xf4, 0xf7, 0x74, 0xf8, 0xe0, 0x68, 0x00, 0x21, 0x41, 0x60, 0x01, 0x60, + 0x81, 0x60, 0xc1, 0x62, 0x4f, 0xf4, 0x7a, 0x71, 0xc1, 0x60, 0xf4, 0xf7, + 0x7e, 0xf8, 0x20, 0x46, 0xfc, 0xf7, 0xd7, 0xfa, 0x06, 0x00, 0x04, 0xd1, + 0x01, 0x21, 0x20, 0x46, 0xfe, 0xf7, 0x80, 0xfd, 0x06, 0x46, 0x20, 0x46, + 0xfc, 0xf7, 0xe7, 0xfa, 0xe0, 0x68, 0x16, 0xb9, 0x01, 0x21, 0xc1, 0x83, + 0x03, 0xe0, 0x00, 0x21, 0xc1, 0x83, 0x06, 0x60, 0x35, 0x46, 0x7f, 0x1c, + 0x02, 0x2f, 0xc2, 0xd3, 0x28, 0x46, 0xbd, 0xe8, 0xf2, 0x83, 0x70, 0x47, + 0x00, 0x28, 0x0c, 0xbf, 0x50, 0x49, 0x51, 0x49, 0x00, 0x22, 0x08, 0x68, + 0x0a, 0x60, 0x70, 0x47, 0x00, 0x28, 0x0c, 0xbf, 0x4c, 0x48, 0x4d, 0x48, + 0x01, 0x60, 0x70, 0x47, 0x2d, 0xe9, 0xf0, 0x47, 0x48, 0x4e, 0xdf, 0xf8, + 0x14, 0xa1, 0x0c, 0x46, 0x80, 0x46, 0x44, 0x20, 0x00, 0xfb, 0x08, 0xf5, + 0xa8, 0x19, 0xa0, 0x60, 0xc4, 0xf8, 0x10, 0x80, 0x4f, 0xf4, 0xd4, 0x70, + 0x00, 0xfb, 0x08, 0x60, 0x88, 0x30, 0x20, 0x60, 0x91, 0x46, 0x94, 0x20, + 0x00, 0xfb, 0x08, 0xa0, 0x44, 0x30, 0xe0, 0x60, 0x01, 0x27, 0xf4, 0xf7, + 0x21, 0xf8, 0xa8, 0x19, 0x51, 0x46, 0x44, 0x22, 0xfb, 0xf7, 0xb4, 0xff, + 0x20, 0x68, 0x90, 0xf8, 0xa1, 0x11, 0x40, 0x46, 0xfc, 0xf7, 0xce, 0xfb, + 0xe0, 0x68, 0x21, 0x68, 0x40, 0x8b, 0x08, 0x70, 0xe0, 0x68, 0x21, 0x68, + 0x00, 0x8b, 0x48, 0x70, 0xf4, 0xf7, 0x21, 0xf8, 0xfc, 0xf7, 0xac, 0xf8, + 0x48, 0xb9, 0x0b, 0x25, 0x29, 0x46, 0x20, 0x46, 0xfe, 0xf7, 0xab, 0xf8, + 0xe0, 0x68, 0x05, 0x60, 0x28, 0x46, 0xbd, 0xe8, 0xf0, 0x87, 0xe0, 0x68, + 0x80, 0x8b, 0x10, 0xb9, 0x03, 0x25, 0xf1, 0xe7, 0x7f, 0x1c, 0x20, 0x46, + 0xfc, 0xf7, 0x67, 0xfa, 0x05, 0x00, 0x06, 0xd0, 0x20, 0x46, 0xfc, 0xf7, + 0x7c, 0xfa, 0x15, 0x2d, 0xe6, 0xd3, 0x00, 0x25, 0xe8, 0xe7, 0x20, 0x68, + 0x01, 0x78, 0x40, 0x46, 0xfc, 0xf7, 0x99, 0xf9, 0x20, 0x46, 0xfe, 0xf7, + 0xbd, 0xf8, 0x05, 0x46, 0xe0, 0x68, 0xc1, 0x6a, 0x49, 0x1c, 0x00, 0x2d, + 0xc1, 0x62, 0xec, 0xd1, 0x81, 0x68, 0x49, 0x1c, 0xb9, 0xf1, 0x00, 0x0f, + 0x81, 0x60, 0xcf, 0xd0, 0xa1, 0x68, 0x09, 0x8b, 0x8f, 0x42, 0xd9, 0xd3, + 0xc0, 0x68, 0xf8, 0xf7, 0x51, 0xfe, 0x21, 0x68, 0xc1, 0xf8, 0x98, 0x01, + 0xc4, 0xe7, 0x10, 0xb5, 0x4f, 0xf4, 0xd4, 0x74, 0x12, 0x49, 0xc8, 0x22, + 0x02, 0xfb, 0x00, 0x12, 0x0a, 0x49, 0x10, 0x61, 0x01, 0xf5, 0xb6, 0x73, + 0x53, 0x60, 0x91, 0x60, 0x0a, 0x4b, 0x04, 0xfb, 0x00, 0x33, 0x88, 0x33, + 0x13, 0x60, 0x94, 0x23, 0x03, 0xfb, 0x00, 0x10, 0x44, 0x30, 0xd0, 0x60, + 0x00, 0x21, 0xbd, 0xe8, 0x10, 0x40, 0x10, 0x46, 0xfe, 0xf7, 0xd0, 0xbc, + 0x30, 0x27, 0x00, 0x20, 0x98, 0xf3, 0x00, 0x20, 0x78, 0x29, 0x00, 0x20, + 0x88, 0xb1, 0x00, 0x20, 0x00, 0x00, 0x40, 0x59, 0x00, 0x00, 0x50, 0x59, + 0x74, 0xe8, 0x00, 0x20, 0x00, 0x00, 0x40, 0x59, 0x00, 0x00, 0x50, 0x59, + 0x2d, 0xe9, 0xf0, 0x41, 0xf9, 0xf7, 0xf2, 0xfe, 0xf8, 0xf7, 0x6a, 0xfd, + 0xf5, 0xf7, 0xf8, 0xf9, 0x01, 0xf0, 0x54, 0xff, 0xf6, 0xf7, 0x68, 0xfe, + 0xf7, 0xf7, 0xf1, 0xfd, 0xff, 0xf7, 0x54, 0xfd, 0xfe, 0xf7, 0xd4, 0xfd, + 0xfa, 0xf7, 0x7e, 0xfa, 0xfa, 0xf7, 0x6d, 0xfa, 0x00, 0x24, 0x0f, 0xf2, + 0x54, 0x15, 0x0f, 0xf2, 0x48, 0x16, 0x36, 0xf8, 0x24, 0x00, 0x93, 0x21, + 0xf5, 0xf7, 0xde, 0xf8, 0x06, 0xeb, 0x84, 0x00, 0x82, 0x21, 0x00, 0xf0, + 0x5d, 0xf8, 0x00, 0xbf, 0x00, 0xbf, 0x00, 0xbf, 0x02, 0x21, 0x00, 0xf0, + 0x58, 0xf8, 0x35, 0xf8, 0x24, 0x00, 0x8c, 0x21, 0xf5, 0xf7, 0xce, 0xf8, + 0x05, 0xeb, 0x84, 0x00, 0x80, 0x21, 0x00, 0xf0, 0x4d, 0xf8, 0x00, 0xbf, + 0x00, 0xbf, 0x00, 0xbf, 0x00, 0x21, 0x00, 0xf0, 0x48, 0xf8, 0x64, 0x1c, + 0x02, 0x2c, 0xdc, 0xd3, 0x0f, 0xf2, 0xe4, 0x06, 0xf7, 0xf7, 0x5c, 0xfc, + 0x00, 0x24, 0x4f, 0xf0, 0x0c, 0x08, 0x00, 0x27, 0x08, 0xfb, 0x04, 0xf5, + 0x09, 0xe0, 0xa8, 0x19, 0x40, 0x68, 0x08, 0xfb, 0x07, 0x00, 0x18, 0xb1, + 0x00, 0x68, 0x01, 0x00, 0x18, 0xbf, 0x80, 0x47, 0x7f, 0x1c, 0xa8, 0x5d, + 0x87, 0x42, 0xf2, 0xd3, 0x64, 0x1c, 0x02, 0x2c, 0xeb, 0xd3, 0x12, 0x48, + 0x12, 0x4a, 0x40, 0x89, 0x10, 0xf0, 0x03, 0x01, 0x18, 0xbf, 0x01, 0x21, + 0x91, 0x60, 0xc0, 0xf3, 0x81, 0x01, 0x01, 0xb1, 0x4e, 0x21, 0x93, 0x68, + 0x19, 0x43, 0x91, 0x60, 0xc0, 0xf3, 0x01, 0x13, 0x03, 0xb1, 0x4e, 0x23, + 0x19, 0x43, 0x91, 0x60, 0xc0, 0xf3, 0x82, 0x10, 0x00, 0xb1, 0x08, 0x20, + 0x08, 0x43, 0x90, 0x60, 0x00, 0x22, 0x70, 0x21, 0x40, 0xf6, 0x8a, 0x50, + 0xf5, 0xf7, 0x8e, 0xf8, 0xbd, 0xe8, 0xf0, 0x41, 0xfb, 0xf7, 0x40, 0xbd, + 0x78, 0x29, 0x00, 0x20, 0xe8, 0xf2, 0x00, 0x20, 0x47, 0x88, 0x38, 0x46, + 0xf5, 0xf7, 0x78, 0xb8, 0x70, 0xb5, 0x04, 0x46, 0x15, 0x46, 0x0e, 0x46, + 0x28, 0x04, 0x48, 0xbf, 0xf3, 0xf7, 0x10, 0xff, 0x26, 0x60, 0x28, 0x06, + 0x44, 0xbf, 0x05, 0xf0, 0x7f, 0x00, 0x60, 0x60, 0xe8, 0x05, 0x48, 0xbf, + 0x00, 0x20, 0x03, 0xd4, 0xa8, 0x05, 0x02, 0xd5, 0xe0, 0x68, 0x40, 0x1c, + 0xe0, 0x60, 0x68, 0x05, 0x48, 0xbf, 0x00, 0x20, 0x03, 0xd4, 0x28, 0x05, + 0x02, 0xd5, 0x20, 0x69, 0x40, 0x1c, 0x20, 0x61, 0xe8, 0x04, 0x44, 0xbf, + 0x00, 0x20, 0xa0, 0x60, 0x28, 0x04, 0x44, 0xbf, 0xbd, 0xe8, 0x70, 0x40, + 0xf3, 0xf7, 0x03, 0xbf, 0x70, 0xbd, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x24, 0x9a, 0x00, 0x01, 0x60, 0xb5, 0x00, 0x20, 0x08, 0x00, 0x00, 0x00, + 0x08, 0x6f, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x06, 0xe7, 0x06, + 0xe8, 0x06, 0xe9, 0x06, 0xe0, 0x08, 0xe1, 0x08, 0xe2, 0x08, 0xe3, 0x08, + 0x2d, 0xe9, 0xf1, 0x41, 0xc0, 0xf3, 0xc7, 0x50, 0xff, 0x28, 0x81, 0xb0, + 0x0c, 0x46, 0x09, 0xd1, 0x01, 0x98, 0x00, 0x26, 0x40, 0x02, 0x02, 0xd1, + 0x01, 0x98, 0x00, 0x28, 0x18, 0xd4, 0x01, 0x98, 0xbd, 0xe8, 0xf6, 0x81, + 0x01, 0x28, 0x0b, 0xda, 0x01, 0xa8, 0x00, 0xf0, 0x0f, 0xff, 0x01, 0x28, + 0x06, 0xdb, 0x00, 0xf0, 0x45, 0xff, 0x22, 0x21, 0x01, 0x60, 0x5a, 0x48, + 0xbd, 0xe8, 0xf6, 0x81, 0x01, 0x99, 0x21, 0xf0, 0xff, 0x41, 0x41, 0xf0, + 0x7c, 0x51, 0x01, 0x91, 0xa0, 0xf1, 0x7e, 0x06, 0x01, 0x98, 0x00, 0x28, + 0x07, 0xd5, 0x00, 0xf0, 0x33, 0xff, 0x21, 0x21, 0x01, 0x60, 0x6f, 0xf0, + 0x00, 0x40, 0xbd, 0xe8, 0xf6, 0x81, 0x50, 0x49, 0xf8, 0xf7, 0xae, 0xfe, + 0x06, 0xd2, 0x01, 0x46, 0x4f, 0xf0, 0x80, 0x40, 0xf8, 0xf7, 0xba, 0xfe, + 0x01, 0x90, 0x76, 0x1e, 0x01, 0x99, 0x4b, 0x48, 0xf8, 0xf7, 0x18, 0xfe, + 0x05, 0x46, 0x01, 0x99, 0x4f, 0xf0, 0x7e, 0x50, 0xf8, 0xf7, 0x12, 0xfe, + 0x01, 0x46, 0x28, 0x46, 0xf8, 0xf7, 0x1c, 0xfd, 0x07, 0x46, 0x39, 0x46, + 0xf8, 0xf7, 0xa6, 0xfe, 0x80, 0x46, 0x43, 0x48, 0x41, 0x46, 0xf8, 0xf7, + 0xa1, 0xfe, 0x42, 0x49, 0xf8, 0xf7, 0x02, 0xfe, 0x41, 0x46, 0xf8, 0xf7, + 0x9b, 0xfe, 0x40, 0x49, 0xf8, 0xf7, 0xfc, 0xfd, 0x41, 0x46, 0xf8, 0xf7, + 0x95, 0xfe, 0x01, 0x46, 0x28, 0x46, 0xf8, 0xf7, 0x81, 0xfd, 0x39, 0x46, + 0xf8, 0xf7, 0x8e, 0xfe, 0x07, 0x46, 0x30, 0xb2, 0xf8, 0xf7, 0xe2, 0xfc, + 0x06, 0x46, 0x84, 0xb9, 0x37, 0x48, 0x31, 0x46, 0xf8, 0xf7, 0x84, 0xfe, + 0x39, 0x46, 0xf8, 0xf7, 0x71, 0xfd, 0x29, 0x46, 0xf8, 0xf7, 0xe2, 0xfd, + 0x04, 0x46, 0x33, 0x48, 0x31, 0x46, 0xf8, 0xf7, 0x79, 0xfe, 0x21, 0x46, + 0x3c, 0xe0, 0x01, 0x2c, 0x23, 0xdb, 0x30, 0x48, 0x29, 0x46, 0xf8, 0xf7, + 0x71, 0xfe, 0x04, 0x46, 0x2e, 0x48, 0x29, 0x46, 0xf8, 0xf7, 0x6c, 0xfe, + 0x05, 0x46, 0x2d, 0x48, 0x31, 0x46, 0xf8, 0xf7, 0x67, 0xfe, 0x80, 0x46, + 0x2b, 0x48, 0x39, 0x46, 0xf8, 0xf7, 0x62, 0xfe, 0x01, 0x46, 0x40, 0x46, + 0xf8, 0xf7, 0x4e, 0xfd, 0x29, 0x46, 0xf8, 0xf7, 0xbf, 0xfd, 0x21, 0x46, + 0xf8, 0xf7, 0xbc, 0xfd, 0x04, 0x46, 0x25, 0x48, 0x31, 0x46, 0xf8, 0xf7, + 0x53, 0xfe, 0x21, 0x46, 0x16, 0xe0, 0x23, 0x4c, 0x28, 0x46, 0x21, 0x46, + 0xf8, 0xf7, 0x4c, 0xfe, 0x80, 0x46, 0x21, 0x48, 0x29, 0x46, 0xf8, 0xf7, + 0x47, 0xfe, 0x05, 0x46, 0x38, 0x46, 0x21, 0x46, 0xf8, 0xf7, 0x42, 0xfe, + 0x01, 0x46, 0x28, 0x46, 0xf8, 0xf7, 0x2e, 0xfd, 0x41, 0x46, 0xf8, 0xf7, + 0x9f, 0xfd, 0x31, 0x46, 0xf8, 0xf7, 0x9c, 0xfd, 0xbd, 0xe8, 0xf6, 0x81, + 0x10, 0xb5, 0x04, 0x46, 0x0a, 0x48, 0x21, 0x46, 0xf8, 0xf7, 0x30, 0xfe, + 0x09, 0x49, 0xf8, 0xf7, 0x91, 0xfd, 0x21, 0x46, 0xf8, 0xf7, 0x2a, 0xfe, + 0xbd, 0xe8, 0x10, 0x40, 0x06, 0x49, 0xf8, 0xf7, 0x89, 0xbd, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xff, 0xf3, 0x04, 0x35, 0x3f, 0x00, 0x00, 0x80, 0xbf, + 0x15, 0x02, 0x99, 0x3e, 0x11, 0xae, 0xcc, 0x3e, 0xc0, 0xaa, 0x2a, 0x3f, + 0xe8, 0xe8, 0xfb, 0x33, 0x16, 0x72, 0x31, 0x3f, 0xd8, 0x5b, 0xde, 0x3e, + 0x28, 0x37, 0xa9, 0x32, 0xf4, 0x3e, 0xa1, 0x33, 0xd9, 0x5b, 0xde, 0x3e, + 0x98, 0x20, 0x9a, 0x3e, 0x3b, 0xaa, 0xb8, 0x3f, 0x60, 0x70, 0xa5, 0x32, + 0xef, 0xf3, 0x11, 0x80, 0x60, 0x21, 0x81, 0xf3, 0x11, 0x88, 0x70, 0x47, + 0x80, 0xb5, 0xff, 0xf7, 0xf7, 0xff, 0xdf, 0xf8, 0x9c, 0x1a, 0xdf, 0xf8, + 0x9c, 0x3a, 0x09, 0x68, 0x4f, 0xf0, 0x00, 0x42, 0x1a, 0x60, 0x04, 0xbd, + 0xdf, 0xf8, 0x88, 0x3a, 0x01, 0xf0, 0x00, 0x42, 0x1a, 0x60, 0x80, 0xf3, + 0x11, 0x88, 0x70, 0x47, 0x2d, 0xe9, 0xf0, 0x41, 0xdf, 0xf8, 0x7c, 0x6a, + 0xdf, 0xf8, 0x7c, 0x4a, 0xdf, 0xf8, 0x7c, 0x5a, 0x82, 0xb0, 0x70, 0x89, + 0xc0, 0xf3, 0x01, 0x10, 0x00, 0x28, 0x41, 0xd0, 0x07, 0x21, 0x05, 0xf1, + 0x32, 0x00, 0x00, 0xf0, 0xa3, 0xfc, 0x00, 0x21, 0x05, 0xf1, 0x34, 0x00, + 0x00, 0xf0, 0xa3, 0xfc, 0x30, 0x6c, 0xdf, 0xf8, 0x5c, 0x8a, 0x00, 0x90, + 0x23, 0x46, 0x13, 0x22, 0x05, 0xf1, 0x36, 0x01, 0x05, 0xf1, 0x38, 0x00, + 0x00, 0xf0, 0x1b, 0xfc, 0x00, 0x20, 0x00, 0x90, 0x4f, 0xf4, 0x00, 0x63, + 0x32, 0x6c, 0x05, 0xf1, 0x36, 0x01, 0x05, 0xf1, 0x38, 0x00, 0x00, 0xf0, + 0x45, 0xfc, 0x33, 0x6c, 0x22, 0x46, 0x0a, 0x21, 0x05, 0xf1, 0x3a, 0x00, + 0x00, 0xf0, 0x21, 0xfc, 0x02, 0x27, 0x0c, 0x20, 0xc0, 0x21, 0x00, 0xfb, + 0x07, 0x80, 0x01, 0xfb, 0x07, 0x81, 0x01, 0xf5, 0x2c, 0x71, 0x01, 0x60, + 0x07, 0xeb, 0x47, 0x01, 0x41, 0x44, 0x01, 0xf2, 0xba, 0x51, 0x41, 0x60, + 0x7f, 0x1c, 0x18, 0x21, 0x01, 0x72, 0x2f, 0x21, 0x41, 0x72, 0x18, 0x21, + 0x00, 0xf0, 0x73, 0xfc, 0x04, 0x2f, 0xe6, 0xd3, 0x70, 0x89, 0xc0, 0xf3, + 0x82, 0x10, 0xd0, 0xb1, 0x07, 0x21, 0x05, 0xf1, 0x40, 0x00, 0x00, 0xf0, + 0x5d, 0xfc, 0x00, 0x21, 0x05, 0xf1, 0x42, 0x00, 0x00, 0xf0, 0x5d, 0xfc, + 0x70, 0x6d, 0x00, 0x90, 0x23, 0x46, 0x13, 0x22, 0x05, 0xf1, 0x44, 0x01, + 0x05, 0xf1, 0x46, 0x00, 0x00, 0xf0, 0xd7, 0xfb, 0x73, 0x6d, 0x22, 0x46, + 0x0a, 0x21, 0x05, 0xf1, 0x48, 0x00, 0x00, 0xf0, 0xe8, 0xfb, 0xbd, 0xe8, + 0xf3, 0x41, 0x00, 0xe0, 0x00, 0xbf, 0xf8, 0xb5, 0xdf, 0xf8, 0xa8, 0x49, + 0xdf, 0xf8, 0x9c, 0x59, 0x0e, 0x22, 0x05, 0xf1, 0x2e, 0x01, 0x20, 0x46, + 0xfb, 0xf7, 0xd8, 0xfc, 0x0e, 0x22, 0x05, 0xf1, 0x3c, 0x01, 0x04, 0xf1, + 0x10, 0x00, 0xfb, 0xf7, 0xe1, 0xfc, 0xa5, 0x88, 0x4f, 0xf6, 0xfe, 0x70, + 0x00, 0xea, 0x05, 0x06, 0x20, 0x78, 0x01, 0x06, 0x45, 0xf0, 0x01, 0x07, + 0x07, 0xd5, 0x00, 0xf0, 0x7f, 0x00, 0x65, 0x84, 0xa5, 0x84, 0x65, 0x85, + 0xa5, 0x85, 0x20, 0x70, 0x1b, 0xe0, 0x02, 0x20, 0xf6, 0xf7, 0xe2, 0xf9, + 0x00, 0x28, 0x14, 0xbf, 0x67, 0x84, 0x66, 0x84, 0x03, 0x20, 0xf6, 0xf7, + 0xdb, 0xf9, 0x00, 0x28, 0x14, 0xbf, 0xa7, 0x84, 0xa6, 0x84, 0x10, 0x20, + 0xf6, 0xf7, 0xd4, 0xf9, 0x00, 0x28, 0x14, 0xbf, 0x67, 0x85, 0x66, 0x85, + 0x11, 0x20, 0xf6, 0xf7, 0xcd, 0xf9, 0x00, 0x28, 0x14, 0xbf, 0xa7, 0x85, + 0xa6, 0x85, 0x20, 0x7c, 0x01, 0x06, 0x04, 0xd5, 0x00, 0xf0, 0x7f, 0x00, + 0x25, 0x85, 0x20, 0x74, 0x06, 0xe0, 0x12, 0x20, 0xf6, 0xf7, 0xbe, 0xf9, + 0x00, 0x28, 0x14, 0xbf, 0x27, 0x85, 0x26, 0x85, 0x21, 0x78, 0x60, 0x88, + 0x00, 0x29, 0x0e, 0xbf, 0x40, 0xf0, 0x10, 0x00, 0x4f, 0xf6, 0xef, 0x71, + 0x08, 0x40, 0x60, 0x80, 0x21, 0x7c, 0x60, 0x8a, 0x00, 0x29, 0x0e, 0xbf, + 0x40, 0xf0, 0x10, 0x00, 0x4f, 0xf6, 0xef, 0x71, 0x08, 0x40, 0x60, 0x82, + 0xf1, 0xbd, 0x30, 0xb5, 0x0f, 0xf6, 0x50, 0x11, 0x0f, 0xf6, 0x2c, 0x12, + 0x51, 0xf8, 0x20, 0x30, 0xdf, 0xf8, 0xd4, 0x18, 0x0f, 0xf6, 0x60, 0x14, + 0xdf, 0xf8, 0xd0, 0x58, 0x0b, 0x63, 0x52, 0xf8, 0x20, 0x20, 0x34, 0xf8, + 0x10, 0x40, 0x2c, 0x80, 0x01, 0xeb, 0x40, 0x00, 0x00, 0x24, 0x1c, 0x70, + 0xdf, 0xf8, 0xbc, 0x38, 0xd4, 0x88, 0x5c, 0x80, 0x14, 0x89, 0x9c, 0x80, + 0x54, 0x89, 0xdc, 0x80, 0x94, 0x89, 0x1c, 0x81, 0x0c, 0x6b, 0xdf, 0xf8, + 0xac, 0x18, 0xa5, 0x89, 0x1d, 0x82, 0xe5, 0x89, 0x5d, 0x82, 0x25, 0x8a, + 0x9d, 0x82, 0x64, 0x8a, 0xdc, 0x82, 0x00, 0x24, 0x1c, 0x80, 0x00, 0x8c, + 0x18, 0x80, 0x50, 0x88, 0x08, 0x80, 0x30, 0xbd, 0xdf, 0xf8, 0x84, 0x08, + 0x4f, 0xf4, 0xc0, 0x41, 0x01, 0x80, 0xdf, 0xf8, 0x74, 0x18, 0x0a, 0x6b, + 0x7a, 0xb1, 0xb0, 0xf9, 0x10, 0x30, 0x93, 0x81, 0xb0, 0xf9, 0x12, 0x30, + 0xd3, 0x81, 0xb0, 0xf9, 0x14, 0x30, 0x13, 0x82, 0xb0, 0xf9, 0x16, 0x00, + 0x50, 0x82, 0x01, 0x20, 0x10, 0x70, 0x00, 0x20, 0x08, 0x63, 0x70, 0x47, + 0xf8, 0xb5, 0x04, 0x46, 0x0f, 0xf6, 0xb4, 0x00, 0xdf, 0xf8, 0x40, 0x78, + 0x50, 0xf8, 0x24, 0x50, 0x0f, 0xf6, 0x88, 0x00, 0x50, 0xf8, 0x24, 0x60, + 0x0f, 0xf6, 0xc0, 0x00, 0x30, 0xf8, 0x14, 0x10, 0xdf, 0xf8, 0x2c, 0x08, + 0xf7, 0xf7, 0x00, 0xf8, 0xf1, 0x88, 0xdf, 0xf8, 0x30, 0x08, 0xf6, 0xf7, + 0xfb, 0xff, 0x31, 0x89, 0xdf, 0xf8, 0x28, 0x08, 0xf6, 0xf7, 0xf6, 0xff, + 0x71, 0x89, 0xdf, 0xf8, 0x24, 0x08, 0xf6, 0xf7, 0xf1, 0xff, 0xb1, 0x89, + 0xdf, 0xf8, 0x1c, 0x08, 0xf6, 0xf7, 0xec, 0xff, 0xa9, 0x89, 0xdf, 0xf8, + 0x18, 0x08, 0xf6, 0xf7, 0xe7, 0xff, 0xe9, 0x89, 0xdf, 0xf8, 0x10, 0x08, + 0xf6, 0xf7, 0xe2, 0xff, 0x29, 0x8a, 0xdf, 0xf8, 0x0c, 0x08, 0xf6, 0xf7, + 0xdd, 0xff, 0x69, 0x8a, 0xdf, 0xf8, 0x04, 0x08, 0xf6, 0xf7, 0xd8, 0xff, + 0x29, 0x46, 0x07, 0xf1, 0x30, 0x00, 0xf6, 0xf7, 0xfb, 0xff, 0x00, 0x21, + 0x28, 0x46, 0xf6, 0xf7, 0xbf, 0xff, 0xdf, 0xf8, 0xc8, 0x57, 0x00, 0x21, + 0x28, 0x46, 0xf6, 0xf7, 0xc9, 0xff, 0x07, 0xeb, 0x44, 0x00, 0x01, 0x8c, + 0x28, 0x46, 0xf6, 0xf7, 0xc3, 0xff, 0x71, 0x88, 0xdf, 0xf8, 0xb0, 0x07, + 0xbd, 0xe8, 0xf4, 0x40, 0xf6, 0xf7, 0xbc, 0xbf, 0x70, 0xb5, 0xdf, 0xf8, + 0xa0, 0x47, 0x4f, 0xf4, 0xc0, 0x41, 0x20, 0x46, 0xf6, 0xf7, 0xb4, 0xff, + 0xdf, 0xf8, 0x88, 0x57, 0x2e, 0x6b, 0xf6, 0xb1, 0x21, 0x8a, 0x06, 0xf1, + 0x0c, 0x00, 0xf6, 0xf7, 0xab, 0xff, 0x61, 0x8a, 0x06, 0xf1, 0x0e, 0x00, + 0xf6, 0xf7, 0xa6, 0xff, 0xa1, 0x8a, 0x06, 0xf1, 0x10, 0x00, 0xf6, 0xf7, + 0xa1, 0xff, 0xe1, 0x8a, 0x06, 0xf1, 0x12, 0x00, 0xf6, 0xf7, 0x9c, 0xff, + 0x01, 0x21, 0x30, 0x46, 0xf6, 0xf7, 0x88, 0xff, 0x05, 0xf1, 0x30, 0x00, + 0xbd, 0xe8, 0x70, 0x40, 0x00, 0x21, 0xf6, 0xf7, 0xb9, 0xbf, 0x70, 0xbd, + 0xdf, 0xf8, 0x38, 0x17, 0xdf, 0xf8, 0x50, 0x07, 0xca, 0x8e, 0x4f, 0xf6, + 0xe0, 0x73, 0x1a, 0x40, 0x02, 0x80, 0x09, 0x8f, 0xc8, 0xe0, 0xdf, 0xf8, + 0x24, 0x17, 0xdf, 0xf8, 0x3c, 0x07, 0xca, 0x8e, 0x02, 0x80, 0x09, 0x8f, + 0x41, 0x80, 0x70, 0x47, 0x70, 0xb5, 0xdf, 0xf8, 0x48, 0x17, 0x82, 0xb0, + 0x00, 0x20, 0x88, 0x61, 0xdf, 0xf8, 0xfc, 0x46, 0x60, 0x89, 0xc0, 0xf3, + 0x81, 0x00, 0xb8, 0xb3, 0xdf, 0xf8, 0xf8, 0x56, 0x07, 0x21, 0x05, 0xf1, + 0x24, 0x00, 0x00, 0xf0, 0xe7, 0xfa, 0x0c, 0x21, 0x05, 0xf1, 0x26, 0x00, + 0x00, 0xf0, 0xe7, 0xfa, 0xe0, 0x6a, 0xdf, 0xf8, 0xdc, 0x66, 0x00, 0x90, + 0x33, 0x46, 0x13, 0x22, 0x05, 0xf1, 0x28, 0x01, 0x05, 0xf1, 0x2a, 0x00, + 0x00, 0xf0, 0x5f, 0xfa, 0xe3, 0x6a, 0x32, 0x46, 0x0a, 0x21, 0x05, 0xf1, + 0x2c, 0x00, 0x00, 0xf0, 0x70, 0xfa, 0x00, 0x24, 0xdf, 0xf8, 0xbc, 0x56, + 0x0c, 0x20, 0x00, 0xfb, 0x04, 0x50, 0x05, 0xeb, 0x44, 0x21, 0x30, 0x31, + 0x01, 0x60, 0x05, 0xeb, 0xc4, 0x01, 0x01, 0xf5, 0xb6, 0x61, 0x41, 0x60, + 0x64, 0x1c, 0xc0, 0x21, 0x01, 0x72, 0xff, 0x21, 0x41, 0x72, 0x40, 0x21, + 0x00, 0xf0, 0xc3, 0xfa, 0x02, 0x2c, 0xe9, 0xd3, 0x73, 0xbd, 0x10, 0xb5, + 0xdf, 0xf8, 0xbc, 0x46, 0xdf, 0xf8, 0xbc, 0x16, 0x0e, 0x22, 0x20, 0x46, + 0xfb, 0xf7, 0x5c, 0xfb, 0x20, 0x78, 0x01, 0x06, 0x03, 0xd5, 0x00, 0xf0, + 0x7f, 0x00, 0x20, 0x70, 0x17, 0xe0, 0x00, 0x20, 0xf6, 0xf7, 0x68, 0xf8, + 0xa1, 0x88, 0x00, 0x28, 0x12, 0xbf, 0x41, 0xf0, 0x01, 0x00, 0x4f, 0xf6, + 0xfe, 0x70, 0x08, 0x40, 0xa0, 0x80, 0x01, 0x20, 0xf6, 0xf7, 0x5c, 0xf8, + 0x00, 0x28, 0xa0, 0x88, 0x12, 0xbf, 0x40, 0xf0, 0x02, 0x00, 0x4f, 0xf6, + 0xfd, 0x71, 0x08, 0x40, 0xa0, 0x80, 0x00, 0x20, 0x20, 0x61, 0x06, 0x21, + 0x4f, 0xf0, 0xff, 0x30, 0xa0, 0x82, 0x02, 0x20, 0xf9, 0xf7, 0x75, 0xfc, + 0xdf, 0xf8, 0x64, 0x06, 0x4f, 0xf6, 0xff, 0x71, 0x01, 0x80, 0x4f, 0xf6, + 0xff, 0x61, 0x41, 0x80, 0x02, 0x20, 0xf9, 0xf7, 0x4f, 0xfc, 0x02, 0x20, + 0xf9, 0xf7, 0x52, 0xfc, 0x61, 0x88, 0x23, 0x78, 0xdf, 0xf8, 0x48, 0x06, + 0xdf, 0xf8, 0x48, 0x26, 0x33, 0xb9, 0x00, 0xf0, 0x11, 0xf8, 0x01, 0x20, + 0xa0, 0x61, 0xbd, 0xe8, 0x10, 0x40, 0x39, 0xe0, 0x4e, 0xf6, 0xef, 0x73, + 0x19, 0x40, 0x00, 0xf0, 0x07, 0xf8, 0x00, 0x21, 0x01, 0x82, 0x41, 0x82, + 0x01, 0x83, 0x41, 0x83, 0xa1, 0x61, 0x10, 0xbd, 0x11, 0x80, 0x4f, 0xf6, + 0xfc, 0x72, 0xa1, 0x88, 0x11, 0x40, 0x01, 0x80, 0x70, 0x47, 0xdf, 0xf8, + 0x00, 0x06, 0x00, 0x21, 0x81, 0x61, 0x4f, 0xf6, 0xfc, 0x72, 0x4f, 0xf0, + 0xff, 0x31, 0x81, 0x82, 0xdf, 0xf8, 0xf8, 0x05, 0x01, 0x88, 0x11, 0x40, + 0x01, 0x80, 0x02, 0x20, 0xf9, 0xf7, 0x29, 0xbc, 0xdf, 0xf8, 0xdc, 0x15, + 0xdf, 0xf8, 0xec, 0x05, 0x0a, 0x89, 0x4f, 0xf6, 0xe0, 0x73, 0x1a, 0x40, + 0x02, 0x80, 0x49, 0x89, 0x19, 0x40, 0x41, 0x80, 0x70, 0x47, 0xdf, 0xf8, + 0xc4, 0x15, 0xdf, 0xf8, 0xd4, 0x05, 0x0a, 0x89, 0x02, 0x80, 0x49, 0x89, + 0x41, 0x80, 0x70, 0x47, 0xf8, 0xb5, 0xdf, 0xf8, 0xb0, 0x45, 0xa0, 0x69, + 0x00, 0x28, 0x5d, 0xd0, 0xdf, 0xf8, 0xb0, 0x55, 0x28, 0x88, 0x4f, 0xf6, + 0xfc, 0x71, 0x08, 0x40, 0x28, 0x80, 0x00, 0xf0, 0x9f, 0xfa, 0x20, 0x79, + 0x00, 0x27, 0xc0, 0x07, 0x4f, 0xf0, 0xff, 0x36, 0x05, 0xd5, 0x00, 0x20, + 0x00, 0xf0, 0x84, 0xfd, 0x08, 0xb9, 0x26, 0x8a, 0x01, 0x27, 0x20, 0x79, + 0x80, 0x07, 0x09, 0xd5, 0x01, 0x20, 0x00, 0xf0, 0x7b, 0xfd, 0x28, 0xb9, + 0x60, 0x8a, 0x86, 0x42, 0x47, 0xf0, 0x02, 0x07, 0x28, 0xbf, 0x06, 0x46, + 0x22, 0x8a, 0xdf, 0xf8, 0x28, 0x05, 0x0a, 0x21, 0x96, 0x42, 0x01, 0xfb, + 0x06, 0x01, 0x06, 0xd2, 0x91, 0xf8, 0x5a, 0x20, 0xd2, 0x07, 0x5c, 0xbf, + 0x4f, 0xf6, 0xfe, 0x72, 0x17, 0x40, 0x62, 0x8a, 0x96, 0x42, 0x06, 0xd2, + 0x91, 0xf8, 0x5a, 0x20, 0x92, 0x07, 0x5c, 0xbf, 0x4f, 0xf6, 0xfd, 0x72, + 0x17, 0x40, 0xbf, 0xb1, 0xb0, 0xf8, 0x58, 0x00, 0x86, 0x42, 0x32, 0xbf, + 0x01, 0xf1, 0x5a, 0x00, 0x06, 0x46, 0x20, 0x1d, 0x41, 0x88, 0x69, 0x80, + 0x81, 0x88, 0xa9, 0x80, 0xc1, 0x88, 0xe9, 0x80, 0x01, 0x89, 0x29, 0x81, + 0x4f, 0xf6, 0xfc, 0x71, 0x00, 0x88, 0x08, 0x40, 0x38, 0x43, 0x28, 0x80, + 0x30, 0x46, 0x01, 0xe0, 0x4f, 0xf0, 0xff, 0x30, 0x47, 0xea, 0x06, 0x11, + 0xa0, 0x82, 0x3d, 0x20, 0xbd, 0xe8, 0xf4, 0x40, 0xf9, 0xf7, 0x3e, 0xbc, + 0xf1, 0xbd, 0x38, 0xb5, 0x04, 0x46, 0xff, 0xf7, 0xf5, 0xfc, 0xdf, 0xf8, + 0xe0, 0x14, 0x05, 0x46, 0x01, 0xeb, 0x44, 0x01, 0x00, 0x20, 0x08, 0x82, + 0x00, 0x22, 0x00, 0x21, 0x20, 0x46, 0x00, 0xf0, 0x03, 0xf8, 0x85, 0xf3, + 0x11, 0x88, 0x31, 0xbd, 0xf8, 0xb5, 0x04, 0x46, 0x0d, 0x46, 0x16, 0x46, + 0xff, 0xf7, 0xe0, 0xfc, 0x07, 0x46, 0xdf, 0xf8, 0xc0, 0x04, 0x01, 0x88, + 0x4f, 0xf6, 0xfc, 0x72, 0x11, 0x40, 0x01, 0x80, 0x14, 0xb9, 0x05, 0x82, + 0x46, 0x82, 0x03, 0xe0, 0x01, 0x2c, 0x04, 0xbf, 0x05, 0x83, 0x46, 0x83, + 0xff, 0xf7, 0x70, 0xff, 0x87, 0xf3, 0x11, 0x88, 0xf1, 0xbd, 0x2d, 0xe9, + 0xf8, 0x43, 0x80, 0x46, 0x0f, 0xf2, 0xc4, 0x40, 0x50, 0xf8, 0x28, 0x50, + 0x0e, 0x46, 0x17, 0x46, 0xff, 0xf7, 0xc6, 0xfc, 0x04, 0x46, 0x89, 0x46, + 0xf9, 0xf7, 0x7e, 0xfd, 0x40, 0x45, 0x0a, 0xd1, 0xdf, 0xf8, 0x40, 0x04, + 0x01, 0x88, 0x4f, 0xf6, 0xfe, 0x72, 0x0a, 0x40, 0x02, 0x80, 0x06, 0x82, + 0x47, 0x82, 0x01, 0x80, 0x03, 0xe0, 0xae, 0x81, 0xef, 0x81, 0x01, 0x20, + 0x28, 0x70, 0x20, 0x46, 0x49, 0x46, 0xbd, 0xe8, 0xf4, 0x43, 0xb7, 0xe4, + 0x00, 0x28, 0xdf, 0xf8, 0x40, 0x14, 0x0c, 0xbf, 0x01, 0x20, 0x02, 0x20, + 0x89, 0x88, 0x08, 0x40, 0x70, 0x47, 0xdf, 0xf8, 0x00, 0x14, 0x01, 0xeb, + 0x40, 0x00, 0x90, 0xf8, 0x20, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x70, 0x47, + 0xdf, 0xf8, 0x1c, 0x24, 0x02, 0xeb, 0x40, 0x00, 0x00, 0x21, 0x01, 0x82, + 0x2e, 0xe7, 0x2d, 0xe9, 0xfc, 0x47, 0x06, 0x46, 0xdf, 0xf8, 0xd4, 0x93, + 0x0c, 0x20, 0x88, 0x46, 0x17, 0x46, 0x00, 0xfb, 0x06, 0x9a, 0x39, 0x46, + 0x50, 0x46, 0x00, 0xf0, 0x6a, 0xf9, 0x00, 0x25, 0x20, 0xb1, 0x39, 0x46, + 0x50, 0x46, 0x00, 0xf0, 0x58, 0xf9, 0x05, 0x46, 0xdf, 0xf8, 0xf0, 0x73, + 0xdf, 0xf8, 0xe0, 0x43, 0x38, 0x88, 0x4f, 0xf6, 0xfc, 0x71, 0x08, 0x40, + 0x38, 0x80, 0x06, 0xbb, 0xb7, 0xf9, 0x10, 0x00, 0xad, 0xf8, 0x00, 0x00, + 0x6a, 0x46, 0xb7, 0xf9, 0x12, 0x00, 0xad, 0xf8, 0x02, 0x00, 0x41, 0x46, + 0xb7, 0xf9, 0x14, 0x00, 0xad, 0xf8, 0x04, 0x00, 0xb7, 0xf9, 0x16, 0x00, + 0xad, 0xf8, 0x06, 0x00, 0x48, 0x46, 0x00, 0xf0, 0x59, 0xf9, 0x3d, 0xb1, + 0x28, 0x88, 0x38, 0x82, 0x68, 0x88, 0x78, 0x82, 0xa8, 0x88, 0xb8, 0x82, + 0xe8, 0x88, 0xf8, 0x82, 0x00, 0x20, 0x20, 0x82, 0x21, 0xe0, 0x01, 0x2e, + 0x1f, 0xd1, 0xb7, 0xf9, 0x18, 0x00, 0xad, 0xf8, 0x00, 0x00, 0x6a, 0x46, + 0xb7, 0xf9, 0x1a, 0x00, 0xad, 0xf8, 0x02, 0x00, 0x41, 0x46, 0xb7, 0xf9, + 0x1c, 0x00, 0xad, 0xf8, 0x04, 0x00, 0xb7, 0xf9, 0x1e, 0x00, 0xad, 0xf8, + 0x06, 0x00, 0x50, 0x46, 0x00, 0xf0, 0x36, 0xf9, 0x3d, 0xb1, 0x28, 0x88, + 0x38, 0x83, 0x68, 0x88, 0x78, 0x83, 0xa8, 0x88, 0xb8, 0x83, 0xe8, 0x88, + 0xf8, 0x83, 0x00, 0x20, 0x60, 0x82, 0xff, 0xf7, 0xcb, 0xfe, 0xbd, 0xe8, + 0xf3, 0x87, 0x2d, 0xe9, 0xfc, 0x47, 0x06, 0x46, 0x04, 0x2e, 0x8a, 0x46, + 0x14, 0x46, 0x57, 0xda, 0xc0, 0x48, 0x0c, 0x21, 0x01, 0xfb, 0x06, 0x08, + 0x21, 0x46, 0x40, 0x46, 0x00, 0xf0, 0x03, 0xf9, 0x00, 0x25, 0x20, 0xb1, + 0x21, 0x46, 0x40, 0x46, 0x00, 0xf0, 0xf1, 0xf8, 0x05, 0x46, 0xff, 0xf7, + 0x15, 0xfc, 0x02, 0x2e, 0x04, 0x46, 0x89, 0x46, 0x02, 0xd1, 0xf5, 0xf7, + 0xec, 0xf8, 0x01, 0xe0, 0xf5, 0xf7, 0xfd, 0xf8, 0x06, 0x46, 0xf9, 0xf7, + 0xc5, 0xfc, 0xb0, 0x42, 0x25, 0xd1, 0xb4, 0x4e, 0x37, 0x88, 0x4f, 0xf6, + 0xfe, 0x70, 0x38, 0x40, 0x30, 0x80, 0x6a, 0x46, 0xb6, 0xf9, 0x10, 0x00, + 0xad, 0xf8, 0x00, 0x00, 0x51, 0x46, 0xb6, 0xf9, 0x12, 0x00, 0xad, 0xf8, + 0x02, 0x00, 0xb6, 0xf9, 0x14, 0x00, 0xad, 0xf8, 0x04, 0x00, 0xb6, 0xf9, + 0x16, 0x00, 0xad, 0xf8, 0x06, 0x00, 0x40, 0x46, 0x00, 0xf0, 0xe6, 0xf8, + 0x3d, 0xb1, 0x28, 0x88, 0x30, 0x82, 0x68, 0x88, 0x70, 0x82, 0xa8, 0x88, + 0xb0, 0x82, 0xe8, 0x88, 0xf0, 0x82, 0x37, 0x80, 0x0e, 0xe0, 0x6d, 0xb1, + 0x0f, 0xf2, 0xe8, 0x20, 0x50, 0xf8, 0x26, 0x00, 0x29, 0x88, 0x81, 0x81, + 0x69, 0x88, 0xc1, 0x81, 0xa9, 0x88, 0x01, 0x82, 0xe9, 0x88, 0x41, 0x82, + 0x01, 0x21, 0x01, 0x70, 0x20, 0x46, 0x49, 0x46, 0xff, 0xf7, 0xda, 0xfb, + 0xbd, 0xe8, 0xf3, 0x87, 0x10, 0xf1, 0x14, 0x0f, 0xb8, 0xbf, 0x1f, 0x20, + 0x04, 0xdb, 0x0a, 0x28, 0xac, 0xbf, 0x00, 0x20, 0xc0, 0xf1, 0x0a, 0x00, + 0x80, 0xb2, 0x70, 0x47, 0x10, 0xb5, 0x91, 0x42, 0x04, 0x46, 0x05, 0xd2, + 0xb2, 0xfb, 0xf1, 0xf0, 0xf9, 0xf7, 0x4f, 0xfa, 0x24, 0x1a, 0x06, 0xe0, + 0x8a, 0x42, 0x04, 0xd2, 0xb1, 0xfb, 0xf2, 0xf0, 0xf9, 0xf7, 0x47, 0xfa, + 0x04, 0x19, 0x20, 0x46, 0x10, 0xbd, 0x38, 0xb5, 0x04, 0x46, 0x1f, 0x2a, + 0xac, 0xbf, 0x6f, 0xf0, 0x14, 0x00, 0xc2, 0xf1, 0x0a, 0x00, 0x0d, 0x46, + 0x04, 0x9a, 0x19, 0x46, 0xff, 0xf7, 0xe0, 0xff, 0xff, 0xf7, 0xd2, 0xff, + 0x21, 0x88, 0x4e, 0xf2, 0xff, 0x02, 0x11, 0x40, 0x41, 0xea, 0x00, 0x21, + 0x21, 0x80, 0x29, 0x88, 0x17, 0xe0, 0x38, 0xb5, 0x05, 0x46, 0x0f, 0x29, + 0x14, 0x46, 0xac, 0xbf, 0x6f, 0xf0, 0x0e, 0x00, 0x48, 0x42, 0x1a, 0x46, + 0x21, 0x46, 0xff, 0xf7, 0xc9, 0xff, 0x00, 0x28, 0x58, 0xbf, 0x00, 0x20, + 0x04, 0xd5, 0x10, 0xf1, 0x0e, 0x0f, 0xb4, 0xbf, 0x0f, 0x20, 0x40, 0x42, + 0x29, 0x88, 0x4f, 0xf2, 0xff, 0x02, 0x11, 0x40, 0x41, 0xea, 0x00, 0x20, + 0x28, 0x80, 0x31, 0xbd, 0xf8, 0xb5, 0x05, 0x46, 0x0c, 0x46, 0x10, 0x46, + 0x1e, 0x46, 0xf7, 0xf7, 0xd3, 0xff, 0x79, 0x49, 0xf8, 0xf7, 0x6e, 0xf9, + 0x07, 0x46, 0x30, 0x46, 0xf7, 0xf7, 0xcc, 0xff, 0x01, 0x46, 0x38, 0x46, + 0xf7, 0xf7, 0xd8, 0xff, 0xff, 0xf7, 0x64, 0xf8, 0x06, 0x99, 0x46, 0x1a, + 0x30, 0x00, 0x18, 0xbf, 0x01, 0x20, 0xc0, 0xb2, 0xf9, 0xf7, 0xb7, 0xf9, + 0x30, 0x46, 0xf7, 0xf7, 0xbb, 0xff, 0x4f, 0xf0, 0xff, 0x37, 0x39, 0x46, + 0xff, 0xf7, 0x5e, 0xfa, 0x01, 0x46, 0x6b, 0x48, 0xf8, 0xf7, 0x40, 0xf8, + 0xf8, 0xf7, 0xba, 0xf9, 0xff, 0xf7, 0x80, 0xff, 0x2a, 0x88, 0x01, 0x02, + 0xc2, 0xf3, 0x04, 0x23, 0x98, 0x42, 0x04, 0xd2, 0x4e, 0xf2, 0xff, 0x03, + 0x1a, 0x40, 0x0a, 0x43, 0x2a, 0x80, 0x22, 0x88, 0xc2, 0xf3, 0x04, 0x23, + 0x98, 0x42, 0x04, 0xd2, 0x4e, 0xf2, 0xff, 0x00, 0x10, 0x40, 0x08, 0x43, + 0x20, 0x80, 0xf1, 0xbd, 0x02, 0x88, 0x61, 0xf3, 0x0a, 0x22, 0x02, 0x80, + 0x70, 0x47, 0x02, 0x88, 0x02, 0xf4, 0x7f, 0x42, 0x11, 0x43, 0x01, 0x80, + 0x70, 0x47, 0x40, 0x68, 0xc9, 0x08, 0xf4, 0xf7, 0x2b, 0xba, 0x38, 0xb5, + 0x04, 0x46, 0x00, 0xf0, 0x3e, 0xf8, 0x00, 0x25, 0x00, 0x28, 0x5c, 0xbf, + 0x21, 0x68, 0x01, 0xeb, 0xc0, 0x05, 0x28, 0x46, 0x32, 0xbd, 0x38, 0xb5, + 0x05, 0x46, 0x00, 0xf0, 0x32, 0xf8, 0x00, 0x24, 0x00, 0x28, 0x0b, 0xd4, + 0x69, 0x68, 0xc2, 0x10, 0x00, 0xf0, 0x07, 0x00, 0x51, 0x5c, 0x01, 0x22, + 0x02, 0xfa, 0x00, 0xf0, 0x08, 0x40, 0x01, 0x28, 0xa8, 0xbf, 0x01, 0x24, + 0x20, 0x46, 0x32, 0xbd, 0x70, 0xb5, 0x04, 0x46, 0x15, 0x46, 0x00, 0xf0, + 0x1c, 0xf8, 0x00, 0x28, 0x18, 0xd4, 0x00, 0xf0, 0x07, 0x02, 0x01, 0x23, + 0x03, 0xfa, 0x02, 0xf2, 0x63, 0x68, 0xc1, 0x10, 0xce, 0x5c, 0x96, 0x43, + 0xce, 0x54, 0x23, 0x68, 0x03, 0xeb, 0xc0, 0x00, 0x2b, 0x88, 0x03, 0x80, + 0x6b, 0x88, 0x43, 0x80, 0xab, 0x88, 0x83, 0x80, 0xeb, 0x88, 0xc3, 0x80, + 0x60, 0x68, 0x0b, 0x5c, 0x1a, 0x43, 0x0a, 0x54, 0x70, 0xbd, 0x03, 0x7a, + 0x4f, 0xf0, 0xff, 0x32, 0x99, 0x42, 0x22, 0xbf, 0x40, 0x7a, 0x88, 0x42, + 0xca, 0x1a, 0x10, 0x46, 0x70, 0x47, 0x70, 0xb5, 0x3c, 0x20, 0xf9, 0xf7, + 0xf6, 0xf9, 0x29, 0x48, 0x04, 0x88, 0x4f, 0xf6, 0xfc, 0x71, 0x21, 0x40, + 0x01, 0x80, 0x00, 0xf0, 0x19, 0xf8, 0x22, 0x48, 0xb0, 0xf9, 0x14, 0x10, + 0x00, 0x29, 0x10, 0xd4, 0x00, 0x22, 0x0f, 0xf2, 0xec, 0x03, 0x33, 0xf8, + 0x12, 0x50, 0x2c, 0x42, 0x06, 0xd0, 0x00, 0xeb, 0x42, 0x05, 0x2e, 0x8a, + 0xb1, 0x42, 0xa4, 0xbf, 0x76, 0x1c, 0x2e, 0x82, 0x52, 0x1c, 0x02, 0x2a, + 0xf1, 0xd3, 0xbd, 0xe8, 0x70, 0x40, 0x51, 0xe5, 0x4f, 0xf4, 0x80, 0x70, + 0x16, 0x49, 0x08, 0x80, 0x02, 0x20, 0xf9, 0xf7, 0x4f, 0xb9, 0x00, 0x00, + 0x00, 0xe1, 0x00, 0xe0, 0x80, 0xe1, 0x00, 0xe0, 0x78, 0x29, 0x00, 0x20, + 0x00, 0x00, 0xa6, 0x0e, 0x4c, 0x1f, 0x00, 0x20, 0x80, 0xa2, 0x00, 0x20, + 0x14, 0xc8, 0x00, 0x20, 0x02, 0x08, 0x00, 0x41, 0x20, 0x01, 0x00, 0x41, + 0xfe, 0x01, 0x00, 0x41, 0x22, 0x01, 0x00, 0x41, 0x24, 0x01, 0x00, 0x41, + 0x26, 0x01, 0x00, 0x41, 0x28, 0x01, 0x00, 0x41, 0x30, 0x01, 0x00, 0x41, + 0x32, 0x01, 0x00, 0x41, 0x34, 0x01, 0x00, 0x41, 0x36, 0x01, 0x00, 0x41, + 0xcc, 0xf2, 0x00, 0x20, 0x6c, 0x1f, 0x00, 0x20, 0x08, 0x08, 0x00, 0x41, + 0x00, 0x01, 0x00, 0x41, 0xfc, 0x01, 0x00, 0x41, 0x04, 0x01, 0x00, 0x41, + 0x34, 0x80, 0x37, 0x3a, 0x48, 0xe1, 0x9a, 0xbf, 0x00, 0x00, 0x00, 0x00, + 0x14, 0xc8, 0x00, 0x20, 0x14, 0xc8, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x24, 0xc8, 0x00, 0x20, 0x14, 0xc8, 0x00, 0x20, 0x14, 0xc8, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x20, 0x00, 0x20, + 0x78, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x20, 0x00, 0x20, + 0xa0, 0x20, 0x00, 0x20, 0xb4, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x1f, 0xb5, 0x00, 0xf0, + 0xb7, 0xf8, 0x21, 0x21, 0x01, 0x60, 0x1f, 0xbd, 0xf8, 0xb5, 0x0c, 0x46, + 0x2b, 0x49, 0xf8, 0xf7, 0x4d, 0xf9, 0x05, 0x46, 0x12, 0xd8, 0x2a, 0x4e, + 0x31, 0x46, 0xf8, 0xf7, 0x3f, 0xf8, 0x29, 0x49, 0xf7, 0xf7, 0xa0, 0xff, + 0x07, 0x46, 0x28, 0x46, 0x31, 0x46, 0xf7, 0xf7, 0x9b, 0xff, 0x01, 0x46, + 0x38, 0x46, 0xf7, 0xf7, 0xa5, 0xfe, 0x05, 0x46, 0x44, 0xf0, 0x01, 0x04, + 0x28, 0x46, 0x22, 0x49, 0xf8, 0xf7, 0x1a, 0xf8, 0x03, 0xd3, 0x21, 0x49, + 0xf8, 0xf7, 0x30, 0xf9, 0x21, 0xd8, 0x29, 0x46, 0xf8, 0xf7, 0x24, 0xf8, + 0x06, 0x46, 0x28, 0x46, 0x31, 0x46, 0xf8, 0xf7, 0x1f, 0xf8, 0x1c, 0x49, + 0xf8, 0xf7, 0x1c, 0xf8, 0x29, 0x46, 0xf7, 0xf7, 0x7d, 0xff, 0x05, 0x46, + 0x19, 0x48, 0x31, 0x46, 0xf8, 0xf7, 0x14, 0xf8, 0x18, 0x49, 0xf7, 0xf7, + 0x75, 0xff, 0x31, 0x46, 0xf8, 0xf7, 0x0e, 0xf8, 0x4f, 0xf0, 0x7e, 0x51, + 0xf7, 0xf7, 0x6e, 0xff, 0x01, 0x46, 0x28, 0x46, 0xf7, 0xf7, 0x78, 0xfe, + 0x05, 0x46, 0xa0, 0x07, 0x48, 0xbf, 0x85, 0xf0, 0x00, 0x45, 0x14, 0xf0, + 0x07, 0x00, 0x07, 0xd0, 0x0f, 0xf2, 0x38, 0x01, 0x51, 0xf8, 0x20, 0x00, + 0x29, 0x46, 0xf7, 0xf7, 0x5b, 0xff, 0x05, 0x46, 0x20, 0x07, 0x48, 0xbf, + 0x85, 0xf0, 0x00, 0x45, 0x28, 0x46, 0xf2, 0xbd, 0xa4, 0x30, 0x89, 0x3e, + 0xd7, 0xb3, 0xdd, 0x3f, 0x00, 0x00, 0x80, 0xbf, 0x00, 0x00, 0x80, 0xb9, + 0x01, 0x00, 0x80, 0x39, 0x6a, 0xd5, 0x03, 0x3f, 0x2b, 0x94, 0xa9, 0x3d, + 0xb8, 0x2a, 0x59, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x92, 0x0a, 0x06, 0x3f, + 0xdb, 0x0f, 0xc9, 0x3f, 0x92, 0x0a, 0x86, 0x3f, 0xdb, 0x0f, 0xc9, 0x3f, + 0x92, 0x0a, 0x06, 0x40, 0xdb, 0x0f, 0x49, 0x40, 0x36, 0x8d, 0x27, 0x40, + 0x02, 0x68, 0x02, 0xf0, 0x00, 0x43, 0x01, 0x21, 0x52, 0x02, 0x52, 0x0a, + 0x02, 0xd1, 0x06, 0xe0, 0x52, 0x00, 0x49, 0x1e, 0x5f, 0xea, 0x02, 0x2c, + 0xfa, 0xd5, 0x52, 0x02, 0x52, 0x0a, 0x1a, 0x43, 0x02, 0x60, 0x08, 0x46, + 0x70, 0x47, 0x02, 0x68, 0xc2, 0xf3, 0xc7, 0x52, 0xff, 0x2a, 0x05, 0xd1, + 0x00, 0x68, 0x40, 0x02, 0x0c, 0xbf, 0x01, 0x20, 0x02, 0x20, 0x70, 0x47, + 0x03, 0x68, 0x5b, 0x00, 0x16, 0xd0, 0xc2, 0xf1, 0x96, 0x02, 0x52, 0x1a, + 0x01, 0x2a, 0x11, 0xdb, 0x18, 0x2a, 0x04, 0xdb, 0x01, 0x68, 0x01, 0xf0, + 0x00, 0x41, 0x01, 0x60, 0x07, 0xe0, 0x01, 0x21, 0x91, 0x40, 0x02, 0x68, + 0x49, 0x1e, 0x11, 0x40, 0x4a, 0x40, 0x02, 0x60, 0x11, 0xb1, 0x4f, 0xf0, + 0xff, 0x30, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x01, 0x48, 0xf1, 0xf7, + 0x86, 0xb9, 0x00, 0x00, 0x1c, 0xbd, 0x00, 0x20, 0x2d, 0xe9, 0xf0, 0x4d, + 0x04, 0x46, 0x0d, 0x46, 0x27, 0x68, 0xc7, 0xf3, 0xc7, 0x51, 0xff, 0x29, + 0x16, 0x46, 0x09, 0xd0, 0x11, 0xb1, 0x4f, 0xf0, 0xff, 0x30, 0x09, 0xe0, + 0x78, 0x02, 0x0c, 0xbf, 0x00, 0x20, 0x6f, 0xf0, 0x01, 0x00, 0x03, 0xe0, + 0x78, 0x02, 0x14, 0xbf, 0x02, 0x20, 0x01, 0x20, 0xc5, 0xf3, 0xc7, 0x52, + 0xff, 0x2a, 0x09, 0xd0, 0x12, 0xb1, 0x4f, 0xf0, 0xff, 0x31, 0x09, 0xe0, + 0x69, 0x02, 0x0c, 0xbf, 0x00, 0x21, 0x6f, 0xf0, 0x01, 0x01, 0x03, 0xe0, + 0x69, 0x02, 0x14, 0xbf, 0x02, 0x21, 0x01, 0x21, 0x02, 0x00, 0x48, 0xbf, + 0x00, 0x29, 0x3e, 0xd4, 0x02, 0x28, 0x00, 0xf0, 0xc6, 0x80, 0x02, 0x29, + 0x08, 0xbf, 0x25, 0x60, 0x18, 0xd0, 0x39, 0xb9, 0x38, 0x46, 0x4f, 0xf0, + 0xff, 0x41, 0xf7, 0xf7, 0x35, 0xff, 0x0a, 0xd0, 0x25, 0x60, 0x38, 0xe0, + 0x01, 0x29, 0x10, 0xd1, 0x38, 0x46, 0x5c, 0x49, 0xf7, 0xf7, 0x2c, 0xff, + 0x18, 0xbf, 0x25, 0x60, 0x40, 0xd1, 0xff, 0xf7, 0xb1, 0xff, 0x21, 0x21, + 0x01, 0x60, 0x6f, 0xf0, 0x00, 0x40, 0x20, 0x60, 0x02, 0x20, 0xbd, 0xe8, + 0xf0, 0x8d, 0x70, 0xb9, 0x25, 0x60, 0x31, 0x46, 0x20, 0x46, 0x00, 0xf0, + 0x61, 0xff, 0x04, 0x00, 0x18, 0xbf, 0x01, 0x2c, 0x40, 0xf0, 0x9a, 0x80, + 0xff, 0xf7, 0x9c, 0xff, 0x22, 0x21, 0x01, 0x60, 0x94, 0xe0, 0x38, 0x46, + 0x4f, 0xf0, 0xff, 0x41, 0xf7, 0xf7, 0x0a, 0xff, 0x0a, 0xd1, 0x08, 0x46, + 0x29, 0x46, 0xf7, 0xf7, 0x25, 0xff, 0x20, 0x60, 0x1a, 0xe0, 0x38, 0x46, + 0x46, 0x49, 0xf7, 0xf7, 0x0d, 0xff, 0x07, 0xd2, 0x00, 0x20, 0x29, 0x46, + 0xf7, 0xf7, 0x1a, 0xff, 0x20, 0x60, 0x00, 0x20, 0xbd, 0xe8, 0xf0, 0x8d, + 0x41, 0x49, 0xf8, 0xf7, 0x1b, 0xf8, 0x0c, 0xd8, 0x4f, 0xf0, 0xff, 0x40, + 0x29, 0x46, 0xf7, 0xf7, 0x0d, 0xff, 0x20, 0x60, 0xff, 0xf7, 0x74, 0xff, + 0x22, 0x21, 0x01, 0x60, 0x01, 0x20, 0xbd, 0xe8, 0xf0, 0x8d, 0x3a, 0x48, + 0x39, 0x46, 0xf7, 0xf7, 0x01, 0xff, 0x00, 0x21, 0xf7, 0xf7, 0xec, 0xfe, + 0x34, 0xbf, 0x4f, 0xf0, 0x3f, 0x41, 0x4f, 0xf0, 0x7c, 0x51, 0xf7, 0xf7, + 0x5b, 0xfe, 0xf7, 0xf7, 0x61, 0xff, 0x80, 0x46, 0xf7, 0xf7, 0x4a, 0xfd, + 0x82, 0x46, 0x31, 0x48, 0x51, 0x46, 0xf7, 0xf7, 0xed, 0xfe, 0x01, 0x46, + 0x38, 0x46, 0xf7, 0xf7, 0xd9, 0xfd, 0x07, 0x46, 0x2d, 0x48, 0x51, 0x46, + 0xf7, 0xf7, 0xe4, 0xfe, 0x01, 0x46, 0x38, 0x46, 0xf7, 0xf7, 0xd0, 0xfd, + 0x4f, 0xf0, 0x33, 0x41, 0xf7, 0xf7, 0xe4, 0xff, 0x82, 0x46, 0x03, 0xd8, + 0x27, 0x49, 0xf7, 0xf7, 0xc5, 0xfe, 0x2d, 0xd3, 0x51, 0x46, 0xf7, 0xf7, + 0xd3, 0xfe, 0x83, 0x46, 0x24, 0x48, 0x59, 0x46, 0xf7, 0xf7, 0xce, 0xfe, + 0x07, 0x46, 0x23, 0x48, 0x59, 0x46, 0xf7, 0xf7, 0xc9, 0xfe, 0x4f, 0xf0, + 0x7c, 0x51, 0xf7, 0xf7, 0x29, 0xfe, 0x51, 0x46, 0xf7, 0xf7, 0xc2, 0xfe, + 0x82, 0x46, 0x38, 0x46, 0x51, 0x46, 0xf7, 0xf7, 0x21, 0xfe, 0x4f, 0xf0, + 0x7e, 0x51, 0xf7, 0xf7, 0x1d, 0xfe, 0x83, 0x46, 0x38, 0x46, 0x51, 0x46, + 0xf7, 0xf7, 0xa4, 0xfd, 0x4f, 0xf0, 0x7e, 0x51, 0xf7, 0xf7, 0x14, 0xfe, + 0x01, 0x46, 0x58, 0x46, 0xf7, 0xf7, 0x1e, 0xfd, 0x29, 0x46, 0xf7, 0xf7, + 0xa9, 0xfe, 0x05, 0x46, 0x25, 0x60, 0x06, 0xeb, 0x08, 0x01, 0x20, 0x46, + 0x00, 0xf0, 0xca, 0xfe, 0x04, 0x00, 0x18, 0xbf, 0x01, 0x2c, 0x03, 0xd1, + 0xff, 0xf7, 0x06, 0xff, 0x22, 0x21, 0x01, 0x60, 0x20, 0x46, 0xbd, 0xe8, + 0xf0, 0x8d, 0x00, 0xbf, 0x00, 0x00, 0x80, 0xff, 0x00, 0x00, 0x65, 0xc3, + 0x01, 0x00, 0x65, 0x43, 0x3b, 0xaa, 0xb8, 0x3f, 0x00, 0x60, 0x31, 0x3f, + 0xbf, 0xbf, 0x90, 0x39, 0x01, 0x00, 0x00, 0x33, 0x9e, 0xbf, 0xcc, 0x3d, + 0x13, 0x54, 0x08, 0x3c, 0x70, 0x47, 0x00, 0x00, 0xd2, 0xb2, 0x20, 0x3a, + 0x22, 0xbf, 0x41, 0xfa, 0x02, 0xf0, 0xc9, 0x17, 0x70, 0x47, 0x20, 0x32, + 0xd1, 0x41, 0xd0, 0x40, 0x48, 0x40, 0x91, 0x40, 0xd1, 0x40, 0x48, 0x40, + 0x91, 0x40, 0x11, 0x41, 0x70, 0x47, 0x70, 0x47, 0x70, 0x47, 0x00, 0xf0, + 0xad, 0xb9, 0x70, 0x47, 0x80, 0xb5, 0xf5, 0xf7, 0x0c, 0xfa, 0xbd, 0xe8, + 0x01, 0x40, 0x00, 0xf0, 0xa5, 0xb9, 0x70, 0x47, 0x00, 0xf0, 0xa1, 0xb8, + 0x00, 0xb5, 0x00, 0xbf, 0x13, 0x00, 0x96, 0x46, 0x94, 0x46, 0x10, 0x39, + 0x28, 0xbf, 0xa0, 0xe8, 0x0c, 0x50, 0xfa, 0xd8, 0x5f, 0xea, 0x41, 0x7c, + 0x28, 0xbf, 0x0c, 0xc0, 0x48, 0xbf, 0x40, 0xf8, 0x04, 0x2b, 0xc9, 0x07, + 0x28, 0xbf, 0x20, 0xf8, 0x02, 0x2b, 0x48, 0xbf, 0x00, 0xf8, 0x01, 0x2b, + 0x00, 0xbd, 0x00, 0x00, 0x80, 0xb5, 0x4f, 0xf0, 0x92, 0x41, 0x00, 0x20, + 0x08, 0x60, 0x06, 0x21, 0x0f, 0x20, 0xf8, 0xf7, 0xfa, 0xfe, 0xbd, 0xe8, + 0x02, 0x40, 0x02, 0xe0, 0x0c, 0x49, 0x08, 0x60, 0x70, 0x47, 0x0f, 0x20, + 0xf8, 0xf7, 0xdc, 0xbe, 0x1c, 0xb5, 0x4f, 0xf0, 0x92, 0x44, 0x08, 0x49, + 0x20, 0x68, 0x00, 0x90, 0x60, 0x68, 0x09, 0x68, 0x01, 0x90, 0x00, 0x98, + 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x90, 0x68, 0x46, 0x88, 0x47, 0x00, 0x20, + 0x20, 0x60, 0x13, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x6c, 0xf3, 0x00, 0x20, + 0x10, 0xb5, 0x93, 0x48, 0x93, 0x4c, 0x4f, 0xf4, 0xf0, 0x01, 0x01, 0x62, + 0xc2, 0x6a, 0x42, 0xf4, 0xf0, 0x02, 0xc2, 0x62, 0x02, 0x6b, 0x42, 0xf4, + 0xf0, 0x02, 0x02, 0x63, 0x01, 0x60, 0x11, 0x20, 0xf8, 0xf7, 0xc3, 0xfe, + 0x06, 0x21, 0x11, 0x20, 0xf8, 0xf7, 0xc5, 0xfe, 0x11, 0x20, 0xf8, 0xf7, + 0xad, 0xfe, 0x4f, 0xf4, 0x40, 0x30, 0xe0, 0x62, 0xa1, 0x6b, 0x41, 0xf4, + 0x40, 0x31, 0xa1, 0x63, 0xe1, 0x6b, 0x41, 0xf4, 0x40, 0x31, 0xe1, 0x63, + 0x20, 0x60, 0x21, 0x20, 0xf8, 0xf7, 0xad, 0xfe, 0x06, 0x21, 0x21, 0x20, + 0xf8, 0xf7, 0xaf, 0xfe, 0x21, 0x20, 0xf8, 0xf7, 0x97, 0xfe, 0x00, 0x20, + 0x60, 0x60, 0x22, 0x20, 0xf8, 0xf7, 0xa1, 0xfe, 0x06, 0x21, 0x22, 0x20, + 0xf8, 0xf7, 0xa3, 0xfe, 0x22, 0x20, 0xf8, 0xf7, 0x8b, 0xfe, 0x00, 0x20, + 0xa0, 0x60, 0x23, 0x20, 0xf8, 0xf7, 0x95, 0xfe, 0x06, 0x21, 0x23, 0x20, + 0xf8, 0xf7, 0x97, 0xfe, 0xbd, 0xe8, 0x10, 0x40, 0x23, 0x20, 0xf8, 0xf7, + 0x7d, 0xbe, 0x80, 0xb5, 0x11, 0x20, 0xf8, 0xf7, 0x82, 0xfe, 0x21, 0x20, + 0xf8, 0xf7, 0x7f, 0xfe, 0x22, 0x20, 0xf8, 0xf7, 0x7c, 0xfe, 0xbd, 0xe8, + 0x02, 0x40, 0x23, 0x20, 0xf8, 0xf7, 0x77, 0xbe, 0x69, 0x49, 0x51, 0xf8, + 0x20, 0x00, 0x00, 0xb1, 0x01, 0x20, 0xc0, 0xb2, 0x70, 0x47, 0x80, 0xb5, + 0x22, 0x20, 0xf8, 0xf7, 0x72, 0xfe, 0xbd, 0xe8, 0x02, 0x40, 0x23, 0x20, + 0xf8, 0xf7, 0x6d, 0xbe, 0xf8, 0xb5, 0x00, 0x24, 0x0f, 0xf2, 0x88, 0x15, + 0x5d, 0x4e, 0x5f, 0x4f, 0x57, 0xf8, 0x24, 0x00, 0x38, 0xb1, 0x30, 0x68, + 0x55, 0xf8, 0x24, 0x10, 0x08, 0x43, 0x30, 0x60, 0x11, 0x20, 0xf8, 0xf7, + 0x5c, 0xfe, 0x07, 0xeb, 0x84, 0x01, 0x64, 0x1c, 0x00, 0x20, 0x02, 0x2c, + 0xc8, 0x60, 0xed, 0xd3, 0xf1, 0xbd, 0x10, 0xb5, 0x54, 0x4c, 0xa0, 0x68, + 0x30, 0xb1, 0x52, 0x49, 0x4f, 0xf4, 0x40, 0x30, 0x08, 0x60, 0x21, 0x20, + 0xf8, 0xf7, 0x49, 0xfe, 0x00, 0x20, 0x60, 0x61, 0x10, 0xbd, 0x2d, 0xe9, + 0xf8, 0x4f, 0x01, 0x21, 0x36, 0x20, 0xf8, 0xf7, 0xba, 0xfe, 0x00, 0x24, + 0x48, 0x4d, 0xdf, 0xf8, 0x2c, 0x81, 0x0f, 0xf2, 0x44, 0x1b, 0x48, 0x4e, + 0x0f, 0xf2, 0x24, 0x19, 0x0f, 0xf2, 0x2c, 0x1a, 0x5a, 0xf8, 0x24, 0x00, + 0x59, 0xf8, 0x24, 0x70, 0x01, 0x68, 0x39, 0x40, 0x29, 0xd0, 0x01, 0x60, + 0xf0, 0x69, 0xa0, 0x42, 0x05, 0xd1, 0x01, 0x20, 0xb0, 0x61, 0x01, 0x21, + 0x3b, 0x20, 0xf8, 0xf7, 0x9e, 0xfe, 0x5b, 0xf8, 0x24, 0x00, 0x00, 0x68, + 0x06, 0xeb, 0x84, 0x01, 0x38, 0x40, 0xca, 0x68, 0x46, 0xf8, 0x24, 0x00, + 0x52, 0x1c, 0xca, 0x60, 0x30, 0xb1, 0xb8, 0xf8, 0x56, 0x00, 0x90, 0x42, + 0x02, 0xd2, 0x28, 0x68, 0xb8, 0x43, 0x28, 0x60, 0x20, 0x46, 0xff, 0xf7, + 0xbf, 0xfa, 0x56, 0xf8, 0x24, 0x10, 0x01, 0xb1, 0x01, 0x21, 0x04, 0xf1, + 0x38, 0x00, 0xc9, 0xb2, 0xc0, 0xb2, 0xf8, 0xf7, 0x7e, 0xfe, 0x64, 0x1c, + 0x02, 0x2c, 0xcb, 0xd3, 0xbd, 0xe8, 0xf4, 0x4f, 0x00, 0x21, 0x36, 0x20, + 0xf8, 0xf7, 0x75, 0xbe, 0x38, 0xb5, 0x01, 0x21, 0x37, 0x20, 0xf8, 0xf7, + 0x70, 0xfe, 0x25, 0x4c, 0x25, 0x4d, 0xe0, 0x6a, 0x00, 0xf4, 0x40, 0x30, + 0xe0, 0x62, 0xe9, 0x69, 0x02, 0x29, 0x06, 0xd1, 0x28, 0xb1, 0x01, 0x20, + 0xa8, 0x61, 0x01, 0x21, 0x3b, 0x20, 0xf8, 0xf7, 0x60, 0xfe, 0x20, 0x6b, + 0x69, 0x69, 0x00, 0xf4, 0x40, 0x30, 0x49, 0x1c, 0xa8, 0x60, 0x69, 0x61, + 0x50, 0xb1, 0x1b, 0x48, 0xb0, 0xf8, 0x56, 0x00, 0x88, 0x42, 0x3c, 0xbf, + 0x00, 0x20, 0x20, 0x60, 0xa9, 0x68, 0x11, 0xb1, 0x01, 0x21, 0x00, 0xe0, + 0x00, 0x21, 0xc9, 0xb2, 0x3a, 0x20, 0xf8, 0xf7, 0x48, 0xfe, 0xbd, 0xe8, + 0x34, 0x40, 0x00, 0x21, 0x37, 0x20, 0xf8, 0xf7, 0x42, 0xbe, 0x0f, 0x49, + 0x0f, 0xf2, 0x58, 0x02, 0x0f, 0xf2, 0x3c, 0x03, 0xc8, 0x61, 0x52, 0xf8, + 0x20, 0x20, 0x12, 0x68, 0x53, 0xf8, 0x20, 0x00, 0x10, 0x40, 0x88, 0x61, + 0x01, 0x00, 0x18, 0xbf, 0x01, 0x21, 0xc9, 0xb2, 0x3b, 0x20, 0xf8, 0xf7, + 0x2e, 0xbe, 0x05, 0x49, 0x89, 0x69, 0x00, 0x20, 0x01, 0xb1, 0x01, 0x20, + 0x70, 0x47, 0x00, 0x00, 0x20, 0x00, 0x00, 0x50, 0x14, 0x00, 0x00, 0x58, + 0xac, 0xf2, 0x00, 0x20, 0x4c, 0x1f, 0x00, 0x20, 0x00, 0x00, 0x50, 0x00, + 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x03, 0x00, 0x40, 0x00, 0x00, 0x50, + 0x40, 0x00, 0x00, 0x50, 0x40, 0x00, 0x00, 0x58, 0x44, 0x00, 0x00, 0x50, + 0x44, 0x00, 0x00, 0x50, 0x44, 0x00, 0x00, 0x58, 0x80, 0xb5, 0x00, 0xf0, + 0x13, 0xf8, 0x19, 0x20, 0xf8, 0xf7, 0x78, 0xfd, 0x4f, 0xf0, 0xa4, 0x41, + 0x15, 0x48, 0x08, 0x60, 0x00, 0x21, 0x19, 0x20, 0xf8, 0xf7, 0x8b, 0xfd, + 0xbd, 0xe8, 0x01, 0x40, 0x12, 0x49, 0x01, 0x20, 0x08, 0x60, 0x19, 0x20, + 0xf8, 0xf7, 0x6e, 0xbd, 0x80, 0xb5, 0x19, 0x20, 0xf8, 0xf7, 0x73, 0xfd, + 0x0d, 0x49, 0x00, 0x20, 0x08, 0x60, 0x01, 0xbd, 0xef, 0xf3, 0x11, 0x80, + 0x60, 0x21, 0x81, 0xf3, 0x11, 0x88, 0x09, 0x49, 0x0a, 0x68, 0x42, 0xf0, + 0x02, 0x03, 0x0b, 0x60, 0x22, 0xf0, 0x02, 0x02, 0x0a, 0x60, 0x80, 0xf3, + 0x11, 0x88, 0x70, 0x47, 0x03, 0x48, 0x00, 0x68, 0x00, 0xf0, 0x01, 0x00, + 0x70, 0x47, 0x00, 0x00, 0x00, 0x70, 0x17, 0x00, 0x04, 0x00, 0x00, 0x52, + 0x00, 0x20, 0xf8, 0xf7, 0xfe, 0xbc, 0x00, 0x00, 0x09, 0x42, 0x40, 0xf1, + 0x0d, 0x80, 0xf4, 0x46, 0x49, 0x42, 0x40, 0x42, 0x71, 0xf1, 0x00, 0x01, + 0x00, 0xf0, 0x06, 0xf8, 0x51, 0xf0, 0x00, 0x41, 0x60, 0x47, 0x00, 0x00, + 0x09, 0x42, 0x00, 0xbf, 0x08, 0xbf, 0x00, 0xf0, 0x15, 0xbd, 0x02, 0x46, + 0x08, 0x46, 0xb0, 0xfa, 0x80, 0xf1, 0x50, 0x40, 0x8a, 0x40, 0xc1, 0xf1, + 0x20, 0x01, 0xc8, 0x41, 0x50, 0x40, 0xc9, 0x1e, 0x01, 0xf5, 0x84, 0x61, + 0x09, 0x05, 0x01, 0xeb, 0xd0, 0x21, 0x40, 0x05, 0x40, 0xea, 0xd2, 0x20, + 0x52, 0x05, 0x72, 0xf1, 0x00, 0x42, 0x50, 0xf1, 0x00, 0x00, 0x41, 0xf1, + 0x00, 0x01, 0x70, 0x47, 0xf0, 0xb4, 0x4f, 0xf0, 0x00, 0x45, 0x91, 0xea, + 0x03, 0x0c, 0x44, 0xbf, 0x6b, 0x40, 0x00, 0xf0, 0xbf, 0xb9, 0x00, 0xbf, + 0x84, 0x1a, 0x71, 0xeb, 0x03, 0x06, 0x03, 0xd2, 0x00, 0x1b, 0xb1, 0x41, + 0x12, 0x19, 0x73, 0x41, 0x4f, 0xf4, 0x00, 0x1c, 0x1c, 0xeb, 0x41, 0x0f, + 0x34, 0xbf, 0x7c, 0xeb, 0x43, 0x04, 0x43, 0xe0, 0x0c, 0x0d, 0xa4, 0xeb, + 0x13, 0x56, 0x35, 0x2e, 0x50, 0xdc, 0x45, 0xea, 0xc3, 0x23, 0xdb, 0x0a, + 0x45, 0xea, 0xc1, 0x21, 0xc9, 0x12, 0xb6, 0xf1, 0x20, 0x05, 0x0d, 0xdd, + 0x63, 0xfa, 0x05, 0xf6, 0xeb, 0x40, 0x86, 0xea, 0x03, 0x05, 0x12, 0x42, + 0x18, 0xbf, 0x45, 0xf0, 0x01, 0x05, 0xc0, 0x18, 0x51, 0xf1, 0x00, 0x01, + 0x0c, 0xd2, 0x13, 0xe0, 0x62, 0xfa, 0x06, 0xf5, 0xf2, 0x40, 0x55, 0x40, + 0xf3, 0x41, 0x5a, 0x40, 0xb3, 0x40, 0xf3, 0x40, 0x5a, 0x40, 0x80, 0x18, + 0x59, 0x41, 0x07, 0xd3, 0x49, 0x08, 0x5f, 0xea, 0x30, 0x00, 0x5f, 0xea, + 0x35, 0x05, 0x28, 0xbf, 0x45, 0xf0, 0x01, 0x05, 0x01, 0xf5, 0x80, 0x11, + 0x42, 0x08, 0x75, 0xf1, 0x00, 0x42, 0x50, 0xf1, 0x00, 0x00, 0x41, 0xeb, + 0x04, 0x51, 0xf0, 0xbc, 0x4f, 0xf4, 0x00, 0x1c, 0x1c, 0xeb, 0x41, 0x0f, + 0x38, 0xbf, 0x70, 0x47, 0x00, 0x20, 0x09, 0x0d, 0x09, 0x05, 0x70, 0x47, + 0x1c, 0xeb, 0x41, 0x0f, 0x10, 0xd2, 0x52, 0xea, 0x43, 0x06, 0x0b, 0xd0, + 0xbc, 0xeb, 0x41, 0x0f, 0x05, 0xd8, 0x0c, 0x0d, 0xab, 0x43, 0x66, 0x1e, + 0x34, 0x2e, 0xb5, 0xdd, 0x02, 0xe0, 0xab, 0x43, 0x80, 0x18, 0x59, 0x41, + 0xf0, 0xbc, 0x70, 0x47, 0xf0, 0xbc, 0x70, 0x47, 0xb0, 0xb5, 0x81, 0xea, + 0x03, 0x0c, 0x0c, 0xf0, 0x00, 0x4c, 0x40, 0xf2, 0xff, 0x75, 0x15, 0xea, + 0x11, 0x54, 0x1d, 0xbf, 0x15, 0xea, 0x13, 0x57, 0xac, 0x42, 0xaf, 0x42, + 0x39, 0xe0, 0xe4, 0x19, 0x23, 0xea, 0x45, 0x53, 0x43, 0xf4, 0x80, 0x13, + 0xc9, 0x02, 0x41, 0xf0, 0x00, 0x41, 0x41, 0xea, 0x50, 0x5e, 0xc7, 0x02, + 0x11, 0x00, 0xa7, 0xfb, 0x02, 0x02, 0x00, 0x28, 0x4f, 0xf0, 0x00, 0x00, + 0xee, 0xfb, 0x01, 0x20, 0x4f, 0xf0, 0x00, 0x01, 0xe3, 0xfb, 0x07, 0x21, + 0x18, 0xbf, 0x42, 0xf0, 0x01, 0x02, 0x40, 0x18, 0x00, 0x21, 0x49, 0x41, + 0xe3, 0xfb, 0x0e, 0x01, 0xa4, 0xf5, 0x80, 0x64, 0x0f, 0x03, 0x02, 0xd2, + 0x52, 0x00, 0x40, 0x41, 0x49, 0x41, 0x54, 0xf1, 0x01, 0x04, 0x6c, 0xdd, + 0x47, 0x08, 0x72, 0xf1, 0x00, 0x42, 0x50, 0xf1, 0x00, 0x00, 0x51, 0xeb, + 0x04, 0x51, 0xa1, 0xf5, 0x80, 0x11, 0x5c, 0xbf, 0x41, 0xea, 0x0c, 0x01, + 0xb0, 0xbd, 0x4c, 0xea, 0x05, 0x51, 0x00, 0x20, 0xb0, 0xbd, 0x05, 0xea, + 0x13, 0x57, 0xac, 0x42, 0x14, 0xbf, 0xaf, 0x42, 0x41, 0xe0, 0x50, 0xea, + 0x41, 0x0e, 0x1c, 0xbf, 0x52, 0xea, 0x43, 0x0e, 0x02, 0xe0, 0x61, 0x46, + 0x00, 0x20, 0xb0, 0xbd, 0x24, 0x42, 0x3c, 0x44, 0x1b, 0xd1, 0x5f, 0xea, + 0x07, 0x0e, 0xf6, 0xd0, 0x09, 0x03, 0x02, 0xbf, 0x01, 0x46, 0x00, 0x20, + 0xae, 0xf1, 0x14, 0x0e, 0xb1, 0xfa, 0x81, 0xf7, 0xae, 0xeb, 0x07, 0x04, + 0x01, 0xfa, 0x07, 0xfe, 0x0c, 0x37, 0xc7, 0xf1, 0x20, 0x01, 0x00, 0xfa, + 0x07, 0xf7, 0xc8, 0x40, 0x4e, 0xea, 0x00, 0x0e, 0x23, 0xea, 0x45, 0x53, + 0x43, 0xf4, 0x80, 0x13, 0xa2, 0xe7, 0x33, 0xf0, 0x00, 0x43, 0xb3, 0xfa, + 0x83, 0xf7, 0x04, 0xbf, 0xb2, 0xfa, 0x82, 0xfe, 0x77, 0x44, 0x0b, 0x3f, + 0xe4, 0x1b, 0xb7, 0xf1, 0x20, 0x0e, 0x2f, 0xbf, 0x02, 0xfa, 0x0e, 0xf3, + 0xbb, 0x40, 0xc7, 0xf1, 0x20, 0x0e, 0x22, 0xfa, 0x0e, 0xfe, 0x38, 0xbf, + 0x43, 0xea, 0x0e, 0x03, 0xba, 0x40, 0x64, 0x1c, 0x82, 0xe7, 0x50, 0xea, + 0x41, 0x0e, 0x14, 0xbf, 0x52, 0xea, 0x43, 0x0e, 0x6f, 0xf0, 0x00, 0x01, + 0x4f, 0xf4, 0x00, 0x17, 0x17, 0xeb, 0x43, 0x0f, 0x8a, 0xbf, 0x19, 0x46, + 0x17, 0xeb, 0x41, 0x0f, 0xb5, 0xe7, 0x4c, 0xea, 0x05, 0x51, 0x00, 0x20, + 0xb0, 0xbd, 0xd4, 0xf1, 0x01, 0x04, 0xb4, 0xf1, 0x20, 0x07, 0x0f, 0xda, + 0xc4, 0xf1, 0x20, 0x07, 0x52, 0x08, 0x28, 0xbf, 0x42, 0xf0, 0x01, 0x02, + 0x10, 0xfa, 0x07, 0xf5, 0x01, 0xfa, 0x07, 0xf7, 0xe1, 0xbf, 0x2a, 0x43, + 0xe0, 0x40, 0x38, 0x43, 0xe1, 0x40, 0x0f, 0xe0, 0x35, 0x2c, 0x98, 0xdc, + 0xc7, 0xf1, 0x20, 0x04, 0x52, 0xea, 0x40, 0x02, 0x20, 0xfa, 0x07, 0xf2, + 0x18, 0xbf, 0x42, 0xf0, 0x01, 0x02, 0x31, 0xfa, 0x07, 0xf0, 0xa1, 0x40, + 0x0a, 0x43, 0x00, 0x21, 0x72, 0xf1, 0x00, 0x42, 0x50, 0xf1, 0x00, 0x00, + 0x51, 0xeb, 0x0c, 0x01, 0xb0, 0xbd, 0x00, 0x00, 0x40, 0xf2, 0xff, 0x7c, + 0x0b, 0x0d, 0x4d, 0xd0, 0x63, 0x45, 0x66, 0xd2, 0x30, 0xb4, 0x21, 0xea, + 0x03, 0x51, 0x41, 0xf4, 0x80, 0x11, 0x03, 0xf2, 0xfd, 0x3c, 0x5f, 0xea, + 0x5c, 0x0c, 0x01, 0xd3, 0x00, 0x18, 0x49, 0x41, 0x89, 0x00, 0x41, 0xea, + 0x90, 0x71, 0x80, 0x00, 0x4f, 0xf4, 0x40, 0x14, 0x00, 0x23, 0xe2, 0x02, + 0xd5, 0x0a, 0xb1, 0xf5, 0x10, 0x01, 0x07, 0xd4, 0x6d, 0x08, 0x1d, 0xd2, + 0x09, 0x1b, 0x64, 0x19, 0x00, 0x18, 0x49, 0x41, 0x49, 0x1b, 0xf7, 0xd5, + 0x6d, 0x08, 0x0a, 0xd2, 0x09, 0x19, 0x64, 0x1b, 0x00, 0x18, 0x49, 0x41, + 0x49, 0x1b, 0xef, 0xd5, 0x6d, 0x08, 0xf7, 0xd3, 0x01, 0xe0, 0x52, 0x08, + 0x17, 0xd0, 0xc0, 0x18, 0x61, 0x41, 0x9b, 0x1a, 0xac, 0x41, 0x00, 0x18, + 0x49, 0x41, 0x80, 0x1a, 0xa9, 0x41, 0xf4, 0xd4, 0x52, 0x08, 0x0a, 0xd0, + 0xc0, 0x1a, 0xa1, 0x41, 0x9b, 0x18, 0x6c, 0x41, 0x00, 0x18, 0x49, 0x41, + 0x80, 0x1a, 0xa9, 0x41, 0xe9, 0xd4, 0x52, 0x08, 0xf4, 0xd1, 0x5b, 0x1c, + 0x6c, 0x41, 0x61, 0x08, 0x4f, 0xea, 0x33, 0x00, 0x01, 0xeb, 0x0c, 0x51, + 0x30, 0xbc, 0x70, 0x47, 0x50, 0xea, 0x01, 0x03, 0xfb, 0xd0, 0x30, 0xb4, + 0xb1, 0xfa, 0x81, 0xf3, 0x11, 0xb9, 0xb0, 0xfa, 0x80, 0xf4, 0x1b, 0x19, + 0x0b, 0x3b, 0xb3, 0xf1, 0x20, 0x04, 0x2f, 0xbf, 0x00, 0xfa, 0x04, 0xf1, + 0x99, 0x40, 0xc3, 0xf1, 0x20, 0x04, 0x20, 0xfa, 0x04, 0xf4, 0x38, 0xbf, + 0x21, 0x43, 0x98, 0x40, 0xd3, 0xf1, 0x01, 0x03, 0x9d, 0xe7, 0x63, 0x45, + 0xe1, 0xd0, 0x11, 0xf5, 0x80, 0x1f, 0xde, 0xd8, 0x50, 0xea, 0x41, 0x01, + 0xdb, 0xd0, 0xd9, 0x43, 0xff, 0xf7, 0x66, 0xba, 0xf0, 0xb4, 0x4f, 0xf0, + 0x00, 0x45, 0x91, 0xea, 0x03, 0x0f, 0x44, 0xbf, 0x6b, 0x40, 0xff, 0xf7, + 0x43, 0xbe, 0x00, 0xbf, 0x84, 0x1a, 0x71, 0xeb, 0x03, 0x06, 0x04, 0xd2, + 0x6e, 0x40, 0x00, 0x1b, 0xb1, 0x41, 0x12, 0x19, 0x73, 0x41, 0x4f, 0xf4, + 0x00, 0x1c, 0x1c, 0xeb, 0x41, 0x0f, 0x34, 0xbf, 0x7c, 0xeb, 0x43, 0x06, + 0x84, 0xe0, 0x0c, 0x0d, 0xa4, 0xeb, 0x13, 0x56, 0x36, 0x2e, 0x7d, 0xdc, + 0x01, 0x2e, 0x43, 0xdc, 0x45, 0xea, 0xc3, 0x23, 0x43, 0xea, 0x52, 0x53, + 0x12, 0xbf, 0xd2, 0x02, 0x92, 0x02, 0x5b, 0x08, 0x24, 0x05, 0x45, 0xea, + 0xc1, 0x21, 0x41, 0xea, 0x50, 0x51, 0xd2, 0xeb, 0xc0, 0x20, 0x99, 0x41, + 0x25, 0xd4, 0x07, 0xd1, 0xb0, 0xfa, 0x80, 0xf6, 0x10, 0xfa, 0x06, 0xf1, + 0x64, 0xd0, 0x00, 0x20, 0x20, 0x36, 0x08, 0xe0, 0xb1, 0xfa, 0x81, 0xf6, + 0xb1, 0x40, 0xc6, 0xf1, 0x20, 0x02, 0x20, 0xfa, 0x02, 0xf2, 0x11, 0x43, + 0xb0, 0x40, 0x4f, 0xea, 0xf4, 0x74, 0xb4, 0xeb, 0x46, 0x54, 0x34, 0xf0, + 0x01, 0x06, 0x4f, 0xea, 0x74, 0x04, 0x0a, 0xd8, 0xd6, 0xf5, 0x00, 0x16, + 0x76, 0x0d, 0x04, 0xf0, 0x00, 0x44, 0xf0, 0x40, 0x61, 0xfa, 0x06, 0xf2, + 0x50, 0x40, 0xf1, 0x40, 0x48, 0x40, 0xc0, 0x0a, 0x40, 0xea, 0x41, 0x50, + 0x21, 0xf0, 0x00, 0x41, 0x28, 0xbf, 0x5f, 0xea, 0x50, 0x05, 0x50, 0xf1, + 0x00, 0x00, 0x44, 0xeb, 0xd1, 0x21, 0x37, 0xe0, 0x45, 0xea, 0xc3, 0x23, + 0xdb, 0x0a, 0x45, 0xea, 0xc1, 0x21, 0xc9, 0x0a, 0xb6, 0xf1, 0x20, 0x05, + 0x0e, 0xdd, 0x42, 0xea, 0x02, 0x42, 0x12, 0x0c, 0xc5, 0xf1, 0x20, 0x06, + 0x03, 0xfa, 0x06, 0xf6, 0xeb, 0x40, 0x42, 0xea, 0x06, 0x05, 0x6d, 0x42, + 0x98, 0x41, 0x61, 0xf1, 0x00, 0x01, 0x0d, 0xe0, 0x62, 0xfa, 0x06, 0xf5, + 0xf2, 0x40, 0x55, 0x40, 0x63, 0xfa, 0x06, 0xfc, 0x82, 0xea, 0x0c, 0x02, + 0xf3, 0x40, 0x5a, 0x40, 0x6d, 0x42, 0x90, 0x41, 0x61, 0xeb, 0x03, 0x01, + 0x11, 0xf4, 0x80, 0x1f, 0x05, 0xd1, 0x64, 0x1e, 0x62, 0x05, 0x02, 0xd0, + 0x6d, 0x00, 0x40, 0x41, 0x49, 0x41, 0x21, 0xf4, 0x80, 0x11, 0x43, 0x08, + 0x75, 0xf1, 0x00, 0x43, 0x50, 0xf1, 0x00, 0x00, 0x41, 0xeb, 0x04, 0x51, + 0xf0, 0xbc, 0x70, 0x47, 0x1c, 0xeb, 0x41, 0x0f, 0x15, 0xd2, 0x23, 0xf0, + 0x00, 0x43, 0x52, 0xea, 0x43, 0x06, 0x0b, 0xd0, 0x4f, 0xea, 0x4c, 0x0c, + 0xbc, 0xeb, 0x41, 0x0f, 0x04, 0xd8, 0x0c, 0x0d, 0x66, 0x1e, 0x34, 0x2e, + 0xb7, 0xdd, 0xeb, 0xe7, 0x80, 0x1a, 0x99, 0x41, 0x50, 0xea, 0x41, 0x06, + 0x08, 0xbf, 0x00, 0x21, 0xe4, 0xe7, 0x08, 0xbf, 0x1c, 0xeb, 0x43, 0x0f, + 0x28, 0xbf, 0x6f, 0xf0, 0x00, 0x01, 0xdd, 0xe7, 0x4f, 0xea, 0xf1, 0x7c, + 0xbc, 0xf1, 0xe0, 0x4c, 0x2c, 0xbf, 0xbc, 0xf5, 0x00, 0x1f, 0x11, 0xe0, + 0x5f, 0xea, 0x4c, 0x0c, 0x34, 0xbf, 0xbc, 0xf1, 0x7f, 0x5f, 0x2e, 0xe0, + 0x5f, 0xea, 0x9c, 0x0c, 0x4f, 0xea, 0x0c, 0x1c, 0x4f, 0xea, 0x3c, 0x0c, + 0xc1, 0x00, 0x71, 0xf1, 0x00, 0x41, 0x4c, 0xeb, 0x50, 0x70, 0x70, 0x47, + 0xc9, 0x02, 0x41, 0xea, 0x50, 0x51, 0xc0, 0x02, 0x18, 0xbf, 0x41, 0xf0, + 0x01, 0x01, 0x41, 0xf0, 0x00, 0x41, 0x4f, 0xea, 0x6c, 0x50, 0xc0, 0xf1, + 0x09, 0x00, 0x21, 0x28, 0x10, 0xd2, 0x40, 0xea, 0xcc, 0x7c, 0xcc, 0xf1, + 0x20, 0x0c, 0x11, 0xfa, 0x0c, 0xf0, 0x70, 0xf1, 0x00, 0x40, 0xcc, 0xf1, + 0x20, 0x0c, 0x21, 0xfa, 0x0c, 0xf0, 0x0c, 0xf0, 0x00, 0x4c, 0x40, 0xeb, + 0x0c, 0x00, 0x70, 0x47, 0x4f, 0xea, 0xcc, 0x70, 0x70, 0x47, 0x49, 0x00, + 0x11, 0xf5, 0x00, 0x1f, 0x04, 0xd8, 0x4f, 0xea, 0xcc, 0x10, 0xff, 0x30, + 0xc0, 0x05, 0x70, 0x47, 0xc8, 0x17, 0x70, 0x47, 0x2d, 0xe9, 0xf0, 0x41, + 0x40, 0xf2, 0xff, 0x75, 0x81, 0xea, 0x03, 0x0c, 0x0c, 0xf0, 0x00, 0x4c, + 0x15, 0xea, 0x11, 0x54, 0x1d, 0xbf, 0x15, 0xea, 0x13, 0x57, 0xac, 0x42, + 0xaf, 0x42, 0xe9, 0xe0, 0xbc, 0x41, 0xc1, 0xf3, 0x13, 0x01, 0xc3, 0xf3, + 0x13, 0x03, 0x80, 0x1a, 0x99, 0x41, 0x43, 0xf4, 0x80, 0x13, 0x04, 0xd2, + 0x64, 0x1e, 0x40, 0x00, 0x49, 0x41, 0x80, 0x18, 0x59, 0x41, 0xc9, 0x02, + 0x41, 0xea, 0x50, 0x51, 0xb1, 0xfb, 0xf3, 0xf6, 0x03, 0xfb, 0x16, 0x11, + 0xa2, 0xfb, 0x06, 0x75, 0xd7, 0xeb, 0xc0, 0x20, 0xa9, 0x41, 0x02, 0xd2, + 0x76, 0x1e, 0x80, 0x18, 0x59, 0x41, 0xc9, 0x02, 0x41, 0xea, 0x50, 0x51, + 0xb1, 0xfb, 0xf3, 0xfe, 0x03, 0xfb, 0x1e, 0x11, 0xa2, 0xfb, 0x0e, 0x75, + 0xd7, 0xeb, 0xc0, 0x20, 0xa9, 0x41, 0x03, 0xd2, 0xae, 0xf1, 0x01, 0x0e, + 0x80, 0x18, 0x59, 0x41, 0x89, 0x02, 0x41, 0xea, 0x90, 0x51, 0x76, 0x05, + 0x46, 0xea, 0x8e, 0x2e, 0xb1, 0xfb, 0xf3, 0xf6, 0x03, 0xfb, 0x16, 0x11, + 0xa2, 0xfb, 0x06, 0x75, 0xd7, 0xeb, 0x80, 0x20, 0xa9, 0x41, 0x02, 0xd2, + 0x76, 0x1e, 0x80, 0x18, 0x59, 0x41, 0xc9, 0x02, 0x41, 0xea, 0x50, 0x51, + 0x4e, 0xea, 0x06, 0x0e, 0xb1, 0xfb, 0xf3, 0xf6, 0x03, 0xfb, 0x16, 0x11, + 0xa2, 0xfb, 0x06, 0x75, 0xd7, 0xeb, 0xc0, 0x20, 0xa9, 0x41, 0x02, 0xd2, + 0x76, 0x1e, 0x80, 0x18, 0x59, 0x41, 0xc9, 0x02, 0x41, 0xea, 0x50, 0x51, + 0xb1, 0xfb, 0xf3, 0xf7, 0x03, 0xfb, 0x17, 0x11, 0xa2, 0xfb, 0x07, 0x35, + 0xd3, 0xeb, 0xc0, 0x20, 0xa9, 0x41, 0x67, 0xf1, 0x00, 0x07, 0x0c, 0xbf, + 0x00, 0x42, 0x47, 0xf0, 0x01, 0x07, 0x66, 0xf3, 0xd5, 0x27, 0x4f, 0xea, + 0x1e, 0x31, 0xb8, 0x08, 0x14, 0xf5, 0x80, 0x64, 0x14, 0xdd, 0xbd, 0x07, + 0x75, 0xf1, 0x00, 0x42, 0x50, 0xeb, 0x0e, 0x50, 0x51, 0xeb, 0x04, 0x51, + 0x11, 0xf5, 0x80, 0x1f, 0x5c, 0xbf, 0x41, 0xea, 0x0c, 0x01, 0xbd, 0xe8, + 0xf0, 0x81, 0x4c, 0xf0, 0x7f, 0x61, 0x41, 0xf0, 0xe0, 0x41, 0x00, 0x20, + 0xbd, 0xe8, 0xf0, 0x81, 0xbd, 0x07, 0x6d, 0x08, 0x40, 0xea, 0x0e, 0x50, + 0x41, 0xf4, 0x80, 0x11, 0xd4, 0xf1, 0x01, 0x04, 0xb4, 0xf1, 0x20, 0x06, + 0x0a, 0xda, 0xc4, 0xf1, 0x20, 0x06, 0x02, 0x00, 0xe0, 0x40, 0x01, 0xfa, + 0x06, 0xf3, 0xe1, 0x40, 0x18, 0x43, 0xb2, 0x40, 0x15, 0x43, 0x0e, 0xe0, + 0x34, 0x2c, 0x14, 0xdc, 0xc6, 0xf1, 0x20, 0x04, 0x45, 0xea, 0x40, 0x05, + 0x6d, 0x08, 0x20, 0xfa, 0x06, 0xf2, 0x15, 0x43, 0x21, 0xfa, 0x06, 0xf0, + 0xa1, 0x40, 0x0d, 0x43, 0x00, 0x21, 0x75, 0xf1, 0x00, 0x42, 0x50, 0xf1, + 0x00, 0x00, 0x51, 0xeb, 0x0c, 0x01, 0xbd, 0xe8, 0xf0, 0x81, 0x00, 0x20, + 0x5f, 0xea, 0x0c, 0x01, 0xbd, 0xe8, 0xf0, 0x81, 0xcf, 0xb9, 0x92, 0x18, + 0x5b, 0x41, 0xb3, 0xfa, 0x83, 0xf7, 0x04, 0xbf, 0xb2, 0xfa, 0x82, 0xf6, + 0xbf, 0x19, 0x0b, 0x3f, 0xb7, 0xf1, 0x20, 0x06, 0x2f, 0xbf, 0x02, 0xfa, + 0x06, 0xf3, 0xbb, 0x40, 0xc7, 0xf1, 0x20, 0x06, 0x22, 0xfa, 0x06, 0xf6, + 0x38, 0xbf, 0x33, 0x43, 0xba, 0x40, 0x1c, 0xb1, 0xe4, 0x19, 0x64, 0x1e, + 0x2f, 0xe7, 0x7f, 0x42, 0x31, 0xf0, 0x00, 0x41, 0xb1, 0xfa, 0x81, 0xf4, + 0x04, 0xbf, 0xb0, 0xfa, 0x80, 0xf6, 0xa4, 0x19, 0x0b, 0x3c, 0xb4, 0xf1, + 0x20, 0x06, 0x2f, 0xbf, 0x00, 0xfa, 0x06, 0xf1, 0xa1, 0x40, 0xc4, 0xf1, + 0x20, 0x06, 0x20, 0xfa, 0x06, 0xf6, 0x38, 0xbf, 0x31, 0x43, 0xa0, 0x40, + 0x3c, 0x1b, 0x16, 0xe7, 0xac, 0x42, 0x1a, 0xbf, 0x05, 0xea, 0x13, 0x57, + 0xaf, 0x42, 0x14, 0xe0, 0x50, 0xea, 0x41, 0x06, 0x1c, 0xbf, 0x52, 0xea, + 0x43, 0x06, 0xbf, 0xe7, 0x50, 0xea, 0x41, 0x07, 0x30, 0x46, 0x61, 0x46, + 0x1c, 0xbf, 0x41, 0xea, 0x05, 0x51, 0xbd, 0xe8, 0xf0, 0x81, 0x52, 0xea, + 0x43, 0x0c, 0x08, 0xbf, 0xc1, 0x43, 0xbd, 0xe8, 0xf0, 0x81, 0x00, 0x20, + 0x4f, 0xf4, 0x00, 0x16, 0x16, 0xeb, 0x41, 0x0f, 0x98, 0xbf, 0x16, 0xeb, + 0x43, 0x0f, 0x08, 0xbf, 0x16, 0xeb, 0x41, 0x0f, 0x24, 0xbf, 0xc1, 0x43, + 0x05, 0xe0, 0x16, 0xeb, 0x43, 0x0f, 0x0c, 0xbf, 0x61, 0x46, 0x4c, 0xea, + 0x05, 0x51, 0xbd, 0xe8, 0xf0, 0x81, 0x00, 0x00, 0x41, 0x00, 0x1d, 0xd2, + 0x09, 0x0e, 0x7f, 0x39, 0x1a, 0xd4, 0x20, 0x29, 0x08, 0xda, 0xc1, 0xf1, + 0x1f, 0x0c, 0x01, 0x02, 0x41, 0xf0, 0x00, 0x41, 0x21, 0xfa, 0x0c, 0xf0, + 0x00, 0x21, 0x70, 0x47, 0xd1, 0xf1, 0x3f, 0x0c, 0x08, 0xd4, 0x01, 0x02, + 0x41, 0xf0, 0x00, 0x41, 0x61, 0xfa, 0x0c, 0xf0, 0x21, 0xfa, 0x0c, 0xf1, + 0x48, 0x40, 0x70, 0x47, 0x6f, 0xf0, 0x00, 0x00, 0x01, 0x00, 0x70, 0x47, + 0x00, 0x20, 0x00, 0x21, 0x70, 0x47, 0x00, 0x00, 0x80, 0xb5, 0x01, 0x20, + 0xf8, 0xf7, 0xb5, 0xf8, 0x01, 0x20, 0xf8, 0xf7, 0xb2, 0xf8, 0x4f, 0xf0, + 0xa0, 0x40, 0x03, 0x21, 0x01, 0x64, 0x01, 0x60, 0x09, 0x20, 0x06, 0x21, + 0xf8, 0xf7, 0x09, 0xf9, 0x09, 0x20, 0xf8, 0xf7, 0x00, 0xf9, 0x09, 0x20, + 0xf8, 0xf7, 0xee, 0xf8, 0x4f, 0xf0, 0xb0, 0x40, 0x4f, 0xf0, 0x00, 0x71, + 0x01, 0x64, 0x01, 0x60, 0x1c, 0x20, 0x06, 0x21, 0xf8, 0xf7, 0xf9, 0xf8, + 0x1c, 0x20, 0xf8, 0xf7, 0xf0, 0xf8, 0xff, 0xe7, 0xbd, 0xe8, 0x02, 0x40, + 0x1c, 0x20, 0xf8, 0xf7, 0xdb, 0xb8, 0x05, 0x28, 0xba, 0xbf, 0x27, 0x49, + 0x40, 0x5c, 0x00, 0x20, 0x70, 0x47, 0x38, 0xb5, 0x25, 0x49, 0x24, 0x4d, + 0x03, 0x20, 0x08, 0x60, 0x00, 0x20, 0xf3, 0xf7, 0xdf, 0xf9, 0x29, 0x78, + 0x04, 0x46, 0x8c, 0x42, 0x0a, 0xd0, 0x22, 0x46, 0x00, 0x20, 0xfe, 0xf7, + 0x8c, 0xfd, 0x00, 0x20, 0x00, 0xf0, 0x77, 0xf9, 0x18, 0x20, 0xf8, 0xf7, + 0x38, 0xf9, 0x2c, 0x70, 0x01, 0x20, 0xf3, 0xf7, 0xcd, 0xf9, 0x69, 0x78, + 0x04, 0x46, 0x8c, 0x42, 0x0a, 0xd0, 0x22, 0x46, 0x01, 0x20, 0xfe, 0xf7, + 0x7a, 0xfd, 0x01, 0x20, 0x00, 0xf0, 0x65, 0xf9, 0x19, 0x20, 0xf8, 0xf7, + 0x26, 0xf9, 0x6c, 0x70, 0x31, 0xbd, 0xf8, 0xb5, 0x11, 0x49, 0x0f, 0x4d, + 0x0f, 0xf2, 0x44, 0x06, 0x4f, 0xf0, 0x00, 0x70, 0x08, 0x60, 0x02, 0x24, + 0x36, 0xf8, 0x14, 0x00, 0x00, 0xf1, 0x8c, 0x40, 0x07, 0x78, 0x61, 0x5d, + 0x8f, 0x42, 0x0a, 0xd0, 0x3a, 0x46, 0xe0, 0xb2, 0xfe, 0xf7, 0xc3, 0xfd, + 0xe0, 0xb2, 0x00, 0xf0, 0x48, 0xf9, 0x1a, 0x20, 0xf8, 0xf7, 0x09, 0xf9, + 0x67, 0x55, 0x64, 0x1c, 0x05, 0x2c, 0xe9, 0xd3, 0xf1, 0xbd, 0x00, 0x00, + 0x50, 0xf3, 0x00, 0x20, 0x40, 0x00, 0x00, 0x50, 0x40, 0x00, 0x00, 0x58, + 0xb0, 0x04, 0xb3, 0x04, 0x5b, 0x04, 0x5c, 0x04, 0x5d, 0x04, 0x00, 0x00, + 0x38, 0xb5, 0x04, 0x46, 0x0d, 0x46, 0x20, 0x68, 0x40, 0x00, 0x00, 0x0e, + 0xff, 0x28, 0x04, 0xd1, 0x20, 0x68, 0x40, 0x02, 0x14, 0xd0, 0x02, 0x20, + 0x32, 0xbd, 0x20, 0xb9, 0x20, 0x46, 0xfe, 0xf7, 0xf7, 0xff, 0x01, 0x28, + 0x46, 0xda, 0x01, 0x2d, 0x0c, 0xdb, 0xc0, 0xf1, 0xff, 0x01, 0x8d, 0x42, + 0x08, 0xd3, 0x20, 0x68, 0x00, 0x28, 0x4c, 0xbf, 0x1f, 0x48, 0x4f, 0xf0, + 0xff, 0x40, 0x20, 0x60, 0x01, 0x20, 0x32, 0xbd, 0x41, 0x42, 0xa9, 0x42, + 0x21, 0x68, 0x06, 0xda, 0x21, 0xf0, 0xff, 0x41, 0x40, 0x19, 0x41, 0xea, + 0xc0, 0x50, 0x20, 0x60, 0x26, 0xe0, 0x22, 0x68, 0x52, 0x02, 0x40, 0x1e, + 0x52, 0x0a, 0x45, 0x19, 0x42, 0xf4, 0x00, 0x02, 0x05, 0xf1, 0x18, 0x00, + 0x01, 0xf0, 0x00, 0x41, 0x22, 0x60, 0x18, 0x28, 0x28, 0xbf, 0x21, 0x60, + 0x1c, 0xd2, 0x00, 0x20, 0x6a, 0x42, 0x06, 0xd0, 0x20, 0x68, 0xc2, 0xf1, + 0x20, 0x03, 0x98, 0x40, 0x23, 0x68, 0xd3, 0x40, 0x23, 0x60, 0x22, 0x68, + 0x0a, 0x43, 0xb0, 0xf1, 0x00, 0x4f, 0x22, 0x60, 0x03, 0xd8, 0x08, 0xd1, + 0x20, 0x78, 0xc0, 0x07, 0x05, 0xd5, 0x20, 0x68, 0x40, 0x1c, 0x20, 0x60, + 0x4f, 0xf0, 0xff, 0x30, 0x32, 0xbd, 0x20, 0x68, 0x88, 0x42, 0xf9, 0xd1, + 0x00, 0x20, 0x32, 0xbd, 0x00, 0x00, 0x80, 0xff, 0x01, 0x00, 0x00, 0xbf, + 0x09, 0xd0, 0xb0, 0xfa, 0x80, 0xf1, 0x88, 0x40, 0xc9, 0x1c, 0xc1, 0xf5, + 0x84, 0x61, 0x09, 0x05, 0x01, 0xeb, 0xd0, 0x21, 0x40, 0x05, 0x70, 0x47, + 0x70, 0xb5, 0x00, 0x24, 0x67, 0x4d, 0x0f, 0xf2, 0xbc, 0x16, 0x56, 0xf8, + 0x24, 0x10, 0x4f, 0xf4, 0x7c, 0x70, 0x00, 0xfb, 0x04, 0x50, 0x00, 0xf0, + 0xf2, 0xf8, 0x64, 0x1c, 0x04, 0x2c, 0xf4, 0xd3, 0x61, 0x4e, 0x62, 0x4d, + 0xf4, 0xf7, 0x0c, 0xfe, 0xf1, 0x6a, 0x04, 0x46, 0x00, 0xf0, 0x43, 0xf8, + 0xa5, 0xf8, 0x4a, 0x00, 0x20, 0x46, 0x31, 0x6c, 0x00, 0xf0, 0x3d, 0xf8, + 0xa5, 0xf8, 0x5a, 0x01, 0x70, 0xbd, 0x0f, 0xf2, 0x80, 0x11, 0x51, 0xf8, + 0x20, 0x00, 0x00, 0xf0, 0x6a, 0xb9, 0x00, 0xe0, 0x00, 0xbf, 0xf0, 0xb5, + 0x14, 0x46, 0x83, 0xb0, 0x20, 0x70, 0x61, 0x70, 0x05, 0x00, 0x0f, 0xf2, + 0x54, 0x11, 0x51, 0xf8, 0x25, 0x60, 0x4f, 0x49, 0x66, 0x60, 0x4f, 0xf4, + 0x7c, 0x72, 0x02, 0xfb, 0x05, 0x11, 0xa1, 0x60, 0x18, 0xbf, 0x01, 0x2d, + 0x4b, 0x49, 0x07, 0xbf, 0xcf, 0x6a, 0x01, 0x20, 0x0f, 0x6c, 0x03, 0x20, + 0xf4, 0xf7, 0x5a, 0xf9, 0x04, 0xf1, 0x10, 0x01, 0x01, 0x91, 0x06, 0xf1, + 0x48, 0x03, 0x04, 0xf1, 0x0c, 0x01, 0x00, 0x91, 0x3a, 0x46, 0x01, 0x46, + 0x30, 0x46, 0x00, 0xf0, 0x27, 0xf8, 0x0f, 0xf2, 0x20, 0x10, 0x50, 0xf8, + 0x25, 0x10, 0x20, 0x46, 0x03, 0xb0, 0xbd, 0xe8, 0xf0, 0x40, 0x00, 0xf0, + 0x4a, 0xb9, 0x38, 0xb5, 0x0d, 0x46, 0x04, 0x46, 0xb5, 0xf1, 0x00, 0x5f, + 0x80, 0x41, 0xc0, 0x0f, 0xf7, 0xf7, 0x63, 0xff, 0xb4, 0xeb, 0x45, 0x0f, + 0x01, 0xd3, 0x00, 0x20, 0x32, 0xbd, 0x28, 0x09, 0x60, 0x21, 0x48, 0x43, + 0x21, 0x09, 0xb0, 0xfb, 0xf1, 0xf0, 0x30, 0x28, 0x01, 0xd2, 0x01, 0x20, + 0x32, 0xbd, 0x2f, 0x38, 0xff, 0x28, 0x88, 0xbf, 0xff, 0x20, 0x32, 0xbd, + 0x2d, 0xe9, 0xf8, 0x43, 0x80, 0x46, 0x08, 0xf1, 0x48, 0x06, 0x0c, 0x46, + 0x70, 0x88, 0x91, 0x46, 0x1d, 0x46, 0xf5, 0xf7, 0x9f, 0xf8, 0x07, 0x46, + 0x15, 0x2c, 0x2c, 0xbf, 0x14, 0x3c, 0x00, 0x24, 0x48, 0x46, 0xf6, 0xf7, + 0x43, 0xfd, 0x81, 0x46, 0x20, 0x46, 0xf6, 0xf7, 0x3f, 0xfd, 0x49, 0x46, + 0xf6, 0xf7, 0xda, 0xfe, 0x04, 0x46, 0x07, 0xf1, 0x30, 0x00, 0x21, 0x49, + 0x48, 0x43, 0xf6, 0xf7, 0x35, 0xfd, 0x01, 0x46, 0x20, 0x46, 0xf6, 0xf7, + 0x41, 0xfd, 0xfd, 0xf7, 0xcd, 0xfd, 0x08, 0x9f, 0x09, 0x9c, 0xd0, 0xb1, + 0xf7, 0xf7, 0x5f, 0xff, 0x0c, 0x28, 0x28, 0xbf, 0x0c, 0x20, 0x31, 0x88, + 0x4f, 0xf2, 0xff, 0x02, 0x11, 0x40, 0x41, 0xea, 0x00, 0x21, 0x29, 0x80, + 0xc0, 0xf1, 0x0c, 0x00, 0x01, 0x21, 0x01, 0xfa, 0x00, 0xf0, 0x08, 0xf5, + 0x84, 0x71, 0x0a, 0x88, 0x02, 0xb9, 0x02, 0x46, 0x3a, 0x60, 0x49, 0x88, + 0x41, 0xb1, 0x21, 0x60, 0x07, 0xe0, 0x30, 0x88, 0x4f, 0xf2, 0xff, 0x01, + 0x08, 0x40, 0x28, 0x80, 0x00, 0x20, 0x38, 0x60, 0x20, 0x60, 0xbd, 0xe8, + 0xf1, 0x83, 0x04, 0x28, 0x06, 0xda, 0x04, 0x49, 0x4f, 0xf4, 0x7c, 0x72, + 0x02, 0xfb, 0x00, 0x10, 0x00, 0xf0, 0xe3, 0xbc, 0x70, 0x47, 0x00, 0x00, + 0xc0, 0x92, 0x00, 0x20, 0x78, 0x29, 0x00, 0x20, 0x98, 0x02, 0x00, 0x20, + 0x40, 0x42, 0x0f, 0x00, 0x98, 0x02, 0x00, 0x20, 0x98, 0x02, 0x00, 0x20, + 0xa8, 0x03, 0x00, 0x20, 0xa8, 0x03, 0x00, 0x20, 0x04, 0xea, 0x00, 0x20, + 0xa0, 0xea, 0x00, 0x20, 0x3c, 0xeb, 0x00, 0x20, 0xd8, 0xeb, 0x00, 0x20, + 0xef, 0xf3, 0x11, 0x80, 0x60, 0x21, 0x81, 0xf3, 0x11, 0x88, 0x70, 0x47, + 0x01, 0x68, 0x11, 0xf1, 0x01, 0x0f, 0x1c, 0xbf, 0x49, 0x1c, 0x01, 0x60, + 0x70, 0x47, 0x01, 0x88, 0x4f, 0xf6, 0xff, 0x72, 0x91, 0x42, 0x1c, 0xbf, + 0x49, 0x1c, 0x01, 0x80, 0x70, 0x47, 0x38, 0xb5, 0x04, 0x46, 0x00, 0x20, + 0x20, 0x80, 0x60, 0x80, 0x60, 0x60, 0x0d, 0x46, 0xc0, 0x21, 0x04, 0xf1, + 0x08, 0x00, 0xf7, 0xf7, 0x11, 0xfd, 0x4f, 0xf0, 0x80, 0x40, 0xa0, 0x66, + 0x00, 0x21, 0x04, 0xf1, 0xd0, 0x00, 0x01, 0x70, 0x4f, 0xf0, 0x7e, 0x51, + 0x41, 0x60, 0x00, 0x21, 0x81, 0x60, 0x01, 0x73, 0x04, 0xf1, 0xe0, 0x00, + 0x01, 0xf0, 0xea, 0xfe, 0x28, 0x46, 0xbd, 0xe8, 0x32, 0x40, 0x58, 0xe0, + 0x38, 0xb5, 0x00, 0x25, 0x05, 0x80, 0x00, 0xf1, 0xe0, 0x04, 0x45, 0x80, + 0xd0, 0x30, 0x65, 0x68, 0x45, 0x60, 0x25, 0x68, 0x85, 0x60, 0x01, 0x25, + 0x05, 0x73, 0x00, 0x25, 0x45, 0x73, 0x05, 0x70, 0x20, 0x46, 0x01, 0xb0, + 0xbd, 0xe8, 0x30, 0x40, 0x01, 0xf0, 0x53, 0xbe, 0x70, 0xb5, 0x0c, 0x46, + 0xc0, 0x21, 0x06, 0x46, 0x00, 0x20, 0x30, 0x80, 0x70, 0x80, 0x70, 0x60, + 0x06, 0xf1, 0xe0, 0x05, 0x06, 0xf1, 0x08, 0x00, 0xf7, 0xf7, 0xd8, 0xfc, + 0x4f, 0xf0, 0x80, 0x40, 0xb0, 0x66, 0x06, 0xf1, 0xd0, 0x01, 0x05, 0xf5, + 0x0a, 0x70, 0x42, 0x68, 0x4a, 0x60, 0x00, 0x68, 0x88, 0x60, 0x01, 0x20, + 0x08, 0x73, 0x00, 0x20, 0x48, 0x73, 0x95, 0xf8, 0xf4, 0x02, 0x08, 0x70, + 0x21, 0x46, 0x28, 0x46, 0xbd, 0xe8, 0x70, 0x40, 0x01, 0xf0, 0xf6, 0xbe, + 0x00, 0x21, 0x01, 0x60, 0x41, 0x60, 0x81, 0x60, 0xc1, 0x60, 0x4f, 0xf0, + 0xff, 0x31, 0x01, 0x61, 0x00, 0x21, 0x41, 0x61, 0x70, 0x47, 0x42, 0x68, + 0x11, 0x43, 0x41, 0x60, 0x08, 0x30, 0x83, 0xe7, 0x02, 0x69, 0x8a, 0x42, + 0x88, 0xbf, 0x0a, 0x46, 0x02, 0x61, 0x42, 0x69, 0x91, 0x42, 0x38, 0xbf, + 0x11, 0x46, 0x41, 0x61, 0x70, 0x47, 0x0c, 0x30, 0x76, 0xe7, 0x10, 0xb5, + 0x04, 0x46, 0x00, 0x20, 0x20, 0x60, 0x28, 0x21, 0x64, 0x20, 0x60, 0x60, + 0x4f, 0xf0, 0xff, 0x30, 0xa0, 0x60, 0x00, 0x20, 0xe0, 0x60, 0x20, 0x61, + 0x04, 0xf1, 0x74, 0x00, 0xf7, 0xf7, 0x92, 0xfc, 0x04, 0xf1, 0x5c, 0x00, + 0xff, 0xf7, 0xce, 0xff, 0x20, 0x46, 0xbd, 0xe8, 0x10, 0x40, 0x10, 0xb5, + 0x04, 0x46, 0x04, 0xf1, 0x44, 0x00, 0xff, 0xf7, 0xc5, 0xff, 0x20, 0x46, + 0xbd, 0xe8, 0x10, 0x40, 0x10, 0xb5, 0x04, 0x46, 0x04, 0xf1, 0x2c, 0x00, + 0xff, 0xf7, 0xbc, 0xff, 0x20, 0x46, 0xbd, 0xe8, 0x10, 0x40, 0x14, 0x30, + 0xb6, 0xe7, 0x2d, 0xe9, 0xf0, 0x41, 0x04, 0x46, 0x0d, 0x46, 0xad, 0xf5, + 0x7c, 0x7d, 0x05, 0xf1, 0x74, 0x00, 0xc4, 0xf8, 0x60, 0x03, 0x00, 0x22, + 0x00, 0x21, 0x04, 0xf1, 0x30, 0x00, 0xf4, 0xf7, 0xea, 0xfe, 0xff, 0xf7, + 0x33, 0xff, 0x06, 0x46, 0x00, 0x20, 0x28, 0x60, 0x68, 0x60, 0x28, 0x46, + 0xff, 0xf7, 0xdc, 0xff, 0x86, 0xf3, 0x11, 0x88, 0x4f, 0xf4, 0x7c, 0x78, + 0xa1, 0x68, 0x42, 0x46, 0x68, 0x46, 0xf9, 0xf7, 0x1f, 0xfd, 0x00, 0x27, + 0x28, 0x46, 0xff, 0xf7, 0xd8, 0xff, 0x69, 0x46, 0x20, 0x46, 0x00, 0xf0, + 0x98, 0xf8, 0xff, 0xf7, 0x19, 0xff, 0x06, 0x46, 0xa0, 0x68, 0x42, 0x46, + 0x69, 0x46, 0xf9, 0xf7, 0x0f, 0xfd, 0xe8, 0x68, 0x40, 0x1c, 0xe8, 0x60, + 0x60, 0x7f, 0x10, 0xb1, 0x28, 0x69, 0x40, 0x1c, 0x28, 0x61, 0xa0, 0x68, + 0x61, 0x68, 0x40, 0x88, 0x89, 0x8a, 0x90, 0xfb, 0xf1, 0xf0, 0x64, 0x28, + 0x28, 0xbf, 0x63, 0x20, 0x68, 0x60, 0x61, 0x69, 0x09, 0xb3, 0x05, 0xf1, + 0x5c, 0x00, 0xff, 0xf7, 0x78, 0xff, 0x61, 0x69, 0x05, 0xf1, 0x44, 0x00, + 0xff, 0xf7, 0x73, 0xff, 0x61, 0x69, 0x05, 0xf1, 0x2c, 0x00, 0xff, 0xf7, + 0x6e, 0xff, 0x61, 0x69, 0x05, 0xf1, 0x14, 0x00, 0xff, 0xf7, 0x69, 0xff, + 0x60, 0x69, 0xc1, 0x06, 0x01, 0xd5, 0x03, 0x20, 0x07, 0xe0, 0x81, 0x07, + 0x02, 0xd5, 0x01, 0x20, 0x28, 0x60, 0x3c, 0xe0, 0xc0, 0x07, 0x3b, 0xd5, + 0x02, 0x20, 0x28, 0x60, 0x37, 0xe0, 0x20, 0x69, 0xa8, 0xb3, 0xa0, 0x7f, + 0x00, 0x28, 0x1c, 0xbf, 0xe0, 0x7f, 0x00, 0x28, 0x30, 0xd0, 0x20, 0x6a, + 0xa8, 0x60, 0x05, 0xf1, 0x14, 0x00, 0x21, 0x6a, 0xff, 0xf7, 0x50, 0xff, + 0x21, 0x6a, 0x05, 0xf1, 0x2c, 0x00, 0xff, 0xf7, 0x4b, 0xff, 0x21, 0x6a, + 0x05, 0xf1, 0x44, 0x00, 0xff, 0xf7, 0x46, 0xff, 0x21, 0x6a, 0x05, 0xf1, + 0x5c, 0x00, 0xff, 0xf7, 0x41, 0xff, 0x20, 0x78, 0xa9, 0x68, 0x32, 0x30, + 0xc0, 0xb2, 0xf7, 0xf7, 0x79, 0xfe, 0xe0, 0x7f, 0x02, 0x28, 0x10, 0xd1, + 0x05, 0xf1, 0x14, 0x00, 0xff, 0xf7, 0x3f, 0xff, 0x05, 0xf1, 0x2c, 0x00, + 0xff, 0xf7, 0x3b, 0xff, 0x05, 0xf1, 0x44, 0x00, 0xff, 0xf7, 0x37, 0xff, + 0x05, 0xf1, 0x5c, 0x00, 0xff, 0xf7, 0x33, 0xff, 0x00, 0xe0, 0x01, 0x27, + 0x05, 0xf1, 0x14, 0x00, 0xff, 0xf7, 0xa6, 0xfe, 0x05, 0xf1, 0x2c, 0x00, + 0xff, 0xf7, 0xa2, 0xfe, 0x05, 0xf1, 0x44, 0x00, 0xff, 0xf7, 0x9e, 0xfe, + 0x05, 0xf1, 0x5c, 0x00, 0xff, 0xf7, 0x9a, 0xfe, 0x60, 0x78, 0x08, 0xb9, + 0x01, 0x27, 0x00, 0xe0, 0x0f, 0xb1, 0x64, 0x20, 0x68, 0x60, 0x86, 0xf3, + 0x11, 0x88, 0x00, 0x2f, 0x3f, 0xf4, 0x66, 0xaf, 0x28, 0x68, 0x0d, 0xf5, + 0x7c, 0x7d, 0xbd, 0xe8, 0xf0, 0x81, 0xf8, 0xb5, 0x04, 0x46, 0x00, 0x20, + 0x60, 0x61, 0x20, 0x76, 0x60, 0x76, 0xa0, 0x76, 0xe0, 0x76, 0x20, 0x77, + 0x60, 0x77, 0x0d, 0x46, 0x04, 0xf1, 0x24, 0x00, 0x00, 0x21, 0x04, 0xf5, + 0x56, 0x76, 0x01, 0x70, 0x41, 0x60, 0x41, 0x70, 0xb1, 0x61, 0xf1, 0x61, + 0x20, 0x69, 0x88, 0xb1, 0x31, 0x68, 0x00, 0x29, 0x1c, 0xbf, 0x71, 0x79, + 0x01, 0x29, 0x0b, 0xd1, 0x61, 0x68, 0x2a, 0x88, 0x4b, 0x8a, 0x9a, 0x42, + 0x06, 0xd3, 0x6a, 0x88, 0x8b, 0x8a, 0x9a, 0x42, 0x89, 0x41, 0xc9, 0x43, + 0xc9, 0x0f, 0x00, 0xe0, 0x00, 0x21, 0xa1, 0x77, 0xa1, 0x7f, 0x01, 0xb9, + 0xe0, 0x68, 0x30, 0x84, 0x01, 0xf0, 0xfc, 0xfe, 0x30, 0x8c, 0x88, 0xb9, + 0x60, 0x69, 0x40, 0xf0, 0x10, 0x00, 0x60, 0x61, 0x0c, 0xe0, 0x20, 0x7e, + 0x03, 0x28, 0x56, 0xd0, 0x02, 0x28, 0x1c, 0xbf, 0x60, 0x7e, 0x01, 0x28, + 0x04, 0xd1, 0x60, 0x68, 0x80, 0x78, 0x08, 0xb1, 0xf2, 0xf7, 0x68, 0xfb, + 0x60, 0x69, 0x00, 0x28, 0x38, 0xd1, 0xdf, 0xf8, 0x74, 0x75, 0x20, 0x78, + 0x47, 0xf8, 0x20, 0x40, 0x00, 0x20, 0xf0, 0x61, 0x20, 0x76, 0x60, 0x76, + 0xa0, 0x76, 0x00, 0x21, 0xf3, 0xf7, 0x47, 0xf8, 0x20, 0x46, 0x00, 0xf0, + 0x4a, 0xf8, 0x20, 0x46, 0x00, 0xf0, 0xed, 0xf8, 0xf0, 0x69, 0x98, 0xb9, + 0x20, 0x46, 0x00, 0xf0, 0x8d, 0xf8, 0x20, 0x7e, 0x70, 0xb9, 0x20, 0x46, + 0x00, 0xf0, 0xaa, 0xf8, 0x28, 0xb3, 0x00, 0x20, 0x60, 0x76, 0x20, 0x46, + 0x00, 0xf0, 0x05, 0xf9, 0x30, 0x68, 0x31, 0x8c, 0x88, 0x42, 0xeb, 0xd3, + 0x01, 0x20, 0xa0, 0x76, 0x00, 0x20, 0x21, 0x78, 0x47, 0xf8, 0x21, 0x00, + 0x20, 0x46, 0x00, 0xf0, 0x5e, 0xf8, 0x00, 0x20, 0xf3, 0xf7, 0x7e, 0xf8, + 0xb0, 0x69, 0x00, 0x28, 0x04, 0xbf, 0xa0, 0x7e, 0x00, 0x28, 0xb6, 0xd0, + 0xa0, 0x7e, 0x70, 0xb1, 0x29, 0x46, 0x20, 0x46, 0x00, 0xf0, 0x05, 0xfa, + 0xe0, 0x7e, 0x28, 0xb9, 0x01, 0x20, 0x20, 0x77, 0x07, 0xe0, 0x01, 0x20, + 0x60, 0x76, 0xe1, 0xe7, 0x00, 0x20, 0x20, 0x77, 0xf1, 0xbd, 0x20, 0x7f, + 0x60, 0xb1, 0x29, 0x46, 0x20, 0x46, 0x00, 0xf0, 0x79, 0xfa, 0x08, 0xb1, + 0x01, 0x20, 0x04, 0xe0, 0x60, 0x69, 0x40, 0xf0, 0x04, 0x00, 0x60, 0x61, + 0x00, 0x20, 0x60, 0x77, 0xf1, 0xbd, 0x38, 0xb5, 0x04, 0x46, 0x60, 0x68, + 0x18, 0x30, 0xf4, 0xf7, 0xdd, 0xfc, 0x20, 0x78, 0x02, 0x28, 0x18, 0xbf, + 0x03, 0x28, 0x27, 0xd1, 0xf3, 0xf7, 0xdc, 0xfa, 0x03, 0x28, 0x23, 0xd1, + 0x20, 0x78, 0x02, 0x28, 0x02, 0xd1, 0xf3, 0xf7, 0x2c, 0xfb, 0x01, 0xe0, + 0xf3, 0xf7, 0x3d, 0xfb, 0x05, 0x46, 0x04, 0xf5, 0x59, 0x70, 0xf4, 0xf7, + 0xc4, 0xff, 0x20, 0x78, 0x03, 0x28, 0x0c, 0xbf, 0x01, 0x20, 0x00, 0x20, + 0xf4, 0xf7, 0xe5, 0xff, 0x05, 0x2d, 0x18, 0xbf, 0x06, 0x2d, 0x02, 0xd1, + 0xf5, 0xf7, 0x17, 0xf8, 0x01, 0xe0, 0xf5, 0xf7, 0x10, 0xf8, 0xf4, 0xf7, + 0xfb, 0xff, 0x28, 0x46, 0xbd, 0xe8, 0x32, 0x40, 0xfd, 0xf7, 0x68, 0xbf, + 0x31, 0xbd, 0x10, 0xb5, 0x04, 0x46, 0xf4, 0xf7, 0xf5, 0xfc, 0x20, 0x78, + 0x02, 0x28, 0x18, 0xbf, 0x03, 0x28, 0x0c, 0xd1, 0xf3, 0xf7, 0xaa, 0xfa, + 0x03, 0x28, 0x08, 0xd1, 0xfd, 0xf7, 0xb0, 0xff, 0x04, 0xf5, 0x59, 0x70, + 0xbd, 0xe8, 0x10, 0x40, 0x00, 0x21, 0xf4, 0xf7, 0xa8, 0xbf, 0x10, 0xbd, + 0x10, 0xb5, 0x00, 0xf0, 0x52, 0xf8, 0xfe, 0xf7, 0x00, 0xff, 0x60, 0x68, + 0x23, 0x78, 0xa1, 0x7f, 0x00, 0xf1, 0x18, 0x02, 0x0f, 0xf2, 0xb4, 0x40, + 0x18, 0x5c, 0xf4, 0xf7, 0xdc, 0xfc, 0x01, 0x28, 0x03, 0xd0, 0xa1, 0x68, + 0xd1, 0xf8, 0xec, 0x13, 0x09, 0xb1, 0x01, 0x20, 0x08, 0xe0, 0x02, 0x28, + 0x18, 0xbf, 0x00, 0x28, 0x04, 0xd0, 0x61, 0x69, 0x41, 0xf0, 0x01, 0x01, + 0x03, 0x20, 0x61, 0x61, 0x20, 0x76, 0x10, 0xbd, 0xd0, 0xb5, 0x00, 0xf0, + 0x30, 0xf8, 0xfe, 0xf7, 0xf2, 0xfe, 0x01, 0x28, 0x20, 0xd0, 0x00, 0x26, + 0x00, 0x27, 0x01, 0x22, 0xdf, 0xf8, 0xd4, 0x03, 0x00, 0xf0, 0x1e, 0xf8, + 0xdf, 0xf8, 0xd0, 0x03, 0x00, 0xf0, 0x1a, 0xf8, 0xdf, 0xf8, 0xcc, 0x03, + 0x50, 0xf8, 0x22, 0x00, 0xc1, 0x17, 0x49, 0x00, 0x41, 0xea, 0xd0, 0x71, + 0x16, 0xeb, 0x40, 0x06, 0x4f, 0x41, 0x52, 0x1c, 0x18, 0x2a, 0xe9, 0xd3, + 0x60, 0x68, 0xd0, 0xe9, 0x02, 0x23, 0x9f, 0x42, 0x04, 0xdc, 0x01, 0xdb, + 0x96, 0x42, 0x01, 0xd2, 0x00, 0x20, 0xd0, 0xbd, 0x01, 0x20, 0xd0, 0xbd, + 0x50, 0xf8, 0x22, 0x00, 0x16, 0xeb, 0x00, 0x16, 0x57, 0xeb, 0x10, 0x77, + 0x70, 0x47, 0x04, 0x46, 0x0f, 0xf2, 0x20, 0x40, 0x21, 0x78, 0x08, 0x5c, + 0x70, 0x47, 0x70, 0xb5, 0x04, 0x46, 0xa5, 0x7f, 0x05, 0xb1, 0x01, 0x25, + 0x21, 0x78, 0x0f, 0xf2, 0x10, 0x40, 0x08, 0x5c, 0xff, 0xf7, 0x7d, 0xfb, + 0x04, 0xf5, 0x54, 0x76, 0xb1, 0x68, 0x29, 0xb1, 0x31, 0x7b, 0x81, 0x42, + 0x04, 0xbf, 0x71, 0x7b, 0xa9, 0x42, 0x08, 0xd0, 0x01, 0x46, 0x2a, 0x46, + 0x04, 0xf1, 0x30, 0x00, 0xf4, 0xf7, 0xd5, 0xfc, 0x00, 0x20, 0xc6, 0xe9, + 0x00, 0x00, 0xa1, 0x68, 0x00, 0x20, 0xc1, 0xf8, 0xec, 0x03, 0x70, 0xbd, + 0x00, 0x22, 0x00, 0x21, 0x30, 0x30, 0xf4, 0xf7, 0xc8, 0xbc, 0x10, 0xb5, + 0x04, 0x46, 0x04, 0xf1, 0x30, 0x00, 0xf4, 0xf7, 0x0a, 0xfd, 0xd4, 0xe9, + 0x0c, 0x01, 0xc4, 0xe9, 0x3e, 0x01, 0x10, 0xbd, 0x2d, 0xe9, 0xf0, 0x4f, + 0x04, 0x46, 0xad, 0xf2, 0xfc, 0x5d, 0xe0, 0x68, 0x00, 0xf5, 0x4b, 0x71, + 0x91, 0xf8, 0x00, 0x80, 0x4f, 0x78, 0x01, 0x21, 0x21, 0x77, 0x04, 0xf1, + 0x24, 0x06, 0x00, 0x21, 0x61, 0x77, 0x71, 0x70, 0xa1, 0x68, 0x67, 0x90, + 0x5c, 0x31, 0x66, 0x91, 0x20, 0x68, 0xe0, 0x30, 0x68, 0x90, 0x60, 0x68, + 0x69, 0x90, 0x61, 0x69, 0x20, 0x69, 0x01, 0xf0, 0xf7, 0xfd, 0x6a, 0x90, + 0x20, 0x68, 0x90, 0xf8, 0xd0, 0x10, 0x88, 0x45, 0x03, 0xd1, 0xd0, 0xf8, + 0xf8, 0x12, 0x01, 0x29, 0x06, 0xd1, 0x68, 0x9a, 0x01, 0x21, 0xc2, 0xf8, + 0x10, 0x12, 0x00, 0x21, 0xc0, 0xf8, 0xf8, 0x12, 0x01, 0x2f, 0x1b, 0xd1, + 0x69, 0x46, 0x66, 0xa8, 0x01, 0xf0, 0x8e, 0xfc, 0x60, 0x77, 0x00, 0x20, + 0x27, 0x68, 0x78, 0x80, 0x65, 0x7f, 0x1d, 0xb9, 0x4f, 0xf0, 0xff, 0x30, + 0x20, 0x62, 0x09, 0xe0, 0x00, 0x98, 0xfd, 0xf7, 0x47, 0xfa, 0x02, 0x2d, + 0x20, 0x62, 0x03, 0xd1, 0x41, 0x46, 0x38, 0x46, 0xff, 0xf7, 0x0a, 0xfd, + 0x01, 0x20, 0x70, 0x70, 0x02, 0x20, 0xbd, 0xe0, 0x00, 0x20, 0x00, 0x90, + 0x68, 0x98, 0x00, 0xf5, 0x04, 0x70, 0x01, 0x68, 0x91, 0xb1, 0x69, 0x46, + 0x66, 0xa8, 0x00, 0xf0, 0xdc, 0xf9, 0x68, 0x99, 0x01, 0xf5, 0x04, 0x71, + 0x48, 0x60, 0x48, 0x68, 0x03, 0x28, 0x14, 0xd0, 0x48, 0x68, 0x01, 0x28, + 0x02, 0xd0, 0x00, 0x20, 0x08, 0x60, 0x0e, 0xe0, 0x00, 0x20, 0x0d, 0xe0, + 0x40, 0x68, 0x02, 0x28, 0x69, 0x46, 0x66, 0xa8, 0x02, 0xd1, 0x00, 0xf0, + 0xc6, 0xf9, 0x01, 0xe0, 0x00, 0xf0, 0x6e, 0xf9, 0x68, 0x99, 0xc1, 0xf8, + 0x14, 0x02, 0x01, 0x20, 0x70, 0x70, 0x00, 0x2f, 0x68, 0x98, 0xd0, 0xf8, + 0x14, 0x02, 0x69, 0x99, 0x48, 0x62, 0x40, 0xf0, 0x8e, 0x80, 0x00, 0x20, + 0x00, 0x90, 0x4f, 0xf0, 0x00, 0x09, 0x27, 0x68, 0x07, 0xf1, 0xe0, 0x05, + 0x05, 0xf1, 0xcc, 0x00, 0x29, 0x68, 0x40, 0x68, 0xf6, 0xf7, 0x62, 0xfa, + 0x33, 0x90, 0x33, 0xa8, 0x05, 0xeb, 0x89, 0x0b, 0x00, 0xeb, 0x89, 0x0a, + 0xdb, 0xf8, 0x04, 0x00, 0xd5, 0xf8, 0xcc, 0x10, 0xf6, 0xf7, 0xf2, 0xfa, + 0xca, 0xf8, 0x04, 0x00, 0x09, 0xf1, 0x01, 0x09, 0xdb, 0xf8, 0x68, 0x00, + 0xca, 0xf8, 0x68, 0x00, 0xb9, 0xf1, 0x19, 0x0f, 0xe9, 0xd3, 0x00, 0x25, + 0x33, 0xa8, 0x00, 0xeb, 0x85, 0x09, 0x74, 0x49, 0xd9, 0xf8, 0x04, 0x00, + 0xf6, 0xf7, 0x42, 0xfa, 0x82, 0x46, 0x33, 0x98, 0xd9, 0xf8, 0x68, 0x10, + 0xf6, 0xf7, 0x3c, 0xfa, 0x81, 0x46, 0x50, 0x46, 0x51, 0x46, 0xf6, 0xf7, + 0xd3, 0xfa, 0x82, 0x46, 0x48, 0x46, 0x49, 0x46, 0xf6, 0xf7, 0xce, 0xfa, + 0x51, 0x46, 0xf6, 0xf7, 0x2f, 0xfa, 0x4f, 0xf0, 0x7a, 0x51, 0xf6, 0xf7, + 0xc7, 0xfa, 0x01, 0x46, 0xa0, 0x68, 0xd0, 0xf8, 0x00, 0x01, 0xf6, 0xf7, + 0xaf, 0xfa, 0x08, 0xd2, 0x01, 0x20, 0x30, 0x70, 0x41, 0x46, 0x20, 0x68, + 0xff, 0xf7, 0x84, 0xfc, 0x01, 0x20, 0x70, 0x70, 0x38, 0xe0, 0x6d, 0x1c, + 0x19, 0x2d, 0xcd, 0xd3, 0x07, 0xf1, 0xd4, 0x00, 0x01, 0x7a, 0x49, 0xb9, + 0x34, 0x99, 0x01, 0x60, 0x33, 0x99, 0x41, 0x60, 0x01, 0x21, 0x01, 0x72, + 0x01, 0x20, 0x21, 0x68, 0x81, 0xf8, 0xdd, 0x00, 0x20, 0x68, 0x80, 0xf8, + 0xd0, 0x80, 0x20, 0x68, 0xff, 0xf7, 0x2b, 0xfc, 0x20, 0x68, 0x80, 0x1c, + 0xff, 0xf7, 0x27, 0xfc, 0xa0, 0x69, 0x98, 0xb9, 0x20, 0x68, 0xd4, 0x30, + 0x18, 0x26, 0x41, 0x68, 0x33, 0x91, 0x00, 0x68, 0x34, 0x99, 0xf6, 0xf7, + 0x03, 0xf9, 0x05, 0x46, 0x33, 0xa8, 0x00, 0xeb, 0x86, 0x07, 0x29, 0x46, + 0x78, 0x68, 0xf6, 0xf7, 0x89, 0xfa, 0x76, 0x1e, 0x78, 0x60, 0xf5, 0xd5, + 0x20, 0x68, 0x01, 0x1d, 0x6b, 0x46, 0x01, 0xaa, 0x33, 0xa8, 0x01, 0xf0, + 0x22, 0xfd, 0x00, 0x20, 0x20, 0x77, 0x0d, 0xf2, 0xfc, 0x5d, 0xbd, 0xe8, + 0xf0, 0x8f, 0x70, 0xb5, 0x82, 0xb0, 0x04, 0x46, 0x0e, 0x46, 0x6a, 0x46, + 0x00, 0x21, 0x00, 0x20, 0xf2, 0xf7, 0xb9, 0xff, 0x00, 0x98, 0x30, 0xb9, + 0x01, 0x20, 0xe0, 0x76, 0x60, 0x69, 0x40, 0xf0, 0x08, 0x00, 0x60, 0x61, + 0x73, 0xbd, 0x20, 0x78, 0x01, 0x46, 0x02, 0x29, 0x04, 0xf1, 0x24, 0x05, + 0x08, 0xd0, 0x03, 0x29, 0x09, 0xd1, 0xf3, 0xf7, 0x4e, 0xf9, 0x68, 0x70, + 0x68, 0x78, 0xfd, 0xf7, 0xb6, 0xff, 0x0b, 0xe0, 0xf3, 0xf7, 0x33, 0xf9, + 0xf7, 0xe7, 0x00, 0x28, 0x18, 0xbf, 0x01, 0x29, 0x08, 0xd1, 0x0f, 0xf2, + 0x3c, 0x10, 0x08, 0x5c, 0xfd, 0xf7, 0xa0, 0xff, 0x40, 0x1e, 0x80, 0x41, + 0xc0, 0x0f, 0x68, 0x60, 0x00, 0x98, 0x06, 0x60, 0x00, 0x99, 0xd4, 0xf8, + 0x60, 0x03, 0x48, 0x60, 0x00, 0x99, 0x60, 0x68, 0x88, 0x60, 0x04, 0xf1, + 0x30, 0x00, 0x00, 0x99, 0xc8, 0x60, 0x00, 0x99, 0x68, 0x68, 0x88, 0x61, + 0x21, 0x78, 0x1f, 0x48, 0x01, 0x29, 0x03, 0xd9, 0x89, 0x1e, 0x01, 0x29, + 0x05, 0xd9, 0x09, 0xe0, 0x00, 0x9a, 0x41, 0x6b, 0x11, 0x61, 0xc0, 0x6a, + 0x08, 0xe0, 0x00, 0x9a, 0x81, 0x6c, 0x11, 0x61, 0x00, 0x6c, 0x03, 0xe0, + 0x00, 0x9a, 0xc1, 0x6d, 0x11, 0x61, 0x40, 0x6d, 0x00, 0x99, 0x15, 0x4a, + 0x48, 0x61, 0x00, 0x21, 0x00, 0x20, 0xf2, 0xf7, 0xf0, 0xff, 0x00, 0x98, + 0x90, 0xf8, 0x25, 0x00, 0x10, 0xb1, 0x20, 0x46, 0xff, 0xf7, 0x7a, 0xfe, + 0x00, 0x98, 0x40, 0x7f, 0xe0, 0x77, 0x00, 0x98, 0x50, 0xf8, 0x20, 0x1f, + 0x21, 0x62, 0x00, 0x79, 0x28, 0x70, 0x00, 0x98, 0x00, 0x7f, 0xe0, 0x76, + 0x00, 0x20, 0xf2, 0xf7, 0x96, 0xff, 0x73, 0xbd, 0x00, 0x00, 0x00, 0x00, + 0x18, 0xf3, 0x00, 0x20, 0x80, 0x16, 0x00, 0x41, 0x00, 0x16, 0x00, 0x41, + 0x80, 0x17, 0x00, 0x41, 0x00, 0x00, 0x80, 0xbf, 0x78, 0x29, 0x00, 0x20, + 0x89, 0x06, 0x01, 0x01, 0x2d, 0xe9, 0xf8, 0x43, 0x0d, 0x46, 0x04, 0x46, + 0x0f, 0xf2, 0x78, 0x00, 0x21, 0x78, 0x0f, 0x5c, 0x38, 0x46, 0xf4, 0xf7, + 0x04, 0xfc, 0x80, 0x46, 0xf1, 0xf7, 0xc8, 0xf9, 0x21, 0x78, 0x0f, 0xf2, + 0x70, 0x00, 0x08, 0x5c, 0x40, 0xf0, 0x02, 0x09, 0x29, 0x1d, 0x40, 0x46, + 0xf4, 0xf7, 0x96, 0xfb, 0x00, 0x26, 0x28, 0xb1, 0x49, 0x46, 0x38, 0x46, + 0xf4, 0xf7, 0xfd, 0xfb, 0x00, 0xb1, 0x01, 0x26, 0x95, 0xf8, 0xdd, 0x00, + 0x00, 0x28, 0x04, 0xbf, 0xa0, 0x6a, 0x00, 0x28, 0x0e, 0xd0, 0x02, 0x2f, + 0x06, 0xd3, 0x94, 0xf8, 0x25, 0x00, 0x00, 0x22, 0x00, 0x21, 0xfd, 0xf7, + 0xf4, 0xfe, 0x02, 0xe0, 0x20, 0x78, 0xfd, 0xf7, 0xc2, 0xfe, 0x00, 0x20, + 0x85, 0xf8, 0xdd, 0x00, 0xf1, 0xf7, 0xb3, 0xf9, 0x30, 0x46, 0xbd, 0xe8, + 0xf2, 0x83, 0x00, 0x21, 0x01, 0x80, 0x01, 0x21, 0xc0, 0xf8, 0xec, 0x13, + 0x70, 0x47, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x00, 0x00, 0x04, 0xf8, 0xb5, 0x04, 0x46, + 0x04, 0xf1, 0x14, 0x06, 0x06, 0xf5, 0xd0, 0x77, 0x0d, 0x46, 0x01, 0x20, + 0xb8, 0x62, 0x05, 0x20, 0xe1, 0x68, 0x08, 0x60, 0xa0, 0x68, 0x00, 0xf0, + 0x89, 0xf9, 0x00, 0x22, 0x31, 0x46, 0x20, 0x46, 0x00, 0xf0, 0xcc, 0xf9, + 0x28, 0x68, 0x20, 0xbb, 0x38, 0x68, 0x10, 0xb3, 0x31, 0x46, 0x20, 0x46, + 0x00, 0xf0, 0x1c, 0xf9, 0xe1, 0x68, 0x00, 0x20, 0x08, 0x62, 0x01, 0x22, + 0x20, 0x68, 0x00, 0x78, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 0x20, 0xf8, + 0x29, 0x68, 0x00, 0x29, 0x08, 0xbf, 0x00, 0x28, 0x0f, 0xd1, 0xa0, 0x68, + 0x00, 0x68, 0xc6, 0xf8, 0x34, 0x02, 0x02, 0x22, 0x20, 0x68, 0x00, 0x88, + 0xc0, 0xf3, 0x03, 0x20, 0x00, 0xf0, 0x10, 0xf8, 0x29, 0x68, 0x00, 0x29, + 0x08, 0xbf, 0x00, 0x28, 0x01, 0xd0, 0x00, 0x20, 0xf2, 0xbd, 0x20, 0x68, + 0x00, 0x88, 0xc0, 0xf3, 0x03, 0x20, 0xf8, 0x62, 0x03, 0x22, 0x00, 0xf0, + 0x03, 0xf8, 0xf4, 0xe7, 0x40, 0x1c, 0xf8, 0x62, 0x31, 0x46, 0x20, 0x46, + 0x00, 0xf0, 0x26, 0xbc, 0x51, 0x46, 0x70, 0x68, 0xf6, 0xf7, 0x5a, 0xb9, + 0x4f, 0xf0, 0x7e, 0x50, 0x29, 0x46, 0xf6, 0xf7, 0x45, 0xb8, 0x2d, 0xe9, + 0xf0, 0x47, 0x04, 0x46, 0x04, 0xf1, 0x14, 0x05, 0x05, 0xf5, 0xd0, 0x76, + 0x84, 0xb0, 0x01, 0x20, 0xb0, 0x62, 0x0f, 0x46, 0xe0, 0x68, 0x02, 0x21, + 0x01, 0x62, 0x02, 0x22, 0x05, 0x21, 0x01, 0x60, 0x20, 0x46, 0x29, 0x46, + 0x00, 0xf0, 0x76, 0xf9, 0x38, 0x68, 0x08, 0xb9, 0x30, 0x68, 0x38, 0xb9, + 0xa0, 0x68, 0xd0, 0xf8, 0x10, 0x02, 0x00, 0x28, 0x0c, 0xbf, 0x02, 0x20, + 0x03, 0x20, 0x3e, 0xe0, 0xa0, 0x68, 0xd0, 0xf8, 0x10, 0x02, 0x30, 0xb1, + 0x60, 0x68, 0xd0, 0xf8, 0x28, 0x03, 0x40, 0x28, 0xb6, 0x41, 0xf6, 0x0f, + 0x00, 0xe0, 0x00, 0x26, 0x01, 0x20, 0x00, 0x90, 0x02, 0xab, 0x01, 0xaa, + 0x29, 0x46, 0x20, 0x46, 0x00, 0xf0, 0x2e, 0xf8, 0xa7, 0x68, 0x02, 0x98, + 0x39, 0x68, 0xf6, 0xf7, 0x0b, 0xf8, 0x04, 0x46, 0x07, 0xf1, 0xcc, 0x05, + 0x1e, 0xb1, 0x01, 0x98, 0x28, 0x60, 0x6c, 0x60, 0x1c, 0xe0, 0xdf, 0xf8, + 0xdc, 0x9d, 0x28, 0x68, 0xdf, 0xf8, 0xd8, 0x8d, 0x01, 0xf0, 0x02, 0xf8, + 0x82, 0x46, 0x01, 0x98, 0x01, 0xf0, 0x03, 0xf8, 0x51, 0x46, 0xf6, 0xf7, + 0x69, 0xf8, 0x28, 0x60, 0x49, 0x46, 0x68, 0x68, 0xf6, 0xf7, 0x00, 0xf9, + 0x81, 0x46, 0x20, 0x46, 0x00, 0xf0, 0xf7, 0xff, 0x00, 0xf0, 0xbc, 0xfb, + 0x68, 0x60, 0x38, 0x46, 0x00, 0xf0, 0xe4, 0xf8, 0x30, 0x46, 0x04, 0xb0, + 0xbd, 0xe8, 0xf0, 0x87, 0x2d, 0xe9, 0xf1, 0x4f, 0x84, 0xb0, 0x4f, 0xf0, + 0x7e, 0x50, 0x03, 0x90, 0x88, 0x46, 0x0e, 0x9f, 0x00, 0x20, 0x02, 0x90, + 0x00, 0x2f, 0x08, 0xf5, 0x13, 0x75, 0x14, 0xbf, 0x6c, 0x46, 0x03, 0xac, + 0x68, 0x60, 0x91, 0x46, 0x9a, 0x46, 0x28, 0x60, 0x01, 0x26, 0x04, 0x98, + 0x80, 0x68, 0x01, 0x90, 0x00, 0xeb, 0x86, 0x00, 0x40, 0x68, 0x00, 0x90, + 0xd8, 0xf8, 0x90, 0x01, 0xf0, 0x40, 0xc0, 0x07, 0x1a, 0xd5, 0x58, 0xf8, + 0x26, 0x10, 0x20, 0x68, 0x08, 0xeb, 0x86, 0x0b, 0xf6, 0xf7, 0xca, 0xf8, + 0xdb, 0xf8, 0xc8, 0x10, 0xf6, 0xf7, 0xc6, 0xf8, 0x69, 0x68, 0xf6, 0xf7, + 0x27, 0xf8, 0x68, 0x60, 0x21, 0x68, 0x08, 0x46, 0xf6, 0xf7, 0xbe, 0xf8, + 0xdb, 0xf8, 0xc8, 0x10, 0xf6, 0xf7, 0xba, 0xf8, 0x29, 0x68, 0xf6, 0xf7, + 0x1b, 0xf8, 0x28, 0x60, 0x76, 0x1c, 0x18, 0x2e, 0xd5, 0xdb, 0x68, 0x68, + 0x29, 0x68, 0xf5, 0xf7, 0x21, 0xff, 0xc9, 0xf8, 0x00, 0x00, 0x00, 0x2f, + 0x14, 0xbf, 0xe9, 0x46, 0x0d, 0xf1, 0x08, 0x09, 0x00, 0x20, 0x68, 0x60, + 0x28, 0x60, 0x01, 0x27, 0x01, 0x98, 0x00, 0xeb, 0x87, 0x00, 0x80, 0x6e, + 0x00, 0x90, 0xd8, 0xf8, 0x90, 0x01, 0xf8, 0x40, 0xc0, 0x07, 0x1b, 0xd5, + 0x08, 0xeb, 0x87, 0x04, 0x04, 0xf1, 0x64, 0x06, 0xd9, 0xf8, 0x00, 0x10, + 0x00, 0xf0, 0xc5, 0xf8, 0x01, 0x46, 0xd4, 0xf8, 0x2c, 0x01, 0xf5, 0xf7, + 0x7d, 0xff, 0x71, 0x6e, 0xf6, 0xf7, 0x8a, 0xf8, 0x69, 0x68, 0xf5, 0xf7, + 0xeb, 0xff, 0x68, 0x60, 0x70, 0x6e, 0x01, 0x46, 0xf6, 0xf7, 0x82, 0xf8, + 0x29, 0x68, 0xf5, 0xf7, 0xe3, 0xff, 0x28, 0x60, 0x7f, 0x1c, 0x18, 0x2f, + 0xd6, 0xdb, 0x68, 0x68, 0x29, 0x68, 0xf5, 0xf7, 0xe9, 0xfe, 0xca, 0xf8, + 0x00, 0x00, 0x05, 0xb0, 0xbd, 0xe8, 0xf0, 0x8f, 0x2d, 0xe9, 0xf8, 0x4f, + 0x04, 0x46, 0x00, 0x26, 0x20, 0x69, 0x00, 0x90, 0x0d, 0x46, 0xb3, 0x46, + 0xb0, 0x46, 0xb1, 0x46, 0xb2, 0x46, 0x01, 0x27, 0x01, 0xe0, 0x03, 0x2f, + 0x0b, 0xda, 0x04, 0xeb, 0x87, 0x00, 0x00, 0xf5, 0x34, 0x70, 0x01, 0x68, + 0x40, 0x6e, 0xf5, 0xf7, 0xbf, 0xff, 0x00, 0xf0, 0x1e, 0xfb, 0x06, 0x46, + 0x0e, 0xe0, 0x00, 0xf0, 0x5b, 0xfe, 0x01, 0x46, 0x00, 0x98, 0xb8, 0x42, + 0x04, 0xda, 0x40, 0x46, 0xf5, 0xf7, 0xb2, 0xff, 0x80, 0x46, 0x03, 0xe0, + 0x58, 0x46, 0xf5, 0xf7, 0xad, 0xff, 0x83, 0x46, 0x00, 0xf0, 0x4c, 0xfe, + 0xd5, 0xf8, 0x9c, 0x11, 0xf9, 0x40, 0xc9, 0x07, 0x03, 0xd5, 0x00, 0xf0, + 0x01, 0xfb, 0x81, 0x46, 0x03, 0xe0, 0x51, 0x46, 0xf5, 0xf7, 0x9e, 0xff, + 0x82, 0x46, 0x7f, 0x1c, 0x18, 0x2f, 0xd0, 0xdb, 0x58, 0x46, 0x41, 0x46, + 0xf5, 0xf7, 0x96, 0xff, 0x02, 0x46, 0x50, 0x46, 0x49, 0x46, 0xf6, 0xf7, + 0x1b, 0xf8, 0x10, 0x46, 0x31, 0x46, 0x05, 0xd2, 0xf6, 0xf7, 0x16, 0xf8, + 0x2c, 0xbf, 0x01, 0x20, 0x04, 0x20, 0x0d, 0xe0, 0xf6, 0xf7, 0x10, 0xf8, + 0x38, 0xbf, 0x02, 0x20, 0x08, 0xd3, 0x58, 0x46, 0xf5, 0xf7, 0x80, 0xff, + 0x41, 0x46, 0xf6, 0xf7, 0x07, 0xf8, 0x34, 0xbf, 0x03, 0x20, 0x00, 0x20, + 0xe1, 0x68, 0x08, 0x60, 0xbd, 0xe8, 0xf2, 0x8f, 0x2d, 0xe9, 0xf0, 0x41, + 0x80, 0x46, 0x00, 0x27, 0x08, 0xf5, 0x01, 0x75, 0x08, 0xf1, 0xcc, 0x06, + 0x08, 0xeb, 0x87, 0x04, 0x30, 0x68, 0x61, 0x68, 0xf6, 0xf7, 0x04, 0xf8, + 0x60, 0x60, 0x28, 0x68, 0xf8, 0x40, 0xc0, 0x07, 0x05, 0xd5, 0xd4, 0xf8, + 0xd4, 0x10, 0x00, 0xf0, 0x2e, 0xf8, 0xc4, 0xf8, 0xd4, 0x00, 0x7f, 0x1c, + 0x18, 0x2f, 0xeb, 0xdb, 0x4f, 0xf0, 0x7e, 0x50, 0x30, 0x60, 0x00, 0x27, + 0xd8, 0xf8, 0x00, 0x10, 0x70, 0x68, 0xf5, 0xf7, 0x51, 0xff, 0xc8, 0xf8, + 0x00, 0x00, 0x08, 0xeb, 0x87, 0x00, 0x00, 0xf5, 0x9c, 0x74, 0x68, 0x68, + 0xf8, 0x40, 0xc0, 0x07, 0x04, 0xd5, 0x20, 0x68, 0x71, 0x68, 0xf5, 0xf7, + 0xcf, 0xfe, 0x20, 0x60, 0xa8, 0x68, 0xf8, 0x40, 0xc0, 0x07, 0x04, 0xd5, + 0x60, 0x6e, 0x71, 0x68, 0xf5, 0xf7, 0xc6, 0xfe, 0x60, 0x66, 0x7f, 0x1c, + 0x18, 0x2f, 0xe6, 0xdb, 0x00, 0x20, 0x70, 0x60, 0xbd, 0xe8, 0xf0, 0x81, + 0xf1, 0x68, 0x30, 0x68, 0xf5, 0xf7, 0xca, 0xbf, 0x2d, 0xe9, 0xf6, 0x4f, + 0x04, 0x46, 0x85, 0xb0, 0x60, 0x68, 0xd0, 0xf8, 0x28, 0x03, 0xf5, 0xf7, + 0x23, 0xfe, 0x05, 0x46, 0x4f, 0xf0, 0x8a, 0x40, 0x00, 0xf0, 0xd1, 0xff, + 0x83, 0x46, 0x82, 0x46, 0x4f, 0xf0, 0x8e, 0x40, 0x00, 0xf0, 0xcb, 0xff, + 0x05, 0x46, 0x06, 0x46, 0x4f, 0xf0, 0x00, 0x08, 0x00, 0xf0, 0x6e, 0xfa, + 0x04, 0xeb, 0x88, 0x07, 0xd2, 0xe9, 0x00, 0x01, 0xf5, 0xf7, 0xde, 0xfd, + 0x59, 0x46, 0x07, 0xf5, 0x34, 0x79, 0xf5, 0xf7, 0x17, 0xfe, 0xc9, 0xf8, + 0x00, 0x00, 0x07, 0xf5, 0x66, 0x77, 0x00, 0xf0, 0x5d, 0xfa, 0xd2, 0xe9, + 0x32, 0x01, 0xf5, 0xf7, 0xcf, 0xfd, 0x51, 0x46, 0xf5, 0xf7, 0x0a, 0xfe, + 0xc9, 0xf8, 0x64, 0x00, 0x00, 0xf0, 0x52, 0xfa, 0xd2, 0xe9, 0x64, 0x01, + 0xf5, 0xf7, 0xb6, 0xfd, 0x29, 0x46, 0xf5, 0xf7, 0xff, 0xfd, 0x38, 0x60, + 0x00, 0xf0, 0x48, 0xfa, 0x08, 0xf1, 0x01, 0x08, 0xd2, 0xe9, 0x96, 0x01, + 0xf5, 0xf7, 0xaa, 0xfd, 0x31, 0x46, 0xf5, 0xf7, 0xf3, 0xfd, 0xb8, 0xf1, + 0x19, 0x0f, 0x78, 0x66, 0xca, 0xd3, 0x62, 0x68, 0x01, 0x25, 0xd2, 0xe9, + 0xc8, 0x01, 0xf5, 0xf7, 0xab, 0xfd, 0x4f, 0xf0, 0x3a, 0x51, 0xf5, 0xf7, + 0x73, 0xff, 0xc4, 0xf8, 0x60, 0x04, 0xd4, 0xf8, 0xd0, 0x02, 0x01, 0x90, + 0x04, 0xeb, 0x85, 0x06, 0x06, 0xf5, 0x34, 0x71, 0x00, 0xf0, 0x72, 0xfd, + 0x07, 0x46, 0xd6, 0xf8, 0x98, 0x03, 0x4f, 0xf0, 0x80, 0x41, 0xf5, 0xf7, + 0x61, 0xff, 0x00, 0xf0, 0x9b, 0xfd, 0x07, 0x46, 0x01, 0x98, 0x39, 0x46, + 0xf5, 0xf7, 0x48, 0xff, 0x38, 0xbf, 0x01, 0x97, 0x6d, 0x1c, 0x15, 0x2d, + 0xe6, 0xd3, 0x01, 0x26, 0x05, 0x98, 0x00, 0xf5, 0xc8, 0x75, 0x00, 0x20, + 0x28, 0x60, 0x68, 0x60, 0xa8, 0x60, 0xe8, 0x60, 0x28, 0x61, 0xa8, 0x61, + 0x68, 0x61, 0xe8, 0x61, 0xe8, 0x62, 0x28, 0x63, 0x28, 0x62, 0x68, 0x62, + 0xa8, 0x62, 0xd4, 0xf8, 0x60, 0x14, 0xdf, 0xf8, 0x40, 0x0a, 0xf5, 0xf7, + 0x3d, 0xff, 0x03, 0x90, 0x04, 0xeb, 0x86, 0x00, 0x00, 0xf5, 0x34, 0x71, + 0x00, 0xf5, 0x66, 0x77, 0xd1, 0xf8, 0x00, 0xa0, 0x49, 0x6e, 0x00, 0x91, + 0x4f, 0xf0, 0x80, 0x41, 0x38, 0x68, 0xf5, 0xf7, 0x2d, 0xff, 0x81, 0x46, + 0x05, 0x98, 0x00, 0xeb, 0x86, 0x08, 0x78, 0x6e, 0xc8, 0xf8, 0x2c, 0x01, + 0x51, 0x46, 0x00, 0x98, 0xf5, 0xf7, 0x86, 0xfe, 0x83, 0x46, 0x00, 0xf0, + 0xe1, 0xf9, 0x02, 0x90, 0x00, 0x21, 0xf5, 0xf7, 0xfb, 0xfe, 0x07, 0x46, + 0x36, 0xd0, 0x58, 0x46, 0x49, 0x46, 0xf5, 0xf7, 0x05, 0xfe, 0x39, 0x46, + 0xf5, 0xf7, 0x84, 0xfd, 0x00, 0x21, 0xf6, 0xf7, 0x17, 0xf8, 0x81, 0x46, + 0x04, 0xd9, 0xdf, 0xf8, 0xdc, 0x09, 0x00, 0xf0, 0xff, 0xfd, 0x81, 0x46, + 0x48, 0x46, 0xf5, 0xf7, 0xab, 0xfe, 0x05, 0x99, 0x41, 0xf8, 0x26, 0x00, + 0x50, 0x46, 0x00, 0x99, 0xf5, 0xf7, 0xee, 0xfd, 0x81, 0x46, 0x4f, 0xf0, + 0x7c, 0x50, 0x49, 0x46, 0x08, 0xf1, 0x64, 0x0a, 0xf5, 0xf7, 0xf6, 0xfe, + 0xca, 0xf8, 0x00, 0x00, 0x39, 0x46, 0x4f, 0xf0, 0x3f, 0x40, 0xf5, 0xf7, + 0xef, 0xfe, 0xca, 0xf8, 0x64, 0x00, 0x00, 0x21, 0xda, 0xf8, 0x00, 0x00, + 0xf5, 0xf7, 0xf0, 0xff, 0x24, 0xbf, 0xdf, 0xf8, 0x90, 0x19, 0xf5, 0xf7, + 0xe3, 0xfe, 0x02, 0xe0, 0x4f, 0xf0, 0x7e, 0x59, 0xd6, 0xe7, 0x29, 0x6b, + 0xf5, 0xf7, 0xca, 0xfe, 0x38, 0xbf, 0x08, 0x46, 0x28, 0x63, 0xda, 0xf8, + 0x64, 0x10, 0xe8, 0x6a, 0xf5, 0xf7, 0xc2, 0xfe, 0x38, 0xbf, 0x01, 0x46, + 0xe9, 0x62, 0x38, 0x46, 0x01, 0x99, 0xd4, 0xf8, 0x00, 0xa0, 0xf5, 0xf7, + 0x3d, 0xfd, 0x0a, 0xf1, 0x08, 0x0b, 0x01, 0x46, 0xdb, 0xf8, 0x04, 0x00, + 0xf5, 0xf7, 0xb2, 0xfe, 0x08, 0xd2, 0xdb, 0xf8, 0x00, 0x00, 0x39, 0x46, + 0xf5, 0xf7, 0xac, 0xfe, 0x38, 0xbf, 0x4f, 0xf0, 0x01, 0x0b, 0x01, 0xd3, + 0x4f, 0xf0, 0x00, 0x0b, 0xa0, 0x68, 0xd0, 0xf8, 0x10, 0x02, 0x10, 0xb9, + 0x06, 0x98, 0x02, 0x28, 0x02, 0xd1, 0xda, 0xf8, 0x8c, 0x00, 0x78, 0xb1, + 0x0a, 0xeb, 0x86, 0x01, 0x03, 0x98, 0x89, 0x6a, 0xf5, 0xf7, 0xa8, 0xfe, + 0x00, 0x90, 0x39, 0x46, 0xdf, 0xf8, 0x10, 0x09, 0xf5, 0xf7, 0xa2, 0xfe, + 0x00, 0x99, 0xf5, 0xf7, 0x8d, 0xfe, 0x29, 0xd3, 0xbb, 0xf1, 0x00, 0x0f, + 0x1c, 0xbf, 0x06, 0x98, 0x01, 0x28, 0x25, 0xd0, 0x05, 0x98, 0xdf, 0xf8, + 0xf0, 0x18, 0x50, 0xf8, 0x26, 0x00, 0xf5, 0xf7, 0xf5, 0xfd, 0x83, 0x46, + 0xd8, 0xf8, 0x2c, 0x01, 0x39, 0x46, 0xf5, 0xf7, 0xfd, 0xfc, 0x80, 0x46, + 0x58, 0x46, 0x00, 0xf0, 0xb1, 0xfc, 0x07, 0x46, 0x40, 0x46, 0x00, 0xf0, + 0x7e, 0xfd, 0x00, 0xf0, 0xbd, 0xfc, 0x4f, 0xf0, 0x7a, 0x51, 0xf5, 0xf7, + 0x7d, 0xfe, 0x0a, 0xf1, 0x8c, 0x01, 0x49, 0x69, 0xf5, 0xf7, 0x66, 0xfe, + 0x38, 0xbf, 0x4f, 0xf0, 0x01, 0x0b, 0x01, 0xd3, 0x4f, 0xf0, 0x00, 0x0b, + 0x28, 0x69, 0x58, 0x44, 0x28, 0x61, 0x0b, 0xfa, 0x06, 0xf1, 0x28, 0x68, + 0x08, 0x43, 0x28, 0x60, 0x48, 0x46, 0x02, 0x99, 0xf5, 0xf7, 0xd8, 0xfc, + 0x01, 0x46, 0x20, 0x68, 0x07, 0x69, 0x38, 0x46, 0xf5, 0xf7, 0x4e, 0xfe, + 0x05, 0xd2, 0x01, 0x20, 0x5f, 0xea, 0x0b, 0x01, 0x0e, 0xd0, 0x01, 0x21, + 0x0c, 0xe0, 0xdf, 0xf8, 0x74, 0x08, 0xf5, 0xf7, 0x55, 0xfe, 0x01, 0x46, + 0x38, 0x46, 0xf5, 0xf7, 0x3f, 0xfe, 0x34, 0xbf, 0x4f, 0xf0, 0xff, 0x30, + 0x00, 0x20, 0x00, 0x21, 0xaa, 0x69, 0x8a, 0x18, 0xaa, 0x61, 0xb1, 0x40, + 0x6a, 0x68, 0x11, 0x43, 0xbb, 0xf1, 0x00, 0x0f, 0x69, 0x60, 0x04, 0xd0, + 0x10, 0xf1, 0x01, 0x0f, 0x08, 0xbf, 0x01, 0x21, 0x00, 0xd0, 0x00, 0x21, + 0x6a, 0x69, 0x8a, 0x18, 0x6a, 0x61, 0xb1, 0x40, 0xaa, 0x68, 0x11, 0x43, + 0xa9, 0x60, 0x40, 0x1e, 0x80, 0x41, 0xe9, 0x69, 0xc0, 0x0f, 0x41, 0x18, + 0xe9, 0x61, 0xb0, 0x40, 0xe9, 0x68, 0x76, 0x1c, 0x08, 0x43, 0x15, 0x2e, + 0xe8, 0x60, 0xff, 0xf4, 0xeb, 0xae, 0x4f, 0xf0, 0x7e, 0x50, 0x05, 0x99, + 0x08, 0x60, 0x00, 0x21, 0x05, 0x98, 0xc8, 0x30, 0x41, 0x66, 0x01, 0x60, + 0x00, 0x20, 0x05, 0x99, 0x48, 0x66, 0x15, 0x26, 0x05, 0x99, 0x4f, 0xf0, + 0x7e, 0x50, 0x41, 0xf8, 0x26, 0x00, 0x00, 0x21, 0x05, 0x98, 0x00, 0xeb, + 0x86, 0x00, 0x76, 0x1c, 0xc0, 0xf8, 0x2c, 0x11, 0x64, 0x30, 0x19, 0x2e, + 0x41, 0x66, 0x01, 0x60, 0xee, 0xd3, 0x06, 0x98, 0x01, 0x28, 0x25, 0xd1, + 0xe9, 0x6a, 0x4f, 0xf0, 0x40, 0x40, 0xf5, 0xf7, 0x01, 0xfe, 0x80, 0x46, + 0x01, 0x26, 0x04, 0xeb, 0x86, 0x07, 0x07, 0xf5, 0x34, 0x71, 0x00, 0xf0, + 0x03, 0xfc, 0x81, 0x46, 0xd7, 0xf8, 0x98, 0x03, 0x4f, 0xf0, 0x80, 0x41, + 0xf5, 0xf7, 0xf2, 0xfd, 0x00, 0xf0, 0xb2, 0xf8, 0x41, 0x46, 0xf5, 0xf7, + 0x5f, 0xfc, 0xdf, 0xf8, 0xa4, 0x17, 0xf5, 0xf7, 0xd7, 0xfd, 0x04, 0xd2, + 0x28, 0x68, 0x01, 0x21, 0xb1, 0x40, 0x88, 0x43, 0x28, 0x60, 0x76, 0x1c, + 0x18, 0x2e, 0xe0, 0xd3, 0x27, 0x68, 0xe9, 0x6a, 0x38, 0x6a, 0xf5, 0xf7, + 0xdb, 0xfd, 0x06, 0x46, 0x29, 0x6b, 0x78, 0x6a, 0xf5, 0xf7, 0xd6, 0xfd, + 0x80, 0x46, 0x01, 0x27, 0x05, 0x98, 0x00, 0xeb, 0x87, 0x00, 0x00, 0xf1, + 0x64, 0x09, 0x28, 0x68, 0xf8, 0x40, 0xc0, 0x07, 0x07, 0xd5, 0xd9, 0xf8, + 0x64, 0x00, 0x31, 0x46, 0xf5, 0xf7, 0xb4, 0xfd, 0x38, 0xbf, 0x01, 0x20, + 0x00, 0xd3, 0x00, 0x20, 0x29, 0x6a, 0xb8, 0x40, 0x08, 0x43, 0x28, 0x62, + 0x68, 0x68, 0xf8, 0x40, 0xc0, 0x07, 0x07, 0xd5, 0xd9, 0xf8, 0x00, 0x10, + 0x40, 0x46, 0xf5, 0xf7, 0xa3, 0xfd, 0x38, 0xbf, 0x01, 0x20, 0x00, 0xd3, + 0x00, 0x20, 0x69, 0x6a, 0xb8, 0x40, 0x08, 0x43, 0x68, 0x62, 0xa8, 0x68, + 0xf8, 0x40, 0xc0, 0x07, 0x0b, 0xd5, 0xdf, 0xf8, 0x14, 0x07, 0x00, 0xf0, + 0xa0, 0xfc, 0x01, 0x46, 0xd9, 0xf8, 0x00, 0x00, 0xf5, 0xf7, 0x8e, 0xfd, + 0x38, 0xbf, 0x01, 0x20, 0x00, 0xd3, 0x00, 0x20, 0xa9, 0x6a, 0xb8, 0x40, + 0x7f, 0x1c, 0x08, 0x43, 0x18, 0x2f, 0xa8, 0x62, 0xc0, 0xd3, 0x04, 0xf5, + 0x34, 0x70, 0xd4, 0xf8, 0x9c, 0x63, 0xd4, 0xf8, 0xd0, 0x12, 0x40, 0x68, + 0xf5, 0xf7, 0xf0, 0xfc, 0x04, 0xf5, 0x34, 0x71, 0x4f, 0xf0, 0x02, 0x08, + 0x89, 0x6e, 0xf5, 0xf7, 0xe9, 0xfc, 0x00, 0xf0, 0x48, 0xf8, 0x00, 0xf0, + 0x46, 0xf8, 0x06, 0x46, 0x00, 0x20, 0x04, 0xeb, 0x88, 0x01, 0x01, 0xf5, + 0x34, 0x79, 0xd1, 0xf8, 0x98, 0x73, 0xd9, 0xf8, 0x00, 0x10, 0xf5, 0xf7, + 0xd9, 0xfc, 0xd9, 0xf8, 0x64, 0x10, 0xf5, 0xf7, 0xd5, 0xfc, 0x00, 0xf0, + 0xab, 0xfb, 0x00, 0xf0, 0xa9, 0xfb, 0x08, 0xf1, 0x01, 0x08, 0xb8, 0xf1, + 0x18, 0x0f, 0xe8, 0xd3, 0xa7, 0x68, 0xdf, 0xf8, 0x3c, 0x1d, 0xf5, 0xf7, + 0x63, 0xfd, 0x01, 0x46, 0x30, 0x46, 0xf5, 0xf7, 0x4d, 0xfd, 0x34, 0xbf, + 0x01, 0x20, 0x00, 0x20, 0x87, 0xf8, 0x08, 0x03, 0xe1, 0x68, 0x28, 0x68, + 0x48, 0x60, 0xe1, 0x68, 0x68, 0x68, 0x88, 0x60, 0xe1, 0x68, 0xa8, 0x68, + 0xc8, 0x60, 0xe1, 0x68, 0xe8, 0x68, 0x08, 0x61, 0xe1, 0x68, 0x28, 0x6a, + 0x48, 0x61, 0xe1, 0x68, 0x68, 0x6a, 0x88, 0x61, 0xe1, 0x68, 0xa8, 0x6a, + 0xc8, 0x61, 0x07, 0xb0, 0xbd, 0xe8, 0xf0, 0x8f, 0x60, 0x68, 0x00, 0xeb, + 0xc8, 0x02, 0x70, 0x47, 0x49, 0x46, 0xf5, 0xf7, 0x9f, 0xbc, 0x31, 0x46, + 0xf5, 0xf7, 0x9c, 0xbc, 0x2d, 0xe9, 0xf7, 0x4f, 0x86, 0xb0, 0x80, 0x68, + 0xd0, 0xf8, 0x00, 0x02, 0x40, 0x08, 0x00, 0xf0, 0x01, 0x00, 0x03, 0x90, + 0x07, 0x98, 0x00, 0xf5, 0xc8, 0x74, 0x20, 0x69, 0x00, 0x28, 0x00, 0xf0, + 0xae, 0x81, 0x07, 0x98, 0xdf, 0xf8, 0x0c, 0xb6, 0x00, 0xf5, 0xe8, 0x70, + 0x04, 0x90, 0x64, 0x21, 0xf6, 0xf7, 0xce, 0xfb, 0x07, 0x98, 0x00, 0xf5, + 0x0d, 0x76, 0x14, 0x21, 0x30, 0x46, 0xf6, 0xf7, 0xc7, 0xfb, 0x07, 0x98, + 0x00, 0xf5, 0xe2, 0x70, 0x00, 0x90, 0x4f, 0xf0, 0x7e, 0x58, 0x08, 0x98, + 0x01, 0x28, 0x46, 0xd1, 0x00, 0xf0, 0xdd, 0xfa, 0x0a, 0xe0, 0xf5, 0xf7, + 0x09, 0xfd, 0x03, 0x2d, 0x30, 0x62, 0x02, 0xd2, 0x00, 0xf0, 0xda, 0xfa, + 0x30, 0x62, 0x6d, 0x1c, 0x00, 0xf0, 0xe9, 0xfa, 0x18, 0x2d, 0x47, 0xd2, + 0x20, 0x68, 0x22, 0x6a, 0x65, 0x63, 0xe8, 0x40, 0x00, 0xf0, 0x01, 0x09, + 0x06, 0x98, 0x81, 0x68, 0xd1, 0xf8, 0x04, 0x02, 0xc6, 0xf8, 0x14, 0x80, + 0xe8, 0x40, 0xea, 0x40, 0xc6, 0xf8, 0x18, 0x80, 0x01, 0x23, 0x00, 0xf0, + 0x01, 0x00, 0x02, 0xf0, 0x01, 0x02, 0xa3, 0x63, 0x4a, 0xb9, 0x28, 0xb1, + 0x00, 0xf0, 0x11, 0xfb, 0x06, 0x99, 0x09, 0x68, 0x49, 0x69, 0xd4, 0xe7, + 0xb9, 0xf1, 0x00, 0x0f, 0x0a, 0xd0, 0x07, 0x98, 0x50, 0xf8, 0x25, 0x00, + 0xf0, 0x61, 0x59, 0x46, 0x07, 0x98, 0x00, 0xeb, 0x85, 0x00, 0xd0, 0xf8, + 0xc8, 0x00, 0xc6, 0xe7, 0x00, 0xf0, 0xfd, 0xfa, 0x01, 0x46, 0x06, 0x98, + 0x03, 0x9a, 0x00, 0x68, 0x00, 0x2a, 0x14, 0xbf, 0x80, 0x69, 0xc0, 0x69, + 0xbb, 0xe7, 0x02, 0x28, 0x72, 0xd1, 0x00, 0xf0, 0x94, 0xfa, 0x0a, 0xe0, + 0xf5, 0xf7, 0xc0, 0xfc, 0x03, 0x2d, 0x30, 0x62, 0x02, 0xd2, 0x00, 0xf0, + 0x91, 0xfa, 0x30, 0x62, 0x00, 0xf0, 0xa1, 0xfa, 0x6d, 0x1c, 0x18, 0x2d, + 0x80, 0xf0, 0xf4, 0x80, 0x60, 0x68, 0x65, 0x63, 0xe8, 0x40, 0xc0, 0x07, + 0x5d, 0xbf, 0xa0, 0x68, 0xe8, 0x40, 0x00, 0xf0, 0x01, 0x09, 0x4f, 0xf0, + 0x01, 0x09, 0x00, 0xf0, 0x99, 0xfa, 0x29, 0xd4, 0xa1, 0x6a, 0xe9, 0x40, + 0xc9, 0x07, 0x25, 0xd4, 0x6f, 0xb1, 0x00, 0xeb, 0x85, 0x00, 0xc6, 0xf8, + 0x14, 0x80, 0xc6, 0xf8, 0x18, 0xb0, 0xd0, 0xf8, 0x38, 0x01, 0x00, 0xf0, + 0xdd, 0xfa, 0x00, 0xf0, 0xb8, 0xfa, 0x00, 0xf0, 0x7b, 0xfa, 0x01, 0x98, + 0x60, 0xb1, 0x00, 0xf0, 0x52, 0xfa, 0x80, 0x68, 0x00, 0xeb, 0x85, 0x00, + 0xd0, 0xf8, 0x9c, 0x01, 0x00, 0xf0, 0xce, 0xfa, 0x00, 0xf0, 0xa9, 0xfa, + 0x00, 0xf0, 0x6c, 0xfa, 0x01, 0x98, 0x38, 0x43, 0xc0, 0xb2, 0x00, 0x28, + 0xc6, 0xd1, 0xb9, 0xf1, 0x00, 0x0f, 0x12, 0xd0, 0x00, 0xf0, 0x43, 0xfa, + 0x06, 0x98, 0x80, 0x68, 0x49, 0x6e, 0x00, 0xeb, 0x85, 0x00, 0x40, 0x68, + 0xf5, 0xf7, 0x72, 0xfc, 0xb0, 0x61, 0xd9, 0xf8, 0x2c, 0x01, 0xf0, 0x61, + 0x01, 0x20, 0xa0, 0x63, 0xc6, 0xf8, 0x20, 0x80, 0xae, 0xe7, 0x70, 0x61, + 0xc6, 0xf8, 0x18, 0xb0, 0x00, 0xf0, 0x4f, 0xfa, 0x00, 0xf0, 0x6c, 0xfa, + 0x4f, 0xf0, 0x7c, 0x51, 0xf5, 0xf7, 0x5e, 0xfc, 0x00, 0xf0, 0xa2, 0xfa, + 0x01, 0x46, 0x31, 0x62, 0x06, 0x98, 0x03, 0x9a, 0x00, 0x68, 0x00, 0x2a, + 0x14, 0xbf, 0x80, 0x69, 0xc0, 0x69, 0x8f, 0xe7, 0x60, 0x6a, 0x00, 0x28, + 0x04, 0xbf, 0xa0, 0x6a, 0x00, 0x28, 0x05, 0xd0, 0x21, 0x6b, 0x08, 0x46, + 0xf5, 0xf7, 0x48, 0xfc, 0x02, 0x90, 0x01, 0xe0, 0xcd, 0xf8, 0x08, 0x80, + 0x00, 0xf0, 0x13, 0xfa, 0x0c, 0xe0, 0x02, 0x98, 0x51, 0x46, 0xf5, 0xf7, + 0x3d, 0xfc, 0x03, 0x2d, 0x30, 0x62, 0x02, 0xd2, 0x00, 0xf0, 0x0f, 0xfa, + 0x30, 0x62, 0x00, 0xf0, 0x1e, 0xfa, 0x6d, 0x1c, 0x18, 0x2d, 0x71, 0xd2, + 0x60, 0x68, 0x65, 0x63, 0xe8, 0x40, 0xc0, 0x07, 0x5d, 0xbf, 0xa0, 0x68, + 0xe8, 0x40, 0x00, 0xf0, 0x01, 0x09, 0x4f, 0xf0, 0x01, 0x09, 0x00, 0xf0, + 0x17, 0xfa, 0x2f, 0xd4, 0xa1, 0x6a, 0xe9, 0x40, 0xc9, 0x07, 0x2b, 0xd4, + 0x06, 0x99, 0x09, 0x68, 0xd1, 0xf8, 0x14, 0xa0, 0x77, 0xb1, 0x00, 0xeb, + 0x85, 0x01, 0xc6, 0xf8, 0x14, 0x80, 0xc6, 0xf8, 0x18, 0x80, 0xd1, 0xf8, + 0x38, 0x11, 0x00, 0x68, 0xf5, 0xf7, 0x74, 0xfb, 0x00, 0xf0, 0x2b, 0xfa, + 0x00, 0xf0, 0xf4, 0xf9, 0x01, 0x98, 0x68, 0xb1, 0x00, 0xf0, 0xcb, 0xf9, + 0x81, 0x68, 0x01, 0xeb, 0x85, 0x00, 0x09, 0x68, 0xd0, 0xf8, 0x9c, 0x01, + 0xf5, 0xf7, 0x64, 0xfb, 0x00, 0xf0, 0x1b, 0xfa, 0x00, 0xf0, 0xe4, 0xf9, + 0x01, 0x98, 0x38, 0x43, 0xc0, 0xb2, 0x00, 0x28, 0xc1, 0xd1, 0xb9, 0xf1, + 0x00, 0x0f, 0x19, 0xd0, 0x00, 0xf0, 0xbb, 0xf9, 0xb0, 0x61, 0x06, 0x98, + 0xd0, 0xf8, 0x08, 0xa0, 0x49, 0x6e, 0x0a, 0xeb, 0x85, 0x00, 0x40, 0x68, + 0xf5, 0xf7, 0xe8, 0xfb, 0xda, 0xf8, 0x00, 0x10, 0xf5, 0xf7, 0xe4, 0xfb, + 0x01, 0x46, 0xd9, 0xf8, 0x2c, 0x01, 0xf5, 0xf7, 0xcf, 0xfa, 0xf0, 0x61, + 0xa5, 0x63, 0xc6, 0xf8, 0x20, 0x80, 0xa2, 0xe7, 0xc6, 0xf8, 0x14, 0x80, + 0xc6, 0xf8, 0x18, 0x80, 0x00, 0xf0, 0xbf, 0xf9, 0x08, 0x68, 0x49, 0x6e, + 0xf5, 0xf7, 0xc0, 0xfa, 0x4f, 0xf0, 0x7c, 0x51, 0xf5, 0xf7, 0xcc, 0xfb, + 0xf0, 0x61, 0xa5, 0x63, 0x06, 0x98, 0x03, 0x99, 0x00, 0x68, 0x00, 0x29, + 0x14, 0xbf, 0xd0, 0xf8, 0x18, 0xa0, 0xd0, 0xf8, 0x1c, 0xa0, 0x7e, 0xe7, + 0xe0, 0x6b, 0x01, 0x28, 0x05, 0xd1, 0x30, 0x68, 0x21, 0x6c, 0xf5, 0xf7, + 0x2b, 0xfa, 0x30, 0x60, 0x04, 0xe0, 0x02, 0x46, 0x04, 0x98, 0x31, 0x46, + 0x00, 0xf0, 0x14, 0xfb, 0x08, 0x98, 0x02, 0x28, 0x26, 0xd1, 0x34, 0x68, + 0x20, 0x46, 0x21, 0x46, 0xf5, 0xf7, 0x8a, 0xfb, 0x2f, 0xd1, 0x06, 0x98, + 0x85, 0x68, 0x95, 0xf8, 0x00, 0x02, 0xc0, 0x07, 0x12, 0xd5, 0x06, 0x98, + 0x00, 0x68, 0x46, 0x68, 0x40, 0x46, 0x31, 0x46, 0xf5, 0xf7, 0x8c, 0xfa, + 0x29, 0x68, 0xf5, 0xf7, 0x99, 0xfb, 0x07, 0x46, 0x20, 0x46, 0x31, 0x46, + 0xf5, 0xf7, 0x94, 0xfb, 0x00, 0xf0, 0xce, 0xf9, 0x28, 0x60, 0x00, 0xe0, + 0x2c, 0x60, 0xd5, 0xf8, 0x00, 0x02, 0x40, 0xf0, 0x01, 0x00, 0xc5, 0xf8, + 0x00, 0x02, 0x46, 0xe1, 0x00, 0x25, 0x00, 0xe0, 0x6d, 0x1c, 0xe0, 0x6b, + 0x85, 0x42, 0x0a, 0xd2, 0x07, 0x98, 0x00, 0xeb, 0x85, 0x00, 0xd0, 0xf8, + 0x34, 0x02, 0x01, 0x46, 0xf5, 0xf7, 0x5a, 0xfb, 0xf2, 0xd0, 0x01, 0x20, + 0x36, 0xe1, 0x08, 0x98, 0x01, 0x28, 0x0c, 0xbf, 0x02, 0x20, 0x01, 0x20, + 0x00, 0x90, 0x31, 0x46, 0x06, 0x98, 0x03, 0x69, 0x07, 0x98, 0xe2, 0x6b, + 0x00, 0xf5, 0x16, 0x70, 0x00, 0xf0, 0x84, 0xfa, 0x08, 0x98, 0x01, 0x28, + 0x10, 0xd1, 0x00, 0x25, 0x09, 0xe0, 0x07, 0x99, 0x01, 0xeb, 0x80, 0x00, + 0x01, 0xeb, 0x85, 0x01, 0xd0, 0xf8, 0x5c, 0x02, 0xc1, 0xf8, 0x58, 0x02, + 0x6d, 0x1c, 0x06, 0x98, 0x07, 0x68, 0x78, 0x88, 0xa8, 0x42, 0xf0, 0xd2, + 0x00, 0x25, 0x07, 0x98, 0x00, 0xeb, 0x85, 0x0b, 0x08, 0x98, 0x01, 0x28, + 0x1f, 0xd1, 0x06, 0x98, 0x81, 0x68, 0xdb, 0xf8, 0x58, 0x62, 0xd1, 0xf8, + 0x04, 0x02, 0x01, 0xeb, 0x85, 0x08, 0x98, 0xb1, 0x06, 0x98, 0x07, 0x68, + 0x7f, 0x68, 0x00, 0xf0, 0x57, 0xfb, 0x01, 0x46, 0xd8, 0xf8, 0x04, 0x00, + 0xf5, 0xf7, 0x3a, 0xfb, 0x83, 0x46, 0x30, 0x46, 0x39, 0x46, 0xf5, 0xf7, + 0x35, 0xfb, 0x00, 0xf0, 0x36, 0xf9, 0xc8, 0xf8, 0x04, 0x00, 0x2a, 0xe0, + 0xc8, 0xf8, 0x04, 0x60, 0x27, 0xe0, 0x03, 0x28, 0x25, 0xd1, 0x06, 0x98, + 0x82, 0x68, 0x02, 0xf5, 0x01, 0x76, 0x70, 0x68, 0x00, 0x28, 0x04, 0xbf, + 0xb0, 0x68, 0x00, 0x28, 0x16, 0xd0, 0x06, 0x98, 0x07, 0x68, 0x7f, 0x68, + 0x02, 0xeb, 0x85, 0x08, 0x00, 0xf0, 0x32, 0xfb, 0x01, 0x46, 0xd8, 0xf8, + 0x68, 0x00, 0xf5, 0xf7, 0x15, 0xfb, 0x06, 0x46, 0xdb, 0xf8, 0x58, 0x02, + 0x39, 0x46, 0xf5, 0xf7, 0x0f, 0xfb, 0xff, 0xf7, 0xd2, 0xfd, 0xc8, 0xf8, + 0x68, 0x00, 0x04, 0xe0, 0xdb, 0xf8, 0x58, 0x02, 0x02, 0xeb, 0x85, 0x01, + 0x88, 0x66, 0x6d, 0x1c, 0x19, 0x2d, 0xae, 0xd3, 0x00, 0x25, 0x01, 0x20, + 0xa8, 0x40, 0x00, 0x90, 0x07, 0x98, 0x00, 0xeb, 0x85, 0x08, 0x08, 0x98, + 0x01, 0x28, 0x38, 0xd1, 0x06, 0x98, 0x82, 0x68, 0x21, 0x6a, 0x02, 0xf5, + 0x01, 0x76, 0xe9, 0x40, 0x30, 0x68, 0xe8, 0x40, 0xc9, 0x07, 0x00, 0xf0, + 0x01, 0x00, 0x18, 0xd5, 0xd8, 0xf8, 0x58, 0x82, 0x02, 0xeb, 0x85, 0x01, + 0x01, 0xf1, 0xd4, 0x0b, 0x50, 0xb1, 0x00, 0xf0, 0x22, 0xf9, 0x00, 0xf0, + 0xf9, 0xf8, 0x00, 0xf0, 0xd8, 0xf9, 0xff, 0xf7, 0x9f, 0xfd, 0xcb, 0xf8, + 0x00, 0x00, 0x01, 0xe0, 0xcb, 0xf8, 0x00, 0x80, 0x30, 0x68, 0x00, 0x99, + 0x08, 0x43, 0x30, 0x60, 0x8d, 0xe0, 0x00, 0x28, 0xfc, 0xd1, 0x02, 0xeb, + 0x85, 0x00, 0x00, 0xf1, 0xd4, 0x0b, 0x00, 0xf0, 0x0a, 0xf9, 0x00, 0xf0, + 0xe1, 0xf8, 0x06, 0x46, 0xd8, 0xf8, 0x58, 0x02, 0x00, 0xf0, 0xe8, 0xfc, + 0xff, 0xf7, 0x87, 0xfd, 0xcb, 0xf8, 0x00, 0x00, 0x79, 0xe0, 0x08, 0x98, + 0x03, 0x28, 0x76, 0xd1, 0x06, 0x98, 0xd0, 0xf8, 0x08, 0xa0, 0x0a, 0xf5, + 0x01, 0x76, 0x70, 0x68, 0xe8, 0x40, 0x00, 0xf0, 0x01, 0x07, 0xb0, 0x68, + 0xe8, 0x40, 0x00, 0xf0, 0x01, 0x00, 0x01, 0x90, 0x60, 0x6a, 0xe8, 0x40, + 0xc0, 0x07, 0x19, 0xd5, 0x00, 0xf0, 0xde, 0xf8, 0x80, 0x46, 0x0a, 0xeb, + 0x85, 0x00, 0x00, 0xf1, 0xd4, 0x0b, 0x57, 0xb1, 0x00, 0xf0, 0xdf, 0xf8, + 0x00, 0xf0, 0xb1, 0xf8, 0x00, 0xf0, 0x95, 0xf9, 0xff, 0xf7, 0x5c, 0xfd, + 0xcb, 0xf8, 0x64, 0x00, 0x01, 0xe0, 0xcb, 0xf8, 0x64, 0x80, 0x70, 0x68, + 0x00, 0x99, 0x08, 0x43, 0x70, 0x60, 0x4a, 0xe0, 0xa0, 0x6a, 0xe8, 0x40, + 0xc0, 0x07, 0x1b, 0xd5, 0x00, 0xf0, 0xb0, 0xfb, 0x83, 0x46, 0x01, 0x98, + 0x0a, 0xeb, 0x85, 0x09, 0x68, 0xb1, 0x00, 0xf0, 0xc2, 0xf8, 0x00, 0xf0, + 0x8f, 0xf8, 0x80, 0x46, 0x78, 0x68, 0x00, 0xf0, 0xa7, 0xf8, 0x41, 0x46, + 0xf5, 0xf7, 0xde, 0xf9, 0xc9, 0xf8, 0x9c, 0x01, 0x01, 0xe0, 0xc9, 0xf8, + 0x9c, 0xb1, 0xb0, 0x68, 0x00, 0x99, 0x08, 0x43, 0xb0, 0x60, 0x2a, 0xe0, + 0x01, 0x98, 0x38, 0x43, 0x27, 0xd1, 0x06, 0x98, 0x07, 0x68, 0x79, 0x68, + 0x4f, 0xf0, 0x7e, 0x50, 0x0a, 0xeb, 0x85, 0x09, 0xf5, 0xf7, 0x54, 0xf9, + 0x09, 0xf1, 0xd4, 0x0b, 0x00, 0xf0, 0x73, 0xf8, 0x06, 0x46, 0x00, 0xf0, + 0x93, 0xf8, 0x00, 0xf0, 0x7f, 0xfc, 0xff, 0xf7, 0x1e, 0xfd, 0xcb, 0xf8, + 0x64, 0x00, 0x4f, 0xf0, 0x7e, 0x50, 0x7e, 0x68, 0x31, 0x46, 0xf5, 0xf7, + 0x41, 0xf9, 0x00, 0xf0, 0x5d, 0xf8, 0x07, 0x46, 0x00, 0xf0, 0x72, 0xfb, + 0x31, 0x46, 0xf5, 0xf7, 0x49, 0xfa, 0x00, 0xf0, 0x83, 0xf8, 0xc9, 0xf8, + 0x9c, 0x01, 0x6d, 0x1c, 0x19, 0x2d, 0xff, 0xf4, 0x40, 0xaf, 0x00, 0x20, + 0x09, 0xb0, 0xbd, 0xe8, 0xf0, 0x8f, 0xc6, 0xf8, 0x14, 0xb0, 0xc6, 0xf8, + 0x18, 0xb0, 0x06, 0x98, 0x70, 0x47, 0x07, 0x98, 0x00, 0xeb, 0x85, 0x09, + 0x09, 0xf1, 0x64, 0x01, 0x08, 0x68, 0x70, 0x61, 0x70, 0x47, 0x06, 0x98, + 0x00, 0x68, 0x40, 0x88, 0x45, 0x1c, 0x70, 0x47, 0x30, 0x6a, 0xdf, 0xf8, + 0x88, 0x18, 0xf5, 0xf7, 0x97, 0xb8, 0x00, 0x00, 0x77, 0xbe, 0x7f, 0x3f, + 0x6f, 0x12, 0x83, 0x3a, 0x80, 0x61, 0x0c, 0x4a, 0x00, 0x00, 0x80, 0xbf, + 0xac, 0xc5, 0x27, 0x37, 0x52, 0x49, 0x9d, 0x39, 0x30, 0x62, 0x00, 0x98, + 0x61, 0xe0, 0x06, 0x98, 0x80, 0x68, 0x00, 0xeb, 0x85, 0x00, 0x00, 0xf5, + 0x9c, 0x71, 0x70, 0x47, 0x06, 0x98, 0x80, 0x68, 0x00, 0xf5, 0x02, 0x71, + 0x0a, 0x68, 0x49, 0x68, 0xe9, 0x40, 0x01, 0xf0, 0x01, 0x01, 0x01, 0x91, + 0xea, 0x40, 0x61, 0x6a, 0xe9, 0x40, 0xc9, 0x07, 0x02, 0xf0, 0x01, 0x07, + 0x70, 0x47, 0x59, 0x46, 0xf5, 0xf7, 0x5e, 0xb9, 0x04, 0xeb, 0x87, 0x00, + 0x00, 0xf5, 0x34, 0x71, 0x08, 0x68, 0x49, 0x6e, 0xf5, 0xf7, 0x56, 0xb9, + 0x01, 0x46, 0xd9, 0xf8, 0x9c, 0x01, 0xf5, 0xf7, 0xed, 0xb9, 0x01, 0x46, + 0xdb, 0xf8, 0x64, 0x00, 0xf5, 0xf7, 0xe8, 0xb9, 0x01, 0x46, 0xdb, 0xf8, + 0x00, 0x00, 0xf5, 0xf7, 0xe3, 0xb9, 0xf0, 0x61, 0xa5, 0x63, 0x51, 0x46, + 0x02, 0x98, 0xf5, 0xf7, 0xdd, 0xb9, 0x01, 0x46, 0x31, 0x62, 0x06, 0x98, + 0x00, 0x68, 0x40, 0x69, 0xf5, 0xf7, 0xd6, 0xb9, 0x59, 0x46, 0xf5, 0xf7, + 0xd3, 0xb9, 0x01, 0xeb, 0x85, 0x00, 0x59, 0x46, 0xd0, 0xf8, 0xd4, 0x00, + 0xf0, 0x61, 0xe0, 0x6a, 0xf5, 0xf7, 0xca, 0xb9, 0xd8, 0xf8, 0x58, 0x02, + 0xda, 0xf8, 0x00, 0x10, 0xf5, 0xf7, 0xb4, 0xb8, 0x39, 0x46, 0xf5, 0xf7, + 0x25, 0xb9, 0x06, 0x98, 0x07, 0x68, 0x79, 0x68, 0x4f, 0xf0, 0x7e, 0x50, + 0xf5, 0xf7, 0xaa, 0xb8, 0xf0, 0x61, 0x01, 0x20, 0xa0, 0x63, 0x20, 0x6b, + 0x01, 0x46, 0xf5, 0xf7, 0xb3, 0xb9, 0x2d, 0xe9, 0xf8, 0x4f, 0x05, 0x46, + 0x05, 0xf1, 0x84, 0x06, 0xf1, 0x68, 0xff, 0xf7, 0x4e, 0xf8, 0xb1, 0x68, + 0xf5, 0xf7, 0xa8, 0xf9, 0x04, 0x46, 0x68, 0x68, 0xf5, 0xf7, 0x06, 0xf8, + 0x00, 0xf0, 0x01, 0xf9, 0x29, 0x6f, 0xf5, 0xf7, 0x03, 0xf9, 0x28, 0x67, + 0x4f, 0xf0, 0x01, 0x0b, 0x68, 0x68, 0x29, 0x68, 0x48, 0x43, 0xf4, 0xf7, + 0xf9, 0xff, 0x80, 0x46, 0xff, 0xf7, 0xc6, 0xf9, 0xb1, 0x68, 0xf5, 0xf7, + 0x91, 0xf9, 0x07, 0x46, 0x10, 0xe0, 0x40, 0x46, 0x39, 0x46, 0x05, 0xeb, + 0x8b, 0x04, 0xf5, 0xf7, 0x89, 0xf9, 0x21, 0x6f, 0xf5, 0xf7, 0xea, 0xf8, + 0x20, 0x67, 0x0b, 0xf1, 0x01, 0x0b, 0x00, 0xf0, 0x7f, 0xf8, 0x00, 0xf0, + 0x7a, 0xf8, 0x80, 0x46, 0xa8, 0x68, 0x83, 0x45, 0xeb, 0xd3, 0x68, 0x68, + 0x40, 0x43, 0xf4, 0xf7, 0xd9, 0xff, 0x83, 0x46, 0x74, 0x68, 0x00, 0xf0, + 0xd1, 0xf8, 0x00, 0xf0, 0xd0, 0xf8, 0xff, 0xf7, 0x99, 0xff, 0xe9, 0x68, + 0xf5, 0xf7, 0xd0, 0xf8, 0xe8, 0x60, 0x01, 0x24, 0x00, 0xf0, 0x66, 0xf8, + 0xff, 0xf7, 0x90, 0xff, 0x81, 0x46, 0xff, 0xf7, 0x95, 0xf9, 0x71, 0x68, + 0xf5, 0xf7, 0x60, 0xf9, 0x00, 0x90, 0xd5, 0xf8, 0x08, 0xa0, 0x19, 0xe0, + 0x00, 0x98, 0x00, 0xf0, 0x4f, 0xf8, 0x05, 0xeb, 0x84, 0x07, 0x80, 0x46, + 0xf8, 0x68, 0x41, 0x46, 0xf5, 0xf7, 0xb6, 0xf8, 0xf8, 0x60, 0x05, 0xeb, + 0x8a, 0x07, 0x41, 0x46, 0xf8, 0x68, 0xf5, 0xf7, 0xaf, 0xf8, 0xf8, 0x60, + 0x64, 0x1c, 0xa8, 0x68, 0x82, 0x44, 0x00, 0xf0, 0x43, 0xf8, 0x00, 0xf0, + 0x39, 0xf8, 0x81, 0x46, 0xd5, 0xf8, 0x08, 0x80, 0x44, 0x45, 0xe1, 0xd3, + 0x34, 0x68, 0x00, 0xf0, 0x99, 0xf8, 0x00, 0xf0, 0x98, 0xf8, 0x06, 0x46, + 0x00, 0xf0, 0x34, 0xf8, 0xff, 0xf7, 0x5e, 0xff, 0x83, 0x46, 0x4f, 0xf0, + 0x01, 0x0a, 0x16, 0xe0, 0x48, 0x46, 0x31, 0x46, 0x05, 0xeb, 0x88, 0x07, + 0xf5, 0xf7, 0x2a, 0xf9, 0xf9, 0x68, 0xf5, 0xf7, 0x8b, 0xf8, 0xf8, 0x60, + 0x08, 0xf1, 0x01, 0x08, 0x00, 0xf0, 0x20, 0xf8, 0x00, 0xf0, 0x16, 0xf8, + 0x81, 0x46, 0x64, 0x1c, 0xa8, 0x68, 0x84, 0x42, 0xea, 0xd3, 0x0a, 0xf1, + 0x01, 0x0a, 0xa8, 0x68, 0x82, 0x45, 0x09, 0xd2, 0x00, 0xf0, 0x12, 0xf8, + 0xff, 0xf7, 0x3c, 0xff, 0x83, 0x46, 0xd9, 0x46, 0x08, 0xf1, 0x01, 0x08, + 0x01, 0x24, 0xed, 0xe7, 0xbd, 0xe8, 0xf1, 0x8f, 0x49, 0x46, 0xf5, 0xf7, + 0x07, 0xb9, 0x81, 0x46, 0x78, 0x68, 0x41, 0x46, 0xf5, 0xf7, 0x02, 0xb9, + 0x28, 0x68, 0xf4, 0xf7, 0x61, 0xbf, 0x2d, 0xe9, 0xf8, 0x43, 0x80, 0x46, + 0x0d, 0x46, 0x16, 0x46, 0x99, 0x46, 0x00, 0x24, 0x00, 0x27, 0x0c, 0xe0, + 0x30, 0x46, 0xf4, 0xf7, 0x55, 0xff, 0x58, 0xf8, 0x27, 0x10, 0xf5, 0xf7, + 0xef, 0xf8, 0x21, 0x46, 0xf5, 0xf7, 0x50, 0xf8, 0x04, 0x46, 0x6e, 0x43, + 0x7f, 0x1c, 0x4f, 0x45, 0xf0, 0xd3, 0x20, 0x46, 0xbd, 0xe8, 0xf2, 0x83, + 0x2d, 0xe9, 0xf8, 0x43, 0x08, 0x9c, 0x80, 0x46, 0x0e, 0x46, 0x17, 0x46, + 0x99, 0x46, 0x00, 0x25, 0xa0, 0x07, 0x4c, 0xbf, 0x01, 0x22, 0x2a, 0x46, + 0x3b, 0x46, 0x29, 0x46, 0x30, 0x46, 0xff, 0xf7, 0xd4, 0xff, 0x48, 0xf8, + 0x25, 0x00, 0x6d, 0x1c, 0x19, 0x2d, 0xf1, 0xd3, 0xe0, 0x07, 0x4c, 0xbf, + 0x00, 0x26, 0x58, 0xf8, 0x29, 0x60, 0x4f, 0x46, 0x20, 0xe0, 0xc7, 0xf1, + 0x18, 0x00, 0xf4, 0xf7, 0x25, 0xff, 0x04, 0x46, 0xc9, 0xf1, 0x18, 0x00, + 0xf4, 0xf7, 0x20, 0xff, 0x01, 0x46, 0x20, 0x46, 0xf4, 0xf7, 0x2c, 0xff, + 0x04, 0x46, 0x58, 0xf8, 0x27, 0x00, 0x00, 0xf0, 0x14, 0xf8, 0x05, 0x46, + 0x4f, 0xf0, 0x7e, 0x50, 0x21, 0x46, 0xf4, 0xf7, 0x9f, 0xff, 0x31, 0x46, + 0xf5, 0xf7, 0xac, 0xf8, 0x29, 0x46, 0xf5, 0xf7, 0x0d, 0xf8, 0x48, 0xf8, + 0x27, 0x00, 0x7f, 0x1c, 0x19, 0x2f, 0xdc, 0xd3, 0xbd, 0xe8, 0xf1, 0x83, + 0xf0, 0x68, 0x21, 0x46, 0xf5, 0xf7, 0x9e, 0xb8, 0x2d, 0xe9, 0xf2, 0x4f, + 0x8a, 0xb0, 0x80, 0x46, 0x91, 0x46, 0x00, 0x26, 0x00, 0xe0, 0x76, 0x1c, + 0x4e, 0x45, 0x47, 0xd2, 0x00, 0x25, 0x12, 0xe0, 0x04, 0xeb, 0x0a, 0x00, + 0x00, 0xf0, 0x9a, 0xf8, 0xff, 0xf7, 0xc8, 0xfe, 0x07, 0x46, 0x64, 0x1c, + 0xac, 0x42, 0xf5, 0xd3, 0x06, 0xeb, 0x0a, 0x04, 0x58, 0xf8, 0x24, 0x00, + 0x00, 0xf0, 0x9c, 0xf8, 0x48, 0xf8, 0x24, 0x00, 0x6d, 0x1c, 0xae, 0x42, + 0x04, 0xd3, 0x00, 0x27, 0x00, 0x24, 0x05, 0xfb, 0x09, 0xfa, 0xed, 0xe7, + 0x06, 0xfb, 0x09, 0x61, 0x58, 0xf8, 0x21, 0x10, 0x4f, 0xf0, 0x7e, 0x50, + 0xf4, 0xf7, 0xe2, 0xfe, 0x05, 0x46, 0x05, 0xa8, 0x06, 0xf1, 0x01, 0x0a, + 0x40, 0xf8, 0x26, 0x50, 0x15, 0xe0, 0x04, 0xeb, 0x0b, 0x00, 0x00, 0xf0, + 0x71, 0xf8, 0xff, 0xf7, 0x9f, 0xfe, 0x07, 0x46, 0x64, 0x1c, 0xb4, 0x42, + 0xf5, 0xd3, 0x06, 0xeb, 0x0b, 0x04, 0x58, 0xf8, 0x24, 0x00, 0x00, 0xf0, + 0x73, 0xf8, 0x00, 0xf0, 0x6c, 0xf8, 0x48, 0xf8, 0x24, 0x00, 0x0a, 0xf1, + 0x01, 0x0a, 0xca, 0x45, 0xb9, 0xd2, 0x00, 0x27, 0x00, 0x24, 0x0a, 0xfb, + 0x09, 0xfb, 0xea, 0xe7, 0x0a, 0x98, 0x00, 0x68, 0x00, 0x90, 0x01, 0x25, + 0x15, 0xe0, 0x05, 0xfb, 0x09, 0x60, 0x58, 0xf8, 0x20, 0x00, 0x5d, 0xf8, + 0x26, 0x10, 0xf5, 0xf7, 0x3f, 0xf8, 0xff, 0xf7, 0x79, 0xfe, 0x07, 0x46, + 0x76, 0x1c, 0xae, 0x42, 0xf1, 0xd3, 0x0a, 0x98, 0x50, 0xf8, 0x25, 0x00, + 0x00, 0xf0, 0x4e, 0xf8, 0x4d, 0xf8, 0x25, 0x00, 0x6d, 0x1c, 0x4d, 0x45, + 0x02, 0xd2, 0x00, 0x27, 0x00, 0x26, 0xf0, 0xe7, 0x68, 0x46, 0x00, 0xeb, + 0x89, 0x00, 0xa9, 0xf1, 0x02, 0x05, 0x50, 0xf8, 0x04, 0x1c, 0x05, 0xa8, + 0x00, 0xeb, 0x89, 0x00, 0x50, 0xf8, 0x04, 0x0c, 0xf5, 0xf7, 0x1e, 0xf8, + 0x0a, 0x99, 0x01, 0xeb, 0x89, 0x01, 0x41, 0xf8, 0x04, 0x0c, 0x1b, 0xe0, + 0x0a, 0x99, 0x51, 0xf8, 0x26, 0x10, 0x05, 0xfb, 0x09, 0x60, 0x58, 0xf8, + 0x20, 0x00, 0xf5, 0xf7, 0x0f, 0xf8, 0xff, 0xf7, 0x49, 0xfe, 0x07, 0x46, + 0x76, 0x1c, 0x4e, 0x45, 0xf0, 0xd3, 0x5d, 0xf8, 0x25, 0x00, 0x00, 0xf0, + 0x1f, 0xf8, 0x05, 0xa9, 0x51, 0xf8, 0x25, 0x10, 0xf5, 0xf7, 0x00, 0xf8, + 0x0a, 0x99, 0x41, 0xf8, 0x25, 0x00, 0x6d, 0x1e, 0x00, 0x2d, 0x02, 0xd4, + 0x00, 0x27, 0x6e, 0x1c, 0xeb, 0xe7, 0x0b, 0xb0, 0xbd, 0xe8, 0xf0, 0x8f, + 0x04, 0xfb, 0x09, 0x61, 0x58, 0xf8, 0x20, 0x00, 0x58, 0xf8, 0x21, 0x10, + 0xf4, 0xf7, 0xec, 0xbf, 0x02, 0x98, 0x29, 0x46, 0xf4, 0xf7, 0xe8, 0xbf, + 0x4f, 0xf0, 0x7e, 0x50, 0x39, 0x46, 0xf4, 0xf7, 0xd3, 0xbe, 0x2d, 0xe9, + 0xf2, 0x4f, 0x04, 0x46, 0x04, 0xf5, 0x00, 0x75, 0x50, 0x08, 0x03, 0x22, + 0x59, 0x08, 0x2a, 0x60, 0x40, 0x00, 0x49, 0x00, 0x41, 0xea, 0x00, 0x02, + 0xa8, 0x60, 0x6a, 0x60, 0xe9, 0x60, 0x4f, 0xf0, 0x00, 0x09, 0x68, 0x68, + 0xc0, 0x08, 0xc0, 0x00, 0x68, 0x60, 0xa8, 0x68, 0xc0, 0x08, 0xc0, 0x00, + 0xa8, 0x60, 0xe8, 0x68, 0xc0, 0x08, 0xc0, 0x00, 0xe8, 0x60, 0x68, 0x68, + 0xc0, 0x02, 0xc0, 0x0a, 0x68, 0x60, 0xa8, 0x68, 0xc0, 0x02, 0xc0, 0x0a, + 0xa8, 0x60, 0xe8, 0x68, 0xc0, 0x02, 0xc0, 0x0a, 0xe8, 0x60, 0x18, 0x20, + 0x69, 0x68, 0xc1, 0x40, 0xc9, 0x07, 0x07, 0xd4, 0xa9, 0x68, 0xc1, 0x40, + 0xc9, 0x07, 0x03, 0xd4, 0xe9, 0x68, 0xc1, 0x40, 0xc9, 0x07, 0x01, 0xd5, + 0x81, 0x46, 0x01, 0xe0, 0x40, 0x1e, 0xef, 0xd5, 0x4f, 0xf0, 0x00, 0x0a, + 0x50, 0x46, 0xca, 0x45, 0xc8, 0xbf, 0x48, 0x46, 0x04, 0xeb, 0x80, 0x07, + 0x04, 0xeb, 0x8a, 0x08, 0x08, 0xf1, 0x04, 0x06, 0x78, 0x68, 0x30, 0x60, + 0x08, 0xf1, 0xd4, 0x0b, 0x78, 0x68, 0xcb, 0xf8, 0x00, 0x00, 0x0a, 0xf1, + 0x01, 0x0a, 0xb8, 0x6e, 0x70, 0x66, 0x21, 0x68, 0xb8, 0x6e, 0xf4, 0xf7, + 0x7d, 0xfe, 0xcb, 0xf8, 0x64, 0x00, 0xb8, 0x6e, 0x21, 0x68, 0x00, 0xf0, + 0xb1, 0xf8, 0xc8, 0xf8, 0x9c, 0x01, 0x08, 0xf5, 0x0b, 0x70, 0x31, 0x68, + 0x01, 0x60, 0xba, 0xf1, 0x19, 0x0f, 0x71, 0x6e, 0x41, 0x66, 0x20, 0x68, + 0xa8, 0x62, 0xd3, 0xdb, 0x20, 0x68, 0xa8, 0x62, 0x04, 0xf5, 0x3d, 0x70, + 0x9d, 0xf8, 0x00, 0x10, 0x00, 0xf0, 0x02, 0xf8, 0xbd, 0xe8, 0xf1, 0x8f, + 0x01, 0x70, 0x29, 0x68, 0x41, 0x60, 0x69, 0x68, 0x81, 0x60, 0xa9, 0x68, + 0xc1, 0x60, 0xe9, 0x68, 0x01, 0x61, 0x70, 0x47, 0x38, 0xb5, 0x04, 0x46, + 0x00, 0xf0, 0x89, 0xfa, 0x04, 0xf1, 0xcc, 0x01, 0x4f, 0xf0, 0x7e, 0x50, + 0x00, 0x22, 0x08, 0x60, 0x4a, 0x60, 0x00, 0x21, 0x00, 0x25, 0x04, 0xeb, + 0x81, 0x02, 0x02, 0xf1, 0xd4, 0x03, 0x49, 0x1c, 0x18, 0x60, 0xc2, 0xf8, + 0x9c, 0x51, 0x00, 0x22, 0x19, 0x29, 0x5a, 0x66, 0xf3, 0xd3, 0x04, 0xf5, + 0x00, 0x75, 0x01, 0x21, 0x29, 0x60, 0x6f, 0xf0, 0x01, 0x01, 0x69, 0x60, + 0xa9, 0x60, 0xe9, 0x60, 0x69, 0x68, 0xc9, 0x08, 0xc9, 0x00, 0x69, 0x60, + 0xa9, 0x68, 0xc9, 0x08, 0xc9, 0x00, 0xa9, 0x60, 0xe9, 0x68, 0xc9, 0x08, + 0xc9, 0x00, 0xe9, 0x60, 0x69, 0x68, 0xc9, 0x02, 0xc9, 0x0a, 0x69, 0x60, + 0xa9, 0x68, 0xc9, 0x02, 0xc9, 0x0a, 0xa9, 0x60, 0xe9, 0x68, 0xc9, 0x02, + 0xc9, 0x0a, 0xe9, 0x60, 0x2a, 0x61, 0x6a, 0x61, 0x28, 0x62, 0xaa, 0x61, + 0xea, 0x61, 0x6a, 0x62, 0x04, 0xf5, 0x0a, 0x70, 0x00, 0xf0, 0x49, 0xfa, + 0x04, 0xf5, 0x3d, 0x70, 0x00, 0x21, 0xff, 0xf7, 0xad, 0xff, 0x01, 0x21, + 0x01, 0x75, 0x31, 0xbd, 0x2d, 0xe9, 0xf8, 0x43, 0x80, 0x46, 0x08, 0xf5, + 0x00, 0x75, 0x00, 0x26, 0xa8, 0x6a, 0xc8, 0xf8, 0x00, 0x00, 0x08, 0xeb, + 0x86, 0x09, 0x09, 0xf5, 0x0b, 0x74, 0x09, 0xf1, 0x04, 0x00, 0x21, 0x68, + 0x01, 0x60, 0x09, 0xf1, 0xd4, 0x07, 0x21, 0x68, 0x39, 0x60, 0x76, 0x1c, + 0x61, 0x6e, 0x41, 0x66, 0x60, 0x6e, 0xa9, 0x6a, 0xf4, 0xf7, 0xee, 0xfd, + 0x78, 0x66, 0x60, 0x6e, 0xa9, 0x6a, 0x00, 0xf0, 0x23, 0xf8, 0x19, 0x2e, + 0xc9, 0xf8, 0x9c, 0x01, 0xe3, 0xd3, 0x08, 0xf1, 0xcc, 0x00, 0x4f, 0xf0, + 0x7e, 0x51, 0x00, 0x22, 0x01, 0x60, 0x42, 0x60, 0x08, 0xf5, 0x3e, 0x70, + 0x02, 0x68, 0x2a, 0x60, 0x42, 0x68, 0x6a, 0x60, 0x82, 0x68, 0xaa, 0x60, + 0xc0, 0x68, 0xe8, 0x60, 0x00, 0x20, 0x68, 0x61, 0x29, 0x62, 0x01, 0x20, + 0xa8, 0x61, 0x00, 0x20, 0xe8, 0x61, 0x68, 0x62, 0xbd, 0xe8, 0xf1, 0x83, + 0xd8, 0xf8, 0x58, 0x02, 0xda, 0xf8, 0x00, 0x10, 0x80, 0xf0, 0x00, 0x40, + 0xf4, 0xf7, 0xc2, 0xbd, 0x80, 0xb5, 0x01, 0x21, 0xfb, 0xf7, 0xd8, 0xff, + 0xbd, 0xe8, 0x04, 0x40, 0x74, 0x49, 0xf4, 0xf7, 0xc9, 0xbe, 0x00, 0x00, + 0x0a, 0xd7, 0x23, 0x3c, 0x2d, 0xe9, 0xfe, 0x4f, 0x04, 0x46, 0x04, 0xf1, + 0x14, 0x07, 0x07, 0xf5, 0xd0, 0x76, 0x01, 0x20, 0xb0, 0x62, 0x88, 0x46, + 0xe0, 0x68, 0x03, 0x21, 0x01, 0x62, 0x01, 0x22, 0x05, 0x21, 0x01, 0x60, + 0x20, 0x46, 0x39, 0x46, 0xfe, 0xf7, 0xe8, 0xfe, 0x30, 0x68, 0x00, 0x28, + 0x00, 0xf0, 0xc7, 0x80, 0x39, 0x46, 0x20, 0x46, 0xfe, 0xf7, 0x38, 0xfe, + 0x06, 0x46, 0x00, 0x20, 0x00, 0x90, 0x01, 0xab, 0x02, 0xaa, 0x39, 0x46, + 0x20, 0x46, 0xfe, 0xf7, 0xaf, 0xfd, 0xa0, 0x68, 0x00, 0xf5, 0x07, 0x77, + 0x3d, 0x68, 0x1d, 0xb9, 0x02, 0x98, 0x78, 0x60, 0x01, 0x98, 0x46, 0xe0, + 0x20, 0x68, 0x00, 0xf1, 0x88, 0x09, 0xd9, 0xf8, 0x0c, 0x00, 0x85, 0x42, + 0x23, 0xd2, 0x28, 0x46, 0xf4, 0xf7, 0xf0, 0xfc, 0x00, 0xf0, 0xb0, 0xf8, + 0x02, 0x99, 0xf4, 0xf7, 0xed, 0xfd, 0x81, 0x46, 0x68, 0x1c, 0xf4, 0xf7, + 0xe7, 0xfc, 0x01, 0x46, 0x48, 0x46, 0xf4, 0xf7, 0xf3, 0xfc, 0x78, 0x60, + 0x3d, 0x68, 0x28, 0x46, 0xf4, 0xf7, 0xde, 0xfc, 0xb9, 0x68, 0xf4, 0xf7, + 0x79, 0xfe, 0x01, 0x99, 0xf4, 0xf7, 0xda, 0xfd, 0x81, 0x46, 0x68, 0x1c, + 0xf4, 0xf7, 0xd4, 0xfc, 0x01, 0x46, 0x48, 0x46, 0xf4, 0xf7, 0xe0, 0xfc, + 0x1b, 0xe0, 0xd9, 0xf8, 0x08, 0x50, 0xfe, 0xf7, 0x0f, 0xfd, 0x00, 0xf0, + 0x8b, 0xf8, 0x82, 0x46, 0xff, 0xf7, 0x78, 0xfe, 0x51, 0x46, 0xf4, 0xf7, + 0xc5, 0xfd, 0x78, 0x60, 0x4f, 0xf0, 0x7e, 0x50, 0xd9, 0xf8, 0x08, 0x50, + 0xfe, 0xf7, 0x02, 0xfd, 0xb9, 0x68, 0xf4, 0xf7, 0x57, 0xfe, 0x81, 0x46, + 0x01, 0x98, 0xff, 0xf7, 0x68, 0xfe, 0xff, 0xf7, 0x13, 0xf9, 0xb8, 0x60, + 0x01, 0x2e, 0x18, 0xbf, 0x04, 0x2e, 0x07, 0xd1, 0x20, 0x68, 0xd0, 0xf8, + 0x88, 0x10, 0x34, 0x48, 0xf4, 0xf7, 0x46, 0xfe, 0x05, 0x46, 0x02, 0xe0, + 0x20, 0x68, 0xd0, 0xf8, 0x88, 0x50, 0x79, 0x68, 0x30, 0x48, 0xf4, 0xf7, + 0xa1, 0xfd, 0xd7, 0xf8, 0x08, 0x90, 0x01, 0x46, 0xf4, 0xf7, 0x38, 0xfe, + 0x83, 0x46, 0x48, 0x46, 0xff, 0xf7, 0x2a, 0xfd, 0xff, 0xf7, 0x35, 0xfc, + 0x4f, 0xf0, 0x7a, 0x5a, 0x51, 0x46, 0xf4, 0xf7, 0x2d, 0xfe, 0x81, 0x46, + 0x01, 0x20, 0x01, 0x2e, 0x18, 0xbf, 0x04, 0x2e, 0x03, 0xd1, 0x21, 0x68, + 0x88, 0x31, 0x49, 0x69, 0x02, 0xe0, 0x21, 0x68, 0x88, 0x31, 0x09, 0x69, + 0x88, 0x40, 0xf4, 0xf7, 0x75, 0xfc, 0xff, 0xf7, 0x30, 0xfe, 0x06, 0x46, + 0x02, 0x99, 0x1d, 0x48, 0xf4, 0xf7, 0x7a, 0xfd, 0x01, 0x46, 0xf4, 0xf7, + 0x13, 0xfe, 0x01, 0x99, 0x83, 0x46, 0x08, 0x46, 0xf4, 0xf7, 0x0e, 0xfe, + 0xff, 0xf7, 0x0f, 0xfc, 0x51, 0x46, 0xf4, 0xf7, 0x09, 0xfe, 0x01, 0x46, + 0x30, 0x46, 0xf4, 0xf7, 0xf3, 0xfd, 0x05, 0xd2, 0x08, 0x46, 0xff, 0xf7, + 0x2f, 0xff, 0xc8, 0xf8, 0x00, 0x00, 0x15, 0xe0, 0x21, 0x68, 0x38, 0x68, + 0x88, 0x31, 0xc9, 0x68, 0x88, 0x42, 0x03, 0xd2, 0x40, 0x1c, 0x38, 0x60, + 0x00, 0x20, 0x0c, 0xe0, 0x48, 0x46, 0xff, 0xf7, 0x1f, 0xff, 0xc8, 0xf8, + 0x00, 0x00, 0x29, 0x46, 0x48, 0x46, 0xf4, 0xf7, 0xd9, 0xfd, 0x38, 0xbf, + 0x01, 0x20, 0x00, 0xd3, 0x02, 0x20, 0xbd, 0xe8, 0xfe, 0x8f, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x42, 0x00, 0x00, 0x20, 0xc1, 0x71, 0x1d, 0x9e, 0x43, + 0x00, 0x00, 0x80, 0xbf, 0x79, 0x68, 0xf4, 0xf7, 0xd9, 0xbd, 0x00, 0x00, + 0x1a, 0x48, 0x01, 0x78, 0x09, 0x06, 0x00, 0xd4, 0x70, 0x47, 0x2d, 0xe9, + 0xf0, 0x41, 0x00, 0x78, 0x17, 0x4d, 0x00, 0xf0, 0x07, 0x04, 0x68, 0x78, + 0x84, 0x42, 0x01, 0xd1, 0x28, 0x78, 0x18, 0xbb, 0x0f, 0xf2, 0x5c, 0x00, + 0x13, 0x4f, 0x50, 0xf8, 0x24, 0x80, 0x4f, 0xf6, 0xff, 0x70, 0x38, 0x80, + 0x01, 0x26, 0x30, 0x46, 0xf4, 0xf7, 0x1e, 0xfc, 0x41, 0x46, 0xf4, 0xf7, + 0xb9, 0xfd, 0x0e, 0x49, 0xf4, 0xf7, 0x28, 0xfc, 0x01, 0x46, 0x0d, 0x48, + 0xf5, 0xf7, 0x29, 0xf8, 0x4f, 0xf0, 0x8f, 0x41, 0xf4, 0xf7, 0xae, 0xfd, + 0xf4, 0xf7, 0x18, 0xfe, 0x27, 0xf8, 0x16, 0x00, 0x76, 0x1c, 0x40, 0x2e, + 0xe7, 0xd3, 0x01, 0x20, 0x6c, 0x70, 0x28, 0x70, 0xbd, 0xe8, 0xf0, 0x81, + 0x13, 0x07, 0x00, 0x46, 0x96, 0xf3, 0x00, 0x20, 0x30, 0xf0, 0x00, 0x20, + 0x00, 0x00, 0xa0, 0x41, 0x00, 0x00, 0x20, 0x41, 0x00, 0x00, 0x80, 0xbe, + 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x80, 0xbf, 0x00, 0x00, 0x00, 0xc0, + 0x00, 0x00, 0x40, 0xc0, 0x00, 0x00, 0x80, 0xc0, 0x00, 0x00, 0xa0, 0xc0, + 0x00, 0x00, 0xc0, 0xc0, 0x80, 0xb5, 0x4f, 0xf0, 0x9e, 0x41, 0xf4, 0xf7, + 0x8b, 0xfe, 0x02, 0xd8, 0x6f, 0xf0, 0x00, 0x40, 0x02, 0xbd, 0x4d, 0x49, + 0xf4, 0xf7, 0x6a, 0xfd, 0x24, 0xbf, 0xbd, 0xe8, 0x02, 0x40, 0xf4, 0xf7, + 0xe3, 0xbd, 0x4f, 0xf0, 0x00, 0x40, 0x02, 0xbd, 0x38, 0xb5, 0x0c, 0x46, + 0xf4, 0xf7, 0xd2, 0xfb, 0x46, 0x49, 0xf4, 0xf7, 0x6d, 0xfd, 0x05, 0x46, + 0x20, 0x46, 0xf4, 0xf7, 0xcb, 0xfb, 0x01, 0x46, 0x28, 0x46, 0xf4, 0xf7, + 0xd7, 0xfb, 0x4f, 0xf0, 0x7e, 0x51, 0xf4, 0xf7, 0xc5, 0xfc, 0xbd, 0xe8, + 0x32, 0x40, 0xfb, 0xf7, 0x5d, 0xbc, 0x2d, 0xe9, 0xfe, 0x4f, 0x04, 0x46, + 0x0f, 0x46, 0x25, 0x68, 0x4f, 0xf0, 0x7c, 0x50, 0x29, 0x46, 0xf4, 0xf7, + 0x53, 0xfd, 0x29, 0x46, 0xf4, 0xf7, 0x50, 0xfd, 0x00, 0xf0, 0x70, 0xf8, + 0x81, 0x46, 0x28, 0x46, 0x49, 0x46, 0xf4, 0xf7, 0xbb, 0xfb, 0x4f, 0xf0, + 0x9d, 0x4b, 0x59, 0x46, 0xf4, 0xf7, 0x44, 0xfd, 0xff, 0xf7, 0xba, 0xff, + 0x38, 0x60, 0x4f, 0xf0, 0x7e, 0x58, 0x38, 0x1d, 0x00, 0x90, 0x68, 0x37, + 0x00, 0x25, 0xdf, 0xf8, 0xb4, 0xa0, 0x04, 0xeb, 0x85, 0x06, 0x4f, 0xf0, + 0x7c, 0x51, 0xb0, 0x6e, 0xf4, 0xf7, 0x32, 0xfd, 0xb1, 0x6e, 0xf4, 0xf7, + 0x2f, 0xfd, 0x00, 0xf0, 0x4f, 0xf8, 0x71, 0x68, 0xf4, 0xf7, 0x9c, 0xfb, + 0x59, 0x46, 0xf4, 0xf7, 0x27, 0xfd, 0x49, 0x46, 0xf4, 0xf7, 0x96, 0xfb, + 0x41, 0x46, 0xf4, 0xf7, 0x21, 0xfd, 0xff, 0xf7, 0x97, 0xff, 0x00, 0x99, + 0x41, 0xf8, 0x25, 0x00, 0x51, 0x46, 0xb0, 0x6e, 0xf4, 0xf7, 0x18, 0xfd, + 0x71, 0x68, 0xf4, 0xf7, 0x87, 0xfb, 0x59, 0x46, 0xf4, 0xf7, 0x12, 0xfd, + 0x49, 0x46, 0xf4, 0xf7, 0x81, 0xfb, 0x41, 0x46, 0xf4, 0xf7, 0x0c, 0xfd, + 0xff, 0xf7, 0x82, 0xff, 0x47, 0xf8, 0x25, 0x00, 0x51, 0x46, 0x40, 0x46, + 0xf4, 0xf7, 0x04, 0xfd, 0x6d, 0x1c, 0x18, 0x2d, 0x80, 0x46, 0xc6, 0xdb, + 0x60, 0x6e, 0x49, 0x46, 0xf4, 0xf7, 0xfc, 0xfc, 0x01, 0x46, 0x58, 0x46, + 0xf4, 0xf7, 0x6a, 0xfb, 0xff, 0xf7, 0x6e, 0xff, 0x00, 0x99, 0x08, 0x66, + 0x00, 0x20, 0x38, 0x66, 0x02, 0x98, 0x00, 0x68, 0x30, 0xb9, 0x01, 0x99, + 0x00, 0x98, 0x03, 0xb0, 0xbd, 0xe8, 0xf0, 0x4f, 0x00, 0xf0, 0x42, 0xb9, + 0xbd, 0xe8, 0xf7, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xce, + 0x00, 0x00, 0xc0, 0x41, 0x00, 0x00, 0x80, 0xbf, 0x01, 0x46, 0x4f, 0xf0, + 0x7e, 0x50, 0xf4, 0xf7, 0xc9, 0xbb, 0x00, 0x21, 0x01, 0x60, 0x00, 0xeb, + 0x81, 0x02, 0x4f, 0xf0, 0x7e, 0x53, 0x53, 0x60, 0x49, 0x1c, 0x00, 0x23, + 0x19, 0x29, 0x93, 0x66, 0xf5, 0xd3, 0x70, 0x47, 0xf8, 0xb5, 0x0f, 0x46, + 0xd7, 0xf8, 0x00, 0xe0, 0xd7, 0xf8, 0x04, 0xc0, 0x06, 0x46, 0x82, 0xfb, + 0x0e, 0x45, 0x83, 0xfb, 0x0c, 0x01, 0x20, 0x1a, 0x65, 0xeb, 0x01, 0x01, + 0x82, 0xfb, 0x0c, 0x45, 0xc3, 0xfb, 0x0e, 0x45, 0x32, 0x68, 0x73, 0x68, + 0xc0, 0x0d, 0x40, 0xea, 0x41, 0x20, 0x81, 0x18, 0x31, 0x60, 0xe4, 0x0d, + 0x44, 0xea, 0x45, 0x24, 0xe1, 0x18, 0x71, 0x60, 0x10, 0x1a, 0x38, 0x60, + 0x18, 0x1b, 0x78, 0x60, 0xf1, 0xbd, 0x10, 0xb5, 0x04, 0x46, 0x00, 0xf0, + 0x5b, 0xf8, 0x04, 0xf1, 0x08, 0x01, 0xff, 0xf7, 0xd5, 0xff, 0x00, 0xf0, + 0x55, 0xf8, 0x04, 0xf1, 0x18, 0x01, 0x04, 0xf1, 0x10, 0x00, 0xff, 0xf7, + 0xcd, 0xff, 0x00, 0xf0, 0x4d, 0xf8, 0x04, 0xf1, 0x10, 0x01, 0x20, 0x46, + 0xff, 0xf7, 0xc6, 0xff, 0x04, 0xf1, 0x18, 0x01, 0x04, 0xf1, 0x08, 0x00, + 0xbd, 0xe8, 0x10, 0x40, 0x4f, 0xf4, 0x00, 0x03, 0x00, 0x22, 0xbb, 0xe7, + 0x30, 0xb5, 0x85, 0xb0, 0x04, 0x46, 0x0d, 0x46, 0x68, 0x46, 0x0f, 0xf2, + 0x1c, 0x31, 0x10, 0x22, 0xf7, 0xf7, 0xf8, 0xfb, 0x00, 0x20, 0x10, 0xf8, + 0x0d, 0x10, 0x54, 0xf8, 0x21, 0x10, 0x45, 0xf8, 0x20, 0x10, 0x40, 0x1c, + 0x10, 0x28, 0xf6, 0xd3, 0x28, 0x46, 0xff, 0xf7, 0xc8, 0xff, 0x05, 0xf1, + 0x20, 0x00, 0xff, 0xf7, 0xc4, 0xff, 0x00, 0xf0, 0x21, 0xf8, 0x05, 0xf1, + 0x20, 0x01, 0x28, 0x46, 0xff, 0xf7, 0x9a, 0xff, 0xb1, 0x4c, 0x23, 0x46, + 0x22, 0x46, 0x05, 0xf1, 0x28, 0x01, 0x05, 0xf1, 0x08, 0x00, 0xff, 0xf7, + 0x91, 0xff, 0x4f, 0xf4, 0x00, 0x03, 0x00, 0x22, 0x05, 0xf1, 0x30, 0x01, + 0x05, 0xf1, 0x10, 0x00, 0xff, 0xf7, 0x88, 0xff, 0x23, 0x46, 0xa9, 0x4a, + 0x05, 0xf1, 0x38, 0x01, 0x05, 0xf1, 0x18, 0x00, 0xff, 0xf7, 0x80, 0xff, + 0x05, 0xb0, 0x30, 0xbd, 0x00, 0x23, 0x4f, 0xf4, 0x00, 0x02, 0x70, 0x47, + 0x2d, 0xe9, 0xf3, 0x43, 0x87, 0xb0, 0xff, 0xf7, 0xb9, 0xff, 0x08, 0x98, + 0x00, 0xf1, 0x40, 0x01, 0x07, 0x98, 0x08, 0x30, 0xff, 0xf7, 0xb2, 0xff, + 0x08, 0x98, 0x00, 0xf1, 0x80, 0x01, 0x07, 0x98, 0x10, 0x30, 0xff, 0xf7, + 0xab, 0xff, 0x00, 0x22, 0x08, 0x98, 0x07, 0x99, 0x50, 0xf8, 0x22, 0x00, + 0x41, 0xf8, 0x22, 0x00, 0x52, 0x1c, 0x30, 0x2a, 0xf6, 0xd3, 0x03, 0x20, + 0x4f, 0xf4, 0x00, 0x0e, 0x4f, 0xf0, 0x00, 0x08, 0x00, 0x27, 0x02, 0x90, + 0x00, 0x22, 0x07, 0x98, 0x50, 0xf8, 0x22, 0xc0, 0x00, 0xeb, 0x82, 0x01, + 0x08, 0x1d, 0x03, 0x68, 0xc4, 0x6b, 0x05, 0x6c, 0xc6, 0x6f, 0x01, 0x96, + 0xd1, 0xf8, 0x84, 0x10, 0x00, 0x91, 0x2f, 0xb9, 0x01, 0x98, 0x00, 0x19, + 0x00, 0xeb, 0x0c, 0x06, 0x48, 0x19, 0x52, 0xe0, 0x86, 0x48, 0x80, 0xfb, + 0x0e, 0x01, 0xcd, 0xe9, 0x04, 0x01, 0x85, 0x48, 0x80, 0xfb, 0x0e, 0x69, + 0x82, 0x48, 0x80, 0xfb, 0x08, 0x01, 0x30, 0x1a, 0x69, 0xeb, 0x01, 0x01, + 0xc0, 0x0d, 0x40, 0xea, 0x41, 0x2e, 0xdd, 0xe9, 0x04, 0x01, 0x7e, 0x4e, + 0xc6, 0xfb, 0x08, 0x01, 0xc0, 0x0d, 0x40, 0xea, 0x41, 0x28, 0x84, 0xfb, + 0x0e, 0x69, 0x85, 0xfb, 0x08, 0x01, 0x30, 0x1a, 0x69, 0xeb, 0x01, 0x01, + 0xc0, 0x0d, 0x40, 0xea, 0x41, 0x20, 0x84, 0x44, 0x85, 0xfb, 0x0e, 0x01, + 0xc4, 0xfb, 0x08, 0x01, 0xc0, 0x0d, 0x40, 0xea, 0x41, 0x20, 0xc3, 0x18, + 0x8e, 0xfb, 0x0e, 0x45, 0x88, 0xfb, 0x08, 0x01, 0x20, 0x1a, 0x65, 0xeb, + 0x01, 0x01, 0xc0, 0x0d, 0x40, 0xea, 0x41, 0x24, 0x88, 0xfb, 0x0e, 0x01, + 0x80, 0x0d, 0x40, 0xea, 0x81, 0x25, 0x01, 0x98, 0x80, 0xfb, 0x04, 0x69, + 0x00, 0x98, 0x80, 0xfb, 0x05, 0x01, 0x30, 0x1a, 0x69, 0xeb, 0x01, 0x01, + 0xc0, 0x0d, 0x40, 0xea, 0x41, 0x20, 0x00, 0xeb, 0x0c, 0x06, 0x00, 0x98, + 0xdd, 0xf8, 0x04, 0x90, 0x80, 0xfb, 0x04, 0x01, 0xc9, 0xfb, 0x05, 0x01, + 0xc0, 0x0d, 0x40, 0xea, 0x41, 0x20, 0x08, 0x99, 0x41, 0xf8, 0x27, 0x60, + 0x92, 0x1c, 0x08, 0x99, 0x01, 0xeb, 0x87, 0x01, 0xbf, 0x1c, 0xc0, 0x18, + 0x10, 0x2a, 0x48, 0x60, 0x8b, 0xd3, 0x02, 0x98, 0x40, 0x1e, 0x02, 0x90, + 0x86, 0xd1, 0x09, 0xb0, 0xbd, 0xe8, 0xf0, 0x83, 0x2d, 0xe9, 0xf3, 0x4f, + 0x87, 0xb0, 0x4f, 0xf4, 0x00, 0x02, 0x4f, 0xf0, 0x00, 0x0e, 0x00, 0x23, + 0x07, 0x98, 0x4f, 0xea, 0xee, 0x79, 0xde, 0xf5, 0x00, 0x0a, 0x50, 0xf8, + 0x23, 0x00, 0x69, 0xeb, 0x49, 0x07, 0xc1, 0x17, 0xaa, 0xfb, 0x00, 0x45, + 0x0a, 0xfb, 0x01, 0x55, 0x07, 0xfb, 0x00, 0x55, 0xcd, 0xe9, 0x04, 0x45, + 0x07, 0x99, 0x03, 0xf1, 0x19, 0x06, 0x51, 0xf8, 0x26, 0x60, 0x04, 0x46, + 0x50, 0x46, 0x39, 0x46, 0xf5, 0x17, 0xa0, 0xfb, 0x06, 0xa7, 0x00, 0xfb, + 0x05, 0x77, 0x1e, 0xf5, 0x00, 0x00, 0x01, 0xfb, 0x06, 0x77, 0x49, 0xf1, + 0x00, 0x01, 0xcd, 0xe9, 0x02, 0x01, 0xc2, 0xfb, 0x04, 0xa7, 0x07, 0x98, + 0x59, 0x42, 0x00, 0xeb, 0x81, 0x00, 0x50, 0xf8, 0x60, 0xcf, 0x40, 0x6e, + 0xcc, 0xf1, 0x00, 0x01, 0xdd, 0xe9, 0x02, 0x45, 0xc2, 0xfb, 0x01, 0xa7, + 0x40, 0x42, 0xd0, 0x46, 0xb9, 0x46, 0xc1, 0x17, 0xa4, 0xfb, 0x00, 0xa7, + 0x04, 0xfb, 0x01, 0x77, 0x05, 0xfb, 0x00, 0x77, 0x4d, 0x46, 0x18, 0xeb, + 0x0a, 0x04, 0x7d, 0x41, 0xdd, 0xe9, 0x04, 0xa7, 0x71, 0x42, 0xc2, 0xfb, + 0x01, 0xa7, 0xcd, 0xe9, 0x00, 0xa7, 0x4f, 0xea, 0xec, 0x71, 0xdd, 0xe9, + 0x02, 0xa7, 0xaa, 0xfb, 0x0c, 0x6b, 0x0a, 0xfb, 0x01, 0xbb, 0x07, 0xfb, + 0x0c, 0xbb, 0xdd, 0xe9, 0x00, 0x17, 0x11, 0xeb, 0x06, 0x0a, 0x47, 0xeb, + 0x0b, 0x07, 0xc2, 0xfb, 0x00, 0xa7, 0x4f, 0xea, 0xda, 0x50, 0x40, 0xea, + 0x47, 0x21, 0x21, 0x48, 0xff, 0x15, 0xa0, 0xfb, 0x01, 0x89, 0x00, 0xfb, + 0x07, 0x99, 0x4f, 0xea, 0xd8, 0x50, 0x40, 0xea, 0x49, 0x21, 0x08, 0x98, + 0xdf, 0xf8, 0x6c, 0xa0, 0x40, 0xf8, 0x33, 0x10, 0xe4, 0x0d, 0x44, 0xea, + 0x45, 0x24, 0xed, 0x15, 0xaa, 0xfb, 0x04, 0x01, 0x0a, 0xfb, 0x05, 0x11, + 0xc0, 0x0d, 0x40, 0xea, 0x41, 0x20, 0x08, 0x99, 0x01, 0xeb, 0xc3, 0x01, + 0x5b, 0x1c, 0x48, 0x60, 0x12, 0x49, 0x13, 0x48, 0x81, 0xfb, 0x02, 0x45, + 0xc0, 0xfb, 0x0e, 0x45, 0x06, 0x46, 0xce, 0xf1, 0x00, 0x00, 0x81, 0xfb, + 0x00, 0x01, 0xc6, 0xfb, 0x02, 0x01, 0xc0, 0x0d, 0xe4, 0x0d, 0x18, 0x2b, + 0x40, 0xea, 0x41, 0x22, 0x44, 0xea, 0x45, 0x2e, 0xff, 0xf4, 0x6a, 0xaf, + 0x07, 0x99, 0x08, 0x98, 0x09, 0xb0, 0xbd, 0xe8, 0xf0, 0x4f, 0xbb, 0xe6, + 0x7a, 0x82, 0x5a, 0x00, 0x86, 0x7d, 0xa5, 0xff, 0xfc, 0x20, 0x21, 0x00, + 0x75, 0xa3, 0x7b, 0x00, 0xab, 0xaa, 0x02, 0x00, 0x15, 0xb5, 0x10, 0x00, + 0xaa, 0xe7, 0x7e, 0x00, 0x00, 0x01, 0x18, 0x19, 0x0c, 0x0d, 0x24, 0x25, + 0x06, 0x07, 0x1e, 0x1f, 0x12, 0x13, 0x2a, 0x2b, 0x2d, 0xe9, 0xf0, 0x4f, + 0x04, 0x46, 0x8b, 0xb0, 0x00, 0x20, 0x20, 0x77, 0x04, 0xf1, 0x1d, 0x05, + 0x60, 0x69, 0x00, 0xf1, 0x68, 0x01, 0x00, 0x1d, 0x07, 0x90, 0x06, 0x91, + 0x04, 0xf5, 0xe8, 0x70, 0x02, 0x90, 0x04, 0xf5, 0x24, 0x70, 0x01, 0x90, + 0x04, 0xf1, 0x50, 0x00, 0x0a, 0x90, 0x01, 0x20, 0xa1, 0x68, 0x46, 0x42, + 0x01, 0xeb, 0x80, 0x02, 0x01, 0xeb, 0x86, 0x01, 0x13, 0x6e, 0xd1, 0xf8, + 0xc0, 0x60, 0x16, 0x66, 0xc1, 0xf8, 0xc0, 0x30, 0x40, 0x1c, 0xd2, 0xf8, + 0x20, 0x31, 0xd1, 0xf8, 0x80, 0x61, 0xc2, 0xf8, 0x20, 0x61, 0x0c, 0x28, + 0xc1, 0xf8, 0x80, 0x31, 0xe8, 0xdb, 0x00, 0x20, 0x28, 0x70, 0x01, 0x26, + 0x02, 0x99, 0x08, 0x60, 0x4f, 0xf0, 0x42, 0x58, 0x01, 0x99, 0x08, 0x60, + 0x20, 0x69, 0xf0, 0x40, 0x00, 0xf0, 0x01, 0x00, 0x70, 0x55, 0xa7, 0x68, + 0x57, 0xf8, 0x26, 0x00, 0xf4, 0xf7, 0x02, 0xf9, 0x00, 0xf0, 0x42, 0xfa, + 0x02, 0x99, 0x41, 0xf8, 0x26, 0x00, 0x07, 0xeb, 0x86, 0x00, 0xd0, 0xf8, + 0xc0, 0x00, 0xf4, 0xf7, 0xf7, 0xf8, 0x00, 0xf0, 0x37, 0xfa, 0x01, 0x99, + 0x41, 0xf8, 0x26, 0x00, 0xa9, 0x1b, 0xe0, 0x68, 0xf0, 0x40, 0x00, 0xf0, + 0x01, 0x00, 0x81, 0xf8, 0x30, 0x00, 0xa0, 0x68, 0x00, 0xeb, 0x86, 0x07, + 0x38, 0x6e, 0xf4, 0xf7, 0xe5, 0xf8, 0x00, 0xf0, 0x25, 0xfa, 0x02, 0x99, + 0x01, 0xeb, 0x86, 0x01, 0x08, 0x66, 0xd7, 0xf8, 0x20, 0x01, 0xf4, 0xf7, + 0xdb, 0xf8, 0x00, 0xf0, 0x1b, 0xfa, 0x01, 0x99, 0x01, 0xeb, 0x86, 0x01, + 0x76, 0x1c, 0x18, 0x2e, 0x08, 0x66, 0xc5, 0xdb, 0x01, 0x22, 0xdf, 0xf8, + 0x00, 0x08, 0x01, 0x46, 0x40, 0x08, 0x49, 0x08, 0xc3, 0x07, 0x5c, 0xbf, + 0x00, 0x23, 0x53, 0x55, 0xcb, 0x07, 0x03, 0xd4, 0xae, 0x1a, 0x00, 0x23, + 0x86, 0xf8, 0x30, 0x30, 0x52, 0x1c, 0x18, 0x2a, 0xf0, 0xdb, 0x00, 0x27, + 0x03, 0xe0, 0x00, 0x2f, 0x18, 0xbf, 0x18, 0x2f, 0x02, 0xd1, 0x4f, 0xf0, + 0xff, 0x39, 0x65, 0xe0, 0x78, 0x5d, 0x00, 0x28, 0x62, 0xd0, 0x01, 0x98, + 0x50, 0xf8, 0x27, 0xa0, 0x02, 0x98, 0x50, 0xf8, 0x27, 0xb0, 0x58, 0x46, + 0x59, 0x46, 0xf4, 0xf7, 0x51, 0xfa, 0x00, 0x90, 0x51, 0x46, 0x50, 0x46, + 0xf4, 0xf7, 0x4c, 0xfa, 0x00, 0x99, 0xf4, 0xf7, 0xad, 0xf9, 0xb9, 0xf1, + 0x00, 0x0f, 0x0e, 0xd5, 0x06, 0x46, 0x58, 0x46, 0x00, 0x21, 0xf4, 0xf7, + 0x21, 0xfa, 0xb9, 0x46, 0x08, 0xbf, 0x88, 0x46, 0x44, 0xd0, 0x50, 0x46, + 0x59, 0x46, 0xf4, 0xf7, 0xab, 0xf8, 0x80, 0x46, 0x3e, 0xe0, 0x00, 0x90, + 0x00, 0x21, 0x58, 0x46, 0xf4, 0xf7, 0x12, 0xfa, 0x08, 0xbf, 0x8a, 0x46, + 0x04, 0xd0, 0x50, 0x46, 0x59, 0x46, 0xf4, 0xf7, 0x9d, 0xf8, 0x82, 0x46, + 0x00, 0x98, 0x31, 0x46, 0xf4, 0xf7, 0x98, 0xf8, 0xf4, 0xf7, 0xca, 0xf9, + 0xdf, 0xf8, 0x58, 0x17, 0xf4, 0xf7, 0x84, 0xf9, 0x06, 0x46, 0x50, 0x46, + 0x41, 0x46, 0xf4, 0xf7, 0x0b, 0xf9, 0x80, 0x46, 0x30, 0x46, 0x31, 0x46, + 0xf4, 0xf7, 0x16, 0xfa, 0x06, 0x46, 0x40, 0x46, 0x00, 0xf0, 0xac, 0xf9, + 0x31, 0x46, 0xf4, 0xf7, 0x73, 0xf9, 0xa7, 0xeb, 0x09, 0x0b, 0x06, 0x46, + 0x0b, 0xfb, 0x0b, 0xf0, 0xf4, 0xf7, 0x60, 0xf8, 0x01, 0x46, 0x30, 0x46, + 0xf4, 0xf7, 0x76, 0xf8, 0xdf, 0xf8, 0x1c, 0x17, 0xf4, 0xf7, 0x08, 0xfb, + 0x03, 0xd8, 0x00, 0x20, 0x09, 0xf8, 0x05, 0x00, 0x78, 0x55, 0xb9, 0x46, + 0x00, 0x9e, 0xd0, 0x46, 0x7f, 0x1c, 0x30, 0x2f, 0x8f, 0xdb, 0x00, 0x20, + 0x00, 0x21, 0x4a, 0x5d, 0x01, 0x2a, 0x08, 0xbf, 0x40, 0x1c, 0x49, 0x1c, + 0x30, 0x29, 0xf8, 0xdb, 0xa1, 0x69, 0x89, 0x78, 0x88, 0x42, 0x03, 0xd2, + 0x20, 0x7f, 0x40, 0xf0, 0x02, 0x00, 0x20, 0x77, 0x00, 0x26, 0x00, 0x20, + 0x02, 0x21, 0x4a, 0x5d, 0x00, 0x2a, 0x1e, 0xbf, 0x6a, 0x1a, 0x92, 0xf8, + 0x30, 0x20, 0x00, 0x2a, 0x02, 0xd0, 0x01, 0x22, 0x8a, 0x40, 0x10, 0x43, + 0x49, 0x1c, 0x18, 0x29, 0xf1, 0xdb, 0x00, 0x21, 0x4f, 0xf4, 0x80, 0x72, + 0x80, 0x23, 0x4f, 0xf0, 0x17, 0x08, 0x18, 0x42, 0x1c, 0xbf, 0x1e, 0x43, + 0x49, 0x1c, 0x0c, 0x29, 0x07, 0xd0, 0x10, 0x42, 0x03, 0xd0, 0x16, 0x43, + 0x49, 0x1c, 0x0c, 0x29, 0x01, 0xd0, 0x5b, 0x10, 0x52, 0x00, 0xb8, 0xf1, + 0x01, 0x08, 0xee, 0xd1, 0x04, 0x29, 0x07, 0xda, 0x68, 0x78, 0x00, 0x28, + 0x1e, 0xbf, 0x95, 0xf8, 0x2f, 0x00, 0x00, 0x28, 0x46, 0xf0, 0x01, 0x06, + 0x00, 0x27, 0x4f, 0xf0, 0x01, 0x09, 0x19, 0xf8, 0x05, 0x00, 0x00, 0x28, + 0x1e, 0xbf, 0xa5, 0xeb, 0x09, 0x00, 0x90, 0xf8, 0x30, 0x00, 0x00, 0x28, + 0xc9, 0xf1, 0x30, 0x0a, 0x00, 0xf0, 0x93, 0x80, 0x01, 0x98, 0x02, 0x99, + 0x50, 0xf8, 0x29, 0x00, 0x51, 0xf8, 0x29, 0x10, 0xf4, 0xf7, 0x0c, 0xf8, + 0x00, 0x90, 0x02, 0x99, 0x01, 0x98, 0x51, 0xf8, 0x2a, 0x10, 0x50, 0xf8, + 0x2a, 0x00, 0xf4, 0xf7, 0x03, 0xf8, 0x83, 0x46, 0x4f, 0xf4, 0x80, 0x10, + 0x05, 0x90, 0x4f, 0xf0, 0x93, 0x40, 0x00, 0x99, 0xf4, 0xf7, 0x88, 0xf9, + 0xf4, 0xf7, 0xf2, 0xf9, 0x00, 0xf0, 0x14, 0xf9, 0x00, 0xf0, 0x1f, 0xf9, + 0x00, 0xf0, 0x20, 0xf9, 0x00, 0xf0, 0x22, 0xf9, 0x09, 0x90, 0x59, 0x46, + 0x00, 0xf0, 0x03, 0xf9, 0xf4, 0xf7, 0xe4, 0xf9, 0x00, 0xf0, 0x06, 0xf9, + 0x00, 0xf0, 0x11, 0xf9, 0x00, 0xf0, 0x12, 0xf9, 0x00, 0xf0, 0x14, 0xf9, + 0x08, 0x90, 0x01, 0x98, 0x50, 0xf8, 0x29, 0xb0, 0x02, 0x98, 0x50, 0xf8, + 0x29, 0x10, 0x08, 0x46, 0xf4, 0xf7, 0x66, 0xf9, 0x00, 0x90, 0x59, 0x46, + 0x58, 0x46, 0xf4, 0xf7, 0x61, 0xf9, 0x00, 0x99, 0xf4, 0xf7, 0xc2, 0xf8, + 0x00, 0x90, 0x01, 0x98, 0x50, 0xf8, 0x2a, 0xb0, 0x02, 0x98, 0x50, 0xf8, + 0x2a, 0x10, 0x08, 0x46, 0xf4, 0xf7, 0x54, 0xf9, 0x82, 0x46, 0x58, 0x46, + 0x59, 0x46, 0xf4, 0xf7, 0x4f, 0xf9, 0x51, 0x46, 0xf4, 0xf7, 0xb0, 0xf8, + 0x82, 0x46, 0x00, 0x98, 0xf4, 0xf7, 0xee, 0xf8, 0x50, 0x46, 0xf4, 0xf7, + 0xeb, 0xf8, 0x08, 0x98, 0x09, 0x99, 0xf4, 0xf7, 0x31, 0xf8, 0x4f, 0xf0, + 0x7c, 0x51, 0xf4, 0xf7, 0x3d, 0xf9, 0x06, 0x99, 0x41, 0xf8, 0x29, 0x00, + 0x51, 0x46, 0x00, 0x98, 0xf4, 0xf7, 0x36, 0xf9, 0xf4, 0xf7, 0xda, 0xf8, + 0xf4, 0xf7, 0xd8, 0xf8, 0x83, 0x46, 0x00, 0x98, 0xf4, 0xf7, 0xd4, 0xf8, + 0x50, 0x46, 0xf4, 0xf7, 0xd1, 0xf8, 0x07, 0x98, 0x40, 0xf8, 0x29, 0xb0, + 0x08, 0x99, 0x09, 0x98, 0xf4, 0xf7, 0x88, 0xf8, 0x4f, 0xf0, 0x7c, 0x51, + 0xf4, 0xf7, 0x20, 0xf9, 0x0a, 0x99, 0x41, 0xf8, 0x29, 0x00, 0x26, 0xfa, + 0x09, 0xf1, 0xc9, 0x07, 0x09, 0xd5, 0x41, 0x46, 0xf4, 0xf7, 0x7a, 0xf8, + 0x80, 0x46, 0x4f, 0xf0, 0x7e, 0x50, 0x39, 0x46, 0xf4, 0xf7, 0x74, 0xf8, + 0x07, 0x46, 0x09, 0xf1, 0x01, 0x09, 0xb9, 0xf1, 0x18, 0x0f, 0xff, 0xf6, + 0x5a, 0xaf, 0x38, 0x46, 0x00, 0x21, 0xf4, 0xf7, 0xe5, 0xf8, 0x08, 0xbf, + 0x00, 0x26, 0x04, 0xd0, 0x40, 0x46, 0x39, 0x46, 0xf3, 0xf7, 0x70, 0xff, + 0x06, 0x46, 0x60, 0x69, 0x06, 0x60, 0x4f, 0xf0, 0x01, 0x08, 0xc8, 0xf1, + 0x30, 0x0a, 0x18, 0xf8, 0x05, 0x00, 0x1a, 0xf8, 0x05, 0x10, 0x00, 0x28, + 0x02, 0xd0, 0x00, 0x29, 0x4d, 0xd1, 0x01, 0xe0, 0x00, 0x29, 0x4a, 0xd0, + 0x40, 0xb1, 0x02, 0x98, 0x50, 0xf8, 0x28, 0x70, 0x01, 0x98, 0x50, 0xf8, + 0x28, 0x00, 0x80, 0xf0, 0x00, 0x49, 0x07, 0xe0, 0x08, 0x00, 0x05, 0xd0, + 0x02, 0x98, 0x50, 0xf8, 0x2a, 0x70, 0x01, 0x98, 0x50, 0xf8, 0x2a, 0x90, + 0x48, 0x46, 0x39, 0x46, 0xf3, 0xf7, 0x48, 0xff, 0x01, 0x46, 0x06, 0x98, + 0x40, 0xf8, 0x28, 0x10, 0x00, 0xf0, 0x59, 0xf8, 0xf4, 0xf7, 0x3a, 0xf9, + 0x00, 0xf0, 0x5c, 0xf8, 0x00, 0xf0, 0x67, 0xf8, 0x00, 0xf0, 0x68, 0xf8, + 0x00, 0xf0, 0x6a, 0xf8, 0x01, 0x46, 0x06, 0x98, 0x40, 0xf8, 0x28, 0x10, + 0x18, 0xf8, 0x05, 0x00, 0x18, 0xb1, 0x30, 0x46, 0xf4, 0xf7, 0x20, 0xf8, + 0x06, 0xe0, 0x1a, 0xf8, 0x05, 0x00, 0x30, 0xb1, 0x08, 0x46, 0x31, 0x46, + 0xf3, 0xf7, 0xa4, 0xff, 0x06, 0x99, 0x41, 0xf8, 0x28, 0x00, 0x38, 0x46, + 0x00, 0xf0, 0x45, 0xf8, 0x82, 0x46, 0x48, 0x46, 0x49, 0x46, 0xf4, 0xf7, + 0xa9, 0xf8, 0x51, 0x46, 0xf4, 0xf7, 0x0a, 0xf8, 0xf4, 0xf7, 0x4a, 0xf8, + 0x07, 0x99, 0x41, 0xf8, 0x28, 0x00, 0x08, 0xf1, 0x01, 0x08, 0xb8, 0xf1, + 0x18, 0x0f, 0xa2, 0xdb, 0xa0, 0x69, 0x01, 0x90, 0x04, 0xf5, 0x88, 0x73, + 0x04, 0xf5, 0x54, 0x70, 0x00, 0x90, 0x04, 0xf1, 0x50, 0x02, 0x60, 0x69, + 0x04, 0xf1, 0x1d, 0x01, 0x00, 0xf0, 0x36, 0xf8, 0x00, 0x24, 0x07, 0x98, + 0x50, 0xf8, 0x24, 0x20, 0x10, 0x46, 0x00, 0x21, 0xf4, 0xf7, 0x66, 0xf8, + 0x4f, 0xf0, 0x7e, 0x50, 0x1c, 0xbf, 0x11, 0x46, 0xf3, 0xf7, 0xf2, 0xfe, + 0x07, 0x99, 0x41, 0xf8, 0x24, 0x00, 0x64, 0x1c, 0x19, 0x2c, 0xec, 0xdb, + 0x0b, 0xb0, 0xbd, 0xe8, 0xf0, 0x8f, 0x4f, 0xf4, 0x80, 0x10, 0x05, 0x90, + 0x4f, 0xf0, 0x93, 0x40, 0xf4, 0xf7, 0x70, 0xb8, 0x04, 0x90, 0x03, 0xab, + 0x00, 0x20, 0x03, 0x90, 0x05, 0xaa, 0x04, 0xa9, 0x8b, 0xe1, 0x39, 0x46, + 0xf4, 0xf7, 0x66, 0xb8, 0x41, 0x46, 0xf4, 0xf7, 0x63, 0xb8, 0x03, 0x98, + 0xf3, 0xf7, 0xb8, 0xbe, 0x4f, 0xf0, 0x56, 0x51, 0xf4, 0xf7, 0x5c, 0xb8, + 0xdf, 0xf8, 0xd0, 0x13, 0xf4, 0xf7, 0x58, 0xb8, 0x2d, 0xe9, 0xf0, 0x4f, + 0x9d, 0xb0, 0x0c, 0x46, 0x00, 0xf1, 0x68, 0x01, 0x00, 0x1d, 0x02, 0x91, + 0x01, 0x90, 0x90, 0x46, 0x9a, 0x46, 0x00, 0x20, 0x00, 0x21, 0x48, 0xf8, + 0x20, 0x10, 0x4a, 0xf8, 0x20, 0x10, 0x40, 0x1c, 0x30, 0x28, 0xf8, 0xdb, + 0x01, 0x20, 0x02, 0x99, 0x51, 0xf8, 0x20, 0x10, 0x81, 0xf0, 0x00, 0x41, + 0x48, 0xf8, 0x20, 0x10, 0x41, 0x42, 0x02, 0x9a, 0x52, 0xf8, 0x20, 0x20, + 0x08, 0xeb, 0x81, 0x03, 0x0a, 0xeb, 0x81, 0x01, 0xc3, 0xf8, 0xc0, 0x20, + 0x01, 0x9a, 0x52, 0xf8, 0x20, 0x20, 0x4a, 0xf8, 0x20, 0x20, 0x01, 0x9a, + 0x52, 0xf8, 0x20, 0x20, 0xc1, 0xf8, 0xc0, 0x20, 0x40, 0x1c, 0x18, 0x28, + 0xe1, 0xdb, 0x4f, 0xf0, 0x18, 0x0b, 0x01, 0x20, 0x01, 0x5d, 0x01, 0x29, + 0x1e, 0xbf, 0x21, 0x1a, 0x91, 0xf8, 0x30, 0x10, 0x01, 0x29, 0x01, 0xd1, + 0x83, 0x46, 0x02, 0xe0, 0x40, 0x1c, 0x18, 0x28, 0xf2, 0xdb, 0x60, 0x78, + 0x00, 0x28, 0x1c, 0xbf, 0x94, 0xf8, 0x2f, 0x10, 0x00, 0x29, 0x21, 0xd1, + 0x01, 0x28, 0x04, 0xbf, 0x94, 0xf8, 0x2f, 0x10, 0x00, 0x29, 0x03, 0xd1, + 0x02, 0x20, 0x84, 0xf8, 0x2f, 0x00, 0x17, 0xe0, 0x00, 0x28, 0x04, 0xbf, + 0x94, 0xf8, 0x2f, 0x00, 0x01, 0x28, 0x02, 0xd1, 0x02, 0x20, 0x60, 0x70, + 0x0e, 0xe0, 0x02, 0x20, 0x60, 0x70, 0x01, 0x98, 0x50, 0xf8, 0x2b, 0x00, + 0xca, 0xf8, 0x04, 0x00, 0x02, 0x20, 0x84, 0xf8, 0x2f, 0x00, 0x01, 0x98, + 0x50, 0xf8, 0x2b, 0x00, 0xca, 0xf8, 0xbc, 0x00, 0x05, 0x20, 0x26, 0x9f, + 0x00, 0xf0, 0x00, 0xf9, 0x00, 0xf0, 0xf9, 0xf8, 0x00, 0x26, 0x07, 0xf1, + 0x84, 0x05, 0x4f, 0xf0, 0x7e, 0x59, 0x03, 0xe0, 0x18, 0x2e, 0x18, 0xd0, + 0x18, 0x2e, 0x01, 0xda, 0x3e, 0x60, 0x02, 0xe0, 0xc6, 0xf1, 0x30, 0x00, + 0x38, 0x60, 0xc5, 0xf8, 0x00, 0x90, 0xc5, 0xf8, 0x04, 0x90, 0x30, 0x5d, + 0x28, 0xb1, 0x5a, 0xf8, 0x26, 0x00, 0xa8, 0x60, 0xc5, 0xf8, 0x0c, 0x90, + 0x03, 0xe0, 0xc5, 0xf8, 0x08, 0x90, 0xac, 0x48, 0xe8, 0x60, 0x00, 0xf0, + 0xe3, 0xf8, 0x76, 0x1c, 0x30, 0x2e, 0xe1, 0xdb, 0xdd, 0xf8, 0x9c, 0xa0, + 0x9a, 0xf9, 0x00, 0x60, 0xba, 0x68, 0x00, 0x2e, 0x3a, 0xd4, 0x96, 0x42, + 0x38, 0xd2, 0x00, 0x20, 0x00, 0x21, 0x0d, 0xf1, 0x0c, 0x0c, 0x10, 0xe0, + 0xb1, 0x42, 0x18, 0xbf, 0xb2, 0x42, 0x07, 0xd0, 0x03, 0xfb, 0x01, 0x23, + 0x07, 0xeb, 0x83, 0x03, 0xdb, 0x68, 0x4c, 0xf8, 0x20, 0x30, 0x40, 0x1c, + 0x52, 0x1c, 0xbb, 0x68, 0x9a, 0x42, 0xef, 0xd3, 0x49, 0x1c, 0xba, 0x68, + 0x91, 0x42, 0x38, 0xbf, 0x00, 0x22, 0xf6, 0xd3, 0x70, 0x1c, 0x04, 0xe0, + 0x07, 0xeb, 0x80, 0x01, 0x40, 0x1c, 0x0a, 0x6f, 0xca, 0x66, 0xb9, 0x68, + 0x88, 0x42, 0xf7, 0xd3, 0x4a, 0x1e, 0x07, 0xf1, 0x70, 0x01, 0x03, 0xa8, + 0xfe, 0xf7, 0xf0, 0xfe, 0xb8, 0x68, 0x03, 0xe0, 0x07, 0xeb, 0x80, 0x01, + 0xca, 0x6e, 0x0a, 0x67, 0x40, 0x1e, 0x86, 0x42, 0xf8, 0xd3, 0x07, 0xeb, + 0x86, 0x01, 0x00, 0x20, 0x08, 0x67, 0x01, 0xe0, 0x00, 0xf0, 0x8b, 0xf8, + 0x02, 0x20, 0x00, 0x90, 0x9a, 0xf8, 0x01, 0x30, 0xba, 0x68, 0x01, 0x98, + 0x07, 0xf1, 0x70, 0x01, 0xfe, 0xf7, 0x90, 0xfe, 0x00, 0x26, 0x0d, 0xe0, + 0x30, 0x5d, 0x02, 0x28, 0x04, 0xbf, 0x00, 0x20, 0x30, 0x55, 0xa0, 0x1b, + 0x90, 0xf8, 0x30, 0x10, 0x02, 0x29, 0x04, 0xbf, 0x00, 0x21, 0x80, 0xf8, + 0x30, 0x10, 0x76, 0x1c, 0x5e, 0x45, 0xef, 0xdb, 0x60, 0x78, 0x00, 0x28, + 0x1c, 0xbf, 0x94, 0xf8, 0x2f, 0x00, 0x00, 0x28, 0x1d, 0xd1, 0xab, 0xf1, + 0x01, 0x06, 0x18, 0xe0, 0x96, 0xfb, 0xfb, 0xf0, 0xf3, 0xf7, 0xac, 0xfd, + 0x02, 0x99, 0x51, 0xf8, 0x2b, 0x10, 0xf3, 0xf7, 0x4f, 0xff, 0x02, 0x21, + 0x31, 0x55, 0x02, 0x22, 0x80, 0xf0, 0x00, 0x41, 0x48, 0xf8, 0x26, 0x10, + 0x71, 0x42, 0x0b, 0x19, 0x08, 0xeb, 0x81, 0x01, 0x83, 0xf8, 0x30, 0x20, + 0xc1, 0xf8, 0xc0, 0x00, 0x76, 0x1e, 0x01, 0x2e, 0xe4, 0xda, 0x05, 0x20, + 0x00, 0xf0, 0x52, 0xf8, 0x00, 0xf0, 0x4b, 0xf8, 0x00, 0x26, 0x03, 0xe0, + 0x18, 0x2e, 0x19, 0xd0, 0x18, 0x2e, 0x03, 0xda, 0x3e, 0x60, 0x5d, 0x48, + 0x28, 0x60, 0x04, 0xe0, 0xc6, 0xf1, 0x30, 0x00, 0x38, 0x60, 0xc5, 0xf8, + 0x00, 0x90, 0xc5, 0xf8, 0x04, 0x90, 0x30, 0x5d, 0x28, 0xb1, 0x58, 0xf8, + 0x26, 0x00, 0xa8, 0x60, 0xc5, 0xf8, 0x0c, 0x90, 0x02, 0xe0, 0xa8, 0x60, + 0x56, 0x48, 0xe8, 0x60, 0x00, 0xf0, 0x38, 0xf8, 0x76, 0x1c, 0x30, 0x2e, + 0xe0, 0xdb, 0xba, 0x68, 0x00, 0xf0, 0x21, 0xf8, 0x00, 0x20, 0x38, 0x67, + 0x07, 0xf1, 0x70, 0x01, 0x03, 0x20, 0x00, 0x90, 0x9a, 0xf8, 0x01, 0x30, + 0xba, 0x68, 0x02, 0x98, 0xfe, 0xf7, 0x24, 0xfe, 0x00, 0x20, 0x0d, 0xe0, + 0x01, 0x5d, 0x02, 0x29, 0x04, 0xbf, 0x00, 0x21, 0x01, 0x55, 0x21, 0x1a, + 0x91, 0xf8, 0x30, 0x20, 0x02, 0x2a, 0x04, 0xbf, 0x00, 0x22, 0x81, 0xf8, + 0x30, 0x20, 0x40, 0x1c, 0x58, 0x45, 0xef, 0xdb, 0x1d, 0xb0, 0xbd, 0xe8, + 0xf0, 0x8f, 0x07, 0xf1, 0x70, 0x01, 0x07, 0xf1, 0x0c, 0x00, 0xfe, 0xf7, + 0x4f, 0xbe, 0x14, 0x21, 0x07, 0xf1, 0x70, 0x00, 0xf4, 0xf7, 0x98, 0xbd, + 0xb8, 0x60, 0x64, 0x21, 0x07, 0xf1, 0x0c, 0x00, 0xf4, 0xf7, 0x92, 0xbd, + 0x01, 0x20, 0x78, 0x60, 0x38, 0x46, 0xfe, 0xf7, 0x2a, 0xbd, 0x2d, 0xe9, + 0xf0, 0x43, 0x01, 0x24, 0x01, 0x26, 0x4f, 0xf0, 0xff, 0x39, 0xa8, 0xb1, + 0x1f, 0x68, 0xb7, 0xf5, 0x80, 0x2f, 0xc8, 0xbf, 0xa7, 0xf5, 0x00, 0x26, + 0x04, 0xdc, 0x17, 0xf5, 0x80, 0x2f, 0x03, 0xda, 0x07, 0xf5, 0x00, 0x26, + 0x1e, 0x60, 0x4e, 0x46, 0x2c, 0x4f, 0x17, 0x60, 0x00, 0x27, 0x0f, 0x60, + 0x1f, 0x68, 0x00, 0x2f, 0x13, 0xd5, 0x11, 0xe0, 0x00, 0x26, 0x1e, 0x60, + 0x17, 0x68, 0x00, 0x2f, 0x09, 0xd5, 0x0e, 0x68, 0x00, 0x2e, 0x54, 0xbf, + 0x01, 0x26, 0x4e, 0x46, 0x7f, 0x42, 0x17, 0x60, 0x0f, 0x68, 0x7f, 0x42, + 0x0f, 0x60, 0x0f, 0x68, 0x00, 0x2f, 0x00, 0xd4, 0x4c, 0x46, 0x00, 0x27, + 0x0f, 0xf2, 0x7c, 0x0c, 0xd2, 0xf8, 0x00, 0xe0, 0x0d, 0x68, 0x4e, 0xfa, + 0x07, 0xf8, 0x3d, 0x41, 0x05, 0xfb, 0x14, 0xee, 0xc2, 0xf8, 0x00, 0xe0, + 0xd1, 0xf8, 0x00, 0xe0, 0x08, 0xfb, 0x04, 0xee, 0xc1, 0xf8, 0x00, 0xe0, + 0x5c, 0xf8, 0x27, 0x50, 0xd3, 0xf8, 0x00, 0xe0, 0x05, 0xfb, 0x14, 0xee, + 0xc3, 0xf8, 0x00, 0xe0, 0x01, 0x24, 0x18, 0xb1, 0xbe, 0xf1, 0x00, 0x0f, + 0x04, 0xd5, 0x02, 0xe0, 0x0d, 0x68, 0x00, 0x2d, 0x00, 0xd4, 0x4c, 0x46, + 0x7f, 0x1c, 0x13, 0x2f, 0xda, 0xdb, 0x10, 0x68, 0x70, 0x43, 0x10, 0x60, + 0x08, 0x68, 0x70, 0x43, 0x08, 0x60, 0x18, 0x68, 0x00, 0xeb, 0xc6, 0x40, + 0x18, 0x60, 0xbd, 0xe8, 0xf0, 0x83, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x80, 0xbf, 0xad, 0xc5, 0x27, 0x38, 0xdb, 0x0f, 0xc9, 0x40, + 0x95, 0xbf, 0xd6, 0x33, 0x4f, 0xb7, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x40, 0x2e, 0x01, 0x00, 0xb4, 0x9f, 0x00, 0x00, 0x11, 0x51, 0x00, 0x00, + 0xb1, 0x28, 0x00, 0x00, 0x5d, 0x14, 0x00, 0x00, 0x2f, 0x0a, 0x00, 0x00, + 0x18, 0x05, 0x00, 0x00, 0x8c, 0x02, 0x00, 0x00, 0x46, 0x01, 0x00, 0x00, + 0xa3, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x70, 0x47, 0x38, 0xb5, 0xdf, 0xf8, 0x34, 0x04, 0x40, 0x89, 0xc0, 0xf3, + 0x81, 0x04, 0xc0, 0xf3, 0x01, 0x10, 0x08, 0xb1, 0x44, 0xf0, 0x04, 0x04, + 0x0c, 0xb9, 0x00, 0x20, 0x32, 0xbd, 0xdf, 0xf8, 0x20, 0x04, 0x05, 0x78, + 0x01, 0x21, 0x4f, 0xf4, 0x82, 0x70, 0xf2, 0xf7, 0x26, 0xf9, 0x20, 0x46, + 0xef, 0xf7, 0xca, 0xff, 0x08, 0xb9, 0x04, 0x20, 0x32, 0xbd, 0x20, 0x46, + 0x00, 0xf0, 0xbd, 0xf8, 0x04, 0x46, 0x29, 0x46, 0x4f, 0xf4, 0x82, 0x70, + 0xf2, 0xf7, 0x17, 0xf9, 0x20, 0x46, 0x32, 0xbd, 0x2d, 0xe9, 0xf0, 0x4c, + 0x06, 0x46, 0x15, 0xb2, 0x6f, 0xf0, 0x02, 0x00, 0x85, 0x42, 0x0c, 0x46, + 0x1f, 0x46, 0xb8, 0xbf, 0x05, 0x46, 0x02, 0xdb, 0x04, 0x2d, 0xa8, 0xbf, + 0x03, 0x25, 0xd7, 0xe9, 0x00, 0xab, 0x0f, 0x20, 0x00, 0x21, 0xa2, 0x00, + 0xf4, 0xf7, 0x82, 0xf8, 0x5b, 0x46, 0x2a, 0xea, 0x00, 0x0a, 0x23, 0xea, + 0x01, 0x0b, 0xe8, 0x1c, 0xc1, 0x17, 0xa2, 0x00, 0xf4, 0xf7, 0x78, 0xf8, + 0x4a, 0xea, 0x00, 0x00, 0x4b, 0xea, 0x01, 0x01, 0xc7, 0xe9, 0x00, 0x01, + 0x72, 0xb6, 0xdf, 0xf8, 0xa4, 0x03, 0x4f, 0xf6, 0xfe, 0x61, 0x01, 0x60, + 0x01, 0x60, 0x86, 0xf0, 0x01, 0x03, 0xdf, 0xf8, 0x98, 0x13, 0x0a, 0x78, + 0x1b, 0x01, 0x02, 0xf0, 0x8f, 0x02, 0x03, 0xf0, 0x70, 0x03, 0x1a, 0x43, + 0x0a, 0x70, 0x04, 0xf0, 0x0f, 0x03, 0x4a, 0x78, 0x02, 0xf0, 0xf0, 0x02, + 0x1a, 0x43, 0x4a, 0x70, 0x8d, 0x70, 0x00, 0x21, 0x01, 0x60, 0x62, 0xb6, + 0xbd, 0xe8, 0xf0, 0x8c, 0x2d, 0xe9, 0xf8, 0x4f, 0x90, 0x46, 0x01, 0xf0, + 0x04, 0x05, 0x72, 0xb6, 0xdf, 0xf8, 0x58, 0xa3, 0x4f, 0xf6, 0xfe, 0x69, + 0x80, 0x00, 0xca, 0xf8, 0x00, 0x90, 0x00, 0xf0, 0x1c, 0x00, 0xd4, 0x4f, + 0xd4, 0x4c, 0xca, 0xf8, 0x00, 0x90, 0x01, 0xf0, 0x03, 0x01, 0x01, 0x43, + 0x39, 0x70, 0x40, 0xea, 0x95, 0x00, 0x20, 0x70, 0x00, 0x20, 0xca, 0xf8, + 0x00, 0x00, 0x62, 0xb6, 0xce, 0x49, 0xf3, 0xf7, 0x91, 0xfb, 0x97, 0xf8, + 0x00, 0xb0, 0x26, 0x78, 0xf1, 0xf7, 0xc9, 0xf9, 0x08, 0xb1, 0x01, 0x26, + 0x0d, 0xe0, 0x03, 0x21, 0x1b, 0xea, 0x01, 0x0f, 0x03, 0xd1, 0xf0, 0x07, + 0x01, 0xd4, 0x00, 0x26, 0x05, 0xe0, 0x00, 0x20, 0xf3, 0xf7, 0x96, 0xfb, + 0x00, 0x28, 0xea, 0xd0, 0x02, 0x26, 0x00, 0x20, 0xf3, 0xf7, 0x08, 0xfb, + 0x86, 0xbb, 0x72, 0xb6, 0xca, 0xf8, 0x00, 0x90, 0xca, 0xf8, 0x00, 0x90, + 0x00, 0x20, 0x41, 0x01, 0x39, 0x70, 0x39, 0x79, 0xfa, 0x78, 0xbb, 0x78, + 0x97, 0xf8, 0x01, 0xc0, 0x42, 0xea, 0x01, 0x21, 0x43, 0xea, 0x01, 0x21, + 0x4c, 0xea, 0x01, 0x21, 0x48, 0xf8, 0x20, 0x10, 0x40, 0x1c, 0x08, 0x28, + 0xed, 0xd3, 0x9d, 0xb1, 0x00, 0x21, 0x08, 0x20, 0x4a, 0x01, 0x22, 0x70, + 0x49, 0x1c, 0x22, 0x79, 0xe3, 0x78, 0xa5, 0x78, 0x67, 0x78, 0x43, 0xea, + 0x02, 0x22, 0x45, 0xea, 0x02, 0x22, 0x47, 0xea, 0x02, 0x22, 0x48, 0xf8, + 0x20, 0x20, 0x40, 0x1c, 0x0c, 0x28, 0xed, 0xd3, 0x00, 0x20, 0xca, 0xf8, + 0x00, 0x00, 0x62, 0xb6, 0x30, 0x46, 0xbd, 0xe8, 0xf2, 0x8f, 0x2d, 0xe9, + 0xf0, 0x4f, 0xa9, 0xb0, 0x80, 0x46, 0x0b, 0xa8, 0x0f, 0xf2, 0xc0, 0x21, + 0x10, 0x22, 0xf6, 0xf7, 0xd9, 0xfc, 0x00, 0x20, 0x00, 0xf0, 0xe2, 0xf9, + 0x00, 0x21, 0x00, 0x20, 0xf0, 0xf7, 0xef, 0xf8, 0x00, 0xf0, 0xec, 0xf9, + 0x00, 0x25, 0x07, 0xae, 0xad, 0x55, 0x6d, 0x1c, 0x10, 0x2d, 0xfb, 0xd3, + 0x00, 0xf0, 0x44, 0xfa, 0x5f, 0xea, 0x00, 0x09, 0xfa, 0xd0, 0x00, 0x24, + 0xdf, 0xf8, 0x5c, 0xa2, 0x00, 0xf0, 0x39, 0xf9, 0x0a, 0xd5, 0x00, 0x25, + 0x0a, 0xf1, 0x30, 0x00, 0x00, 0xeb, 0xc4, 0x03, 0x00, 0x22, 0x00, 0xf0, + 0x37, 0xf9, 0x6d, 0x1c, 0x10, 0x2d, 0xf5, 0xd3, 0x0a, 0xeb, 0x84, 0x01, + 0x64, 0x1c, 0x6f, 0xf0, 0x00, 0x40, 0x06, 0x2c, 0x08, 0x66, 0xe9, 0xdb, + 0x00, 0xf0, 0x1f, 0xf9, 0x04, 0x00, 0x55, 0xd1, 0x01, 0x90, 0x0d, 0xf1, + 0x3c, 0x0b, 0x00, 0x20, 0x00, 0x90, 0x01, 0x98, 0x30, 0xb9, 0x00, 0x99, + 0x0f, 0xf2, 0x54, 0x20, 0x00, 0xeb, 0x41, 0x10, 0x03, 0x90, 0x24, 0xe0, + 0x15, 0xa8, 0x03, 0x90, 0x02, 0x20, 0x09, 0xf0, 0x01, 0x01, 0x49, 0x42, + 0x80, 0x4a, 0x11, 0x40, 0x81, 0xea, 0x59, 0x09, 0x00, 0x27, 0x3a, 0x1d, + 0x29, 0xfa, 0x07, 0xf1, 0x29, 0xfa, 0x02, 0xf3, 0x01, 0xf0, 0x0f, 0x01, + 0x03, 0xf0, 0x0f, 0x03, 0x8a, 0x5d, 0x9c, 0x5d, 0x8c, 0x55, 0x08, 0x37, + 0x9a, 0x55, 0x20, 0x2f, 0xef, 0xd3, 0x40, 0x1e, 0xe5, 0xd1, 0x00, 0x25, + 0x15, 0xa9, 0xa8, 0x5d, 0x21, 0xf8, 0x15, 0x00, 0x6d, 0x1c, 0x10, 0x2d, + 0xf9, 0xd3, 0x00, 0x25, 0x03, 0x98, 0x30, 0xf9, 0x15, 0x00, 0x02, 0x90, + 0x04, 0xaa, 0x00, 0x20, 0x6f, 0xf0, 0x00, 0x41, 0x4b, 0xf8, 0x20, 0x10, + 0x00, 0x21, 0x22, 0xf8, 0x10, 0x10, 0x40, 0x1c, 0x06, 0x28, 0xf5, 0xdb, + 0x00, 0x27, 0x00, 0x24, 0x00, 0xf0, 0xd9, 0xf8, 0x05, 0xd5, 0x00, 0xf0, + 0xcd, 0xf8, 0x02, 0x99, 0xfa, 0x1e, 0x00, 0xf0, 0xda, 0xf8, 0x64, 0x1c, + 0x06, 0x2c, 0xf3, 0xdb, 0x00, 0xf0, 0xc9, 0xf8, 0x04, 0x00, 0x06, 0xd0, + 0x00, 0xf0, 0x96, 0xf9, 0x00, 0x20, 0xf0, 0xf7, 0xc7, 0xf8, 0x20, 0x46, + 0xa4, 0xe0, 0x00, 0xeb, 0xd0, 0x71, 0x49, 0x10, 0x28, 0xfa, 0x01, 0xf2, + 0xd1, 0x07, 0x0b, 0xd5, 0x1d, 0xa9, 0x5b, 0xf8, 0x20, 0x20, 0x51, 0xf8, + 0x30, 0x10, 0x91, 0x42, 0x04, 0xda, 0x4b, 0xf8, 0x20, 0x10, 0x04, 0xa9, + 0x21, 0xf8, 0x10, 0x70, 0x40, 0x1c, 0x06, 0x28, 0xe9, 0xdb, 0x7f, 0x1c, + 0x07, 0x2f, 0xce, 0xd3, 0x00, 0xf0, 0xa9, 0xf8, 0x16, 0xd5, 0x04, 0xa8, + 0x0a, 0xeb, 0xc4, 0x07, 0x30, 0xf9, 0x14, 0x00, 0x02, 0x99, 0xc2, 0x1e, + 0x07, 0xf1, 0x30, 0x03, 0x00, 0xf0, 0xa5, 0xf8, 0x0a, 0xeb, 0x84, 0x03, + 0x5b, 0xf8, 0x24, 0x20, 0x18, 0x6e, 0x82, 0x42, 0x04, 0xda, 0xd7, 0xe9, + 0x0c, 0x01, 0xc7, 0xe9, 0x00, 0x01, 0x1a, 0x66, 0x64, 0x1c, 0x06, 0x2c, + 0xe2, 0xdb, 0x6d, 0x1c, 0x10, 0x2d, 0x9d, 0xd3, 0x00, 0x98, 0x40, 0x1c, + 0x04, 0x28, 0x00, 0x90, 0xff, 0xf4, 0x69, 0xaf, 0x01, 0x98, 0x07, 0x28, + 0x41, 0xd2, 0x40, 0x1c, 0x01, 0x90, 0x0b, 0xa8, 0x01, 0x99, 0x00, 0xeb, + 0x41, 0x00, 0x00, 0x25, 0x00, 0x90, 0x00, 0x24, 0x00, 0xf0, 0x77, 0xf8, + 0x2d, 0xd5, 0x0a, 0xeb, 0xc4, 0x02, 0xd2, 0xe9, 0x00, 0x01, 0xaa, 0x00, + 0xfb, 0xf7, 0xfa, 0xfd, 0x00, 0xf0, 0x0f, 0x00, 0xc7, 0x1e, 0x3f, 0xb2, + 0x00, 0x2f, 0x09, 0xd4, 0x01, 0x2f, 0x0c, 0xda, 0x00, 0xf0, 0x68, 0xf9, + 0x00, 0xeb, 0xd0, 0x71, 0x49, 0x10, 0xb0, 0xeb, 0x41, 0x00, 0x04, 0xd0, + 0x00, 0x98, 0x30, 0xf8, 0x02, 0x0c, 0xc2, 0x19, 0x03, 0xe0, 0x00, 0x98, + 0x30, 0xf8, 0x02, 0x0c, 0x3a, 0x1a, 0x12, 0xb2, 0x04, 0x2a, 0xa8, 0xbf, + 0x03, 0x22, 0x04, 0xda, 0x12, 0xf1, 0x03, 0x0f, 0xb8, 0xbf, 0x6f, 0xf0, + 0x02, 0x02, 0x00, 0xf0, 0x41, 0xf8, 0x00, 0xf0, 0x4f, 0xf8, 0x64, 0x1c, + 0x06, 0x2c, 0xcb, 0xdb, 0x6d, 0x1c, 0x10, 0x2d, 0xbf, 0xf4, 0x23, 0xaf, + 0xc5, 0xe7, 0x00, 0x25, 0x00, 0x24, 0x00, 0xf0, 0x3c, 0xf8, 0x0f, 0xd5, + 0x0a, 0xeb, 0xc4, 0x02, 0x00, 0xf0, 0x2e, 0xf8, 0xd2, 0xe9, 0x00, 0x01, + 0x1e, 0x46, 0xaa, 0x00, 0xfb, 0xf7, 0xbc, 0xfd, 0x00, 0xf0, 0x0f, 0x00, + 0xc2, 0x1e, 0x33, 0x46, 0x00, 0xf0, 0x32, 0xf8, 0x64, 0x1c, 0x06, 0x2c, + 0xe9, 0xdb, 0x6d, 0x1c, 0x10, 0x2d, 0xe5, 0xd3, 0x00, 0xf0, 0xf0, 0xf8, + 0x00, 0x20, 0xf0, 0xf7, 0x21, 0xf8, 0x00, 0x20, 0x29, 0xb0, 0xbd, 0xe8, + 0xf0, 0x8f, 0x00, 0x00, 0x78, 0x29, 0x00, 0x20, 0x04, 0x01, 0x00, 0x46, + 0x48, 0x00, 0x00, 0x50, 0xb0, 0x05, 0x00, 0x46, 0xb8, 0x05, 0x00, 0x46, + 0x48, 0x08, 0x00, 0x46, 0x20, 0xa1, 0x07, 0x00, 0xb0, 0xf0, 0x00, 0x20, + 0x01, 0x00, 0x00, 0xd0, 0x0a, 0xeb, 0xc4, 0x00, 0x00, 0xf1, 0x30, 0x03, + 0x70, 0x47, 0x1d, 0xaa, 0x41, 0x46, 0x04, 0x20, 0x34, 0xe6, 0x04, 0xeb, + 0xd4, 0x70, 0x40, 0x10, 0x28, 0xfa, 0x00, 0xf1, 0xc8, 0x07, 0x70, 0x47, + 0x29, 0x46, 0x20, 0x46, 0xe4, 0xe5, 0x00, 0x00, 0x04, 0x00, 0xfc, 0xff, + 0xfe, 0xff, 0x02, 0x00, 0x01, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x07, 0x00, 0x08, 0x00, 0x09, 0x00, 0x0a, 0x00, 0x0b, 0x00, + 0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0e, 0x00, + 0x0d, 0x00, 0x0c, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x08, 0x00, + 0x07, 0x00, 0x06, 0x00, 0x05, 0x00, 0x04, 0x00, 0x03, 0x00, 0x02, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x09, 0x00, 0x0a, 0x00, 0x0b, 0x00, + 0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, + 0x07, 0x00, 0x06, 0x00, 0x05, 0x00, 0x04, 0x00, 0x03, 0x00, 0x02, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0x0d, 0x00, 0x0c, 0x00, + 0x0b, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x04, 0x00, 0x06, 0x00, 0x08, 0x00, 0x0a, 0x00, 0x0c, 0x00, 0x0e, 0x00, + 0x01, 0x00, 0x03, 0x00, 0x05, 0x00, 0x07, 0x00, 0x09, 0x00, 0x0b, 0x00, + 0x0d, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0x0b, 0x00, 0x09, 0x00, + 0x07, 0x00, 0x05, 0x00, 0x03, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x0c, 0x00, + 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x03, 0x00, 0x05, 0x00, 0x07, 0x00, 0x09, 0x00, 0x0b, 0x00, + 0x0d, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00, 0x06, 0x00, + 0x08, 0x00, 0x0a, 0x00, 0x0c, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0c, 0x00, + 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x0d, 0x00, 0x0b, 0x00, 0x09, 0x00, 0x07, 0x00, 0x05, 0x00, + 0x03, 0x00, 0x01, 0x00, 0x10, 0xb5, 0x04, 0x46, 0x04, 0x48, 0xc0, 0x46, + 0xc0, 0x46, 0x00, 0x21, 0x01, 0x70, 0x03, 0x48, 0xc0, 0x46, 0xc0, 0x46, + 0x04, 0x60, 0x10, 0xbd, 0x90, 0xbc, 0x00, 0x20, 0x94, 0xbc, 0x00, 0x20, + 0x38, 0xb5, 0x2c, 0x48, 0x01, 0x78, 0x80, 0x7d, 0xc0, 0x07, 0x03, 0xd5, + 0x48, 0x07, 0x58, 0xbf, 0x08, 0x22, 0x00, 0xd5, 0x04, 0x22, 0x0c, 0x21, + 0x4f, 0xf4, 0xb6, 0x60, 0xef, 0xf7, 0xa6, 0xfc, 0x40, 0x22, 0x00, 0xf0, + 0x41, 0xf8, 0x40, 0x22, 0x00, 0xf0, 0x39, 0xf8, 0x40, 0x22, 0x00, 0xf0, + 0x31, 0xf8, 0x21, 0x4c, 0x21, 0x4d, 0x20, 0x78, 0x28, 0x70, 0x40, 0x22, + 0x00, 0xf0, 0x25, 0xf8, 0x60, 0x78, 0x68, 0x70, 0x40, 0x22, 0xbd, 0xe8, + 0x38, 0x40, 0x40, 0x21, 0x40, 0xf2, 0xe1, 0x50, 0xef, 0xf7, 0x8c, 0xbc, + 0x80, 0xb5, 0x00, 0x22, 0x00, 0xf0, 0x26, 0xf8, 0x00, 0x22, 0x00, 0xf0, + 0x1e, 0xf8, 0x00, 0x22, 0x00, 0xf0, 0x16, 0xf8, 0x00, 0x22, 0x00, 0xf0, + 0x0e, 0xf8, 0x00, 0x22, 0x40, 0x21, 0x40, 0xf2, 0xe1, 0x50, 0xef, 0xf7, + 0x79, 0xfc, 0xbd, 0xe8, 0x08, 0x40, 0x00, 0x22, 0x0c, 0x21, 0x4f, 0xf4, + 0xb6, 0x60, 0xef, 0xf7, 0x71, 0xbc, 0x40, 0x21, 0x4f, 0xf4, 0xbc, 0x60, + 0xef, 0xf7, 0x6c, 0xbc, 0x40, 0x21, 0x40, 0xf2, 0xdf, 0x50, 0xef, 0xf7, + 0x67, 0xbc, 0x40, 0x21, 0x40, 0xf2, 0xde, 0x50, 0xef, 0xf7, 0x62, 0xbc, + 0x40, 0x21, 0x40, 0xf2, 0xdd, 0x50, 0xef, 0xf7, 0x5d, 0xbc, 0x00, 0x00, + 0x02, 0x01, 0x00, 0x46, 0xe0, 0x05, 0x00, 0x46, 0x9a, 0xf3, 0x00, 0x20, + 0xf8, 0xb5, 0x34, 0x4f, 0x38, 0x46, 0xc0, 0x46, 0xc0, 0x46, 0x04, 0x46, + 0x38, 0x1d, 0xc0, 0x46, 0xc0, 0x46, 0x05, 0x46, 0x07, 0xf1, 0x08, 0x00, + 0xc0, 0x46, 0xc0, 0x46, 0x06, 0x46, 0x07, 0xf1, 0x0c, 0x00, 0xc0, 0x46, + 0xc0, 0x46, 0x23, 0x78, 0x2b, 0x49, 0x2c, 0x4a, 0x00, 0x2b, 0x40, 0xd1, + 0x2b, 0x68, 0x02, 0xfb, 0x03, 0x13, 0x2b, 0x60, 0x08, 0x27, 0x02, 0xfb, + 0x03, 0x13, 0x2b, 0x60, 0x02, 0xfb, 0x03, 0x13, 0x2b, 0x60, 0x02, 0xfb, + 0x03, 0x13, 0x2b, 0x60, 0x02, 0xfb, 0x03, 0x13, 0x2b, 0x60, 0x02, 0xfb, + 0x03, 0x13, 0x2b, 0x60, 0x02, 0xfb, 0x03, 0x13, 0x2b, 0x60, 0x02, 0xfb, + 0x03, 0x13, 0x2b, 0x60, 0x03, 0x46, 0xd5, 0xf8, 0x00, 0xc0, 0x02, 0xfb, + 0x0c, 0x1c, 0xc5, 0xf8, 0x00, 0xc0, 0x43, 0xf8, 0x04, 0xcb, 0x7f, 0x1e, + 0xd5, 0xf8, 0x00, 0xc0, 0x02, 0xfb, 0x0c, 0x1c, 0xc5, 0xf8, 0x00, 0xc0, + 0x43, 0xf8, 0x04, 0xcb, 0xd5, 0xf8, 0x00, 0xc0, 0x02, 0xfb, 0x0c, 0x1c, + 0xc5, 0xf8, 0x00, 0xc0, 0x43, 0xf8, 0x04, 0xcb, 0xd5, 0xf8, 0x00, 0xc0, + 0x02, 0xfb, 0x0c, 0x1c, 0xc5, 0xf8, 0x00, 0xc0, 0x43, 0xf8, 0x04, 0xcb, + 0xdd, 0xd1, 0xc3, 0x6f, 0x33, 0x60, 0x01, 0x23, 0x23, 0x70, 0x2b, 0x68, + 0x02, 0xfb, 0x03, 0x11, 0x29, 0x60, 0x31, 0x78, 0x01, 0xf0, 0x1f, 0x01, + 0x50, 0xf8, 0x21, 0x20, 0x32, 0x60, 0x2a, 0x68, 0x40, 0xf8, 0x21, 0x20, + 0x30, 0x68, 0x80, 0x00, 0x80, 0x08, 0xf2, 0xbd, 0x90, 0xbc, 0x00, 0x20, + 0x5f, 0xf3, 0x6e, 0x3c, 0x0d, 0x66, 0x19, 0x00, 0x00, 0xb5, 0x32, 0x38, + 0xa1, 0xfb, 0x00, 0x01, 0xdf, 0xf8, 0x98, 0x24, 0x00, 0x23, 0xf3, 0xf7, + 0x01, 0xfe, 0x80, 0xb2, 0x00, 0xbd, 0x10, 0xb5, 0xdf, 0xf8, 0x8c, 0x44, + 0x61, 0x89, 0x00, 0x20, 0xc1, 0xf3, 0x81, 0x01, 0x11, 0xb1, 0x00, 0xf0, + 0x1b, 0xf8, 0x28, 0xb9, 0x61, 0x89, 0xc1, 0xf3, 0x82, 0x11, 0x11, 0xb1, + 0x00, 0xf0, 0x85, 0xf9, 0x88, 0xb9, 0x61, 0x89, 0xc1, 0xf3, 0x01, 0x11, + 0x69, 0xb1, 0xf1, 0xf7, 0x0a, 0xf9, 0x21, 0x6c, 0xff, 0xf7, 0xda, 0xff, + 0xdf, 0xf8, 0x5c, 0x14, 0x08, 0x80, 0x08, 0x20, 0xf4, 0xf7, 0xae, 0xfa, + 0xbd, 0xe8, 0x10, 0x40, 0xb5, 0xe0, 0x10, 0xbd, 0x00, 0x21, 0x00, 0x20, + 0x2d, 0xe9, 0xf8, 0x4f, 0xef, 0xf7, 0xfb, 0xfd, 0x00, 0x22, 0x03, 0x21, + 0x40, 0xf6, 0x84, 0x50, 0xef, 0xf7, 0xaa, 0xfb, 0x10, 0x21, 0x4f, 0xf4, + 0xc6, 0x60, 0xef, 0xf7, 0x9b, 0xfb, 0x40, 0x21, 0x40, 0xf2, 0x31, 0x60, + 0xef, 0xf7, 0x96, 0xfb, 0x00, 0x21, 0x40, 0xf2, 0x32, 0x60, 0xef, 0xf7, + 0x91, 0xfb, 0x33, 0x21, 0x40, 0xf2, 0x33, 0x60, 0xef, 0xf7, 0x8c, 0xfb, + 0x00, 0xf0, 0x81, 0xf8, 0x00, 0xf0, 0x7a, 0xf8, 0x00, 0xf0, 0x73, 0xf8, + 0x32, 0x21, 0x40, 0xf2, 0x34, 0x60, 0xef, 0xf7, 0x81, 0xfb, 0x40, 0xf2, + 0x35, 0x65, 0x1b, 0x22, 0x1f, 0x21, 0x28, 0x46, 0xef, 0xf7, 0x84, 0xfb, + 0x40, 0xf2, 0x36, 0x66, 0x13, 0x21, 0x00, 0xf0, 0x16, 0xfa, 0x40, 0xf2, + 0x37, 0x6b, 0x0a, 0x21, 0x00, 0xf0, 0x1d, 0xfa, 0x40, 0xf2, 0x3a, 0x68, + 0x00, 0xf0, 0x14, 0xfa, 0x40, 0xf2, 0x3b, 0x69, 0x00, 0xf0, 0x68, 0xf8, + 0x40, 0xf2, 0x39, 0x6a, 0x00, 0xf0, 0x60, 0xf8, 0xdf, 0xf8, 0xbc, 0x03, + 0x00, 0x78, 0x8d, 0xf8, 0x00, 0x00, 0x40, 0xf2, 0x76, 0x67, 0x00, 0x21, + 0x38, 0x46, 0xef, 0xf7, 0x59, 0xfb, 0x02, 0x22, 0x00, 0xf0, 0x5a, 0xf8, + 0xe9, 0x4b, 0x00, 0x22, 0x02, 0x21, 0x4f, 0xf4, 0xd9, 0x70, 0xf6, 0xf7, + 0x13, 0xf8, 0x00, 0x24, 0x18, 0xb1, 0x00, 0x22, 0x00, 0xf0, 0x4e, 0xf8, + 0x01, 0x24, 0x9d, 0xf8, 0x00, 0x10, 0x38, 0x46, 0xef, 0xf7, 0x44, 0xfb, + 0xf1, 0xf7, 0x97, 0xf8, 0xdc, 0x49, 0xc9, 0x6a, 0xff, 0xf7, 0x62, 0xff, + 0x07, 0x46, 0xf9, 0xb2, 0x40, 0xf2, 0x31, 0x60, 0xef, 0xf7, 0x38, 0xfb, + 0x39, 0x0a, 0x40, 0xf2, 0x32, 0x60, 0xef, 0xf7, 0x33, 0xfb, 0x00, 0x21, + 0x40, 0xf2, 0x33, 0x60, 0xef, 0xf7, 0x2e, 0xfb, 0x61, 0x21, 0x00, 0xf0, + 0xcc, 0xf9, 0x0a, 0x21, 0x00, 0xf0, 0xd5, 0xf9, 0x00, 0xf0, 0x22, 0xf8, + 0x00, 0xf0, 0xcc, 0xf9, 0x00, 0xf0, 0x22, 0xf8, 0x00, 0xf0, 0x17, 0xf8, + 0x00, 0xf0, 0x10, 0xf8, 0x00, 0xf0, 0x09, 0xf8, 0x7b, 0x21, 0x00, 0xf0, + 0xbe, 0xf9, 0x00, 0x20, 0xef, 0xf7, 0xc8, 0xfd, 0x20, 0x46, 0xbd, 0xe8, + 0xf2, 0x8f, 0x11, 0x21, 0x40, 0xf2, 0x41, 0x60, 0xef, 0xf7, 0x0e, 0xbb, + 0x00, 0x21, 0x4f, 0xf4, 0xc8, 0x60, 0xef, 0xf7, 0x09, 0xbb, 0x00, 0x21, + 0x40, 0xf2, 0x3f, 0x60, 0xef, 0xf7, 0x04, 0xbb, 0x3f, 0x21, 0x50, 0x46, + 0xef, 0xf7, 0x00, 0xbb, 0x00, 0x21, 0x48, 0x46, 0xef, 0xf7, 0xfc, 0xba, + 0x02, 0x21, 0x4f, 0xf4, 0xd9, 0x70, 0xef, 0xf7, 0x01, 0xbb, 0x2d, 0xe9, + 0xf0, 0x4f, 0x87, 0xb0, 0x00, 0x21, 0x00, 0x20, 0xef, 0xf7, 0x45, 0xfd, + 0x10, 0x22, 0x00, 0xf0, 0xad, 0xf8, 0x00, 0xf0, 0xa0, 0xf9, 0x10, 0x21, + 0x40, 0xf2, 0x4f, 0x60, 0xef, 0xf7, 0xe6, 0xfa, 0x40, 0x21, 0x4f, 0xf4, + 0xca, 0x60, 0xef, 0xf7, 0xe1, 0xfa, 0x00, 0x21, 0x40, 0xf2, 0x51, 0x60, + 0xef, 0xf7, 0xdc, 0xfa, 0x40, 0xf2, 0x52, 0x64, 0x33, 0x21, 0x20, 0x46, + 0xef, 0xf7, 0xd6, 0xfa, 0x32, 0x21, 0x40, 0xf2, 0x53, 0x60, 0xef, 0xf7, + 0xd1, 0xfa, 0x7b, 0x22, 0x7f, 0x21, 0x40, 0xf2, 0x54, 0x60, 0xef, 0xf7, + 0xd5, 0xfa, 0x01, 0x21, 0x40, 0xf2, 0x55, 0x60, 0xef, 0xf7, 0xc6, 0xfa, + 0x40, 0xf2, 0x56, 0x65, 0x00, 0xf0, 0x66, 0xf9, 0x40, 0xf2, 0x57, 0x6a, + 0x3c, 0x21, 0xff, 0xf7, 0xba, 0xff, 0x40, 0xf2, 0x59, 0x6b, 0x00, 0xf0, + 0x65, 0xf9, 0x40, 0xf2, 0x5a, 0x68, 0x00, 0x21, 0x00, 0xf0, 0x5d, 0xf9, + 0x00, 0xf0, 0x6d, 0xf8, 0x98, 0x48, 0x97, 0x4f, 0x00, 0x78, 0x01, 0x90, + 0x40, 0xf2, 0x42, 0x69, 0x04, 0xa8, 0xf1, 0xf7, 0xe4, 0xfc, 0x00, 0x20, + 0xf1, 0xf7, 0x09, 0xfd, 0x93, 0x48, 0x00, 0x78, 0x00, 0x90, 0x02, 0x21, + 0xff, 0xf7, 0xa1, 0xff, 0x3b, 0x46, 0x00, 0x22, 0x02, 0x21, 0x48, 0x46, + 0xf5, 0xf7, 0x5e, 0xff, 0x06, 0x46, 0x00, 0x21, 0x04, 0xa8, 0xf1, 0xf7, + 0xe2, 0xfc, 0x1e, 0xb1, 0xff, 0xf7, 0x92, 0xff, 0x02, 0x26, 0x16, 0xe0, + 0x02, 0xa8, 0xf1, 0xf7, 0x3a, 0xff, 0x01, 0x21, 0x00, 0x20, 0xf1, 0xf7, + 0x37, 0xfe, 0x04, 0x21, 0xff, 0xf7, 0x87, 0xff, 0x3b, 0x46, 0x00, 0x22, + 0x04, 0x21, 0x48, 0x46, 0xf5, 0xf7, 0x44, 0xff, 0x10, 0xb1, 0xff, 0xf7, + 0x7d, 0xff, 0x03, 0x26, 0x02, 0xa8, 0xf1, 0xf7, 0x33, 0xff, 0x00, 0xf0, + 0x02, 0xf9, 0x00, 0x22, 0x00, 0xf0, 0x34, 0xf8, 0xff, 0x21, 0x40, 0xf2, + 0x4f, 0x60, 0xef, 0xf7, 0x6f, 0xfa, 0x74, 0x4f, 0x39, 0x88, 0xc9, 0xb2, + 0x4f, 0xf4, 0xca, 0x60, 0xef, 0xf7, 0x68, 0xfa, 0x38, 0x88, 0x01, 0x0a, + 0x40, 0xf2, 0x51, 0x60, 0xef, 0xf7, 0x62, 0xfa, 0x00, 0x21, 0x20, 0x46, + 0xef, 0xf7, 0x5e, 0xfa, 0x00, 0xf0, 0x00, 0xf9, 0x3c, 0x21, 0xff, 0xf7, + 0x56, 0xff, 0x00, 0xf0, 0x12, 0xf8, 0x00, 0xf0, 0x01, 0xf9, 0x00, 0x21, + 0x00, 0xf0, 0xfb, 0xf8, 0x00, 0x98, 0x40, 0xf0, 0x10, 0x01, 0xc9, 0xb2, + 0xff, 0xf7, 0x4d, 0xff, 0x00, 0x20, 0xef, 0xf7, 0xfb, 0xfc, 0x30, 0x46, + 0x07, 0xb0, 0xbd, 0xe8, 0xf0, 0x8f, 0x3f, 0x21, 0x4f, 0xf4, 0xcb, 0x60, + 0xef, 0xf7, 0x40, 0xba, 0x10, 0x21, 0x40, 0xf6, 0x82, 0x50, 0xef, 0xf7, + 0x45, 0xba, 0x00, 0x20, 0x2d, 0xe9, 0xfe, 0x4f, 0x00, 0x21, 0xef, 0xf7, + 0x8a, 0xfc, 0x00, 0xf0, 0xe8, 0xf8, 0x5b, 0x48, 0x00, 0x78, 0x8d, 0xf8, + 0x08, 0x00, 0x03, 0x21, 0x40, 0xf6, 0x1a, 0x00, 0xef, 0xf7, 0x2a, 0xfa, + 0x00, 0xf0, 0xd8, 0xf8, 0x40, 0x21, 0x40, 0xf2, 0x44, 0x60, 0xef, 0xf7, + 0x23, 0xfa, 0x30, 0x21, 0x40, 0xf2, 0x45, 0x60, 0xef, 0xf7, 0x1e, 0xfa, + 0x00, 0xf0, 0xb7, 0xf8, 0x32, 0x21, 0x40, 0xf2, 0x47, 0x60, 0xef, 0xf7, + 0x17, 0xfa, 0x1b, 0x22, 0x1f, 0x21, 0x4f, 0xf4, 0xc9, 0x60, 0xef, 0xf7, + 0x1b, 0xfa, 0x00, 0xf0, 0xa5, 0xf8, 0x00, 0xf0, 0x9e, 0xf8, 0x40, 0xf2, + 0x4b, 0x65, 0x08, 0x21, 0x00, 0xf0, 0xad, 0xf8, 0x40, 0xf2, 0x4d, 0x66, + 0x00, 0xf0, 0xa4, 0xf8, 0x40, 0xf2, 0x4e, 0x69, 0xff, 0xf7, 0x00, 0xff, + 0x40, 0xf2, 0x4c, 0x68, 0x14, 0x21, 0x00, 0xf0, 0xa4, 0xf8, 0x00, 0x22, + 0x00, 0xf0, 0x7e, 0xf8, 0x40, 0xf6, 0x1f, 0x07, 0x00, 0x22, 0xc0, 0x21, + 0x38, 0x46, 0xf1, 0xf7, 0xcd, 0xfb, 0x38, 0x48, 0x00, 0x78, 0x01, 0x90, + 0x04, 0x21, 0x4f, 0xf4, 0x82, 0x70, 0xf1, 0xf7, 0x9e, 0xfb, 0x40, 0xf6, + 0x15, 0x0a, 0x20, 0x22, 0x20, 0x21, 0x50, 0x46, 0xf1, 0xf7, 0xbe, 0xfb, + 0x31, 0x48, 0x00, 0x78, 0x00, 0x90, 0x40, 0xf2, 0x42, 0x6b, 0x01, 0x21, + 0x00, 0xf0, 0x87, 0xf8, 0x2b, 0x4b, 0x00, 0x22, 0x01, 0x21, 0x58, 0x46, + 0xf5, 0xf7, 0x98, 0xfe, 0x00, 0x24, 0x10, 0xb1, 0x00, 0xf0, 0x7c, 0xf8, + 0x04, 0x24, 0x00, 0x22, 0x20, 0x21, 0x50, 0x46, 0xf1, 0xf7, 0xa6, 0xfb, + 0x00, 0xf0, 0x53, 0xf8, 0x80, 0x22, 0x00, 0xf0, 0x4b, 0xf8, 0xc0, 0x22, + 0xc0, 0x21, 0x38, 0x46, 0xf1, 0xf7, 0x9c, 0xfb, 0x9d, 0xf8, 0x08, 0x10, + 0x40, 0xf6, 0x1a, 0x00, 0xef, 0xf7, 0xba, 0xf9, 0x00, 0xf0, 0x68, 0xf8, + 0xf0, 0xf7, 0x03, 0xff, 0x16, 0x49, 0x49, 0x6d, 0xff, 0xf7, 0xd6, 0xfd, + 0x07, 0x46, 0xf9, 0xb2, 0x40, 0xf2, 0x44, 0x60, 0xef, 0xf7, 0xac, 0xf9, + 0x39, 0x0a, 0x40, 0xf2, 0x45, 0x60, 0xef, 0xf7, 0xa7, 0xf9, 0x00, 0xf0, + 0x40, 0xf8, 0x00, 0xf0, 0x39, 0xf8, 0x00, 0xf0, 0x32, 0xf8, 0x08, 0x21, + 0x00, 0xf0, 0x43, 0xf8, 0x14, 0x21, 0x00, 0xf0, 0x44, 0xf8, 0x00, 0xf0, + 0x39, 0xf8, 0xff, 0xf7, 0x97, 0xfe, 0x00, 0x98, 0x40, 0xf0, 0x08, 0x01, + 0xc9, 0xb2, 0x00, 0xf0, 0x3e, 0xf8, 0x00, 0x20, 0xef, 0xf7, 0x40, 0xfc, + 0x20, 0x46, 0xbd, 0xe8, 0xfe, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x09, 0x3d, + 0x78, 0x29, 0x00, 0x20, 0x94, 0xf3, 0x00, 0x20, 0x76, 0x06, 0x00, 0x46, + 0x40, 0x42, 0x0f, 0x00, 0x04, 0x01, 0x00, 0x46, 0x42, 0x06, 0x00, 0x46, + 0x1a, 0x08, 0x00, 0x46, 0x80, 0x21, 0x4f, 0xf4, 0x02, 0x60, 0xf1, 0xf7, + 0x51, 0xbb, 0x01, 0x99, 0xc9, 0xb2, 0x4f, 0xf4, 0x82, 0x70, 0xf1, 0xf7, + 0x24, 0xbb, 0x0a, 0x21, 0x40, 0xf2, 0x4a, 0x60, 0xef, 0xf7, 0x6a, 0xb9, + 0x13, 0x21, 0x40, 0xf2, 0x49, 0x60, 0xef, 0xf7, 0x65, 0xb9, 0x00, 0x21, + 0x40, 0xf2, 0x46, 0x60, 0xef, 0xf7, 0x60, 0xb9, 0x00, 0x21, 0x30, 0x46, + 0xef, 0xf7, 0x5c, 0xb9, 0x0a, 0x21, 0x28, 0x46, 0xef, 0xf7, 0x58, 0xb9, + 0x01, 0x21, 0x40, 0x46, 0xef, 0xf7, 0x54, 0xb9, 0x00, 0x21, 0x58, 0x46, + 0xef, 0xf7, 0x50, 0xb9, 0x10, 0x21, 0x40, 0xf2, 0x43, 0x60, 0xef, 0xf7, + 0x4b, 0xb9, 0x00, 0x22, 0x01, 0x21, 0x40, 0xf6, 0x87, 0x50, 0xef, 0xf7, + 0x4f, 0xb9, 0x00, 0x00, 0x2d, 0xe9, 0xf0, 0x4f, 0x00, 0xf1, 0x58, 0x06, + 0x83, 0xb0, 0x00, 0xf1, 0x08, 0x05, 0x30, 0x78, 0x0c, 0x46, 0x60, 0xb1, + 0xf1, 0x78, 0xb0, 0x78, 0x22, 0x46, 0xf0, 0xf7, 0x44, 0xff, 0x30, 0xb9, + 0x01, 0x20, 0x68, 0x64, 0x28, 0x64, 0xe8, 0x68, 0x40, 0xf0, 0x02, 0x00, + 0xe8, 0x60, 0x00, 0x2c, 0xc4, 0xf1, 0x00, 0x0b, 0x4f, 0xf0, 0x82, 0x40, + 0x4f, 0xf0, 0x01, 0x0a, 0x04, 0xd5, 0x0a, 0xfa, 0x0b, 0xf1, 0x01, 0x60, + 0x00, 0x21, 0x03, 0xe0, 0x00, 0x21, 0x01, 0x60, 0x0a, 0xfa, 0x04, 0xf1, + 0x41, 0x60, 0x68, 0x6c, 0x00, 0x28, 0x71, 0xd1, 0x70, 0x78, 0x00, 0x21, + 0xf0, 0xf7, 0xef, 0xff, 0x00, 0x28, 0x5f, 0xd1, 0x6a, 0x46, 0x01, 0xa9, + 0x20, 0x46, 0xf1, 0xf7, 0x35, 0xf8, 0xd6, 0xe9, 0x02, 0x23, 0x01, 0x98, + 0x12, 0xeb, 0x00, 0x08, 0x43, 0xeb, 0xe0, 0x79, 0xc6, 0xe9, 0x02, 0x89, + 0xd6, 0xe9, 0x04, 0x23, 0x00, 0x98, 0xc1, 0x17, 0x10, 0x18, 0x59, 0x41, + 0xc6, 0xe9, 0x04, 0x01, 0x72, 0x68, 0x52, 0x1c, 0x72, 0x60, 0x2b, 0x68, + 0x5b, 0x88, 0x9a, 0x42, 0xd9, 0xd3, 0x6f, 0x68, 0x00, 0x2c, 0x1d, 0xd4, + 0xa3, 0x46, 0x77, 0xb1, 0x00, 0x23, 0xf3, 0xf7, 0xf9, 0xfa, 0x07, 0xeb, + 0x8b, 0x01, 0x00, 0x23, 0xc1, 0xf8, 0xc0, 0x00, 0x40, 0x46, 0x72, 0x68, + 0x49, 0x46, 0xf3, 0xf7, 0xef, 0xfa, 0x47, 0xf8, 0x2b, 0x00, 0xac, 0x61, + 0xc5, 0xe9, 0x08, 0x89, 0xd6, 0xe9, 0x04, 0x01, 0xc5, 0xe9, 0x0a, 0x01, + 0xe8, 0x6c, 0x0a, 0xfa, 0x0b, 0xf1, 0x88, 0x43, 0xe8, 0x64, 0x1a, 0xe0, + 0x6f, 0xb1, 0x00, 0x23, 0x07, 0xeb, 0x8b, 0x07, 0xf3, 0xf7, 0xda, 0xfa, + 0xc7, 0xf8, 0x20, 0x01, 0x40, 0x46, 0x72, 0x68, 0x49, 0x46, 0x00, 0x23, + 0xf3, 0xf7, 0xd2, 0xfa, 0x38, 0x66, 0xec, 0x61, 0xc5, 0xe9, 0x0c, 0x89, + 0xd6, 0xe9, 0x04, 0x01, 0xc5, 0xe9, 0x0e, 0x01, 0xa8, 0x6c, 0x0a, 0xfa, + 0x0b, 0xf1, 0x88, 0x43, 0xa8, 0x64, 0x00, 0x20, 0x70, 0x60, 0xc6, 0xe9, + 0x04, 0x00, 0xc6, 0xe9, 0x02, 0x00, 0x0b, 0xe0, 0x01, 0x28, 0x08, 0xbf, + 0x68, 0x64, 0x07, 0xd0, 0xe8, 0x68, 0xc5, 0xf8, 0x44, 0xa0, 0x40, 0xf0, + 0x04, 0x00, 0xc5, 0xf8, 0x40, 0xa0, 0xe8, 0x60, 0xbd, 0xe8, 0xf7, 0x8f, + 0x2d, 0xe9, 0xfe, 0x4f, 0x04, 0x46, 0xdf, 0xf8, 0x90, 0x13, 0x20, 0x78, + 0xdf, 0xf8, 0x8c, 0x53, 0x00, 0xf0, 0x01, 0x00, 0x00, 0x90, 0x00, 0x20, + 0x60, 0x61, 0x60, 0x78, 0x01, 0x28, 0x04, 0xd1, 0xd1, 0xe9, 0x08, 0x6b, + 0x2b, 0x6c, 0xaa, 0x69, 0x03, 0xe0, 0xd1, 0xe9, 0x06, 0x6b, 0xeb, 0x6a, + 0x6a, 0x6b, 0xa1, 0x68, 0x0f, 0x88, 0x39, 0x0a, 0x01, 0xf0, 0x03, 0x0a, + 0x01, 0x28, 0x08, 0xbf, 0x4f, 0xf0, 0x00, 0x0a, 0x09, 0xd0, 0x00, 0x21, + 0x8b, 0x45, 0xd5, 0x48, 0x05, 0xd8, 0x86, 0x42, 0x3c, 0xbf, 0xba, 0xf1, + 0x03, 0x0f, 0x4f, 0xf0, 0x03, 0x0a, 0x4f, 0xf6, 0xff, 0x40, 0x38, 0x40, + 0x40, 0xea, 0x0a, 0x20, 0xad, 0xf8, 0x0a, 0x00, 0x28, 0x68, 0xb0, 0xeb, + 0x83, 0x0f, 0x39, 0xd3, 0x60, 0x68, 0x01, 0x89, 0xad, 0xf8, 0x04, 0x10, + 0x4f, 0xf0, 0x01, 0x09, 0x40, 0x89, 0xad, 0xf8, 0x06, 0x00, 0x4f, 0xf0, + 0x00, 0x0c, 0x01, 0xa8, 0x4f, 0xf4, 0x7a, 0x78, 0x30, 0xf8, 0x1c, 0x50, + 0xa8, 0x05, 0x80, 0x0d, 0xb3, 0xfb, 0xf8, 0xf8, 0xc5, 0xf3, 0x81, 0x21, + 0x08, 0xfb, 0x00, 0xf7, 0x21, 0xb9, 0x4f, 0xf4, 0x7a, 0x70, 0xb7, 0xfb, + 0xf0, 0xf0, 0x07, 0xe0, 0x01, 0x29, 0x05, 0xd1, 0xbc, 0x48, 0xa0, 0xfb, + 0x07, 0x01, 0xc0, 0x0f, 0x40, 0xea, 0x41, 0x00, 0xb0, 0xf5, 0x80, 0x6f, + 0x02, 0xd3, 0xc4, 0xf8, 0x14, 0x90, 0x64, 0xe1, 0x05, 0xf4, 0x70, 0x41, + 0x08, 0x43, 0x01, 0xa9, 0x40, 0xf4, 0x00, 0x60, 0x21, 0xf8, 0x1c, 0x00, + 0x0c, 0xf1, 0x01, 0x0c, 0xbc, 0xf1, 0x02, 0x0f, 0xd1, 0xd3, 0x01, 0xe0, + 0x4f, 0xf0, 0x00, 0x09, 0x19, 0x46, 0x10, 0x46, 0xfe, 0xf7, 0x76, 0xf9, + 0x05, 0x28, 0x38, 0xbf, 0x04, 0x20, 0x01, 0x21, 0x40, 0x1c, 0x01, 0xfa, + 0x00, 0xf0, 0x61, 0x68, 0x0a, 0x68, 0x49, 0x68, 0x40, 0x1e, 0x02, 0x40, + 0x08, 0x40, 0xa1, 0x78, 0xa2, 0x61, 0x22, 0x65, 0xe0, 0x61, 0x60, 0x65, + 0x00, 0x29, 0x18, 0xbf, 0x01, 0x29, 0x04, 0xf1, 0x58, 0x00, 0x28, 0xd1, + 0x01, 0x21, 0x01, 0x70, 0xa1, 0x78, 0x01, 0x29, 0x08, 0xbf, 0x04, 0x21, + 0x04, 0xd0, 0x00, 0x99, 0x00, 0x29, 0x0c, 0xbf, 0x01, 0x21, 0x02, 0x21, + 0xc1, 0x70, 0x61, 0x78, 0x09, 0xb9, 0x81, 0x70, 0x1a, 0xe0, 0x01, 0x21, + 0x81, 0x70, 0x02, 0x21, 0x41, 0x70, 0x00, 0x21, 0xa1, 0x64, 0xc0, 0xe9, + 0x02, 0x11, 0xc0, 0xe9, 0x04, 0x11, 0x41, 0x60, 0x30, 0x46, 0x59, 0x46, + 0xf1, 0xf7, 0x52, 0xfc, 0x8d, 0xf8, 0x08, 0x00, 0x04, 0xf1, 0x7a, 0x06, + 0xdf, 0xf8, 0x3c, 0x82, 0x40, 0xf6, 0x41, 0x4b, 0x21, 0xe0, 0x61, 0x78, + 0x00, 0x29, 0xe6, 0xd1, 0x00, 0x99, 0xe5, 0xe7, 0xee, 0xf7, 0xe4, 0xff, + 0xf1, 0x78, 0x40, 0xf2, 0x35, 0x40, 0xee, 0xf7, 0xdf, 0xff, 0x31, 0x79, + 0x40, 0xf2, 0x36, 0x40, 0xee, 0xf7, 0xda, 0xff, 0xb1, 0x78, 0x40, 0xf2, + 0x33, 0x40, 0xee, 0xf7, 0xd5, 0xff, 0x71, 0x78, 0x40, 0xf2, 0x2e, 0x40, + 0xee, 0xf7, 0xd0, 0xff, 0x00, 0xf0, 0x08, 0xf9, 0xee, 0xf7, 0xea, 0xff, + 0x00, 0x20, 0xef, 0xf7, 0x7b, 0xfa, 0xa1, 0x6c, 0x20, 0x6d, 0x00, 0x29, + 0x40, 0xf0, 0xe2, 0x80, 0x00, 0x28, 0x04, 0xbf, 0x60, 0x6d, 0x00, 0x28, + 0x00, 0xf0, 0xe1, 0x80, 0x00, 0x20, 0xe0, 0x64, 0xef, 0xf7, 0x0f, 0xfa, + 0x00, 0xf0, 0xf2, 0xf8, 0xee, 0xf7, 0xe7, 0xff, 0x73, 0x48, 0x00, 0x78, + 0x30, 0x70, 0x04, 0xf1, 0x70, 0x00, 0xf1, 0xf7, 0x5c, 0xfc, 0x60, 0x78, + 0x01, 0x28, 0x0c, 0xbf, 0x02, 0x21, 0x03, 0x21, 0x00, 0x98, 0xc0, 0xb2, + 0xf1, 0xf7, 0x54, 0xfb, 0x00, 0x98, 0x9d, 0xf8, 0x08, 0x10, 0xc0, 0xb2, + 0xf1, 0xf7, 0x1c, 0xfc, 0x50, 0x46, 0xf1, 0xf7, 0x21, 0xfc, 0x00, 0x98, + 0x03, 0x21, 0xc0, 0xb2, 0xf1, 0xf7, 0x2f, 0xfc, 0x00, 0x98, 0x3f, 0x21, + 0xc0, 0xb2, 0xf1, 0xf7, 0x35, 0xfc, 0xf1, 0xf7, 0x98, 0xfb, 0xf1, 0xf7, + 0x7a, 0xfb, 0x60, 0x78, 0x01, 0x28, 0x0b, 0xd1, 0x60, 0x68, 0x00, 0x7d, + 0x20, 0xb1, 0xc0, 0x22, 0xc0, 0x21, 0x58, 0x46, 0xf1, 0xf7, 0x60, 0xf9, + 0xff, 0x20, 0x60, 0x74, 0x04, 0x20, 0x5f, 0xe0, 0x98, 0xf8, 0x00, 0x00, + 0x70, 0x70, 0x98, 0xf8, 0x05, 0x00, 0xb0, 0x70, 0x00, 0xf0, 0xfc, 0x01, + 0x40, 0xf2, 0x33, 0x40, 0xee, 0xf7, 0x74, 0xff, 0x70, 0x78, 0x00, 0xf0, + 0xf0, 0x01, 0x40, 0xf2, 0x2e, 0x40, 0xee, 0xf7, 0x6d, 0xff, 0x98, 0xf8, + 0x07, 0x00, 0xf0, 0x70, 0x98, 0xf8, 0x08, 0x00, 0x30, 0x71, 0x00, 0x20, + 0xf8, 0xf7, 0x10, 0xfc, 0x00, 0x23, 0x99, 0x42, 0x4a, 0x4a, 0x05, 0xd8, + 0x90, 0x42, 0x03, 0xd2, 0x49, 0x48, 0x90, 0xf9, 0x1d, 0x50, 0x02, 0xe0, + 0x47, 0x48, 0x90, 0xf9, 0x24, 0x50, 0x60, 0x68, 0x00, 0x99, 0x00, 0x7d, + 0xc9, 0xb9, 0x20, 0xb1, 0x0c, 0x22, 0x0c, 0x21, 0x58, 0x46, 0xee, 0xf7, + 0x57, 0xff, 0xf0, 0x78, 0x60, 0x74, 0xff, 0x27, 0xf9, 0xb2, 0x00, 0x20, + 0xee, 0xf7, 0xf9, 0xff, 0x85, 0x42, 0x06, 0xdb, 0x67, 0x74, 0xf9, 0xb2, + 0x40, 0xf2, 0x35, 0x40, 0xee, 0xf7, 0x3e, 0xff, 0x01, 0xe0, 0x7f, 0x1e, + 0xf0, 0xd5, 0x00, 0x20, 0x18, 0xe0, 0x20, 0xb1, 0x30, 0x22, 0x30, 0x21, + 0x58, 0x46, 0xee, 0xf7, 0x3d, 0xff, 0x30, 0x79, 0x60, 0x74, 0xff, 0x27, + 0xf9, 0xb2, 0x01, 0x20, 0xee, 0xf7, 0xdf, 0xff, 0x85, 0x42, 0x06, 0xdb, + 0x67, 0x74, 0xf9, 0xb2, 0x40, 0xf2, 0x36, 0x40, 0xee, 0xf7, 0x24, 0xff, + 0x01, 0xe0, 0x7f, 0x1e, 0xf0, 0xd5, 0x01, 0x20, 0xee, 0xf7, 0xca, 0xff, + 0x20, 0x74, 0x60, 0x68, 0xf0, 0xf7, 0x8c, 0xfd, 0xbd, 0xf8, 0x0a, 0x00, + 0xf0, 0xf7, 0x84, 0xfd, 0xb9, 0xf1, 0x00, 0x0f, 0x06, 0xd0, 0xbd, 0xf8, + 0x04, 0x00, 0x24, 0x49, 0x08, 0x80, 0xbd, 0xf8, 0x06, 0x00, 0x48, 0x80, + 0x01, 0x25, 0x07, 0xe0, 0x60, 0x6d, 0xe8, 0x40, 0xc0, 0x07, 0x08, 0xd5, + 0x29, 0x46, 0x20, 0x46, 0xff, 0xf7, 0xbe, 0xfd, 0xe0, 0x6c, 0x00, 0x28, + 0xf4, 0xd0, 0xe0, 0x6c, 0x40, 0xb9, 0x20, 0x6d, 0xe8, 0x40, 0xc0, 0x07, + 0x04, 0xd5, 0x69, 0x42, 0x20, 0x46, 0xff, 0xf7, 0xb1, 0xfd, 0xf4, 0xe7, + 0x6d, 0x1c, 0x18, 0x2d, 0xee, 0xd3, 0xf0, 0xf7, 0xc1, 0xfd, 0x04, 0xf1, + 0x70, 0x00, 0xf1, 0xf7, 0xa5, 0xfb, 0x60, 0x78, 0x31, 0x78, 0x01, 0x28, + 0x58, 0x46, 0x7f, 0xf4, 0xff, 0xae, 0xf1, 0xf7, 0x98, 0xf8, 0x11, 0xe7, + 0x00, 0x28, 0x04, 0xbf, 0x60, 0x6d, 0x00, 0x28, 0x01, 0xd1, 0x01, 0x20, + 0x00, 0xe0, 0x00, 0x20, 0xbd, 0xe8, 0xfe, 0x8f, 0x00, 0xf2, 0x00, 0x20, + 0x78, 0x29, 0x00, 0x20, 0x00, 0x9c, 0xe4, 0xa6, 0x98, 0x6e, 0x12, 0x83, + 0x2e, 0x04, 0x00, 0x46, 0x41, 0x0c, 0x00, 0x46, 0x00, 0x28, 0x6b, 0xee, + 0xdc, 0x29, 0x00, 0x20, 0x08, 0x00, 0x00, 0x41, 0x02, 0x22, 0x04, 0xf1, + 0x78, 0x01, 0x0f, 0xf2, 0x1c, 0x00, 0x70, 0x47, 0x00, 0x29, 0x18, 0xbf, + 0x01, 0x29, 0x05, 0xd1, 0x01, 0x00, 0x18, 0xbf, 0x01, 0x21, 0x08, 0x46, + 0xf0, 0xf7, 0x7e, 0xbc, 0x70, 0x47, 0x00, 0x00, 0x82, 0x01, 0x0b, 0x02, + 0x38, 0xb5, 0x04, 0x46, 0x0d, 0x46, 0xf1, 0xf7, 0x7e, 0xfc, 0x20, 0x68, + 0xf1, 0xf7, 0x77, 0xfc, 0x28, 0x46, 0xbd, 0xe8, 0x32, 0x40, 0xf1, 0xf7, + 0x7d, 0xbc, 0x2d, 0xe9, 0xf0, 0x41, 0x0d, 0x46, 0x04, 0x46, 0x00, 0x26, + 0x05, 0xf5, 0x98, 0x77, 0x05, 0xf5, 0x90, 0x78, 0x64, 0x42, 0x28, 0x68, + 0x21, 0xb2, 0x00, 0xf0, 0x7a, 0xfa, 0xf1, 0xf7, 0x0a, 0xfc, 0xf1, 0xf7, + 0x24, 0xfc, 0x08, 0xb1, 0x04, 0x26, 0x17, 0xe0, 0xf9, 0x68, 0xa8, 0x68, + 0xf1, 0xf7, 0xe0, 0xfd, 0xa8, 0x68, 0x41, 0x46, 0x00, 0xf0, 0xa1, 0xfa, + 0x69, 0x68, 0xdf, 0xf8, 0x44, 0x04, 0xf2, 0xf7, 0x41, 0xfd, 0x01, 0x46, + 0x38, 0x68, 0xf2, 0xf7, 0x45, 0xfe, 0xe1, 0xd8, 0x28, 0x68, 0x05, 0xf5, + 0x9a, 0x72, 0x41, 0x46, 0x00, 0xf0, 0x32, 0xfb, 0xa8, 0x68, 0x00, 0xf0, + 0x8b, 0xfa, 0x30, 0x46, 0xbd, 0xe8, 0xf0, 0x81, 0x2d, 0xe9, 0xf8, 0x4f, + 0x04, 0x46, 0x80, 0x25, 0xb4, 0xf9, 0x18, 0x61, 0x31, 0x00, 0x48, 0xbf, + 0x49, 0x42, 0x80, 0x29, 0x4f, 0xf0, 0x00, 0x0a, 0x4f, 0xf0, 0x04, 0x08, + 0x04, 0xda, 0x00, 0x2e, 0x46, 0xbf, 0x75, 0x42, 0x2d, 0xb2, 0x35, 0x46, + 0x77, 0x1b, 0x3f, 0xb2, 0xd1, 0x46, 0x5f, 0xea, 0xc9, 0x70, 0x52, 0xbf, + 0x07, 0xeb, 0x45, 0x07, 0x3f, 0xb2, 0xa7, 0xeb, 0x45, 0x07, 0x20, 0x68, + 0x3a, 0xb2, 0x00, 0x21, 0xf1, 0xf7, 0x74, 0xfb, 0x21, 0x46, 0x40, 0x46, + 0xff, 0xf7, 0xa5, 0xff, 0x5f, 0xea, 0x00, 0x0b, 0x16, 0xd1, 0x04, 0xf5, + 0x8c, 0x70, 0x00, 0x21, 0xc2, 0x69, 0x10, 0x46, 0xf2, 0xf7, 0xec, 0xfc, + 0x38, 0xbf, 0x82, 0xf0, 0x00, 0x42, 0x50, 0x46, 0x11, 0x46, 0xf2, 0xf7, + 0xe5, 0xfc, 0x38, 0xbf, 0x92, 0x46, 0x09, 0xf1, 0x01, 0x09, 0xb9, 0xf1, + 0x04, 0x0f, 0x4f, 0xf0, 0x00, 0x08, 0xd4, 0xd3, 0x20, 0x68, 0x32, 0x46, + 0x00, 0x21, 0xf1, 0xf7, 0x51, 0xfb, 0xbb, 0xf1, 0x00, 0x0f, 0x14, 0xd1, + 0x28, 0x46, 0xf2, 0xf7, 0x3b, 0xfb, 0x51, 0x46, 0xf2, 0xf7, 0x52, 0xfb, + 0xdf, 0x49, 0xf2, 0xf7, 0xcb, 0xfc, 0x38, 0xbf, 0x08, 0x46, 0x04, 0xd3, + 0xdd, 0x49, 0xf2, 0xf7, 0xdf, 0xfd, 0x98, 0xbf, 0xdc, 0x48, 0x01, 0x46, + 0x20, 0x68, 0x00, 0xf0, 0xc4, 0xfa, 0x58, 0x46, 0xbd, 0xe8, 0xf2, 0x8f, + 0x2d, 0xe9, 0xf0, 0x47, 0x05, 0x46, 0x8a, 0x46, 0x17, 0x46, 0x4f, 0xf0, + 0x00, 0x09, 0x4f, 0xf0, 0x06, 0x08, 0x05, 0xf5, 0x8e, 0x74, 0x38, 0x68, + 0x41, 0x42, 0x39, 0x60, 0x09, 0xb2, 0x28, 0x68, 0x00, 0xf0, 0xe1, 0xf9, + 0xf1, 0xf7, 0x71, 0xfb, 0xf1, 0xf7, 0x8b, 0xfb, 0x10, 0xb1, 0x4f, 0xf0, + 0x04, 0x09, 0x28, 0xe0, 0x21, 0x6a, 0xa8, 0x68, 0xf1, 0xf7, 0x46, 0xfd, + 0x39, 0x68, 0xa8, 0x68, 0x05, 0xf5, 0x90, 0x72, 0x00, 0xf0, 0x14, 0xfb, + 0x21, 0x68, 0x08, 0x1a, 0x20, 0x60, 0x81, 0x11, 0x00, 0xeb, 0x51, 0x60, + 0x46, 0x02, 0x36, 0x14, 0x30, 0x46, 0x48, 0xbf, 0x40, 0x42, 0x7f, 0x28, + 0x04, 0xdb, 0x01, 0x2e, 0xac, 0xbf, 0x7f, 0x26, 0x6f, 0xf0, 0x7e, 0x06, + 0x28, 0x68, 0x32, 0x46, 0x02, 0x21, 0xf1, 0xf7, 0xfb, 0xfa, 0xa8, 0x68, + 0x00, 0xf0, 0xe8, 0xf9, 0xb8, 0xf1, 0x01, 0x08, 0xc9, 0xd1, 0xaa, 0xf8, + 0x00, 0x61, 0x48, 0x46, 0xbd, 0xe8, 0xf0, 0x87, 0x2d, 0xe9, 0xf0, 0x4f, + 0x04, 0x46, 0x8f, 0xb0, 0x20, 0x68, 0x02, 0x90, 0x88, 0x46, 0xf9, 0xf7, + 0x91, 0xfb, 0xb2, 0x4a, 0x06, 0x90, 0xd2, 0xe9, 0x08, 0x01, 0x27, 0x69, + 0xb0, 0x4a, 0x00, 0x23, 0xf2, 0xf7, 0xe6, 0xff, 0x39, 0x8b, 0x00, 0x26, + 0x80, 0xb2, 0x88, 0x42, 0x34, 0xbf, 0xb8, 0x7c, 0xb8, 0x7e, 0x8d, 0xf8, + 0x04, 0x00, 0xaa, 0x49, 0xb7, 0xf9, 0x0e, 0x00, 0x81, 0xfb, 0x00, 0x01, + 0x00, 0xf0, 0xa5, 0xf9, 0x05, 0x90, 0x04, 0xf5, 0x8a, 0x77, 0x02, 0x98, + 0xc0, 0xf1, 0x01, 0x00, 0x38, 0x70, 0xc0, 0xb2, 0x00, 0xf0, 0x86, 0xfc, + 0x78, 0x80, 0x00, 0x21, 0x00, 0x20, 0xee, 0xf7, 0xee, 0xff, 0x3a, 0x78, + 0x79, 0x88, 0x04, 0xf1, 0x14, 0x00, 0x00, 0xf0, 0xfa, 0xfb, 0x38, 0x78, + 0x00, 0xf0, 0x50, 0xfc, 0x20, 0xb1, 0x00, 0x20, 0xef, 0xf7, 0x3e, 0xf8, + 0x05, 0x20, 0x22, 0xe1, 0x02, 0x98, 0x0b, 0xa9, 0xf1, 0xf7, 0x82, 0xfd, + 0x40, 0xf2, 0xee, 0x20, 0xb8, 0x80, 0xfe, 0x80, 0xbe, 0x60, 0x02, 0x98, + 0xf1, 0xf7, 0x70, 0xfa, 0xa0, 0x68, 0x00, 0xf0, 0x91, 0xf9, 0x02, 0x98, + 0x09, 0xa9, 0xf2, 0xf7, 0xc1, 0xfe, 0xdd, 0xe9, 0x09, 0x01, 0xcd, 0xe9, + 0x07, 0x01, 0x8d, 0xf8, 0x1e, 0x60, 0x07, 0xaa, 0x02, 0x98, 0x02, 0x21, + 0xf2, 0xf7, 0xed, 0xfe, 0xe2, 0x68, 0x12, 0x78, 0x02, 0x99, 0x20, 0x69, + 0x52, 0x1e, 0x12, 0x04, 0x02, 0xf4, 0xfe, 0x02, 0x42, 0xea, 0x81, 0x71, + 0x9d, 0xf8, 0x04, 0x20, 0xd2, 0x05, 0x02, 0xf0, 0x7e, 0x52, 0x11, 0x43, + 0x82, 0x7d, 0xd2, 0x03, 0x02, 0xf4, 0x00, 0x42, 0x11, 0x43, 0x02, 0x7d, + 0x02, 0xf0, 0x07, 0x02, 0x11, 0x43, 0x41, 0xf0, 0x00, 0x41, 0x41, 0xf4, + 0x80, 0x41, 0x04, 0x91, 0x85, 0x78, 0x00, 0xe0, 0x6d, 0x1c, 0x20, 0x69, + 0xc1, 0x78, 0xa9, 0x42, 0xc0, 0xf0, 0x83, 0x80, 0x28, 0x18, 0x01, 0x79, + 0x03, 0x91, 0x06, 0x99, 0x03, 0x29, 0x07, 0xd1, 0x03, 0x98, 0x1b, 0x28, + 0x34, 0xbf, 0xc0, 0xf1, 0x64, 0x09, 0x4f, 0xf0, 0x32, 0x09, 0x01, 0xe0, + 0x90, 0xf8, 0x1b, 0x90, 0x03, 0x9a, 0x02, 0x98, 0x5f, 0xfa, 0x89, 0xf1, + 0xf2, 0xf7, 0xe8, 0xfe, 0x9d, 0xf8, 0x04, 0x10, 0x04, 0xa8, 0xff, 0xf7, + 0x79, 0xfe, 0xb8, 0x62, 0xe0, 0x68, 0x40, 0x78, 0xf1, 0xf7, 0x16, 0xfb, + 0x01, 0x2d, 0x03, 0xd1, 0x20, 0x46, 0xff, 0xf7, 0xaf, 0xfe, 0x06, 0x46, + 0x4f, 0xf0, 0x04, 0x0a, 0x86, 0xbb, 0x21, 0x46, 0x04, 0x20, 0xff, 0xf7, + 0x74, 0xfe, 0x06, 0x00, 0x2a, 0xd1, 0x78, 0x6a, 0x5e, 0x49, 0xf2, 0xf7, + 0xd1, 0xfb, 0x78, 0x62, 0x5c, 0x49, 0x38, 0x6a, 0xf2, 0xf7, 0xcc, 0xfb, + 0x83, 0x46, 0xf8, 0x88, 0xc7, 0xf8, 0x20, 0xb0, 0x00, 0x90, 0x78, 0x6a, + 0xf2, 0xf7, 0x30, 0xfc, 0x00, 0x99, 0x40, 0x18, 0xf8, 0x80, 0xb8, 0x88, + 0x00, 0x90, 0x58, 0x46, 0xf2, 0xf7, 0x28, 0xfc, 0x00, 0x99, 0x42, 0x18, + 0xba, 0x80, 0x12, 0xb2, 0x02, 0x98, 0x00, 0x21, 0xf1, 0xf7, 0x1c, 0xfa, + 0xb7, 0xf9, 0x06, 0x20, 0x02, 0x98, 0x01, 0x21, 0xf1, 0xf7, 0x16, 0xfa, + 0xba, 0xf1, 0x01, 0x0a, 0xcf, 0xd1, 0x00, 0xe0, 0x3e, 0xbb, 0x20, 0x69, + 0xb9, 0x88, 0x28, 0x18, 0x04, 0x2d, 0x00, 0x79, 0x28, 0xf8, 0x10, 0x10, + 0x08, 0xeb, 0x40, 0x00, 0xf9, 0x88, 0xa0, 0xf8, 0x80, 0x10, 0x91, 0xd2, + 0x0f, 0xf2, 0x0c, 0x10, 0x28, 0x5c, 0x03, 0x9a, 0x00, 0xeb, 0x09, 0x01, + 0x02, 0x98, 0xd2, 0xb2, 0xc9, 0xb2, 0xf2, 0xf7, 0x8b, 0xfe, 0x9d, 0xf8, + 0x04, 0x00, 0x29, 0x18, 0xc9, 0xb2, 0x04, 0xa8, 0xff, 0xf7, 0x1a, 0xfe, + 0xb8, 0x62, 0x05, 0xaa, 0x41, 0x46, 0x20, 0x46, 0xff, 0xf7, 0xb6, 0xfe, + 0x06, 0x00, 0x3f, 0xf4, 0x77, 0xaf, 0x00, 0xf0, 0x6d, 0xf8, 0x20, 0x69, + 0x80, 0x78, 0x45, 0x1c, 0x10, 0xe0, 0x28, 0x18, 0x90, 0xf8, 0x04, 0x90, + 0x90, 0xf8, 0x05, 0xa0, 0x52, 0x46, 0x49, 0x46, 0x40, 0x46, 0x00, 0xf0, + 0xc2, 0xfa, 0x52, 0x46, 0x49, 0x46, 0x08, 0xf1, 0x80, 0x00, 0x00, 0xf0, + 0xbc, 0xfa, 0x6d, 0x1c, 0x20, 0x69, 0xc1, 0x78, 0x8d, 0x42, 0xea, 0xd3, + 0x81, 0x78, 0x09, 0x18, 0x00, 0x22, 0x49, 0x79, 0x0c, 0xe0, 0x38, 0xf8, + 0x11, 0x30, 0x28, 0xf8, 0x12, 0x30, 0x08, 0xeb, 0x42, 0x05, 0x08, 0xeb, + 0x41, 0x03, 0x52, 0x1c, 0xb3, 0xf8, 0x80, 0x30, 0xa5, 0xf8, 0x80, 0x30, + 0x8a, 0x42, 0xf0, 0xdb, 0xc1, 0x78, 0x08, 0x18, 0x00, 0x79, 0x41, 0x1c, + 0x0c, 0xe0, 0x38, 0xf8, 0x10, 0x20, 0x28, 0xf8, 0x11, 0x20, 0x08, 0xeb, + 0x41, 0x03, 0x08, 0xeb, 0x40, 0x02, 0x49, 0x1c, 0xb2, 0xf8, 0x80, 0x20, + 0xa3, 0xf8, 0x80, 0x20, 0x40, 0x29, 0xf0, 0xdb, 0x02, 0x98, 0x09, 0xa9, + 0xf2, 0xf7, 0xe6, 0xfd, 0x02, 0x98, 0x0b, 0xa9, 0xf1, 0xf7, 0x8a, 0xfc, + 0x3a, 0x78, 0x79, 0x88, 0x04, 0xf1, 0x14, 0x00, 0x00, 0xf0, 0xff, 0xfa, + 0x08, 0xb1, 0x06, 0xb9, 0x05, 0x26, 0x00, 0x20, 0xee, 0xf7, 0x1e, 0xff, + 0x02, 0x98, 0x41, 0x46, 0x00, 0xf0, 0x27, 0xfa, 0x30, 0x46, 0x0f, 0xb0, + 0xbd, 0xe8, 0xf0, 0x8f, 0xb7, 0x43, 0xba, 0x51, 0xcd, 0xcc, 0xcc, 0x3e, + 0x01, 0x00, 0x20, 0x40, 0x00, 0x00, 0x20, 0x40, 0x00, 0xf2, 0x00, 0x20, + 0x40, 0x42, 0x0f, 0x00, 0x66, 0x66, 0x26, 0x3f, 0x00, 0x00, 0x0a, 0x1c, + 0x00, 0x21, 0x4f, 0xf4, 0x44, 0x60, 0xee, 0xf7, 0x4f, 0xbc, 0x80, 0xb5, + 0x80, 0x21, 0x4f, 0xf4, 0x44, 0x60, 0xee, 0xf7, 0x49, 0xfc, 0xbd, 0xe8, + 0x02, 0x40, 0x28, 0x20, 0xf2, 0xf7, 0x88, 0xb8, 0x70, 0xb5, 0x0d, 0x46, + 0x04, 0x46, 0x2e, 0x12, 0x00, 0x2c, 0x0c, 0xbf, 0x31, 0x46, 0x00, 0x21, + 0xc9, 0xb2, 0x40, 0xf6, 0xcb, 0x10, 0xee, 0xf7, 0x37, 0xfc, 0x00, 0x2c, + 0x0c, 0xbf, 0x29, 0x46, 0x00, 0x21, 0xc9, 0xb2, 0x40, 0xf6, 0xcc, 0x10, + 0xee, 0xf7, 0x2e, 0xfc, 0x04, 0xb9, 0x00, 0x26, 0xf1, 0xb2, 0x40, 0xf6, + 0xcd, 0x10, 0xee, 0xf7, 0x27, 0xfc, 0x04, 0xb9, 0x00, 0x25, 0xe9, 0xb2, + 0x40, 0xf6, 0xce, 0x10, 0xee, 0xf7, 0x20, 0xfc, 0xbd, 0xe8, 0x70, 0x40, + 0xcd, 0xe7, 0x31, 0xb1, 0xc9, 0x03, 0xc0, 0x22, 0x91, 0xfb, 0xf2, 0xf1, + 0xc1, 0xf5, 0x80, 0x31, 0xd0, 0xe7, 0x70, 0x47, 0x10, 0xb5, 0x04, 0x46, + 0x1b, 0x04, 0x43, 0xea, 0x12, 0x41, 0x10, 0x04, 0x0d, 0x4a, 0x52, 0x69, + 0x00, 0x23, 0xf2, 0xf7, 0x15, 0xfe, 0xc0, 0xf5, 0x80, 0x31, 0x20, 0x46, + 0xbd, 0xe8, 0x10, 0x40, 0xbe, 0xe7, 0x10, 0xb5, 0x4f, 0xf4, 0xc0, 0x74, + 0xa4, 0xfb, 0x00, 0x23, 0x10, 0x46, 0x05, 0x4a, 0x52, 0x69, 0x04, 0xfb, + 0x01, 0x33, 0x19, 0x46, 0x00, 0x23, 0xf2, 0xf7, 0x01, 0xfe, 0x00, 0xb2, + 0x10, 0xbd, 0x00, 0x00, 0x78, 0x29, 0x00, 0x20, 0xef, 0xf3, 0x11, 0x80, + 0x60, 0x21, 0x81, 0xf3, 0x11, 0x88, 0x70, 0x47, 0x50, 0x21, 0xee, 0xf7, + 0xa9, 0xbb, 0x2d, 0xe9, 0xf0, 0x41, 0x00, 0xf1, 0x34, 0x05, 0x0c, 0x46, + 0xd5, 0xf8, 0x04, 0x80, 0xaf, 0x68, 0x28, 0x68, 0x00, 0xf0, 0x98, 0xf9, + 0x06, 0x46, 0x00, 0xf0, 0x91, 0xf9, 0x01, 0x46, 0x30, 0x46, 0xf2, 0xf7, + 0x83, 0xf9, 0x06, 0x46, 0x31, 0x46, 0xf2, 0xf7, 0x8f, 0xfa, 0xba, 0x49, + 0xf2, 0xf7, 0x94, 0xfb, 0x4c, 0xd8, 0xe8, 0x68, 0x00, 0xf0, 0x86, 0xf9, + 0x80, 0x46, 0x68, 0x69, 0x00, 0xf0, 0x7f, 0xf9, 0x01, 0x46, 0x40, 0x46, + 0xf2, 0xf7, 0x70, 0xf9, 0x00, 0xf0, 0x48, 0xf8, 0x20, 0x60, 0x29, 0x69, + 0x68, 0x68, 0xf2, 0xf7, 0x79, 0xfa, 0x07, 0x46, 0xa9, 0x69, 0xa8, 0x68, + 0xf2, 0xf7, 0x74, 0xfa, 0x00, 0xf0, 0xd8, 0xf8, 0x00, 0xf0, 0x3a, 0xf8, + 0x60, 0x60, 0x69, 0x69, 0x28, 0x68, 0xf2, 0xf7, 0x6b, 0xfa, 0x07, 0x46, + 0xe9, 0x68, 0xa8, 0x68, 0xf2, 0xf7, 0x66, 0xfa, 0x00, 0xf0, 0xca, 0xf8, + 0x00, 0xf0, 0x2c, 0xf8, 0xa0, 0x60, 0xa9, 0x69, 0x28, 0x68, 0xf2, 0xf7, + 0x5d, 0xfa, 0x07, 0x46, 0x29, 0x69, 0xa8, 0x68, 0xf2, 0xf7, 0x58, 0xfa, + 0x00, 0xf0, 0xbc, 0xf8, 0x00, 0xf0, 0x1e, 0xf8, 0xe0, 0x60, 0x66, 0x68, + 0x27, 0x68, 0x29, 0x68, 0x68, 0x68, 0xf2, 0xf7, 0xb1, 0xf9, 0x05, 0x46, + 0x00, 0xf0, 0x44, 0xf9, 0x07, 0x46, 0x30, 0x46, 0x31, 0x46, 0xf2, 0xf7, + 0x45, 0xfa, 0x39, 0x46, 0xf2, 0xf7, 0xa6, 0xf9, 0x00, 0xf0, 0xa3, 0xf8, + 0x20, 0x61, 0x05, 0xe0, 0x20, 0x46, 0xbd, 0xe8, 0xf0, 0x41, 0x14, 0x21, + 0xee, 0xf7, 0x3c, 0xbb, 0xbd, 0xe8, 0xf0, 0x81, 0x31, 0x46, 0xf2, 0xf7, + 0xa5, 0xb8, 0x30, 0xb5, 0x0c, 0x46, 0x15, 0x46, 0x85, 0xb0, 0x29, 0x46, + 0xff, 0xf7, 0x87, 0xff, 0x69, 0x46, 0x20, 0x46, 0xff, 0xf7, 0x83, 0xff, + 0x28, 0x68, 0x00, 0x99, 0xf2, 0xf7, 0x14, 0xf9, 0x28, 0x60, 0x01, 0x99, + 0x68, 0x68, 0xf2, 0xf7, 0x0f, 0xf9, 0x68, 0x60, 0x02, 0x99, 0xa8, 0x68, + 0xf2, 0xf7, 0x0a, 0xf9, 0xa8, 0x60, 0x03, 0x99, 0xe8, 0x68, 0xf2, 0xf7, + 0x05, 0xf9, 0xe8, 0x60, 0x29, 0x69, 0x04, 0x98, 0xf2, 0xf7, 0x74, 0xf9, + 0x28, 0x61, 0x05, 0xb0, 0x30, 0xbd, 0x10, 0xb5, 0x04, 0x46, 0x79, 0x48, + 0xf2, 0xf7, 0x08, 0xfa, 0x78, 0x49, 0x41, 0xf8, 0x24, 0x00, 0x10, 0xbd, + 0x2d, 0xe9, 0xf0, 0x4f, 0x82, 0x46, 0x83, 0xb0, 0x0f, 0x46, 0x14, 0x46, + 0x01, 0x20, 0xf7, 0xf7, 0xe9, 0xff, 0x3d, 0x68, 0x7e, 0x68, 0xd7, 0xf8, + 0x08, 0xb0, 0xff, 0x68, 0x80, 0x46, 0x89, 0x46, 0x28, 0x46, 0x00, 0xf0, + 0x54, 0xf8, 0x00, 0x90, 0x31, 0x46, 0x30, 0x46, 0xf2, 0xf7, 0xec, 0xf9, + 0x00, 0x99, 0xf2, 0xf7, 0x4d, 0xf9, 0x01, 0x90, 0x59, 0x46, 0x58, 0x46, + 0xf2, 0xf7, 0xe4, 0xf9, 0x00, 0x90, 0x39, 0x46, 0x38, 0x46, 0xf2, 0xf7, + 0xdf, 0xf9, 0x00, 0x99, 0xf2, 0xf7, 0x40, 0xf9, 0x01, 0x46, 0x01, 0x98, + 0xf2, 0xf7, 0x4a, 0xf8, 0xf2, 0xf7, 0x7c, 0xf9, 0x60, 0x49, 0xf2, 0xf7, + 0x37, 0xf9, 0x60, 0x49, 0xf2, 0xf7, 0xd0, 0xf9, 0x60, 0x60, 0x59, 0x46, + 0x28, 0x46, 0xf2, 0xf7, 0xcb, 0xf9, 0x00, 0x90, 0x39, 0x46, 0x30, 0x46, + 0xf2, 0xf7, 0xc6, 0xf9, 0x00, 0x99, 0xf2, 0xf7, 0x27, 0xf9, 0x00, 0x90, + 0x39, 0x46, 0x28, 0x46, 0xf2, 0xf7, 0xbe, 0xf9, 0x07, 0x46, 0x30, 0x46, + 0x59, 0x46, 0xf2, 0xf7, 0xb9, 0xf9, 0x00, 0xf0, 0x1d, 0xf8, 0x01, 0x46, + 0x00, 0x98, 0xf2, 0xf7, 0x25, 0xf8, 0x4e, 0x49, 0x51, 0xf8, 0x2a, 0x10, + 0xf2, 0xf7, 0xae, 0xf9, 0x05, 0x46, 0x40, 0x46, 0x49, 0x46, 0xf1, 0xf7, + 0xdd, 0xff, 0x4c, 0x49, 0xf2, 0xf7, 0x18, 0xf8, 0x01, 0x46, 0x28, 0x46, + 0xf2, 0xf7, 0x14, 0xf8, 0x80, 0xf0, 0x00, 0x40, 0x20, 0x60, 0xbd, 0xe8, + 0xf7, 0x8f, 0x29, 0x46, 0xf2, 0xf7, 0x9a, 0xb9, 0x01, 0x46, 0x38, 0x46, + 0xf2, 0xf7, 0x86, 0xb8, 0x2d, 0xe9, 0xf2, 0x4f, 0x82, 0xb0, 0xd7, 0x68, + 0xd2, 0xf8, 0x00, 0x80, 0x95, 0x68, 0x56, 0x68, 0x00, 0xf1, 0x34, 0x04, + 0x40, 0x46, 0x00, 0xf0, 0x84, 0xf8, 0x81, 0x46, 0x30, 0x46, 0xff, 0xf7, + 0xe8, 0xff, 0x01, 0x46, 0x48, 0x46, 0xf2, 0xf7, 0x71, 0xf8, 0x81, 0x46, + 0x20, 0x69, 0x01, 0x90, 0x38, 0x46, 0xd4, 0xf8, 0x0c, 0xa0, 0x51, 0x46, + 0xf2, 0xf7, 0x78, 0xf9, 0x83, 0x46, 0x01, 0x98, 0xff, 0xf7, 0xd7, 0xff, + 0x01, 0x46, 0x58, 0x46, 0xf2, 0xf7, 0x60, 0xf8, 0x00, 0xf0, 0x62, 0xf8, + 0x83, 0x46, 0x01, 0x98, 0x00, 0xf0, 0x68, 0xf8, 0x00, 0x90, 0x51, 0x46, + 0x30, 0x46, 0xf2, 0xf7, 0x65, 0xf9, 0x01, 0x46, 0x00, 0x98, 0xf2, 0xf7, + 0x51, 0xf8, 0x00, 0xf0, 0x53, 0xf8, 0x82, 0x46, 0xa0, 0x69, 0x00, 0x90, + 0x38, 0x46, 0x64, 0x69, 0x00, 0xf0, 0x4f, 0xf8, 0x07, 0x46, 0x00, 0x98, + 0xff, 0xf7, 0xb7, 0xff, 0xff, 0xf7, 0xb8, 0xff, 0x00, 0xf0, 0x44, 0xf8, + 0x05, 0x46, 0x00, 0x98, 0x00, 0xf0, 0x4a, 0xf8, 0x07, 0x46, 0x30, 0x46, + 0x00, 0xf0, 0x3f, 0xf8, 0xff, 0xf7, 0xac, 0xff, 0x00, 0xf0, 0x38, 0xf8, + 0x04, 0x46, 0x28, 0x46, 0x00, 0xf0, 0x37, 0xf8, 0x06, 0x46, 0x58, 0x46, + 0x51, 0x46, 0xf2, 0xf7, 0x3b, 0xf9, 0x31, 0x46, 0xf2, 0xf7, 0x9c, 0xf8, + 0x06, 0x46, 0x28, 0x46, 0x51, 0x46, 0xf2, 0xf7, 0x33, 0xf9, 0x05, 0x46, + 0x58, 0x46, 0x00, 0xf0, 0x26, 0xf8, 0x01, 0x46, 0x28, 0x46, 0xf2, 0xf7, + 0x1b, 0xf8, 0x01, 0x46, 0x30, 0x46, 0xf1, 0xf7, 0x99, 0xff, 0x04, 0x46, + 0x02, 0x98, 0xf1, 0xf7, 0x7b, 0xff, 0x0a, 0x49, 0xf2, 0xf7, 0x20, 0xf9, + 0x00, 0xf0, 0x15, 0xf8, 0xbd, 0xe8, 0xfe, 0x4f, 0xf2, 0xf7, 0x86, 0xb9, + 0x00, 0x24, 0x74, 0x49, 0x00, 0xcc, 0x6e, 0x46, 0x84, 0xb8, 0x00, 0x20, + 0x00, 0x00, 0x80, 0xbf, 0x00, 0xff, 0x7f, 0x47, 0x28, 0x6b, 0x6e, 0x4e, + 0x00, 0x30, 0x81, 0x45, 0x49, 0x46, 0xf1, 0xf7, 0x7b, 0xbf, 0x21, 0x46, + 0xf2, 0xf7, 0x06, 0xb9, 0x38, 0x46, 0x39, 0x46, 0xf2, 0xf7, 0x02, 0xb9, + 0x41, 0x46, 0xf2, 0xf7, 0xff, 0xb8, 0xf8, 0xb5, 0x04, 0x46, 0x0d, 0x46, + 0xff, 0xf7, 0x4c, 0xfe, 0x06, 0x46, 0x20, 0x46, 0xee, 0xf7, 0xa0, 0xfb, + 0x07, 0x46, 0x35, 0xf9, 0x17, 0x20, 0x00, 0x21, 0x20, 0x46, 0xf0, 0xf7, + 0x57, 0xff, 0x05, 0xeb, 0x47, 0x00, 0x01, 0x21, 0xb0, 0xf9, 0x80, 0x20, + 0x20, 0x46, 0xf0, 0xf7, 0x4f, 0xff, 0x00, 0x20, 0x85, 0xf8, 0x02, 0x01, + 0x86, 0xf3, 0x11, 0x88, 0xf1, 0xbd, 0xf8, 0xb5, 0x04, 0x46, 0x0d, 0x46, + 0x17, 0x46, 0x1e, 0x46, 0xff, 0xf7, 0x2c, 0xfe, 0x06, 0x99, 0xfa, 0x07, + 0x44, 0xbf, 0x0a, 0x88, 0x25, 0xf8, 0x16, 0x20, 0xba, 0x07, 0x04, 0xd5, + 0x49, 0x88, 0x05, 0xeb, 0x46, 0x02, 0xa2, 0xf8, 0x80, 0x10, 0x80, 0xf3, + 0x11, 0x88, 0x29, 0x46, 0x20, 0x46, 0xbd, 0xe8, 0xf4, 0x40, 0xc6, 0xe7, + 0xf8, 0xb5, 0x04, 0x46, 0x0d, 0x46, 0x16, 0x46, 0xff, 0xf7, 0x12, 0xfe, + 0x07, 0x46, 0x20, 0x46, 0xee, 0xf7, 0x66, 0xfb, 0xa9, 0x19, 0x91, 0xf8, + 0x02, 0x21, 0x01, 0x2a, 0x18, 0xbf, 0x40, 0xf0, 0x00, 0x40, 0x01, 0x22, + 0x81, 0xf8, 0x02, 0x21, 0x87, 0xf3, 0x11, 0x88, 0xf2, 0xbd, 0xf0, 0xb5, + 0x30, 0xf9, 0x11, 0x30, 0x30, 0xf9, 0x12, 0x40, 0x4d, 0x1c, 0x09, 0xe0, + 0xe6, 0x1a, 0x6f, 0x1a, 0x7e, 0x43, 0x57, 0x1a, 0x96, 0xfb, 0xf7, 0xf6, + 0x9e, 0x19, 0x20, 0xf8, 0x15, 0x60, 0x6d, 0x1c, 0x95, 0x42, 0xf3, 0xdb, + 0xf0, 0xbd, 0x00, 0x00, 0x2d, 0xe9, 0xf0, 0x41, 0x05, 0x46, 0x0f, 0x46, + 0x16, 0x46, 0x98, 0x46, 0x00, 0x24, 0xef, 0xf7, 0xa8, 0xfc, 0x08, 0xb1, + 0x02, 0x24, 0x0d, 0xe0, 0x05, 0xf1, 0x8c, 0x40, 0x07, 0xea, 0x06, 0x01, + 0x00, 0x78, 0x38, 0x40, 0x88, 0x42, 0x05, 0xd0, 0x40, 0x46, 0xf1, 0xf7, + 0x75, 0xfe, 0x00, 0x28, 0xed, 0xd0, 0x01, 0x24, 0x20, 0x46, 0xbd, 0xe8, + 0xf0, 0x81, 0x10, 0xb5, 0x4f, 0xf4, 0x7a, 0x71, 0x00, 0x20, 0xf1, 0xf7, + 0x51, 0xfe, 0x00, 0x23, 0x00, 0x22, 0x40, 0x21, 0x40, 0xf6, 0xff, 0x50, + 0xff, 0xf7, 0xd6, 0xff, 0x04, 0x46, 0x00, 0x20, 0xf1, 0xf7, 0xd6, 0xfd, + 0x01, 0x2c, 0x16, 0xbf, 0x03, 0x2c, 0x01, 0x20, 0x00, 0x20, 0x10, 0xbd, + 0x10, 0xb5, 0x01, 0x21, 0x01, 0xfa, 0x00, 0xf0, 0x40, 0xf0, 0x80, 0x04, + 0xe1, 0xb2, 0x40, 0xf6, 0xff, 0x50, 0xee, 0xf7, 0x9d, 0xf9, 0x44, 0xf0, + 0x40, 0x00, 0xc0, 0xb2, 0x10, 0xbd, 0x2d, 0xe9, 0xf0, 0x41, 0x04, 0x46, + 0x88, 0x46, 0x10, 0x46, 0xff, 0xf7, 0xea, 0xff, 0x00, 0x27, 0x00, 0x26, + 0x12, 0xe0, 0x00, 0x20, 0x24, 0xf8, 0x16, 0x00, 0x00, 0x25, 0x00, 0xf0, + 0x44, 0xf8, 0x47, 0x48, 0x00, 0x78, 0x34, 0xf8, 0x16, 0x10, 0xa8, 0x40, + 0x7f, 0x1c, 0x08, 0x43, 0x08, 0x35, 0x24, 0xf8, 0x16, 0x00, 0x09, 0x2d, + 0xf1, 0xd3, 0x76, 0x1c, 0x46, 0x45, 0xea, 0xd3, 0xbd, 0xe8, 0xf0, 0x41, + 0x00, 0x21, 0x40, 0xf6, 0xff, 0x50, 0xee, 0xf7, 0x73, 0xb9, 0x2d, 0xe9, + 0xf8, 0x4f, 0x80, 0x46, 0x8a, 0x46, 0x10, 0x46, 0xff, 0xf7, 0xc4, 0xff, + 0x00, 0x26, 0x00, 0x27, 0x83, 0x46, 0x00, 0x24, 0x40, 0xf6, 0xff, 0x59, + 0x16, 0xe0, 0x00, 0x25, 0x00, 0xf0, 0x1d, 0xf8, 0x38, 0xf9, 0x14, 0x00, + 0x28, 0x41, 0xc1, 0xb2, 0x4f, 0xf4, 0x60, 0x60, 0xee, 0xf7, 0x5a, 0xf9, + 0x59, 0x46, 0x48, 0x46, 0xee, 0xf7, 0x56, 0xf9, 0xff, 0xf7, 0x95, 0xff, + 0x7f, 0x1c, 0x06, 0x43, 0x08, 0x35, 0x09, 0x2d, 0xea, 0xd3, 0x64, 0x1c, + 0x54, 0x45, 0xe6, 0xd3, 0x00, 0x21, 0x48, 0x46, 0xee, 0xf7, 0x48, 0xf9, + 0x30, 0x46, 0xbd, 0xe8, 0xf2, 0x8f, 0xf9, 0xb2, 0x40, 0xf6, 0x01, 0x60, + 0xee, 0xf7, 0x40, 0xb9, 0x2d, 0xe9, 0xf0, 0x41, 0x04, 0x46, 0xff, 0xf7, + 0x93, 0xff, 0x06, 0x46, 0x20, 0x46, 0x00, 0xf0, 0x1f, 0xf8, 0x44, 0x00, + 0x00, 0x25, 0xa4, 0xb2, 0x00, 0x27, 0x40, 0xf6, 0xff, 0x58, 0x0e, 0xe0, + 0xff, 0xf7, 0xe9, 0xff, 0x00, 0x21, 0x4f, 0xf4, 0x60, 0x60, 0xee, 0xf7, + 0x29, 0xf9, 0x31, 0x46, 0x40, 0x46, 0xee, 0xf7, 0x25, 0xf9, 0xff, 0xf7, + 0x64, 0xff, 0x05, 0x43, 0x7f, 0x1c, 0xa7, 0x42, 0xee, 0xd3, 0x00, 0x21, + 0x40, 0x46, 0xee, 0xf7, 0x1b, 0xf9, 0x28, 0x46, 0xbd, 0xe8, 0xf0, 0x81, + 0x18, 0x21, 0x04, 0x28, 0x0e, 0x4a, 0x12, 0xd8, 0xdf, 0xe8, 0x00, 0xf0, + 0x03, 0x03, 0x09, 0x09, 0x0d, 0x00, 0x0c, 0x48, 0x00, 0x78, 0x40, 0x09, + 0x40, 0x1c, 0x00, 0x01, 0x70, 0x47, 0x10, 0x78, 0xc0, 0xf3, 0x41, 0x10, + 0x06, 0xe0, 0x10, 0x78, 0xc0, 0xf3, 0x41, 0x00, 0x02, 0xe0, 0x10, 0x78, + 0xc0, 0xf3, 0xc1, 0x00, 0x40, 0x1c, 0x48, 0x43, 0x70, 0x47, 0x00, 0x00, + 0x00, 0x0e, 0x00, 0x46, 0x10, 0x04, 0x00, 0x46, 0x10, 0x09, 0x00, 0x46, + 0xef, 0xf3, 0x11, 0x80, 0x60, 0x21, 0x81, 0xf3, 0x11, 0x88, 0x70, 0x47, + 0x2d, 0xe9, 0xf0, 0x47, 0xad, 0xf5, 0x08, 0x7d, 0x04, 0x46, 0x4f, 0xf0, + 0x00, 0x08, 0xdf, 0xf8, 0xbc, 0x93, 0x00, 0x21, 0x00, 0x20, 0xee, 0xf7, + 0x36, 0xfb, 0x20, 0x88, 0x01, 0xa9, 0xf1, 0xf7, 0x94, 0xf8, 0xa2, 0x69, + 0x12, 0x78, 0x21, 0x88, 0xa0, 0x68, 0x52, 0x1e, 0x12, 0x04, 0x02, 0xf4, + 0xfe, 0x02, 0x42, 0xea, 0x81, 0x71, 0xa2, 0x78, 0xd2, 0x05, 0x02, 0xf0, + 0x7e, 0x52, 0x11, 0x43, 0x42, 0x78, 0x00, 0x79, 0xd2, 0x03, 0x02, 0xf4, + 0x00, 0x42, 0x11, 0x43, 0x00, 0xf0, 0x07, 0x00, 0x08, 0x43, 0x40, 0xf0, + 0x00, 0x40, 0x40, 0xf4, 0x80, 0x40, 0xf0, 0xf7, 0x8c, 0xfe, 0xa0, 0x69, + 0x40, 0x78, 0xf0, 0xf7, 0xab, 0xfe, 0x00, 0x27, 0x00, 0x25, 0x04, 0xeb, + 0x85, 0x00, 0x06, 0x69, 0x6d, 0xb1, 0x00, 0x2f, 0x02, 0xbf, 0xe0, 0x69, + 0x00, 0x68, 0x00, 0x28, 0x4b, 0xd1, 0x20, 0x88, 0x01, 0x21, 0xc0, 0xb2, + 0xf0, 0xf7, 0x77, 0xfd, 0x02, 0x20, 0xf1, 0xf7, 0xeb, 0xfc, 0x00, 0xf0, + 0x18, 0xf9, 0x0f, 0xfa, 0x80, 0xfa, 0x30, 0x6b, 0x82, 0x45, 0x18, 0xd0, + 0x04, 0xa8, 0x31, 0x46, 0x50, 0x22, 0xf4, 0xf7, 0xd3, 0xfe, 0x30, 0x46, + 0x06, 0xf1, 0x50, 0x01, 0x50, 0x22, 0xf4, 0xf7, 0xcd, 0xfe, 0x06, 0xf1, + 0x50, 0x00, 0x04, 0xa9, 0x50, 0x22, 0xf4, 0xf7, 0xc7, 0xfe, 0x30, 0x6b, + 0x82, 0x45, 0x04, 0xd0, 0x30, 0x46, 0xff, 0xf7, 0x9f, 0xfc, 0xc6, 0xf8, + 0x30, 0xa0, 0xf0, 0xf7, 0xfa, 0xfd, 0xf0, 0xf7, 0x14, 0xfe, 0x02, 0x28, + 0x06, 0xd1, 0xe0, 0x69, 0x81, 0x8a, 0x09, 0x04, 0x41, 0xf0, 0x01, 0x01, + 0x01, 0x60, 0x02, 0xe0, 0x01, 0x28, 0x08, 0xbf, 0x01, 0x27, 0x00, 0xf0, + 0xe8, 0xf8, 0x06, 0x46, 0x17, 0xb9, 0xef, 0xf7, 0x46, 0xfb, 0x00, 0xe0, + 0x01, 0x20, 0x36, 0xb2, 0x40, 0xea, 0xd6, 0x77, 0x18, 0xa8, 0xe0, 0x21, + 0x01, 0xfb, 0x05, 0x00, 0xf0, 0xf7, 0x9a, 0xfe, 0x6d, 0x1c, 0x02, 0x2d, + 0xa9, 0xd3, 0x01, 0xa8, 0xf1, 0xf7, 0x67, 0xf8, 0x00, 0x20, 0xee, 0xf7, + 0x0f, 0xfb, 0xe0, 0x69, 0x00, 0x68, 0x00, 0x28, 0x4a, 0xd1, 0x00, 0x2f, + 0x42, 0xd1, 0xa0, 0x78, 0xf0, 0xf7, 0x2c, 0xfe, 0x02, 0x46, 0xa0, 0x68, + 0x62, 0x64, 0xc1, 0x68, 0x18, 0xa8, 0xf0, 0xf7, 0xaf, 0xff, 0x98, 0xb3, + 0x62, 0x6c, 0x20, 0x69, 0x18, 0xa9, 0xf0, 0xf7, 0x85, 0xfe, 0x62, 0x6c, + 0x60, 0x69, 0x50, 0xa9, 0xf0, 0xf7, 0x80, 0xfe, 0x61, 0x69, 0x20, 0x69, + 0x04, 0xf1, 0x28, 0x02, 0xff, 0xf7, 0xc7, 0xfc, 0xa0, 0x6b, 0x49, 0x46, + 0xf1, 0xf7, 0xf6, 0xfe, 0x05, 0x46, 0x61, 0x68, 0x97, 0x48, 0xf1, 0xf7, + 0xf1, 0xfe, 0x01, 0x46, 0x28, 0x46, 0xf1, 0xf7, 0x5f, 0xfd, 0x80, 0x46, + 0xff, 0xf7, 0x38, 0xff, 0x07, 0x46, 0xe0, 0x69, 0xc1, 0x8a, 0x49, 0x1c, + 0xc1, 0x82, 0x40, 0x46, 0x49, 0x46, 0xf1, 0xf7, 0xe9, 0xff, 0x98, 0xbf, + 0x64, 0x20, 0x02, 0xd9, 0xf1, 0xf7, 0x48, 0xff, 0x80, 0xb2, 0xe1, 0x69, + 0x48, 0x60, 0x87, 0xf3, 0x11, 0x88, 0x03, 0xe0, 0xa0, 0x68, 0x80, 0x68, + 0xed, 0xf7, 0x7a, 0xfd, 0x40, 0x46, 0x49, 0x46, 0xf1, 0xf7, 0xbc, 0xfe, + 0xff, 0xf4, 0x29, 0xaf, 0xe0, 0x69, 0x00, 0x68, 0x00, 0x28, 0x72, 0xd1, + 0x20, 0x88, 0x03, 0x22, 0x04, 0xf1, 0x24, 0x01, 0xf0, 0xf7, 0x07, 0xfe, + 0xb4, 0xf9, 0x24, 0x60, 0xb4, 0xf9, 0x26, 0x90, 0x20, 0x88, 0x04, 0xf1, + 0x3c, 0x02, 0x04, 0xf1, 0x28, 0x01, 0xff, 0xf7, 0xb3, 0xfc, 0x27, 0x6c, + 0x38, 0x46, 0x00, 0x21, 0xf1, 0xf7, 0xa0, 0xfe, 0x38, 0xbf, 0x87, 0xf0, + 0x00, 0x47, 0xe0, 0x6b, 0xf1, 0xf7, 0x9a, 0xfe, 0x38, 0xbf, 0x80, 0xf0, + 0x00, 0x40, 0x39, 0x46, 0xf1, 0xf7, 0x0a, 0xfe, 0xf8, 0xf7, 0xa4, 0xfd, + 0x05, 0x46, 0x21, 0x46, 0x00, 0x20, 0x00, 0xf0, 0x59, 0xf8, 0x21, 0x46, + 0x01, 0x20, 0x00, 0xf0, 0x55, 0xf8, 0xb4, 0xf9, 0x26, 0x00, 0xb0, 0xf5, + 0x00, 0x5f, 0xa8, 0xbf, 0x41, 0xf6, 0xff, 0x70, 0x03, 0xda, 0x10, 0xf5, + 0x00, 0x5f, 0x01, 0xda, 0x66, 0x48, 0xe0, 0x84, 0xb4, 0xf9, 0x24, 0x00, + 0xb0, 0xf5, 0x80, 0x6f, 0xa8, 0xbf, 0x40, 0xf2, 0xff, 0x30, 0x02, 0xda, + 0x00, 0x28, 0x01, 0xd5, 0x00, 0x20, 0xa0, 0x84, 0xff, 0xf7, 0xce, 0xfe, + 0x07, 0x46, 0xb4, 0xf9, 0x26, 0x00, 0x48, 0x45, 0x04, 0xbf, 0xb4, 0xf9, + 0x24, 0x00, 0xb0, 0x42, 0x13, 0xd0, 0x04, 0xf1, 0x24, 0x00, 0x00, 0x90, + 0x03, 0x22, 0x60, 0x69, 0x03, 0x6b, 0xe1, 0x68, 0x20, 0x88, 0xff, 0xf7, + 0x8c, 0xfd, 0x22, 0x88, 0x20, 0x6a, 0x01, 0x21, 0x91, 0x40, 0x08, 0x43, + 0x20, 0x62, 0xe0, 0x69, 0x01, 0x69, 0x49, 0x1c, 0x01, 0x61, 0x64, 0x20, + 0xe1, 0x69, 0x48, 0x60, 0xe0, 0x69, 0x85, 0x60, 0xe0, 0x69, 0xc1, 0x68, + 0x49, 0x1c, 0xc1, 0x60, 0xe0, 0x69, 0xc1, 0x8a, 0x01, 0x83, 0x87, 0xf3, + 0x11, 0x88, 0x20, 0x69, 0xff, 0xf7, 0xaa, 0xfb, 0x60, 0x69, 0xff, 0xf7, + 0xa7, 0xfb, 0x0d, 0xf5, 0x08, 0x7d, 0xbd, 0xe8, 0xf0, 0x87, 0xe2, 0x68, + 0x20, 0x88, 0x00, 0x21, 0xff, 0xf7, 0x80, 0xbd, 0x2d, 0xe9, 0xf0, 0x41, + 0x8e, 0x68, 0x00, 0x28, 0xb0, 0x7c, 0x07, 0xbf, 0xcd, 0x6b, 0x01, 0xf1, + 0x24, 0x04, 0x0d, 0x6c, 0x01, 0xf1, 0x26, 0x04, 0x80, 0xb1, 0x28, 0x46, + 0x00, 0x21, 0xf1, 0xf7, 0x3d, 0xff, 0x38, 0xbf, 0x4f, 0xf0, 0x7c, 0x50, + 0x04, 0xd3, 0xf1, 0xf7, 0x1d, 0xfe, 0x05, 0xd2, 0x4f, 0xf0, 0x3f, 0x40, + 0x29, 0x46, 0xf1, 0xf7, 0x8d, 0xfd, 0x05, 0x46, 0x36, 0x7c, 0x27, 0x88, + 0x30, 0x09, 0xf1, 0xf7, 0x85, 0xfc, 0x80, 0x46, 0x06, 0xf0, 0x0f, 0x00, + 0xf1, 0xf7, 0x76, 0xfc, 0x01, 0x46, 0x40, 0x46, 0xf1, 0xf7, 0x8c, 0xfc, + 0x29, 0x46, 0xf1, 0xf7, 0x17, 0xfe, 0xf1, 0xf7, 0x81, 0xfe, 0xc0, 0x19, + 0x20, 0x80, 0xbd, 0xe8, 0xf0, 0x81, 0xfe, 0xb5, 0x0d, 0x46, 0x06, 0x46, + 0x28, 0x68, 0x00, 0x28, 0x41, 0xd0, 0x00, 0x21, 0x00, 0x20, 0xee, 0xf7, + 0x9e, 0xf9, 0x30, 0x88, 0x69, 0x46, 0xf0, 0xf7, 0xfc, 0xfe, 0x28, 0x68, + 0xc0, 0xf3, 0x07, 0x20, 0xc0, 0xb1, 0x95, 0xf9, 0x01, 0x00, 0x1e, 0x49, + 0x01, 0xfb, 0x00, 0xf4, 0x30, 0x88, 0x02, 0x21, 0xc0, 0xb2, 0xf0, 0xf7, + 0xe5, 0xfa, 0x30, 0x88, 0x1a, 0x49, 0x00, 0x28, 0x14, 0xbf, 0x02, 0x20, + 0x01, 0x20, 0xd1, 0xe9, 0x08, 0x67, 0x32, 0x19, 0x47, 0xeb, 0xe4, 0x73, + 0xf8, 0xf7, 0x79, 0xfc, 0xf8, 0xf7, 0x54, 0xfc, 0x14, 0x48, 0x04, 0x78, + 0x40, 0xf6, 0x41, 0x46, 0x00, 0x22, 0xc0, 0x21, 0x30, 0x46, 0xf0, 0xf7, + 0xfb, 0xf8, 0x01, 0x20, 0x68, 0x60, 0x28, 0x68, 0x18, 0xb1, 0xef, 0xf7, + 0xee, 0xf9, 0x00, 0x28, 0xf9, 0xd0, 0x00, 0x20, 0x68, 0x60, 0x21, 0x46, + 0x30, 0x46, 0xf0, 0xf7, 0xc6, 0xf8, 0x68, 0x46, 0xf0, 0xf7, 0x15, 0xff, + 0x00, 0x20, 0xee, 0xf7, 0xbd, 0xf9, 0x00, 0x20, 0xfe, 0xbd, 0x00, 0x00, + 0x00, 0x00, 0xc8, 0x42, 0xb7, 0x43, 0xba, 0x51, 0x00, 0xe0, 0xff, 0xff, + 0x40, 0x42, 0x0f, 0x00, 0x00, 0xf2, 0x00, 0x20, 0x41, 0x0c, 0x00, 0x46, + 0x2d, 0xe9, 0xf0, 0x47, 0xc0, 0x48, 0x04, 0x78, 0x45, 0x78, 0x86, 0x78, + 0xc7, 0x78, 0x90, 0xf8, 0x08, 0x80, 0x90, 0xf8, 0x09, 0x90, 0xbd, 0x48, + 0x00, 0x6a, 0xf1, 0xf7, 0x0d, 0xfc, 0x01, 0x46, 0xbb, 0x48, 0xf1, 0xf7, + 0x19, 0xfc, 0x82, 0x46, 0x07, 0xf0, 0x0f, 0x00, 0x06, 0xeb, 0x00, 0x20, + 0xf1, 0xf7, 0x02, 0xfc, 0x06, 0x46, 0x09, 0xf0, 0x0f, 0x00, 0x08, 0xeb, + 0x00, 0x20, 0xf1, 0xf7, 0xfb, 0xfb, 0x01, 0x46, 0x30, 0x46, 0xf1, 0xf7, + 0x07, 0xfc, 0x06, 0x46, 0x04, 0xeb, 0x05, 0x20, 0xf1, 0xf7, 0xe8, 0xfb, + 0x4f, 0xf0, 0x76, 0x51, 0xf1, 0xf7, 0x8c, 0xfd, 0x31, 0x46, 0xf1, 0xf7, + 0x89, 0xfd, 0x51, 0x46, 0xf1, 0xf7, 0x86, 0xfd, 0xf1, 0xf7, 0xf0, 0xfd, + 0x80, 0xf3, 0x09, 0x04, 0xa0, 0x05, 0x01, 0x0e, 0x40, 0xf6, 0xad, 0x10, + 0xed, 0xf7, 0xbe, 0xfe, 0x04, 0xf0, 0x03, 0x01, 0xbd, 0xe8, 0xf0, 0x47, + 0x40, 0xf6, 0xae, 0x10, 0xed, 0xf7, 0xb6, 0xbe, 0x10, 0xb5, 0xf1, 0xf7, + 0xe3, 0xfb, 0x4f, 0xf0, 0x81, 0x44, 0x21, 0x46, 0xf1, 0xf7, 0xe3, 0xff, + 0x4f, 0xf0, 0x7e, 0x51, 0xf1, 0xf7, 0xcc, 0xfc, 0x01, 0x21, 0xf8, 0xf7, + 0x6f, 0xfe, 0x9a, 0x49, 0xf1, 0xf7, 0x62, 0xfd, 0x99, 0x49, 0xf1, 0xf7, + 0xc3, 0xfc, 0x99, 0x49, 0xf1, 0xf7, 0xce, 0xfb, 0xf1, 0xf7, 0xc6, 0xfd, + 0xc0, 0xb2, 0x10, 0xbd, 0x2d, 0xe9, 0xf0, 0x4f, 0x0d, 0x46, 0x85, 0xb0, + 0x00, 0x21, 0x00, 0x20, 0xee, 0xf7, 0xe7, 0xf8, 0x92, 0x48, 0x00, 0x78, + 0x00, 0x24, 0xc0, 0x07, 0x00, 0xf1, 0x0c, 0x81, 0x8a, 0x4f, 0x97, 0xf8, + 0x10, 0x80, 0xb8, 0xf1, 0x03, 0x0f, 0xa8, 0xbf, 0x03, 0x24, 0x80, 0xf2, + 0x03, 0x81, 0x0f, 0xf2, 0x68, 0x21, 0x4c, 0xc9, 0x02, 0xa8, 0x40, 0xf2, + 0x01, 0x1a, 0x4c, 0xc0, 0x78, 0x6a, 0xf1, 0xf7, 0x99, 0xfb, 0x87, 0x49, + 0xf1, 0xf7, 0xa6, 0xfb, 0x06, 0x46, 0x86, 0x48, 0x00, 0x6b, 0xf1, 0xf7, + 0x91, 0xfb, 0x81, 0x46, 0x02, 0xa8, 0x84, 0x49, 0x50, 0xf8, 0x28, 0x00, + 0xf1, 0xf7, 0x28, 0xfd, 0x01, 0x46, 0x48, 0x46, 0xf1, 0xf7, 0x96, 0xfb, + 0x80, 0x46, 0xb8, 0x7a, 0x7f, 0x49, 0x00, 0xf0, 0x03, 0x00, 0x00, 0x90, + 0x40, 0xf2, 0xca, 0x2b, 0x40, 0x46, 0xf1, 0xf7, 0x19, 0xfd, 0x31, 0x46, + 0xf1, 0xf7, 0x04, 0xfd, 0x81, 0x46, 0x28, 0xbf, 0xb1, 0x46, 0x48, 0x46, + 0xff, 0xf7, 0x9c, 0xff, 0x8d, 0xf8, 0x04, 0x00, 0x4f, 0xf0, 0x7d, 0x51, + 0x48, 0x46, 0xf1, 0xf7, 0x09, 0xfd, 0x31, 0x46, 0xff, 0xf7, 0x92, 0xff, + 0x07, 0x46, 0x4f, 0xf0, 0x88, 0x41, 0x48, 0x46, 0xf1, 0xf7, 0x00, 0xfd, + 0x41, 0x46, 0xf1, 0xf7, 0x6f, 0xfb, 0xf1, 0xf7, 0x67, 0xfd, 0x80, 0x46, + 0x6c, 0x48, 0x00, 0x78, 0x05, 0xf5, 0x80, 0x79, 0x89, 0xf8, 0x00, 0x00, + 0x6a, 0x48, 0x00, 0x78, 0x89, 0xf8, 0x01, 0x00, 0x69, 0x48, 0x00, 0x78, + 0x89, 0xf8, 0x02, 0x00, 0x00, 0x98, 0x80, 0x01, 0x40, 0xf0, 0x11, 0x01, + 0xc9, 0xb2, 0x50, 0x46, 0xed, 0xf7, 0x26, 0xfe, 0x64, 0x48, 0x00, 0x57, + 0x06, 0x28, 0x0c, 0xbf, 0x01, 0x21, 0x00, 0x21, 0x4f, 0xf4, 0x11, 0x60, + 0xed, 0xf7, 0x1c, 0xfe, 0x6e, 0x21, 0x40, 0xf6, 0xc1, 0x10, 0xed, 0xf7, + 0x17, 0xfe, 0x03, 0x21, 0x40, 0xf6, 0xc2, 0x10, 0xed, 0xf7, 0x12, 0xfe, + 0x03, 0x21, 0x40, 0xf6, 0xac, 0x10, 0xed, 0xf7, 0x0d, 0xfe, 0x12, 0x21, + 0x58, 0x46, 0xed, 0xf7, 0x09, 0xfe, 0x30, 0x46, 0x56, 0x49, 0xf1, 0xf7, + 0xb1, 0xfc, 0x34, 0xbf, 0x02, 0x26, 0x01, 0x26, 0x31, 0x46, 0x4f, 0xf4, + 0x1a, 0x60, 0xed, 0xf7, 0xfd, 0xfd, 0x31, 0x46, 0x40, 0xf6, 0xa1, 0x10, + 0xed, 0xf7, 0xf8, 0xfd, 0x9d, 0xf8, 0x04, 0x10, 0x40, 0xf6, 0xc3, 0x10, + 0xed, 0xf7, 0xf2, 0xfd, 0x39, 0x46, 0x40, 0xf6, 0xc4, 0x10, 0xed, 0xf7, + 0xed, 0xfd, 0x3c, 0x21, 0x40, 0xf6, 0xc5, 0x10, 0xed, 0xf7, 0xe8, 0xfd, + 0x5f, 0xfa, 0x88, 0xf1, 0x40, 0xf6, 0xc6, 0x10, 0xed, 0xf7, 0xe2, 0xfd, + 0x00, 0x21, 0x40, 0xf6, 0xa4, 0x10, 0xed, 0xf7, 0xdd, 0xfd, 0x00, 0x21, + 0x40, 0xf6, 0xa5, 0x10, 0xed, 0xf7, 0xd8, 0xfd, 0x00, 0x21, 0x40, 0xf6, + 0xa8, 0x10, 0xed, 0xf7, 0xd3, 0xfd, 0x00, 0x21, 0x40, 0xf6, 0xa9, 0x10, + 0xed, 0xf7, 0xce, 0xfd, 0x00, 0x26, 0x01, 0x20, 0x00, 0x99, 0xb0, 0x40, + 0x01, 0x42, 0x34, 0xd0, 0x47, 0x1e, 0xf8, 0xb2, 0xff, 0xf7, 0xac, 0xfc, + 0x80, 0x46, 0xfa, 0xb2, 0x1f, 0xfa, 0x88, 0xf1, 0x28, 0x46, 0xff, 0xf7, + 0x24, 0xfc, 0xf8, 0xb2, 0xff, 0xf7, 0x7a, 0xfc, 0x18, 0xbb, 0xfa, 0xb2, + 0x10, 0x21, 0x2f, 0x48, 0xff, 0xf7, 0x41, 0xfc, 0xe8, 0xb9, 0x00, 0x2e, + 0x0c, 0xbf, 0x2d, 0x21, 0x2c, 0x21, 0x4f, 0xf4, 0x1c, 0x60, 0xed, 0xf7, + 0xab, 0xfd, 0x01, 0x22, 0x00, 0xf0, 0x54, 0xf8, 0x28, 0x4b, 0x00, 0x22, + 0x01, 0x21, 0x4f, 0xf4, 0xd9, 0x70, 0xf4, 0xf7, 0x65, 0xfa, 0x18, 0xb1, + 0x00, 0x22, 0x00, 0xf0, 0x49, 0xf8, 0x02, 0x24, 0xfa, 0xb2, 0x1f, 0xfa, + 0x88, 0xf1, 0x28, 0x46, 0xff, 0xf7, 0x23, 0xfc, 0x08, 0xb1, 0x04, 0x24, + 0x02, 0xe0, 0x76, 0x1c, 0x02, 0x2e, 0xc2, 0xd3, 0x99, 0xf8, 0x00, 0x10, + 0x50, 0x46, 0xed, 0xf7, 0x8b, 0xfd, 0x99, 0xf8, 0x01, 0x10, 0x4f, 0xf4, + 0x11, 0x60, 0xed, 0xf7, 0x85, 0xfd, 0x99, 0xf8, 0x02, 0x10, 0x58, 0x46, + 0xed, 0xf7, 0x80, 0xfd, 0x00, 0x20, 0xee, 0xf7, 0x2f, 0xf8, 0x20, 0x46, + 0x05, 0xb0, 0xbd, 0xe8, 0xf0, 0x8f, 0x00, 0x00, 0xd3, 0x05, 0x00, 0x46, + 0x78, 0x29, 0x00, 0x20, 0xc6, 0xe3, 0x33, 0x4c, 0x00, 0x00, 0x20, 0x41, + 0x00, 0x00, 0x40, 0x40, 0xcd, 0xcc, 0x4c, 0x3d, 0xe8, 0xf2, 0x00, 0x20, + 0x00, 0x00, 0x7a, 0x44, 0x00, 0xf2, 0x00, 0x20, 0x00, 0x00, 0xfa, 0x44, + 0x4e, 0x62, 0xd0, 0x3e, 0x01, 0x01, 0x00, 0x46, 0x10, 0x09, 0x00, 0x46, + 0xca, 0x02, 0x00, 0x46, 0xb8, 0x2a, 0x00, 0x20, 0x00, 0x40, 0x9c, 0x47, + 0xba, 0x2a, 0x00, 0x20, 0x20, 0xa1, 0x07, 0x00, 0x01, 0x21, 0x4f, 0xf4, + 0xd9, 0x70, 0xed, 0xf7, 0x59, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x20, 0x40, 0x00, 0x00, 0x80, 0x40, 0x70, 0x47, 0xf0, 0xb5, + 0x0d, 0x46, 0x83, 0xb0, 0x00, 0x21, 0x00, 0x20, 0xed, 0xf7, 0x95, 0xff, + 0x69, 0x46, 0x28, 0x46, 0x00, 0xf0, 0x54, 0xf8, 0x04, 0x00, 0x4c, 0xd1, + 0x00, 0x26, 0x69, 0x4f, 0x07, 0xeb, 0x46, 0x12, 0xf1, 0xb2, 0x28, 0x46, + 0x00, 0xf0, 0xe8, 0xf8, 0x76, 0x1c, 0x04, 0x2e, 0xf6, 0xdb, 0x07, 0xf1, + 0x80, 0x05, 0x40, 0xf2, 0xdd, 0x50, 0x29, 0x78, 0xed, 0xf7, 0x28, 0xfd, + 0x69, 0x78, 0x40, 0xf2, 0xde, 0x50, 0xed, 0xf7, 0x23, 0xfd, 0xa9, 0x78, + 0x40, 0xf2, 0xdf, 0x50, 0xed, 0xf7, 0x1e, 0xfd, 0xe9, 0x78, 0x4f, 0xf4, + 0xbc, 0x60, 0xed, 0xf7, 0x19, 0xfd, 0x29, 0x79, 0x40, 0xf2, 0xe1, 0x50, + 0xed, 0xf7, 0x14, 0xfd, 0x57, 0x48, 0x58, 0x4a, 0x01, 0x78, 0x40, 0x78, + 0x93, 0x78, 0xd5, 0x78, 0x43, 0xea, 0x05, 0x23, 0x15, 0x78, 0x52, 0x78, + 0x41, 0xea, 0x00, 0x20, 0x45, 0xea, 0x02, 0x21, 0xc0, 0x1a, 0xc9, 0x1a, + 0x00, 0x01, 0x49, 0x1c, 0x90, 0xfb, 0xf1, 0xf1, 0x89, 0xb2, 0x10, 0x29, + 0xa8, 0xbf, 0x0f, 0x21, 0xc9, 0xb2, 0x4f, 0xf4, 0x09, 0x70, 0xed, 0xf7, + 0xf7, 0xfc, 0x4b, 0x48, 0x80, 0x7a, 0x03, 0x21, 0x08, 0x42, 0x04, 0xd0, + 0xff, 0xf7, 0xf4, 0xfd, 0x68, 0x46, 0xf0, 0xf7, 0xe2, 0xf8, 0x00, 0x20, + 0xed, 0xf7, 0x9c, 0xff, 0x20, 0x46, 0xfe, 0xbd, 0x2d, 0xe9, 0xf0, 0x41, + 0x04, 0x46, 0x0d, 0x46, 0x00, 0x22, 0x03, 0x21, 0x40, 0xf2, 0xd1, 0x50, + 0xed, 0xf7, 0xe8, 0xfc, 0x4f, 0xf4, 0x7a, 0x70, 0xf1, 0xf7, 0x1e, 0xf9, + 0xc0, 0x22, 0xc0, 0x21, 0x4f, 0xf4, 0xd9, 0x70, 0xed, 0xf7, 0xde, 0xfc, + 0x41, 0xf2, 0x88, 0x33, 0x00, 0x22, 0xc0, 0x21, 0x4f, 0xf4, 0xd9, 0x70, + 0xf4, 0xf7, 0x90, 0xf9, 0x08, 0xb1, 0x01, 0x20, 0x60, 0xe0, 0x35, 0x4e, + 0x70, 0x79, 0xb1, 0x79, 0xf2, 0x79, 0x33, 0x7a, 0x37, 0x78, 0x01, 0xf0, + 0x07, 0x01, 0x40, 0xea, 0x01, 0x20, 0x03, 0xf0, 0x07, 0x01, 0x42, 0xea, + 0x01, 0x21, 0x08, 0x18, 0x80, 0xb2, 0x07, 0xf0, 0x3f, 0x01, 0xc1, 0xeb, + 0x50, 0x07, 0x2c, 0x48, 0x2c, 0x49, 0x00, 0x78, 0x09, 0x6b, 0x40, 0x07, + 0x4c, 0xbf, 0x2b, 0x48, 0x2b, 0x48, 0xb1, 0xfb, 0xf0, 0xf0, 0x00, 0x04, + 0xc0, 0x0a, 0xf1, 0xf7, 0xbd, 0xf9, 0x80, 0x46, 0xb8, 0xb2, 0xf1, 0xf7, + 0xc3, 0xf9, 0x01, 0x46, 0x40, 0x46, 0xf1, 0xf7, 0xcf, 0xf9, 0x07, 0x46, + 0x2f, 0x60, 0xf1, 0xf7, 0xc5, 0xfb, 0x80, 0x46, 0xa4, 0xf8, 0x00, 0x80, + 0x4f, 0xf0, 0x76, 0x50, 0x39, 0x46, 0xf1, 0xf7, 0x51, 0xfb, 0x28, 0x60, + 0x5f, 0xfa, 0x88, 0xf1, 0x40, 0xf2, 0xd3, 0x50, 0xed, 0xf7, 0x8c, 0xfc, + 0x20, 0x88, 0x01, 0x0a, 0x40, 0xf2, 0xd4, 0x50, 0xed, 0xf7, 0x86, 0xfc, + 0x70, 0x7a, 0xb1, 0x7a, 0xf7, 0x78, 0x36, 0x79, 0x40, 0xea, 0x01, 0x20, + 0x00, 0x03, 0xf1, 0xf7, 0x93, 0xf9, 0x80, 0x46, 0x47, 0xea, 0x06, 0x20, + 0xf1, 0xf7, 0x98, 0xf9, 0x01, 0x46, 0x40, 0x46, 0xf1, 0xf7, 0xa4, 0xf9, + 0x06, 0x46, 0x6e, 0x60, 0xf1, 0xf7, 0x9a, 0xfb, 0x60, 0x80, 0x31, 0x46, + 0x4f, 0xf0, 0x66, 0x50, 0xf1, 0xf7, 0x28, 0xfb, 0x68, 0x60, 0x00, 0x20, + 0xbd, 0xe8, 0xf0, 0x81, 0x00, 0x02, 0x00, 0x20, 0xdb, 0x05, 0x00, 0x46, + 0x20, 0x02, 0x00, 0x46, 0x78, 0x29, 0x00, 0x20, 0xd2, 0x05, 0x00, 0x46, + 0x02, 0x01, 0x00, 0x46, 0x00, 0xf2, 0x00, 0x20, 0x40, 0x4b, 0x4c, 0x00, + 0x00, 0x09, 0x3d, 0x00, 0x01, 0x22, 0x40, 0x1c, 0x02, 0xfa, 0x00, 0xf0, + 0x40, 0x1e, 0x80, 0xb2, 0x88, 0x42, 0x88, 0xbf, 0x08, 0x46, 0x70, 0x47, + 0x2d, 0xe9, 0xf0, 0x4f, 0x91, 0x46, 0x0f, 0xf2, 0xe0, 0x02, 0x83, 0xb0, + 0x04, 0x46, 0xb2, 0xe8, 0x08, 0x04, 0x68, 0x46, 0x00, 0x25, 0xa0, 0xe8, + 0x08, 0x04, 0x01, 0xf0, 0x07, 0x00, 0x40, 0xf0, 0x20, 0x01, 0x40, 0xf2, + 0xdd, 0x50, 0xed, 0xf7, 0x35, 0xfc, 0x00, 0x21, 0x40, 0xf2, 0xe2, 0x50, + 0xed, 0xf7, 0x30, 0xfc, 0x00, 0x27, 0x40, 0xf2, 0xe4, 0x5a, 0x40, 0xf2, + 0xe3, 0x5b, 0x0f, 0xf2, 0xc8, 0x08, 0x20, 0x88, 0x39, 0xf8, 0x17, 0x10, + 0x48, 0x43, 0x3d, 0xf8, 0x17, 0x10, 0xc1, 0xeb, 0x10, 0x11, 0x15, 0xf8, + 0x08, 0x00, 0x89, 0xb2, 0xff, 0xf7, 0xc8, 0xff, 0x00, 0xf0, 0x3e, 0xf8, + 0x00, 0xf0, 0x38, 0xf8, 0x6d, 0x1c, 0x7f, 0x1c, 0x04, 0x2f, 0xea, 0xdb, + 0x00, 0x27, 0x09, 0xeb, 0x47, 0x01, 0x60, 0x88, 0x09, 0x89, 0x48, 0x43, + 0x01, 0x01, 0x15, 0xf8, 0x08, 0x00, 0x09, 0x0c, 0xff, 0xf7, 0xb4, 0xff, + 0x00, 0xf0, 0x2a, 0xf8, 0x00, 0xf0, 0x24, 0xf8, 0x6d, 0x1c, 0x7f, 0x1c, + 0x07, 0x2f, 0xec, 0xdb, 0x00, 0x24, 0x09, 0xeb, 0x44, 0x00, 0x64, 0x1c, + 0xc1, 0x8a, 0x15, 0xf8, 0x08, 0x00, 0xff, 0xf7, 0xa3, 0xff, 0x00, 0xf0, + 0x19, 0xf8, 0x00, 0xf0, 0x13, 0xf8, 0x6d, 0x1c, 0x05, 0x2c, 0xf0, 0xdb, + 0x0f, 0xf2, 0x38, 0x05, 0x00, 0x24, 0x00, 0x21, 0x58, 0x46, 0xed, 0xf7, + 0xe9, 0xfb, 0x61, 0x5d, 0x50, 0x46, 0xed, 0xf7, 0xe5, 0xfb, 0x64, 0x1c, + 0x15, 0x2c, 0xf4, 0xdb, 0xbd, 0xe8, 0xf7, 0x8f, 0xf1, 0xb2, 0x50, 0x46, + 0xed, 0xf7, 0xdc, 0xbb, 0x06, 0x46, 0x30, 0x04, 0x01, 0x0e, 0x58, 0x46, + 0xed, 0xf7, 0xd6, 0xbb, 0x30, 0x01, 0xa0, 0x00, 0x70, 0x00, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, + 0x2a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x0a, 0x08, 0x06, 0x05, 0x0a, 0x0a, 0x0b, 0x09, 0x0a, 0x09, 0x0a, 0x05, + 0x05, 0x05, 0x05, 0x07, 0xb3, 0x49, 0x4f, 0xf4, 0x82, 0x72, 0x02, 0xfb, + 0x00, 0x11, 0x01, 0xf5, 0x21, 0x71, 0xff, 0xf7, 0x74, 0xb9, 0x38, 0xb5, + 0xae, 0x4c, 0x00, 0x20, 0x20, 0x70, 0x00, 0x21, 0x01, 0x20, 0xed, 0xf7, + 0xec, 0xfc, 0x00, 0x20, 0xf0, 0xf7, 0x9c, 0xf8, 0x00, 0x20, 0x01, 0x25, + 0x60, 0x70, 0x01, 0x21, 0x04, 0xe0, 0x00, 0x20, 0x28, 0x55, 0x29, 0x00, + 0x18, 0xbf, 0x01, 0x21, 0xc9, 0xb2, 0x01, 0x20, 0xed, 0xf7, 0xdb, 0xfc, + 0x28, 0x46, 0xf0, 0xf7, 0x8b, 0xf8, 0x6d, 0x1c, 0x02, 0x2d, 0xf0, 0xd3, + 0x31, 0xbd, 0x2d, 0xe9, 0xf0, 0x47, 0x9f, 0x4e, 0xdf, 0xf8, 0x7c, 0x82, + 0x70, 0x69, 0xdf, 0xf8, 0x70, 0x92, 0x0c, 0x46, 0xb1, 0x69, 0x00, 0x25, + 0x81, 0x42, 0x38, 0xbf, 0x08, 0x46, 0xf1, 0xf7, 0xa5, 0xf8, 0x4f, 0xf0, + 0x7c, 0x51, 0xf1, 0xf7, 0x3f, 0xfa, 0x98, 0x49, 0xf1, 0xf7, 0xae, 0xf8, + 0xf1, 0xf7, 0xa6, 0xfa, 0x96, 0x49, 0xb1, 0xf9, 0x0e, 0x20, 0x00, 0xb2, + 0x90, 0x42, 0xc8, 0xbf, 0x10, 0x46, 0xc8, 0x81, 0x00, 0x27, 0xb0, 0x7a, + 0x21, 0x61, 0x00, 0xf0, 0x03, 0x06, 0x08, 0x8a, 0x00, 0xf0, 0x03, 0xf9, + 0x60, 0x60, 0x26, 0xfa, 0x07, 0xf0, 0xc0, 0x07, 0x3e, 0xd5, 0x01, 0x20, + 0xb8, 0x40, 0xed, 0xf7, 0xcd, 0xfb, 0x08, 0xb9, 0x02, 0x25, 0x3a, 0xe0, + 0x39, 0x46, 0x01, 0x20, 0xf1, 0xf7, 0x73, 0xfe, 0x08, 0xb9, 0x03, 0x25, + 0x33, 0xe0, 0x27, 0x60, 0x39, 0x46, 0x00, 0xf0, 0xe7, 0xf8, 0xe0, 0x60, + 0x4f, 0xf4, 0xa0, 0x70, 0x00, 0xfb, 0x07, 0x9a, 0x0a, 0xf1, 0x04, 0x00, + 0xa0, 0x60, 0xed, 0xf7, 0x8d, 0xfc, 0x4f, 0xf0, 0x7e, 0x51, 0x38, 0x46, + 0xfe, 0xf7, 0xf7, 0xff, 0x4f, 0xf4, 0x82, 0x70, 0x00, 0xfb, 0x07, 0x90, + 0x00, 0xf5, 0x21, 0x71, 0x20, 0x46, 0xfe, 0xf7, 0x73, 0xfd, 0x05, 0x46, + 0x0a, 0xf1, 0x04, 0x00, 0xfe, 0xf7, 0x4e, 0xff, 0x0a, 0xf1, 0x54, 0x00, + 0xfe, 0xf7, 0x4a, 0xff, 0x43, 0x46, 0x01, 0x22, 0xf9, 0xb2, 0x01, 0x20, + 0xed, 0xf7, 0x5a, 0xfc, 0xed, 0xf7, 0x71, 0xfc, 0x15, 0xb9, 0x01, 0x20, + 0x07, 0xf8, 0x09, 0x00, 0x7f, 0x1c, 0x02, 0x2f, 0xb9, 0xd3, 0x28, 0x46, + 0xbd, 0xe8, 0xf0, 0x87, 0x38, 0x21, 0x6a, 0x48, 0xf2, 0xf7, 0x8c, 0xb8, + 0x2d, 0xe9, 0xfc, 0x4e, 0x81, 0x46, 0x68, 0x4e, 0x1c, 0x20, 0x00, 0xfb, + 0x09, 0x60, 0x0d, 0x46, 0x00, 0xf1, 0x28, 0x07, 0xef, 0xf3, 0x11, 0x80, + 0x60, 0x21, 0x81, 0xf3, 0x11, 0x88, 0x00, 0x21, 0xb9, 0x82, 0x39, 0x60, + 0x64, 0x21, 0x79, 0x60, 0x00, 0x21, 0xf9, 0x82, 0x80, 0xf3, 0x11, 0x88, + 0x06, 0xeb, 0xc9, 0x00, 0x01, 0x90, 0x34, 0x78, 0xdf, 0xf8, 0x54, 0xb1, + 0x20, 0x07, 0x44, 0xbf, 0x01, 0x98, 0x84, 0x69, 0x4f, 0xf4, 0x82, 0x70, + 0x00, 0xfb, 0x09, 0xb0, 0x00, 0xf5, 0x21, 0x7a, 0xe0, 0x07, 0x0a, 0xd5, + 0x01, 0x20, 0xb8, 0x82, 0x29, 0x46, 0x48, 0x46, 0x00, 0xf0, 0x3a, 0xf9, + 0x30, 0xb3, 0xb9, 0x8a, 0x40, 0xea, 0x01, 0x40, 0x38, 0x60, 0x38, 0x68, + 0x60, 0xb9, 0xa0, 0x07, 0x0d, 0xd5, 0x02, 0x20, 0xb8, 0x82, 0x29, 0x46, + 0x48, 0x46, 0x00, 0xf0, 0xd1, 0xf9, 0xc8, 0xb1, 0xb9, 0x8a, 0x40, 0xea, + 0x01, 0x40, 0x38, 0x60, 0x38, 0x68, 0x00, 0x28, 0x4d, 0xd1, 0x60, 0x07, + 0x4d, 0xd5, 0x03, 0x20, 0xb8, 0x82, 0x19, 0xf8, 0x0b, 0x00, 0x20, 0xb1, + 0x49, 0x46, 0x01, 0x20, 0xf1, 0xf7, 0xe3, 0xfd, 0x40, 0xb9, 0xb8, 0x8a, + 0x00, 0x04, 0x40, 0xf0, 0x03, 0x00, 0x3b, 0xe0, 0x38, 0x60, 0xdc, 0xe7, + 0x38, 0x60, 0xea, 0xe7, 0xa5, 0xf8, 0x00, 0x90, 0x30, 0x1d, 0xa8, 0x60, + 0xf0, 0x88, 0x00, 0xf0, 0x52, 0xf8, 0x68, 0x60, 0xc5, 0xf8, 0x0c, 0xa0, + 0x4f, 0xf4, 0xa0, 0x70, 0x00, 0xfb, 0x09, 0xb0, 0x01, 0x1d, 0xa4, 0x30, + 0x29, 0x61, 0x68, 0x61, 0x00, 0xf0, 0x3e, 0xf8, 0xa8, 0x61, 0x00, 0x20, + 0x28, 0x62, 0xee, 0xf7, 0x99, 0xfb, 0x83, 0x46, 0xbb, 0xf1, 0x2e, 0x0f, + 0x16, 0xd3, 0x00, 0xf0, 0x48, 0xf8, 0x29, 0x49, 0xf0, 0xf7, 0xd0, 0xff, + 0x00, 0x90, 0xab, 0xf1, 0x2d, 0x00, 0xf0, 0xf7, 0xbb, 0xff, 0x00, 0x99, + 0xf1, 0xf7, 0x56, 0xf9, 0xf8, 0xf7, 0x54, 0xf8, 0x40, 0x08, 0xf0, 0xf7, + 0x75, 0xf8, 0xa8, 0x70, 0x28, 0x46, 0xff, 0xf7, 0xa1, 0xf9, 0x04, 0xe0, + 0xb8, 0x8a, 0x00, 0x04, 0x40, 0xf0, 0x04, 0x00, 0x38, 0x60, 0x38, 0x68, + 0x98, 0xb9, 0x20, 0x07, 0x11, 0xd5, 0xa5, 0xf8, 0x00, 0x90, 0x30, 0x1d, + 0xa8, 0x60, 0xc5, 0xf8, 0x0c, 0xa0, 0x00, 0xf0, 0x0d, 0xf8, 0xa8, 0x61, + 0x00, 0x20, 0x28, 0x62, 0x01, 0x98, 0x00, 0xf1, 0x18, 0x01, 0x28, 0x46, + 0xff, 0xf7, 0x21, 0xfb, 0x38, 0x60, 0x38, 0x68, 0xbd, 0xe8, 0xf6, 0x8e, + 0xef, 0x61, 0x49, 0x46, 0x01, 0x20, 0xf1, 0xf7, 0x87, 0xbd, 0x00, 0xf0, + 0xc0, 0xb8, 0x10, 0xb5, 0xf0, 0xf7, 0x86, 0xff, 0x04, 0x46, 0x00, 0xf0, + 0x08, 0xf8, 0x21, 0x46, 0xf1, 0xf7, 0x1e, 0xf9, 0xbd, 0xe8, 0x10, 0x40, + 0x0a, 0x49, 0xf0, 0xf7, 0x8b, 0xbf, 0x03, 0x48, 0x00, 0x6c, 0xf0, 0xf7, + 0x77, 0xbf, 0x00, 0x00, 0x48, 0xa8, 0x00, 0x20, 0x78, 0x29, 0x00, 0x20, + 0xa5, 0x58, 0x01, 0x01, 0x00, 0x24, 0x74, 0x49, 0x68, 0x2b, 0x00, 0x20, + 0xb4, 0x2b, 0x00, 0x20, 0x8c, 0x2b, 0x00, 0x20, 0x00, 0x7c, 0x92, 0x4d, + 0x53, 0x48, 0x41, 0x89, 0x03, 0x22, 0x11, 0x42, 0x00, 0xd1, 0x70, 0x47, + 0x80, 0xb5, 0xc1, 0xf3, 0x01, 0x11, 0x61, 0xb1, 0x01, 0x6c, 0x80, 0x69, + 0xfc, 0xf7, 0x82, 0xfb, 0x05, 0x28, 0x28, 0xbf, 0x05, 0x20, 0x01, 0x21, + 0x01, 0xfa, 0x00, 0xf0, 0x4a, 0x49, 0x88, 0x60, 0xc8, 0x60, 0x01, 0xbd, + 0xc1, 0x68, 0xca, 0x07, 0x01, 0xd5, 0x04, 0x20, 0x70, 0x47, 0x8a, 0x07, + 0x01, 0xd5, 0x03, 0x20, 0x70, 0x47, 0x49, 0x07, 0x01, 0xd5, 0x05, 0x20, + 0x70, 0x47, 0x00, 0x69, 0x00, 0xb1, 0x06, 0x20, 0x70, 0x47, 0x2d, 0xe9, + 0xf0, 0x41, 0x04, 0x46, 0x0d, 0x46, 0xdf, 0xf8, 0xf8, 0x80, 0x08, 0xf1, + 0x08, 0x00, 0x68, 0x60, 0x00, 0x26, 0x00, 0x20, 0xee, 0xf7, 0x00, 0xfb, + 0x32, 0x28, 0x28, 0xd3, 0x6b, 0x68, 0x37, 0x49, 0x9f, 0x89, 0x93, 0xf8, + 0x0e, 0xc0, 0x5b, 0x8a, 0x09, 0x6c, 0x1b, 0x0a, 0x0c, 0xf0, 0x07, 0x0c, + 0x03, 0xf0, 0x07, 0x03, 0x01, 0x22, 0x63, 0x44, 0x9a, 0x40, 0x32, 0x38, + 0x92, 0xb2, 0xb0, 0xfb, 0xf2, 0xf0, 0xef, 0xf7, 0x8b, 0xf8, 0x4f, 0xf6, + 0xc0, 0x71, 0x39, 0x40, 0x01, 0x43, 0x29, 0x81, 0xef, 0xf7, 0xab, 0xf8, + 0xf0, 0xf7, 0x10, 0xff, 0x01, 0x46, 0x4f, 0xf0, 0x8f, 0x40, 0xf0, 0xf7, + 0x1b, 0xff, 0x00, 0xf0, 0xb5, 0xf9, 0xf7, 0xf7, 0xa5, 0xff, 0x68, 0x81, + 0x00, 0xe0, 0x07, 0x26, 0x00, 0x27, 0x86, 0xb9, 0x24, 0xfa, 0x07, 0xf0, + 0xc0, 0x07, 0x0c, 0xd5, 0x2f, 0x60, 0x28, 0x46, 0x00, 0xf0, 0xc7, 0xf9, + 0x28, 0x46, 0xff, 0xf7, 0xa9, 0xff, 0x06, 0x00, 0x03, 0xd1, 0x68, 0x69, + 0x08, 0xeb, 0x87, 0x01, 0x08, 0x62, 0x7f, 0x1c, 0x02, 0x2f, 0xea, 0xd3, + 0x30, 0x46, 0xbd, 0xe8, 0xf0, 0x81, 0x38, 0xb5, 0x0c, 0x46, 0x16, 0x48, + 0x14, 0x49, 0x00, 0x68, 0x89, 0x7a, 0x80, 0x08, 0x01, 0xf0, 0x03, 0x01, + 0x41, 0xea, 0x80, 0x05, 0x05, 0xf0, 0x03, 0x00, 0xed, 0xf7, 0x26, 0xfa, + 0x08, 0xb9, 0x02, 0x20, 0x32, 0xbd, 0x21, 0x46, 0x28, 0x46, 0xbd, 0xe8, + 0x34, 0x40, 0x96, 0xe7, 0x0b, 0x4a, 0x52, 0x68, 0x01, 0x23, 0x00, 0xf0, + 0x01, 0x00, 0x92, 0x08, 0x03, 0xfa, 0x00, 0xf0, 0x40, 0xea, 0x82, 0x00, + 0x8b, 0xe7, 0x02, 0x28, 0x06, 0xd2, 0x01, 0x46, 0x04, 0x4a, 0x02, 0xeb, + 0x80, 0x00, 0x00, 0x6a, 0x00, 0xf0, 0x2b, 0xba, 0x70, 0x47, 0x00, 0x00, + 0x78, 0x29, 0x00, 0x20, 0xf8, 0x28, 0x00, 0x20, 0xef, 0xf3, 0x11, 0x80, + 0x60, 0x21, 0x81, 0xf3, 0x11, 0x88, 0x70, 0x47, 0x80, 0xb5, 0x8a, 0x48, + 0xc1, 0x6a, 0x40, 0x6b, 0xfc, 0xf7, 0xd8, 0xfa, 0x88, 0x49, 0x4a, 0xe0, + 0x2d, 0xe9, 0xf8, 0x43, 0x0c, 0x46, 0x00, 0x27, 0x61, 0x68, 0x8d, 0x89, + 0x8e, 0x7d, 0x61, 0x78, 0x01, 0x29, 0x08, 0xbf, 0x01, 0x28, 0x32, 0xd1, + 0x00, 0x20, 0xee, 0xf7, 0x6d, 0xfa, 0x0f, 0x28, 0x38, 0xbf, 0x01, 0x27, + 0x2b, 0xd3, 0x62, 0x68, 0x7c, 0x49, 0x92, 0xf8, 0x0e, 0xc0, 0x52, 0x8a, + 0x09, 0x6c, 0x12, 0x0a, 0x0c, 0xf0, 0x07, 0x0c, 0x02, 0xf0, 0x07, 0x02, + 0x01, 0x23, 0x62, 0x44, 0x03, 0xfa, 0x02, 0xf2, 0x0f, 0x38, 0x92, 0xb2, + 0xb0, 0xfb, 0xf2, 0xf0, 0xee, 0xf7, 0xf6, 0xff, 0x80, 0x46, 0x05, 0xf0, + 0x3f, 0x00, 0xef, 0xf7, 0x18, 0xf8, 0x81, 0x46, 0x40, 0x46, 0xef, 0xf7, + 0x14, 0xf8, 0x48, 0x45, 0x0b, 0xd2, 0xb9, 0xfb, 0xf0, 0xf6, 0xb6, 0xb2, + 0x4f, 0xf6, 0xc0, 0x71, 0x70, 0x43, 0x29, 0x40, 0x48, 0x45, 0x48, 0xea, + 0x01, 0x05, 0x38, 0xbf, 0x76, 0x1c, 0x25, 0x81, 0x66, 0x81, 0x38, 0x46, + 0xbd, 0xe8, 0xf2, 0x83, 0x80, 0xb5, 0x64, 0x48, 0x01, 0x6c, 0x80, 0x69, + 0xfc, 0xf7, 0x8c, 0xfa, 0x63, 0x49, 0x81, 0xf8, 0x21, 0x00, 0x01, 0xbd, + 0x38, 0xb5, 0x0c, 0x46, 0x5f, 0x48, 0x5e, 0x49, 0x00, 0x68, 0x49, 0x89, + 0x80, 0x08, 0xc1, 0xf3, 0x81, 0x01, 0x41, 0xea, 0x80, 0x05, 0x05, 0xf0, + 0x03, 0x00, 0xed, 0xf7, 0x8b, 0xf9, 0x08, 0xb9, 0x01, 0x20, 0x32, 0xbd, + 0x22, 0x46, 0x29, 0x46, 0xbd, 0xe8, 0x38, 0x40, 0x00, 0x20, 0x22, 0xe0, + 0x38, 0xb5, 0x0c, 0x46, 0x54, 0x48, 0x52, 0x49, 0x00, 0x68, 0x89, 0x7a, + 0x80, 0x08, 0x01, 0xf0, 0x03, 0x01, 0x41, 0xea, 0x80, 0x05, 0x05, 0xf0, + 0x03, 0x00, 0xed, 0xf7, 0x81, 0xf9, 0x08, 0xb9, 0x02, 0x20, 0x32, 0xbd, + 0x22, 0x46, 0x29, 0x46, 0xbd, 0xe8, 0x38, 0x40, 0x00, 0x20, 0x54, 0xe0, + 0x0a, 0x46, 0x49, 0x49, 0x01, 0x23, 0x49, 0x68, 0x00, 0xf0, 0x01, 0x00, + 0x03, 0xfa, 0x00, 0xf0, 0x01, 0x43, 0x01, 0x20, 0x49, 0xe0, 0x2d, 0xe9, + 0xf8, 0x43, 0x0c, 0x46, 0x04, 0xf0, 0x04, 0x01, 0xdf, 0xf8, 0x00, 0x81, + 0x15, 0x46, 0x00, 0x26, 0xa9, 0x70, 0x6e, 0x70, 0x04, 0xf0, 0x08, 0x01, + 0xe9, 0x70, 0x2e, 0x61, 0x08, 0xf1, 0x08, 0x01, 0x69, 0x60, 0x29, 0x46, + 0xff, 0xf7, 0x62, 0xff, 0x00, 0xb1, 0x08, 0x26, 0x00, 0x27, 0x00, 0x20, + 0x02, 0xe0, 0x38, 0x00, 0x18, 0xbf, 0x01, 0x20, 0x2e, 0xbb, 0x24, 0xfa, + 0x07, 0xf1, 0xc9, 0x07, 0x21, 0xd5, 0x34, 0x49, 0x2f, 0x70, 0x4f, 0xf4, + 0x7c, 0x72, 0x02, 0xfb, 0x00, 0x16, 0x06, 0xf1, 0xe0, 0x00, 0xe8, 0x60, + 0x30, 0x1d, 0x68, 0x61, 0x14, 0x20, 0x00, 0xfb, 0x07, 0x89, 0x09, 0xf1, + 0x28, 0x01, 0x28, 0x46, 0x00, 0xf0, 0x58, 0xf8, 0x28, 0x46, 0x00, 0xf0, + 0x09, 0xfa, 0x6b, 0x6a, 0xaa, 0x6a, 0x29, 0x7e, 0x30, 0x46, 0xfa, 0xf7, + 0x37, 0xf9, 0x09, 0xf1, 0x28, 0x01, 0x28, 0x46, 0x00, 0xf0, 0x58, 0xf8, + 0x06, 0x46, 0x7f, 0x1c, 0x02, 0x2f, 0xd2, 0xd3, 0x30, 0x46, 0xbd, 0xe8, + 0xf2, 0x83, 0x2d, 0xe9, 0xf0, 0x41, 0x0c, 0x46, 0x15, 0x46, 0x01, 0x21, + 0x69, 0x70, 0x04, 0xf0, 0x04, 0x01, 0xa9, 0x70, 0x04, 0xf0, 0x08, 0x01, + 0xe9, 0x70, 0x00, 0x26, 0xdf, 0xf8, 0x60, 0x80, 0x6e, 0x61, 0x08, 0xf1, + 0x08, 0x01, 0x69, 0x60, 0x2e, 0x61, 0x05, 0xf5, 0xde, 0x71, 0xe9, 0x60, + 0x29, 0x46, 0xff, 0xf7, 0x13, 0xff, 0x00, 0xb1, 0x08, 0x26, 0x00, 0x27, + 0xae, 0xb9, 0x24, 0xfa, 0x07, 0xf0, 0xc0, 0x07, 0x11, 0xd5, 0x14, 0x20, + 0x00, 0xfb, 0x07, 0x86, 0x2f, 0x70, 0x06, 0xf1, 0x24, 0x01, 0x28, 0x46, + 0x00, 0xf0, 0x18, 0xf8, 0x28, 0x46, 0x00, 0xf0, 0xc9, 0xf9, 0x06, 0xf1, + 0x24, 0x01, 0x28, 0x46, 0x00, 0xf0, 0x1e, 0xf8, 0x06, 0x46, 0x7f, 0x1c, + 0x02, 0x2f, 0xe5, 0xd3, 0x30, 0x46, 0xbd, 0xe8, 0xf0, 0x81, 0x00, 0x00, + 0x78, 0x29, 0x00, 0x20, 0xdc, 0x29, 0x00, 0x20, 0x2c, 0x2a, 0x00, 0x20, + 0xc0, 0x92, 0x00, 0x20, 0x10, 0xb5, 0x0c, 0x46, 0xff, 0xf7, 0xd8, 0xfe, + 0x01, 0x21, 0x61, 0x60, 0x00, 0x21, 0x21, 0x60, 0xa1, 0x60, 0xe1, 0x60, + 0x21, 0x61, 0x80, 0xf3, 0x11, 0x88, 0x10, 0xbd, 0x70, 0xb5, 0x04, 0x46, + 0x0d, 0x46, 0x20, 0x6a, 0xc1, 0x07, 0x48, 0xbf, 0x04, 0x26, 0x1b, 0xd4, + 0x81, 0x07, 0x48, 0xbf, 0x03, 0x26, 0x17, 0xd4, 0x40, 0x07, 0x48, 0xbf, + 0x07, 0x26, 0x13, 0xd4, 0x60, 0x7e, 0x08, 0xb1, 0x0a, 0x26, 0x0f, 0xe0, + 0xa0, 0x7e, 0x81, 0x07, 0x48, 0xbf, 0x09, 0x26, 0x0a, 0xd4, 0xc0, 0x07, + 0x05, 0xd4, 0xe0, 0x7e, 0x08, 0xb1, 0x05, 0x26, 0x04, 0xe0, 0x20, 0x7f, + 0x08, 0xb1, 0x06, 0x26, 0x00, 0xe0, 0x00, 0x26, 0xff, 0xf7, 0xa8, 0xfe, + 0x2e, 0x60, 0xa1, 0x6a, 0xa9, 0x60, 0x61, 0x6a, 0xe9, 0x60, 0x21, 0x7e, + 0x29, 0x61, 0x00, 0x21, 0x69, 0x60, 0x80, 0xf3, 0x11, 0x88, 0x30, 0x46, + 0x70, 0xbd, 0x00, 0x00, 0xc0, 0xf3, 0xc7, 0x52, 0x7e, 0x3a, 0xcc, 0xbf, + 0xd2, 0xf1, 0x18, 0x0c, 0x07, 0xe0, 0x6f, 0xf0, 0x7f, 0x41, 0xd1, 0x40, + 0x00, 0x42, 0x58, 0xbf, 0x40, 0x18, 0x88, 0x43, 0x70, 0x47, 0x18, 0x2a, + 0x06, 0xda, 0x41, 0x00, 0x18, 0xbf, 0x4f, 0xf0, 0x7e, 0x50, 0x28, 0xbf, + 0x4f, 0xf0, 0x00, 0x40, 0x70, 0x47, 0x00, 0x00, 0x00, 0x21, 0xc0, 0xf8, + 0x98, 0x10, 0x40, 0xf8, 0x0c, 0x1f, 0x41, 0x60, 0x70, 0x47, 0x10, 0xb5, + 0x04, 0x46, 0xff, 0xf7, 0xf5, 0xff, 0x00, 0x21, 0x01, 0x20, 0xfe, 0xf7, + 0x4b, 0xf9, 0x20, 0x46, 0xbd, 0xe8, 0x10, 0x40, 0x2d, 0xe9, 0xf0, 0x41, + 0x05, 0x46, 0x4f, 0xf4, 0x80, 0x70, 0x29, 0x68, 0x00, 0xf0, 0x8b, 0xf8, + 0x00, 0xf0, 0x87, 0xf8, 0x04, 0x46, 0xd5, 0xf8, 0x98, 0x00, 0x00, 0x28, + 0x7a, 0xd1, 0x29, 0x68, 0x4f, 0xf4, 0x40, 0x70, 0x00, 0xf0, 0x7f, 0xf8, + 0x00, 0xf0, 0x7b, 0xf8, 0x01, 0x46, 0xd5, 0xf8, 0x98, 0x00, 0x00, 0x28, + 0x6e, 0xd1, 0x20, 0x46, 0xf0, 0xf7, 0x98, 0xfd, 0x01, 0x46, 0x4f, 0xf0, + 0x44, 0x40, 0xf0, 0xf7, 0x15, 0xfd, 0x80, 0x46, 0x20, 0x46, 0x41, 0x46, + 0xf0, 0xf7, 0x9e, 0xfe, 0x00, 0x21, 0xf0, 0xf7, 0xa3, 0xff, 0x94, 0xbf, + 0x4f, 0xf0, 0x7c, 0x51, 0x4f, 0xf0, 0x3f, 0x41, 0xf0, 0xf7, 0xf8, 0xfd, + 0xf0, 0xf7, 0xfe, 0xfe, 0xc0, 0xf5, 0x80, 0x70, 0x00, 0xf0, 0x54, 0xf8, + 0x00, 0xf0, 0x57, 0xf8, 0x07, 0x46, 0xd5, 0xf8, 0x98, 0x00, 0x00, 0x28, + 0x4a, 0xd1, 0x4f, 0xf0, 0x40, 0x40, 0x39, 0x46, 0xf0, 0xf7, 0x82, 0xfe, + 0x41, 0x46, 0xf0, 0xf7, 0x7f, 0xfe, 0x00, 0x21, 0xf0, 0xf7, 0x84, 0xff, + 0x04, 0x46, 0x94, 0xbf, 0x4f, 0xf0, 0x7c, 0x50, 0x4f, 0xf0, 0x3f, 0x40, + 0x21, 0x46, 0xf0, 0xf7, 0xd7, 0xfd, 0xf0, 0xf7, 0xdd, 0xfe, 0x00, 0x28, + 0x54, 0xbf, 0x08, 0x20, 0x6f, 0xf0, 0x07, 0x00, 0x84, 0x19, 0xb4, 0xf5, + 0x80, 0x6f, 0x28, 0xbf, 0x34, 0x1a, 0x29, 0x68, 0x20, 0x46, 0x00, 0xf0, + 0x30, 0xf8, 0x00, 0xf0, 0x2c, 0xf8, 0x80, 0x46, 0xd5, 0xf8, 0x98, 0x00, + 0x00, 0xbb, 0xa0, 0x1b, 0xf0, 0xf7, 0xb2, 0xfc, 0x39, 0x46, 0xf0, 0xf7, + 0x57, 0xfe, 0x04, 0x46, 0x40, 0x46, 0x39, 0x46, 0xf0, 0xf7, 0x42, 0xfd, + 0x01, 0x46, 0x20, 0x46, 0xf0, 0xf7, 0xc0, 0xfc, 0x00, 0x21, 0xf0, 0xf7, + 0x53, 0xff, 0x04, 0x46, 0x94, 0xbf, 0x4f, 0xf0, 0x7c, 0x50, 0x4f, 0xf0, + 0x3f, 0x40, 0x21, 0x46, 0xf0, 0xf7, 0xa6, 0xfd, 0xf0, 0xf7, 0xac, 0xfe, + 0x30, 0x1a, 0x00, 0xf0, 0x03, 0xf8, 0x6e, 0x61, 0xbd, 0xe8, 0xf0, 0x81, + 0x80, 0xf3, 0x0a, 0x06, 0x29, 0x68, 0x30, 0x46, 0x01, 0xe0, 0x28, 0x46, + 0x38, 0xe0, 0x70, 0xb5, 0x04, 0x46, 0x00, 0x29, 0x07, 0xbf, 0x40, 0xf2, + 0xe1, 0x65, 0x4f, 0xf4, 0xdc, 0x60, 0x40, 0xf2, 0xe3, 0x65, 0x40, 0xf2, + 0xe2, 0x60, 0xef, 0xf3, 0x11, 0x86, 0x60, 0x21, 0x81, 0xf3, 0x11, 0x88, + 0xa1, 0x05, 0x09, 0x0e, 0xec, 0xf7, 0x60, 0xff, 0x04, 0xf0, 0x03, 0x04, + 0x00, 0xf0, 0x0f, 0xf8, 0x44, 0xf0, 0x80, 0x01, 0x00, 0xf0, 0x0c, 0xf8, + 0x00, 0xf0, 0x09, 0xf8, 0x00, 0xf0, 0x07, 0xf8, 0x05, 0xf1, 0x8c, 0x40, + 0x01, 0x78, 0x00, 0x78, 0x86, 0xf3, 0x11, 0x88, 0x70, 0xbd, 0x21, 0x46, + 0x28, 0x46, 0xec, 0xf7, 0x49, 0xbf, 0x00, 0x21, 0x01, 0x22, 0x20, 0xfa, + 0x02, 0xf3, 0xdb, 0x07, 0x01, 0xd5, 0x11, 0x46, 0x02, 0xe0, 0x52, 0x1c, + 0x18, 0x2a, 0xf6, 0xd3, 0x08, 0x46, 0x70, 0x47, 0x70, 0xb5, 0x04, 0x46, + 0x60, 0x68, 0x40, 0x68, 0xff, 0xf7, 0xed, 0xff, 0x05, 0xb2, 0x20, 0x68, + 0x20, 0x76, 0x01, 0x20, 0x60, 0x76, 0x00, 0x20, 0xa0, 0x76, 0x60, 0x68, + 0xe0, 0x61, 0x04, 0xf1, 0x08, 0x00, 0x20, 0x62, 0x00, 0x20, 0x60, 0x62, + 0x04, 0xf1, 0x18, 0x00, 0xfd, 0xf7, 0x80, 0xfe, 0xe0, 0x6a, 0xe0, 0x60, + 0x08, 0xb1, 0x01, 0x20, 0x07, 0xe0, 0xa0, 0x6b, 0xa8, 0x42, 0x04, 0xbf, + 0xe0, 0x6b, 0xe8, 0x42, 0x03, 0xd0, 0x01, 0x20, 0x20, 0x61, 0xc4, 0xf8, + 0x98, 0x00, 0x00, 0x20, 0xd4, 0xf8, 0x98, 0x10, 0x00, 0x29, 0x41, 0xd1, + 0xd4, 0xe9, 0x12, 0x01, 0xf0, 0xf7, 0xf0, 0xfb, 0x05, 0x46, 0xd4, 0xe9, + 0x10, 0x01, 0xf0, 0xf7, 0xeb, 0xfb, 0x01, 0x46, 0x28, 0x46, 0xf0, 0xf7, + 0x33, 0xfc, 0x05, 0x46, 0xd4, 0xe9, 0x16, 0x01, 0xf0, 0xf7, 0xe2, 0xfb, + 0x06, 0x46, 0xd4, 0xe9, 0x14, 0x01, 0xf0, 0xf7, 0xdd, 0xfb, 0x01, 0x46, + 0x30, 0x46, 0xf0, 0xf7, 0x25, 0xfc, 0x04, 0x46, 0x28, 0x46, 0x29, 0x46, + 0xf0, 0xf7, 0xae, 0xfd, 0x29, 0x46, 0xf0, 0xf7, 0xab, 0xfd, 0x10, 0x49, + 0xf0, 0xf7, 0x1a, 0xfc, 0x01, 0x46, 0x28, 0x46, 0xf0, 0xf7, 0x94, 0xfc, + 0x05, 0x46, 0x20, 0x46, 0x21, 0x46, 0xf0, 0xf7, 0x9f, 0xfd, 0x21, 0x46, + 0xf0, 0xf7, 0x9c, 0xfd, 0x08, 0x49, 0xf0, 0xf7, 0x0b, 0xfc, 0x01, 0x46, + 0x20, 0x46, 0xf0, 0xf7, 0x85, 0xfc, 0x29, 0x46, 0xf0, 0xf7, 0xf6, 0xfc, + 0xbd, 0xe8, 0x70, 0x40, 0x4f, 0xf0, 0x7c, 0x51, 0xf0, 0xf7, 0x8c, 0xbd, + 0x70, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x00, 0x21, 0x41, 0x63, + 0x01, 0x62, 0x41, 0x76, 0x81, 0x76, 0xc1, 0x76, 0x01, 0x77, 0x70, 0x47, + 0x10, 0xb5, 0x04, 0x46, 0xff, 0xf7, 0xf4, 0xff, 0x20, 0x46, 0x00, 0xf0, + 0x8f, 0xf8, 0x20, 0x6a, 0x60, 0xb9, 0xa0, 0x78, 0x02, 0x28, 0x09, 0xd0, + 0xe0, 0x78, 0x00, 0x28, 0x04, 0xbf, 0x60, 0x6b, 0x00, 0x28, 0x03, 0xd1, + 0x20, 0x46, 0xbd, 0xe8, 0x10, 0x40, 0x13, 0xe0, 0x10, 0xbd, 0x10, 0xb5, + 0xb4, 0xb0, 0x04, 0x46, 0x00, 0x20, 0x00, 0x90, 0x69, 0x46, 0x20, 0x46, + 0xfc, 0xf7, 0x74, 0xfa, 0x6b, 0x46, 0x01, 0xaa, 0x04, 0xf5, 0x79, 0x71, + 0x04, 0xf5, 0x96, 0x60, 0xfb, 0xf7, 0xfb, 0xff, 0x34, 0xb0, 0x10, 0xbd, + 0xf8, 0xb5, 0x04, 0x46, 0x6a, 0x46, 0x60, 0x78, 0x25, 0x78, 0x00, 0x28, + 0x0c, 0xbf, 0x2e, 0x46, 0x02, 0x26, 0x00, 0x21, 0x00, 0x20, 0xed, 0xf7, + 0x92, 0xfa, 0x00, 0x98, 0x10, 0xb9, 0x01, 0x20, 0x60, 0x76, 0xf1, 0xbd, + 0x00, 0x99, 0x2b, 0x4a, 0x00, 0x20, 0x08, 0x60, 0x00, 0x99, 0x48, 0x71, + 0x00, 0x99, 0x94, 0xf8, 0xb8, 0x01, 0x08, 0x71, 0x00, 0x99, 0x60, 0x6a, + 0xc8, 0x60, 0x00, 0x99, 0xa0, 0x6a, 0x08, 0x61, 0x00, 0x99, 0x00, 0x98, + 0x00, 0xf5, 0x96, 0x60, 0x48, 0x61, 0x04, 0xf1, 0x38, 0x00, 0x00, 0x99, + 0x88, 0x60, 0x60, 0x68, 0x00, 0x99, 0x18, 0x30, 0x88, 0x61, 0x00, 0x21, + 0x00, 0x20, 0xed, 0xf7, 0xf8, 0xfa, 0x00, 0x98, 0x00, 0x7f, 0xa0, 0x76, + 0x60, 0x69, 0x28, 0xb1, 0x00, 0x99, 0xcc, 0x22, 0x01, 0xf5, 0x79, 0x71, + 0xf3, 0xf7, 0x92, 0xfc, 0xe0, 0x68, 0x28, 0xb1, 0x00, 0x99, 0xcc, 0x22, + 0x01, 0xf5, 0x96, 0x61, 0xf3, 0xf7, 0x8a, 0xfc, 0xef, 0xf3, 0x11, 0x87, + 0x60, 0x20, 0x80, 0xf3, 0x11, 0x88, 0x30, 0x46, 0xee, 0xf7, 0x23, 0xff, + 0x00, 0x99, 0x01, 0xf5, 0x79, 0x71, 0xee, 0xf7, 0xbd, 0xfe, 0x10, 0xb9, + 0x01, 0x20, 0xe0, 0x76, 0x0b, 0xe0, 0x00, 0x2d, 0x0c, 0xbf, 0x0a, 0x21, + 0x0e, 0x21, 0x30, 0x46, 0xee, 0xf7, 0x1f, 0xff, 0x60, 0x78, 0x10, 0xb9, + 0x28, 0x46, 0xf8, 0xf7, 0xf4, 0xf9, 0x87, 0xf3, 0x11, 0x88, 0x00, 0x20, + 0xed, 0xf7, 0x7f, 0xfa, 0xf1, 0xbd, 0x00, 0x00, 0xcb, 0x62, 0x01, 0x01, + 0x10, 0xb5, 0x04, 0x46, 0xa0, 0xb0, 0x20, 0x78, 0x8d, 0xf8, 0x00, 0x00, + 0x60, 0x78, 0x8d, 0xf8, 0x01, 0x00, 0xa0, 0x78, 0x8d, 0xf8, 0x02, 0x00, + 0x60, 0x68, 0x01, 0x90, 0x04, 0xf1, 0x08, 0x00, 0x02, 0x90, 0x04, 0xf1, + 0x38, 0x00, 0x03, 0x90, 0xa1, 0x78, 0x60, 0x78, 0xfd, 0xf7, 0x54, 0xff, + 0x68, 0x46, 0xfd, 0xf7, 0x6d, 0xfd, 0x20, 0x69, 0x20, 0xb1, 0x03, 0x99, + 0x4f, 0xf4, 0xc0, 0x72, 0xf3, 0xf7, 0x42, 0xfc, 0x9d, 0xf9, 0x10, 0x00, + 0x40, 0x42, 0x84, 0xf8, 0xb8, 0x01, 0x9d, 0xf8, 0x11, 0x00, 0x20, 0x76, + 0x05, 0x98, 0x20, 0x62, 0x06, 0x98, 0x60, 0x62, 0x07, 0x98, 0xa0, 0x62, + 0x20, 0xb0, 0x10, 0xbd, 0x00, 0x21, 0x00, 0x20, 0x10, 0xb5, 0xed, 0xf7, + 0x4a, 0xf8, 0x60, 0x48, 0x01, 0x78, 0x00, 0x24, 0x39, 0xb1, 0x41, 0x78, + 0x90, 0xf9, 0x02, 0x00, 0x40, 0x18, 0xc0, 0xb2, 0x00, 0xf0, 0x00, 0xf9, + 0x0d, 0xe0, 0x5b, 0x48, 0x80, 0x7a, 0x10, 0xf0, 0x03, 0x00, 0x08, 0xbf, + 0x01, 0x24, 0x06, 0xd0, 0x00, 0xf0, 0x01, 0x00, 0x80, 0xf0, 0x01, 0x00, + 0x00, 0xf0, 0x06, 0xf8, 0x04, 0x46, 0x00, 0x20, 0xed, 0xf7, 0x8a, 0xf8, + 0x20, 0x46, 0x10, 0xbd, 0x2d, 0xe9, 0xf0, 0x4f, 0x89, 0xb0, 0x05, 0x46, + 0x04, 0xa8, 0xef, 0xf7, 0x7c, 0xfa, 0x69, 0x46, 0x28, 0x46, 0xf0, 0xf7, + 0x15, 0xff, 0xdd, 0xe9, 0x00, 0x01, 0xcd, 0xe9, 0x02, 0x01, 0x02, 0xaa, + 0x02, 0x21, 0x28, 0x46, 0xf0, 0xf7, 0x43, 0xff, 0x00, 0x21, 0x00, 0x20, + 0x00, 0xf0, 0xd4, 0xf8, 0x01, 0x21, 0xe8, 0xb2, 0xef, 0xf7, 0x68, 0xf9, + 0x44, 0x4a, 0x0f, 0xf2, 0xc0, 0x19, 0xd2, 0xe9, 0x08, 0x01, 0xef, 0xf7, + 0x11, 0xfa, 0x01, 0x46, 0xe8, 0xb2, 0xef, 0xf7, 0x2b, 0xfa, 0x3e, 0x48, + 0xc0, 0x69, 0x40, 0x00, 0x05, 0x21, 0xb0, 0xfb, 0xf1, 0xf2, 0x00, 0x23, + 0x28, 0x46, 0xfe, 0xf7, 0x91, 0xf9, 0x3b, 0x48, 0x3b, 0x49, 0x00, 0x78, + 0x08, 0x70, 0x06, 0x23, 0x0f, 0xf2, 0x84, 0x12, 0x80, 0x08, 0x06, 0x21, + 0x90, 0xfb, 0xf1, 0xf1, 0x03, 0xfb, 0x11, 0x00, 0x88, 0x46, 0x10, 0xf8, + 0x02, 0xa0, 0x00, 0x26, 0x01, 0xe0, 0x00, 0x2c, 0x46, 0xd1, 0x00, 0x27, + 0x5f, 0xfa, 0x87, 0xfb, 0x19, 0xf8, 0x1b, 0x10, 0x40, 0xf2, 0x32, 0x70, + 0xec, 0xf7, 0x88, 0xfd, 0x09, 0xeb, 0x4b, 0x00, 0x00, 0x24, 0x41, 0x78, + 0x40, 0xf2, 0x34, 0x70, 0xec, 0xf7, 0x80, 0xfd, 0x01, 0x21, 0x40, 0xf2, + 0x33, 0x70, 0xec, 0xf7, 0x7b, 0xfd, 0x00, 0x21, 0x40, 0xf2, 0x35, 0x70, + 0xec, 0xf7, 0x76, 0xfd, 0x51, 0x46, 0x40, 0xf2, 0x36, 0x70, 0xec, 0xf7, + 0x71, 0xfd, 0xff, 0x21, 0x40, 0xf2, 0x31, 0x70, 0xec, 0xf7, 0x6c, 0xfd, + 0x00, 0x2d, 0x0c, 0xbf, 0x4f, 0xf0, 0x01, 0x0b, 0x4f, 0xf0, 0x02, 0x0b, + 0x4b, 0xea, 0x48, 0x11, 0xc9, 0xb2, 0x4f, 0xf4, 0xe6, 0x60, 0xec, 0xf7, + 0x5f, 0xfd, 0x42, 0xf2, 0x10, 0x73, 0x00, 0x22, 0x59, 0x46, 0x4f, 0xf4, + 0xe6, 0x60, 0xf3, 0xf7, 0x1b, 0xfa, 0x00, 0xb1, 0x03, 0x24, 0x4c, 0xb9, + 0x14, 0x48, 0x00, 0x78, 0x06, 0xa9, 0x71, 0x18, 0x07, 0xeb, 0x47, 0x02, + 0x7f, 0x1c, 0x50, 0x54, 0x02, 0x2f, 0xb9, 0xd3, 0x76, 0x1c, 0x03, 0x2e, + 0xb3, 0xd3, 0x1c, 0xb9, 0x06, 0xa8, 0x00, 0xf0, 0x1b, 0xf8, 0x04, 0x46, + 0x69, 0x46, 0x28, 0x46, 0xf0, 0xf7, 0xa8, 0xfe, 0xfe, 0xf7, 0xe8, 0xf8, + 0x04, 0xa8, 0xef, 0xf7, 0xf3, 0xf9, 0x20, 0x46, 0x09, 0xb0, 0xbd, 0xe8, + 0xf0, 0x8f, 0x00, 0x00, 0xb4, 0x2a, 0x00, 0x20, 0x78, 0x29, 0x00, 0x20, + 0x00, 0xf2, 0x00, 0x20, 0xe6, 0x04, 0x00, 0x46, 0x9f, 0xf3, 0x00, 0x20, + 0x37, 0x07, 0x00, 0x46, 0x70, 0xb5, 0x00, 0x24, 0x00, 0x22, 0x00, 0xeb, + 0x42, 0x03, 0x00, 0x21, 0xd9, 0x80, 0x02, 0xeb, 0x42, 0x06, 0x36, 0x18, + 0xdd, 0x88, 0x8e, 0x5d, 0x49, 0x1c, 0x75, 0x19, 0x03, 0x29, 0xdd, 0x80, + 0xf5, 0xd3, 0xad, 0xb2, 0x03, 0x21, 0x52, 0x1c, 0xb5, 0xfb, 0xf1, 0xf1, + 0x02, 0x2a, 0xd9, 0x80, 0xe9, 0xd3, 0x00, 0x22, 0x00, 0x21, 0x02, 0xeb, + 0x42, 0x03, 0x1b, 0x18, 0xcb, 0x5c, 0x5b, 0xb1, 0x80, 0x2b, 0x09, 0xda, + 0x00, 0xeb, 0x42, 0x06, 0xf6, 0x88, 0x9d, 0x1b, 0x4c, 0xbf, 0xf3, 0x1a, + 0x9b, 0x1b, 0x9b, 0xb2, 0x04, 0x2b, 0x00, 0xd3, 0x02, 0x24, 0x49, 0x1c, + 0x03, 0x29, 0xea, 0xd3, 0x52, 0x1c, 0x02, 0x2a, 0xe6, 0xd3, 0x3c, 0xb9, + 0xc1, 0x88, 0x00, 0x89, 0x09, 0x1a, 0xc9, 0xb2, 0x48, 0x1e, 0xc0, 0xb2, + 0x00, 0xf0, 0x02, 0xf8, 0x20, 0x46, 0x70, 0xbd, 0x10, 0xb5, 0x0c, 0x46, + 0x01, 0x46, 0x40, 0xf6, 0x65, 0x10, 0xec, 0xf7, 0xe3, 0xfc, 0x21, 0x46, + 0xbd, 0xe8, 0x10, 0x40, 0x40, 0xf6, 0x66, 0x10, 0xec, 0xf7, 0xdc, 0xbc, + 0xcb, 0xb5, 0xa1, 0x8f, 0x80, 0x72, 0x00, 0x00, 0x78, 0x00, 0x01, 0x28, + 0x3e, 0x48, 0x0f, 0xf2, 0x10, 0x12, 0x2d, 0xe9, 0xf0, 0x4f, 0x44, 0x68, + 0xef, 0xf3, 0x08, 0x80, 0x20, 0x60, 0x00, 0x21, 0xef, 0xf3, 0x09, 0x80, + 0x60, 0x60, 0xef, 0xf3, 0x03, 0x80, 0xe0, 0x60, 0x04, 0xf1, 0x10, 0x00, + 0x52, 0xf8, 0x21, 0x30, 0x1b, 0x68, 0x40, 0xf8, 0x21, 0x30, 0x49, 0x1c, + 0x13, 0x29, 0xf7, 0xd3, 0x15, 0x22, 0x04, 0xf1, 0x5c, 0x01, 0x0f, 0xf2, + 0x24, 0x10, 0xec, 0xf7, 0xe6, 0xfc, 0x20, 0x68, 0x41, 0x6c, 0xa1, 0x60, + 0x11, 0xf1, 0x0f, 0x0f, 0x18, 0xbf, 0x11, 0xf1, 0x07, 0x0f, 0x06, 0xd1, + 0xc1, 0x6d, 0x61, 0x67, 0x00, 0x6e, 0xa0, 0x67, 0x20, 0x68, 0x40, 0x6e, + 0x02, 0xe0, 0x00, 0x20, 0x60, 0x67, 0xa0, 0x67, 0xe0, 0x67, 0x25, 0x48, + 0x00, 0x68, 0x90, 0xf8, 0x32, 0x00, 0xc4, 0xf8, 0x80, 0x00, 0xbd, 0xe8, + 0xf0, 0x4f, 0x70, 0x47, 0x2d, 0xe9, 0xf0, 0x4f, 0x20, 0x4c, 0x4f, 0xf0, + 0xee, 0x31, 0x20, 0x46, 0xec, 0xf7, 0xd9, 0xfc, 0x1b, 0x4d, 0x1e, 0x49, + 0xef, 0xf3, 0x08, 0x80, 0xa8, 0x60, 0x88, 0x42, 0x24, 0xbf, 0x1c, 0x4a, + 0x82, 0x42, 0x04, 0xd2, 0x1b, 0x48, 0x08, 0x18, 0x40, 0x08, 0x80, 0xf3, + 0x08, 0x88, 0x05, 0xf1, 0x0c, 0x00, 0x68, 0x60, 0xff, 0xf7, 0xa6, 0xff, + 0x0d, 0x20, 0xf1, 0xf7, 0x56, 0xfc, 0x4f, 0xf0, 0xff, 0x31, 0x20, 0x46, + 0xec, 0xf7, 0xbd, 0xfc, 0x80, 0x22, 0x00, 0x23, 0x80, 0x20, 0x00, 0x21, + 0xf1, 0xf7, 0xd6, 0xfc, 0x0a, 0x20, 0xf7, 0xf7, 0xc1, 0xf8, 0xf8, 0xf7, + 0x77, 0xfe, 0x00, 0xb1, 0x01, 0x20, 0x28, 0x70, 0xf8, 0xf7, 0x5a, 0xfe, + 0x20, 0x68, 0x00, 0x28, 0xfc, 0xd1, 0x28, 0x78, 0x08, 0xb1, 0xf8, 0xf7, + 0x4d, 0xfe, 0xf7, 0xf7, 0xbb, 0xf8, 0xbd, 0xe8, 0xf0, 0x4f, 0x70, 0x47, + 0xe8, 0xb7, 0x00, 0x20, 0x40, 0xbd, 0x00, 0x20, 0xf0, 0x7f, 0x01, 0x01, + 0x90, 0xb8, 0x00, 0x20, 0x6c, 0xbc, 0x00, 0x20, 0x90, 0xbc, 0x00, 0x20, + 0x00, 0xe3, 0x00, 0xe0, 0x04, 0xe3, 0x00, 0xe0, 0x04, 0xed, 0x00, 0xe0, + 0x24, 0xed, 0x00, 0xe0, 0x28, 0xed, 0x00, 0xe0, 0x2c, 0xed, 0x00, 0xe0, + 0x38, 0xed, 0x00, 0xe0, 0x40, 0x00, 0x00, 0x50, 0x44, 0x00, 0x00, 0x50, + 0x48, 0x00, 0x00, 0x50, 0x40, 0x00, 0x00, 0x58, 0x44, 0x00, 0x00, 0x58, + 0x00, 0x00, 0x00, 0x49, 0x04, 0x00, 0x00, 0x49, 0x08, 0x00, 0x00, 0x49, + 0x0c, 0x00, 0x00, 0x49, 0x10, 0x00, 0x00, 0x49, 0x14, 0x00, 0x00, 0x49, + 0x18, 0x00, 0x00, 0x49, 0x00, 0x0d, 0x01, 0x0d, 0x08, 0x0d, 0x09, 0x0d, + 0x50, 0x0c, 0x51, 0x0c, 0x52, 0x0c, 0x53, 0x0c, 0x54, 0x0c, 0x55, 0x0c, + 0x56, 0x0c, 0x57, 0x0c, 0x58, 0x0c, 0x59, 0x0c, 0x5a, 0x0c, 0x5b, 0x0c, + 0x5c, 0x0c, 0x5d, 0x0c, 0x5e, 0x0c, 0x5f, 0x0c, 0x60, 0x0c, 0x00, 0x00, + 0xb8, 0x2a, 0x00, 0x20, 0x22, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x20, + 0x86, 0x00, 0x00, 0x00, 0x88, 0xf3, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x2a, 0x00, 0x20, + 0x03, 0x00, 0x00, 0x00, 0x70, 0x29, 0x00, 0x20, 0x08, 0x00, 0x00, 0x00, + 0x68, 0xf3, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x20, 0x29, 0x00, 0x20, + 0x2c, 0x00, 0x00, 0x00, 0xdc, 0x2a, 0x00, 0x20, 0x48, 0x00, 0x00, 0x00, + 0xdc, 0x2a, 0x00, 0x20, 0x48, 0x00, 0x00, 0x00, 0x68, 0x2b, 0x00, 0x20, + 0x24, 0x00, 0x00, 0x00, 0xf8, 0x28, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, + 0x2c, 0x2a, 0x00, 0x20, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xdc, 0x29, 0x00, 0x20, 0x28, 0x00, 0x00, 0x00, + 0x9c, 0x28, 0x00, 0x20, 0x18, 0x00, 0x00, 0x00, 0xc0, 0x26, 0x00, 0x20, + 0x18, 0x00, 0x00, 0x00, 0x2c, 0x2c, 0x00, 0x20, 0x2c, 0x00, 0x00, 0x00, + 0x70, 0xf3, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x2a, 0x00, 0x20, + 0x64, 0x2a, 0x00, 0x20, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x2a, 0x00, 0x20, + 0x18, 0x2a, 0x00, 0x20, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x47, 0x2d, 0xe9, + 0xf8, 0x46, 0x89, 0x46, 0x00, 0x21, 0x00, 0x20, 0xec, 0xf7, 0x9f, 0xfd, + 0x48, 0x46, 0x00, 0xf0, 0x8d, 0xf8, 0x42, 0x4d, 0x42, 0x4c, 0x68, 0x89, + 0x00, 0x26, 0xc0, 0xf3, 0x01, 0x10, 0x00, 0x28, 0x40, 0xf2, 0x99, 0x6a, + 0x2c, 0xd0, 0xe8, 0x6c, 0x00, 0xf0, 0x6f, 0xf8, 0x10, 0xb1, 0xf7, 0xf7, + 0x63, 0xf8, 0x08, 0xb9, 0x01, 0x26, 0x42, 0xe0, 0xe8, 0x6c, 0x00, 0xf0, + 0x4e, 0xf8, 0xa8, 0xbf, 0x64, 0x20, 0x00, 0xf0, 0x45, 0xf8, 0x00, 0xf0, + 0x5b, 0xf8, 0x9c, 0x21, 0x00, 0xf0, 0x59, 0xf8, 0x00, 0xf0, 0x49, 0xf8, + 0x00, 0xf0, 0x4c, 0xf8, 0x08, 0xb1, 0x02, 0x26, 0x2f, 0xe0, 0x31, 0x4f, + 0x39, 0x78, 0x40, 0xf6, 0x93, 0x00, 0xec, 0xf7, 0x1b, 0xfb, 0x7a, 0x78, + 0x1f, 0x21, 0x40, 0xf6, 0x94, 0x00, 0xec, 0xf7, 0x1f, 0xfb, 0x39, 0x79, + 0x40, 0xf6, 0x95, 0x00, 0xec, 0xf7, 0x10, 0xfb, 0x68, 0x89, 0xc0, 0xf3, + 0x81, 0x00, 0xd0, 0xb1, 0xa8, 0x6b, 0x00, 0xf0, 0x3e, 0xf8, 0x10, 0xb1, + 0xf7, 0xf7, 0x32, 0xf8, 0x08, 0xb9, 0x03, 0x26, 0x11, 0xe0, 0xa8, 0x6b, + 0x00, 0xf0, 0x1d, 0xf8, 0xa8, 0xbf, 0x64, 0x20, 0x00, 0xf0, 0x14, 0xf8, + 0x00, 0xf0, 0x2a, 0xf8, 0x9c, 0x21, 0x00, 0xf0, 0x28, 0xf8, 0x00, 0xf0, + 0x18, 0xf8, 0x00, 0xf0, 0x1b, 0xf8, 0x00, 0xb1, 0x04, 0x26, 0x48, 0x46, + 0x00, 0xf0, 0x43, 0xf8, 0x00, 0x20, 0xec, 0xf7, 0x9d, 0xfd, 0x30, 0x46, + 0xbd, 0xe8, 0xf2, 0x86, 0x00, 0xf0, 0x7f, 0x01, 0x50, 0x46, 0xec, 0xf7, + 0xe3, 0xba, 0x13, 0x49, 0xb0, 0xfb, 0xf1, 0xf0, 0xc0, 0xb2, 0x65, 0x28, + 0x70, 0x47, 0x20, 0x21, 0x4f, 0xf4, 0xd9, 0x70, 0xec, 0xf7, 0xd8, 0xba, + 0x4f, 0xf4, 0x7a, 0x73, 0x00, 0x22, 0x20, 0x21, 0x4f, 0xf4, 0xd9, 0x70, + 0xf2, 0xf7, 0x94, 0xbf, 0x1c, 0x21, 0x4f, 0xf4, 0xd2, 0x60, 0xec, 0xf7, + 0xcb, 0xba, 0xa4, 0xfb, 0x00, 0x23, 0x12, 0x0f, 0x42, 0xea, 0x03, 0x12, + 0x1b, 0x0f, 0x00, 0x20, 0xf7, 0xf7, 0x11, 0xb8, 0x78, 0x29, 0x00, 0x20, + 0x22, 0x18, 0x09, 0x91, 0x93, 0x06, 0x00, 0x46, 0x40, 0x42, 0x0f, 0x00, + 0x80, 0xb5, 0x00, 0x21, 0xff, 0xf7, 0xda, 0xff, 0x00, 0xf0, 0x18, 0xf8, + 0x1b, 0x21, 0x40, 0xf2, 0x91, 0x60, 0xec, 0xf7, 0xaf, 0xfa, 0xbd, 0xe8, + 0x04, 0x40, 0x7c, 0x21, 0x0a, 0xe0, 0x80, 0xb5, 0x00, 0xf0, 0x0c, 0xf8, + 0xdb, 0x21, 0x40, 0xf2, 0x91, 0x60, 0xec, 0xf7, 0xa3, 0xfa, 0xbd, 0xe8, + 0x04, 0x40, 0x7e, 0x21, 0x40, 0xf2, 0x0b, 0x20, 0xec, 0xf7, 0x9c, 0xba, + 0x07, 0x21, 0x40, 0xf2, 0x83, 0x10, 0xec, 0xf7, 0x97, 0xba, 0x00, 0x00, + 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, + 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, + 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, + 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, + 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, + 0xfe, 0xe7, 0xfe, 0xe7, 0x2e, 0x4c, 0x2f, 0x48, 0x2f, 0x4d, 0x30, 0x49, + 0x20, 0x60, 0x20, 0x60, 0x01, 0x22, 0x00, 0x20, 0x28, 0x60, 0x08, 0x60, + 0x2d, 0x49, 0x08, 0x60, 0x0f, 0xf2, 0xd0, 0x01, 0x0f, 0xf2, 0xc8, 0x00, + 0x00, 0xf0, 0x66, 0xf8, 0x2a, 0x49, 0x28, 0x60, 0x09, 0x68, 0x88, 0x42, + 0x00, 0xd0, 0xfe, 0xe7, 0x00, 0x20, 0x20, 0x60, 0x20, 0x60, 0x27, 0x49, + 0x27, 0x48, 0x01, 0x60, 0x4f, 0xf4, 0xe0, 0x21, 0xc1, 0x61, 0x00, 0xf0, + 0x02, 0xf8, 0x00, 0xf0, 0xab, 0xb8, 0x1c, 0x48, 0x23, 0x4c, 0x4f, 0xf6, + 0xfe, 0x61, 0x01, 0x60, 0x01, 0x60, 0x22, 0x49, 0x0a, 0x78, 0x0b, 0x78, + 0x43, 0xf0, 0x08, 0x03, 0x0b, 0x70, 0x23, 0x46, 0x1d, 0x68, 0x1d, 0x60, + 0x1e, 0x68, 0xae, 0x42, 0x03, 0xd0, 0x17, 0x48, 0x00, 0x68, 0x03, 0x60, + 0xfe, 0xe7, 0x1b, 0x1d, 0x04, 0xf5, 0x80, 0x75, 0xab, 0x42, 0xf1, 0xd3, + 0x18, 0x4d, 0xab, 0x42, 0x14, 0xd2, 0x4f, 0xf0, 0xff, 0x35, 0x1d, 0x60, + 0x1d, 0x68, 0x15, 0xf1, 0x01, 0x0f, 0x03, 0xd0, 0x0d, 0x48, 0x00, 0x68, + 0x03, 0x60, 0xfe, 0xe7, 0x00, 0x25, 0x1d, 0x60, 0x1d, 0x68, 0x1d, 0xb1, + 0x09, 0x48, 0x00, 0x68, 0x03, 0x60, 0xfe, 0xe7, 0x1b, 0x1d, 0xe7, 0xe7, + 0x0a, 0x70, 0x00, 0x21, 0x01, 0x60, 0x01, 0x60, 0x70, 0x47, 0x00, 0x00, + 0x48, 0x00, 0x00, 0x50, 0x00, 0x00, 0xab, 0xab, 0xe4, 0x7f, 0x01, 0x01, + 0xf0, 0x7f, 0x01, 0x01, 0xf4, 0x7f, 0x01, 0x01, 0xe0, 0x7f, 0x01, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x08, 0xed, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x0d, 0x00, 0x46, 0xff, 0xff, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, + 0xdf, 0x7f, 0x01, 0x01, 0x2d, 0xe9, 0xf0, 0x41, 0x00, 0x23, 0x00, 0x25, + 0x0f, 0xf2, 0x64, 0x08, 0x15, 0xe0, 0x17, 0xf8, 0x06, 0xe0, 0x4f, 0xea, + 0x1e, 0x14, 0x44, 0xea, 0x03, 0x14, 0x1b, 0x0f, 0x58, 0xf8, 0x23, 0x30, + 0x63, 0x40, 0x0e, 0xf0, 0x0f, 0x04, 0x44, 0xea, 0x03, 0x14, 0x1b, 0x0f, + 0x58, 0xf8, 0x23, 0x30, 0x63, 0x40, 0x7f, 0x1c, 0x67, 0x45, 0xea, 0xd3, + 0x6d, 0x1c, 0x95, 0x42, 0x08, 0xd2, 0x50, 0xf8, 0x25, 0x60, 0x51, 0xf8, + 0x25, 0x70, 0xbf, 0x1b, 0x07, 0xf1, 0x01, 0x0c, 0x00, 0x27, 0xf1, 0xe7, + 0x04, 0x20, 0x19, 0x0f, 0x58, 0xf8, 0x21, 0x10, 0x81, 0xea, 0x03, 0x11, + 0x0a, 0x0f, 0x58, 0xf8, 0x22, 0x20, 0x40, 0x1e, 0x82, 0xea, 0x01, 0x13, + 0xf3, 0xd1, 0x18, 0x46, 0xbd, 0xe8, 0xf0, 0x81, 0x00, 0x00, 0x00, 0x00, + 0xb7, 0x1d, 0xc1, 0x04, 0x6e, 0x3b, 0x82, 0x09, 0xd9, 0x26, 0x43, 0x0d, + 0xdc, 0x76, 0x04, 0x13, 0x6b, 0x6b, 0xc5, 0x17, 0xb2, 0x4d, 0x86, 0x1a, + 0x05, 0x50, 0x47, 0x1e, 0xb8, 0xed, 0x08, 0x26, 0x0f, 0xf0, 0xc9, 0x22, + 0xd6, 0xd6, 0x8a, 0x2f, 0x61, 0xcb, 0x4b, 0x2b, 0x64, 0x9b, 0x0c, 0x35, + 0xd3, 0x86, 0xcd, 0x31, 0x0a, 0xa0, 0x8e, 0x3c, 0xbd, 0xbd, 0x4f, 0x38, + 0x01, 0x20, 0xc0, 0x46, 0x00, 0x28, 0x01, 0xd0, 0x00, 0xf0, 0x08, 0xf8, + 0x00, 0x20, 0xc0, 0x46, 0xc0, 0x46, 0x00, 0xf0, 0x17, 0xf8, 0x00, 0xf0, + 0x6f, 0xf8, 0x00, 0x00, 0x10, 0xb5, 0x07, 0x49, 0x79, 0x44, 0x18, 0x31, + 0x06, 0x4c, 0x7c, 0x44, 0x16, 0x34, 0x04, 0xe0, 0x0a, 0x68, 0x08, 0x1d, + 0x51, 0x18, 0x88, 0x47, 0x01, 0x46, 0xa1, 0x42, 0xf8, 0xd1, 0x10, 0xbd, + 0x20, 0x0a, 0x00, 0x00, 0xfc, 0x0a, 0x00, 0x00, 0x00, 0xb5, 0x87, 0xb0, + 0xf1, 0xf7, 0x12, 0xf9, 0xc0, 0x46, 0xc0, 0x46, 0xc0, 0x46, 0xc0, 0x46, + 0xea, 0xf7, 0x74, 0xff, 0x03, 0x21, 0x04, 0x91, 0x00, 0x21, 0x03, 0x91, + 0x64, 0x21, 0x02, 0x91, 0x05, 0x21, 0x1e, 0x48, 0x01, 0x90, 0x00, 0x91, + 0x00, 0xf5, 0xc6, 0x72, 0x05, 0x23, 0x00, 0x21, 0x0f, 0xf2, 0x1d, 0x00, + 0xeb, 0xf7, 0xdd, 0xfd, 0x05, 0xaa, 0x0f, 0xf2, 0x70, 0x01, 0x05, 0x20, + 0xeb, 0xf7, 0x8e, 0xfe, 0xeb, 0xf7, 0x2b, 0xf8, 0x00, 0x20, 0x07, 0xb0, + 0x00, 0xbd, 0x00, 0x00, 0x80, 0xb5, 0xf0, 0xf7, 0x71, 0xff, 0x40, 0x1e, + 0x80, 0x41, 0xc0, 0x0f, 0xf1, 0xf7, 0x6d, 0xf8, 0xf7, 0xf7, 0x54, 0xf8, + 0x0e, 0x48, 0x00, 0x6c, 0x40, 0x1e, 0xb0, 0xf1, 0x80, 0x7f, 0x08, 0xd2, + 0x0c, 0x49, 0x0d, 0x4a, 0x48, 0x60, 0xf0, 0x20, 0x10, 0x70, 0x00, 0x20, + 0x88, 0x60, 0x07, 0x20, 0x08, 0x60, 0xea, 0xf7, 0xe1, 0xff, 0x68, 0x46, + 0xf2, 0xf7, 0xba, 0xfb, 0xea, 0xf7, 0xf1, 0xff, 0xf2, 0xf7, 0xec, 0xff, + 0xf2, 0xf7, 0xb2, 0xff, 0xfc, 0xe7, 0x00, 0x00, 0x48, 0x80, 0x00, 0x20, + 0x00, 0xf2, 0x00, 0x20, 0x10, 0xe0, 0x00, 0xe0, 0x23, 0xed, 0x00, 0xe0, + 0x53, 0x74, 0x61, 0x72, 0x74, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0xb8, + 0x07, 0x46, 0x38, 0x46, 0x00, 0xf0, 0x02, 0xf8, 0xfb, 0xe7, 0x00, 0x00, + 0x80, 0xb5, 0xc0, 0x46, 0xc0, 0x46, 0x02, 0x4a, 0x11, 0x00, 0x18, 0x20, + 0xab, 0xbe, 0xfb, 0xe7, 0x26, 0x00, 0x02, 0x00, 0x49, 0x6e, 0x69, 0x74, + 0x20, 0x43, 0x61, 0x6c, 0x54, 0x61, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, + 0x52, 0x78, 0x31, 0x20, 0x43, 0x61, 0x6c, 0x54, 0x61, 0x73, 0x6b, 0x00, + 0x52, 0x78, 0x32, 0x20, 0x43, 0x61, 0x6c, 0x54, 0x61, 0x73, 0x6b, 0x00, + 0x54, 0x78, 0x31, 0x20, 0x43, 0x61, 0x6c, 0x54, 0x61, 0x73, 0x6b, 0x00, + 0x54, 0x78, 0x32, 0x20, 0x43, 0x61, 0x6c, 0x54, 0x61, 0x73, 0x6b, 0x00, + 0x54, 0x78, 0x31, 0x20, 0x4c, 0x4f, 0x4c, 0x20, 0x43, 0x61, 0x6c, 0x54, + 0x61, 0x73, 0x6b, 0x00, 0x54, 0x78, 0x32, 0x20, 0x4c, 0x4f, 0x4c, 0x20, + 0x43, 0x61, 0x6c, 0x54, 0x61, 0x73, 0x6b, 0x00, 0x4f, 0x52, 0x58, 0x31, + 0x20, 0x43, 0x61, 0x6c, 0x54, 0x61, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, + 0x4f, 0x52, 0x58, 0x32, 0x20, 0x43, 0x61, 0x6c, 0x54, 0x61, 0x73, 0x6b, + 0x00, 0x00, 0x00, 0x00, 0x54, 0x78, 0x31, 0x20, 0x44, 0x50, 0x44, 0x20, + 0x43, 0x61, 0x6c, 0x54, 0x61, 0x73, 0x6b, 0x00, 0x54, 0x78, 0x32, 0x20, + 0x44, 0x50, 0x44, 0x20, 0x43, 0x61, 0x6c, 0x54, 0x61, 0x73, 0x6b, 0x00, + 0x54, 0x78, 0x31, 0x20, 0x43, 0x4c, 0x47, 0x43, 0x20, 0x43, 0x61, 0x6c, + 0x54, 0x61, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x54, 0x78, 0x32, 0x20, + 0x43, 0x4c, 0x47, 0x43, 0x20, 0x43, 0x61, 0x6c, 0x54, 0x61, 0x73, 0x6b, + 0x00, 0x00, 0x00, 0x00, 0x54, 0x78, 0x31, 0x20, 0x56, 0x53, 0x57, 0x52, + 0x20, 0x43, 0x61, 0x6c, 0x54, 0x61, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, + 0x54, 0x78, 0x32, 0x20, 0x56, 0x53, 0x57, 0x52, 0x20, 0x43, 0x61, 0x6c, + 0x54, 0x61, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x54, 0x78, 0x31, 0x20, + 0x50, 0x41, 0x20, 0x42, 0x49, 0x41, 0x53, 0x20, 0x43, 0x61, 0x6c, 0x54, + 0x61, 0x73, 0x6b, 0x00, 0x54, 0x78, 0x32, 0x20, 0x50, 0x41, 0x20, 0x42, + 0x49, 0x41, 0x53, 0x20, 0x43, 0x61, 0x6c, 0x54, 0x61, 0x73, 0x6b, 0x00, + 0xc5, 0xfe, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x31, 0x16, 0x00, 0x01, 0x38, 0x00, 0x00, 0x00, + 0xdd, 0x59, 0x01, 0x01, 0xe5, 0x59, 0x01, 0x01, 0x38, 0x00, 0x00, 0x00, + 0xc7, 0xdc, 0x00, 0x01, 0xe5, 0xdc, 0x00, 0x01, 0xf8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf5, 0x61, 0x00, 0x01, 0xf7, 0x61, 0x00, 0x01, 0xf8, 0x00, 0x00, 0x00, + 0x4b, 0x34, 0x00, 0x01, 0x4d, 0x34, 0x00, 0x01, 0xf8, 0x00, 0x00, 0x00, + 0x98, 0x02, 0x00, 0x20, 0x10, 0x01, 0x00, 0x00, 0xa8, 0x03, 0x00, 0x20, + 0x10, 0x01, 0x00, 0x00, 0xdc, 0x2a, 0x00, 0x20, 0x48, 0x00, 0x00, 0x00, + 0x8c, 0x2b, 0x00, 0x20, 0x18, 0x00, 0x00, 0x00, 0x30, 0x27, 0x00, 0x20, + 0x44, 0x00, 0x01, 0x00, 0xd8, 0x26, 0x00, 0x20, 0x3a, 0x00, 0x01, 0x00, + 0xf8, 0x2b, 0x00, 0x20, 0x1a, 0x00, 0x00, 0x00, 0x74, 0xf3, 0x00, 0x20, + 0x02, 0x00, 0x00, 0x00, 0x04, 0xea, 0x00, 0x20, 0xa0, 0xea, 0x00, 0x20, + 0x9c, 0x00, 0x00, 0x00, 0x3c, 0xeb, 0x00, 0x20, 0xd8, 0xeb, 0x00, 0x20, + 0x9c, 0x00, 0x00, 0x00, 0x98, 0xf1, 0x00, 0x20, 0xcc, 0xf1, 0x00, 0x20, + 0x34, 0x00, 0x00, 0x00, 0xb4, 0x2b, 0x00, 0x20, 0xd0, 0x2b, 0x00, 0x20, + 0x1c, 0x00, 0x00, 0x00, 0x74, 0x27, 0x00, 0x20, 0x08, 0x28, 0x00, 0x20, + 0x94, 0x00, 0x00, 0x00, 0xa8, 0xef, 0x00, 0x20, 0xec, 0xef, 0x00, 0x20, + 0x44, 0x00, 0x00, 0x00, 0x94, 0xed, 0x00, 0x20, 0xe8, 0xed, 0x00, 0x20, + 0x54, 0x00, 0x00, 0x00, 0x40, 0xf3, 0x00, 0x20, 0x44, 0xf3, 0x00, 0x20, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x20, 0x70, 0x47, 0x2d, 0xe9, 0xf0, 0x4f, + 0x83, 0xb0, 0x07, 0x46, 0xed, 0xf7, 0x12, 0xf9, 0xed, 0xf7, 0xe6, 0xf8, + 0x00, 0x2f, 0x04, 0x46, 0x0c, 0xbf, 0x02, 0x25, 0x03, 0x25, 0x35, 0x4e, + 0xdf, 0xf8, 0xd4, 0x80, 0xed, 0xf7, 0x13, 0xf9, 0xb8, 0x55, 0x4f, 0xf0, + 0x6c, 0x0a, 0x28, 0x46, 0xf8, 0xf7, 0x65, 0xff, 0x07, 0xf1, 0x1f, 0x00, + 0x8d, 0xf8, 0x04, 0x00, 0x4c, 0xb9, 0x06, 0xe0, 0x01, 0x21, 0xed, 0xf7, + 0x27, 0xf9, 0x14, 0xb1, 0x14, 0xf1, 0x01, 0x0f, 0x01, 0xd0, 0xed, 0xf7, + 0x81, 0xf9, 0xb8, 0x5d, 0x03, 0x21, 0xed, 0xf7, 0x1d, 0xf9, 0xb8, 0x5d, + 0x00, 0x21, 0xed, 0xf7, 0x19, 0xf9, 0x9d, 0xf8, 0x04, 0x00, 0x01, 0x21, + 0xf0, 0xf7, 0xc3, 0xff, 0xed, 0xf7, 0x48, 0xf9, 0xed, 0xf7, 0xed, 0xf8, + 0x0a, 0xfb, 0x00, 0x89, 0xeb, 0xf7, 0x56, 0xfd, 0xc9, 0xf8, 0x38, 0x00, + 0x4f, 0xf4, 0x60, 0x71, 0x06, 0xf1, 0x08, 0x00, 0x01, 0xfb, 0x07, 0x02, + 0x01, 0x21, 0x28, 0x46, 0xf8, 0xf7, 0x3c, 0xff, 0x81, 0x46, 0x00, 0x20, + 0xec, 0xf7, 0xb5, 0xfa, 0xed, 0xf7, 0xd7, 0xf8, 0x83, 0x46, 0xeb, 0xf7, + 0x41, 0xfd, 0x0a, 0xfb, 0x0b, 0x81, 0x8a, 0x6b, 0x82, 0x42, 0x23, 0xbf, + 0x4f, 0xf0, 0xff, 0x33, 0x9a, 0x1a, 0x80, 0x18, 0x80, 0x1a, 0xc8, 0x63, + 0x00, 0x21, 0x9d, 0xf8, 0x04, 0x00, 0xf0, 0xf7, 0x96, 0xff, 0xb8, 0x5d, + 0xb9, 0xf1, 0x00, 0x0f, 0xb8, 0xd0, 0x02, 0x21, 0xed, 0xf7, 0xe0, 0xf8, + 0xb8, 0x5d, 0x01, 0x21, 0xed, 0xf7, 0xdc, 0xf8, 0xed, 0xf7, 0xbe, 0xf8, + 0x0d, 0xf1, 0x05, 0x01, 0x00, 0x91, 0x00, 0x23, 0x82, 0x22, 0x20, 0x21, + 0xeb, 0xf7, 0xbe, 0xf8, 0xa9, 0xe7, 0x00, 0x00, 0x48, 0xc8, 0x00, 0x20, + 0x8c, 0x09, 0x00, 0x20, 0x00, 0x20, 0x70, 0x47, 0x2d, 0xe9, 0xf0, 0x4f, + 0x83, 0xb0, 0x07, 0x46, 0xed, 0xf7, 0x94, 0xf8, 0xed, 0xf7, 0x68, 0xf8, + 0x04, 0x46, 0x38, 0x00, 0x18, 0xbf, 0x01, 0x20, 0x8d, 0xf8, 0x04, 0x00, + 0xed, 0xf7, 0x97, 0xf8, 0x32, 0x4d, 0xdf, 0xf8, 0xcc, 0x80, 0x78, 0x55, + 0x07, 0xf1, 0x1d, 0x06, 0x9d, 0xf8, 0x04, 0x00, 0xf8, 0xf7, 0xe5, 0xfe, + 0x4f, 0xf0, 0x6c, 0x0a, 0x4c, 0xb9, 0x06, 0xe0, 0x01, 0x21, 0xed, 0xf7, + 0xa9, 0xf8, 0x14, 0xb1, 0x14, 0xf1, 0x01, 0x0f, 0x01, 0xd0, 0xed, 0xf7, + 0x03, 0xf9, 0x78, 0x5d, 0x03, 0x21, 0xed, 0xf7, 0x9f, 0xf8, 0x78, 0x5d, + 0x00, 0x21, 0xed, 0xf7, 0x9b, 0xf8, 0x01, 0x21, 0xf0, 0xb2, 0xf0, 0xf7, + 0x46, 0xff, 0xed, 0xf7, 0xcb, 0xf8, 0xed, 0xf7, 0x70, 0xf8, 0x0a, 0xfb, + 0x00, 0x89, 0xeb, 0xf7, 0xd9, 0xfc, 0xc9, 0xf8, 0x38, 0x00, 0x4f, 0xf4, + 0x60, 0x71, 0x05, 0xf1, 0x08, 0x00, 0x01, 0xfb, 0x07, 0x02, 0x9d, 0xf8, + 0x04, 0x00, 0x01, 0x21, 0xf8, 0xf7, 0xbd, 0xfe, 0x81, 0x46, 0x00, 0x20, + 0xec, 0xf7, 0x37, 0xfa, 0xed, 0xf7, 0x59, 0xf8, 0x83, 0x46, 0xeb, 0xf7, + 0xc3, 0xfc, 0x0a, 0xfb, 0x0b, 0x81, 0x8a, 0x6b, 0x82, 0x42, 0x23, 0xbf, + 0x4f, 0xf0, 0xff, 0x33, 0x9a, 0x1a, 0x80, 0x18, 0x80, 0x1a, 0xc8, 0x63, + 0x00, 0x21, 0xf0, 0xb2, 0xf0, 0xf7, 0x19, 0xff, 0x78, 0x5d, 0xb9, 0xf1, + 0x00, 0x0f, 0xb9, 0xd0, 0x02, 0x21, 0xed, 0xf7, 0x63, 0xf8, 0x78, 0x5d, + 0x01, 0x21, 0xed, 0xf7, 0x5f, 0xf8, 0xed, 0xf7, 0x41, 0xf8, 0x0d, 0xf1, + 0x05, 0x01, 0x00, 0x91, 0x00, 0x23, 0x82, 0x22, 0x20, 0x21, 0xeb, 0xf7, + 0x41, 0xf8, 0xaa, 0xe7, 0x50, 0xcf, 0x00, 0x20, 0x8c, 0x09, 0x00, 0x20, + 0x00, 0x20, 0x70, 0x47, 0x2d, 0xe9, 0xfe, 0x4f, 0x05, 0x46, 0xed, 0xf7, + 0x19, 0xf8, 0xec, 0xf7, 0xed, 0xff, 0x04, 0x46, 0x02, 0x95, 0xed, 0xf7, + 0x20, 0xf8, 0x81, 0x46, 0x02, 0x98, 0xdf, 0xf8, 0xb8, 0x80, 0x01, 0x27, + 0x00, 0xf1, 0x25, 0x06, 0x4f, 0xf0, 0x6c, 0x0a, 0x44, 0xb9, 0x05, 0xe0, + 0x00, 0xf0, 0x56, 0xf8, 0x14, 0xb1, 0x14, 0xf1, 0x01, 0x0f, 0x01, 0xd0, + 0xed, 0xf7, 0x90, 0xf8, 0x00, 0x21, 0x00, 0xf0, 0x4e, 0xf8, 0x01, 0x21, + 0xf0, 0xb2, 0xf0, 0xf7, 0xd8, 0xfe, 0xed, 0xf7, 0x5d, 0xf8, 0xed, 0xf7, + 0x02, 0xf8, 0x0a, 0xfb, 0x00, 0x85, 0xeb, 0xf7, 0x6b, 0xfc, 0xa8, 0x63, + 0xc8, 0x23, 0x02, 0x99, 0x1d, 0x48, 0x03, 0xfb, 0x01, 0x01, 0x02, 0x98, + 0x3a, 0x46, 0xf6, 0xf7, 0x3b, 0xfd, 0x05, 0x46, 0x00, 0x21, 0xf0, 0xb2, + 0xf0, 0xf7, 0xc1, 0xfe, 0x00, 0x20, 0xec, 0xf7, 0xc8, 0xf9, 0xec, 0xf7, + 0xea, 0xff, 0x83, 0x46, 0xeb, 0xf7, 0x54, 0xfc, 0x0a, 0xfb, 0x0b, 0x81, + 0x00, 0x27, 0x8a, 0x6b, 0x82, 0x42, 0x23, 0xbf, 0x4f, 0xf0, 0xff, 0x33, + 0x9a, 0x1a, 0x80, 0x18, 0x80, 0x1a, 0xc8, 0x63, 0x01, 0x2d, 0x18, 0xbf, + 0x02, 0x2d, 0x04, 0xd0, 0x03, 0x2d, 0x1c, 0xbf, 0x04, 0x2d, 0x0c, 0x2d, + 0xbc, 0xd1, 0x02, 0x21, 0x00, 0xf0, 0x13, 0xf8, 0x00, 0xf0, 0x10, 0xf8, + 0xec, 0xf7, 0xd2, 0xff, 0x01, 0xa9, 0x00, 0x91, 0x00, 0x23, 0x82, 0x22, + 0x20, 0x21, 0xea, 0xf7, 0xd3, 0xff, 0xaf, 0xe7, 0x00, 0x00, 0x00, 0x00, + 0x8c, 0x09, 0x00, 0x20, 0x74, 0xe8, 0x00, 0x20, 0x01, 0x21, 0x48, 0x46, + 0xec, 0xf7, 0xdc, 0xbf, 0x00, 0x20, 0x70, 0x47, 0x2d, 0xe9, 0xf0, 0x4f, + 0x83, 0xb0, 0x83, 0x46, 0xec, 0xf7, 0xa4, 0xff, 0xec, 0xf7, 0x78, 0xff, + 0x04, 0x46, 0xec, 0xf7, 0xac, 0xff, 0x81, 0x46, 0x0b, 0xf1, 0x29, 0x06, + 0x6c, 0x27, 0xdf, 0xf8, 0xac, 0x80, 0x4c, 0xb9, 0x06, 0xe0, 0x01, 0x21, + 0x00, 0xf0, 0x54, 0xf8, 0x14, 0xb1, 0x14, 0xf1, 0x01, 0x0f, 0x01, 0xd0, + 0xed, 0xf7, 0x1e, 0xf8, 0x00, 0x21, 0x00, 0xf0, 0x4b, 0xf8, 0x01, 0x21, + 0xf0, 0xb2, 0xf0, 0xf7, 0x66, 0xfe, 0xec, 0xf7, 0xeb, 0xff, 0xec, 0xf7, + 0x90, 0xff, 0x07, 0xfb, 0x00, 0x85, 0xeb, 0xf7, 0xf9, 0xfb, 0xa8, 0x63, + 0x1d, 0x48, 0x00, 0xeb, 0x4b, 0x11, 0x58, 0x46, 0xee, 0xf7, 0x55, 0xff, + 0x05, 0x46, 0x00, 0x20, 0xec, 0xf7, 0x5d, 0xf9, 0xec, 0xf7, 0x7f, 0xff, + 0x82, 0x46, 0xeb, 0xf7, 0xe9, 0xfb, 0x07, 0xfb, 0x0a, 0x81, 0x8a, 0x6b, + 0x82, 0x42, 0x23, 0xbf, 0x4f, 0xf0, 0xff, 0x33, 0x9a, 0x1a, 0x80, 0x18, + 0x80, 0x1a, 0xc8, 0x63, 0x00, 0x21, 0xf0, 0xb2, 0xf0, 0xf7, 0x3f, 0xfe, + 0x01, 0x2d, 0x18, 0xbf, 0x02, 0x2d, 0x04, 0xd0, 0x04, 0x2d, 0x1c, 0xbf, + 0x05, 0x2d, 0x0b, 0x2d, 0xbf, 0xd1, 0x02, 0x21, 0x00, 0xf0, 0x14, 0xf8, + 0x01, 0x21, 0x00, 0xf0, 0x11, 0xf8, 0xec, 0xf7, 0x63, 0xff, 0x01, 0xa9, + 0x00, 0x91, 0x00, 0x23, 0x82, 0x22, 0x20, 0x21, 0xea, 0xf7, 0x64, 0xff, + 0x03, 0x21, 0xaf, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x09, 0x00, 0x20, + 0x48, 0xf2, 0x00, 0x20, 0x48, 0x46, 0xec, 0xf7, 0x6d, 0xbf, 0x00, 0x00, + 0x80, 0xb5, 0x01, 0x29, 0x08, 0xbf, 0xfe, 0xf7, 0xbe, 0xfb, 0x00, 0x20, + 0x02, 0xbd, 0x2d, 0xe9, 0xf0, 0x4f, 0x83, 0xb0, 0x83, 0x46, 0xec, 0xf7, + 0x2f, 0xff, 0xec, 0xf7, 0x03, 0xff, 0x04, 0x46, 0xec, 0xf7, 0x37, 0xff, + 0x81, 0x46, 0x0b, 0xf1, 0x23, 0x06, 0x6c, 0x27, 0xdf, 0xf8, 0x98, 0x80, + 0x44, 0xb9, 0x05, 0xe0, 0x00, 0xf0, 0x4c, 0xf8, 0x14, 0xb1, 0x14, 0xf1, + 0x01, 0x0f, 0x01, 0xd0, 0xec, 0xf7, 0xaa, 0xff, 0x00, 0x21, 0x00, 0xf0, + 0x44, 0xf8, 0x01, 0x21, 0xf0, 0xb2, 0xf0, 0xf7, 0xf2, 0xfd, 0xec, 0xf7, + 0x77, 0xff, 0xec, 0xf7, 0x1c, 0xff, 0x07, 0xfb, 0x00, 0x85, 0xeb, 0xf7, + 0x85, 0xfb, 0xa8, 0x63, 0x4f, 0xf4, 0x22, 0x71, 0x18, 0x48, 0x01, 0xfb, + 0x0b, 0x01, 0x58, 0x46, 0xfe, 0xf7, 0xd6, 0xfa, 0x05, 0x46, 0x00, 0x20, + 0xec, 0xf7, 0xe7, 0xf8, 0xec, 0xf7, 0x09, 0xff, 0x82, 0x46, 0xeb, 0xf7, + 0x73, 0xfb, 0x07, 0xfb, 0x0a, 0x81, 0x8a, 0x6b, 0x82, 0x42, 0x23, 0xbf, + 0x4f, 0xf0, 0xff, 0x33, 0x9a, 0x1a, 0x80, 0x18, 0x80, 0x1a, 0xc8, 0x63, + 0x00, 0x21, 0xf0, 0xb2, 0xf0, 0xf7, 0xc9, 0xfd, 0x00, 0x2d, 0xc5, 0xd0, + 0x02, 0x21, 0x00, 0xf0, 0x12, 0xf8, 0x00, 0xf0, 0x0f, 0xf8, 0xec, 0xf7, + 0xf5, 0xfe, 0x01, 0xa9, 0x00, 0x91, 0x00, 0x23, 0x82, 0x22, 0x20, 0x21, + 0xea, 0xf7, 0xf6, 0xfe, 0xb8, 0xe7, 0x00, 0x00, 0x8c, 0x09, 0x00, 0x20, + 0x58, 0xd6, 0x00, 0x20, 0x01, 0x21, 0x48, 0x46, 0xec, 0xf7, 0x00, 0xbf, + 0x00, 0x20, 0x70, 0x47, 0x2d, 0xe9, 0xf0, 0x4f, 0x83, 0xb0, 0x83, 0x46, + 0xec, 0xf7, 0xc8, 0xfe, 0xec, 0xf7, 0x9c, 0xfe, 0x04, 0x46, 0xec, 0xf7, + 0xd0, 0xfe, 0x81, 0x46, 0x0b, 0xf1, 0x27, 0x06, 0x6c, 0x27, 0xdf, 0xf8, + 0xa0, 0x80, 0x44, 0xb9, 0x05, 0xe0, 0x00, 0xf0, 0x4d, 0xf8, 0x14, 0xb1, + 0x14, 0xf1, 0x01, 0x0f, 0x01, 0xd0, 0xec, 0xf7, 0x43, 0xff, 0x00, 0x21, + 0x00, 0xf0, 0x45, 0xf8, 0x01, 0x21, 0xf0, 0xb2, 0xf0, 0xf7, 0x8b, 0xfd, + 0xec, 0xf7, 0x10, 0xff, 0xec, 0xf7, 0xb5, 0xfe, 0x07, 0xfb, 0x00, 0x85, + 0xeb, 0xf7, 0x1e, 0xfb, 0xa8, 0x63, 0x58, 0x46, 0xf3, 0xf7, 0xea, 0xf8, + 0x05, 0x46, 0x00, 0x20, 0xec, 0xf7, 0x85, 0xf8, 0xec, 0xf7, 0xa7, 0xfe, + 0x82, 0x46, 0xeb, 0xf7, 0x11, 0xfb, 0x07, 0xfb, 0x0a, 0x81, 0x8a, 0x6b, + 0x82, 0x42, 0x23, 0xbf, 0x4f, 0xf0, 0xff, 0x33, 0x9a, 0x1a, 0x80, 0x18, + 0x80, 0x1a, 0xc8, 0x63, 0x00, 0x21, 0xf0, 0xb2, 0xf0, 0xf7, 0x67, 0xfd, + 0x05, 0x2d, 0x18, 0xbf, 0x01, 0x2d, 0x04, 0xd0, 0x06, 0x2d, 0x1c, 0xbf, + 0x02, 0x2d, 0x0e, 0x2d, 0xc3, 0xd1, 0x02, 0x21, 0x00, 0xf0, 0x11, 0xf8, + 0x00, 0xf0, 0x0e, 0xf8, 0xec, 0xf7, 0x8c, 0xfe, 0x01, 0xa9, 0x00, 0x91, + 0x00, 0x23, 0x82, 0x22, 0x20, 0x21, 0xea, 0xf7, 0x8d, 0xfe, 0xb6, 0xe7, + 0x00, 0x00, 0x00, 0x00, 0x8c, 0x09, 0x00, 0x20, 0x01, 0x21, 0x48, 0x46, + 0xec, 0xf7, 0x98, 0xbe, 0x00, 0x20, 0x70, 0x47, 0x2d, 0xe9, 0xf0, 0x4f, + 0x83, 0xb0, 0x83, 0x46, 0xec, 0xf7, 0x60, 0xfe, 0xec, 0xf7, 0x34, 0xfe, + 0x04, 0x46, 0xec, 0xf7, 0x68, 0xfe, 0x81, 0x46, 0x0b, 0xf1, 0x21, 0x06, + 0x6c, 0x27, 0xdf, 0xf8, 0x98, 0x80, 0x44, 0xb9, 0x05, 0xe0, 0x00, 0xf0, + 0x4b, 0xf8, 0x14, 0xb1, 0x14, 0xf1, 0x01, 0x0f, 0x01, 0xd0, 0xec, 0xf7, + 0xdb, 0xfe, 0x00, 0x21, 0x00, 0xf0, 0x43, 0xf8, 0x01, 0x21, 0xf0, 0xb2, + 0xf0, 0xf7, 0x23, 0xfd, 0xec, 0xf7, 0xa8, 0xfe, 0xec, 0xf7, 0x4d, 0xfe, + 0x07, 0xfb, 0x00, 0x85, 0xeb, 0xf7, 0xb6, 0xfa, 0xa8, 0x63, 0x38, 0x21, + 0x18, 0x48, 0x01, 0xfb, 0x0b, 0x01, 0x58, 0x46, 0xea, 0xf7, 0x2e, 0xf8, + 0x05, 0x46, 0x00, 0x20, 0xec, 0xf7, 0x19, 0xf8, 0xec, 0xf7, 0x3b, 0xfe, + 0x82, 0x46, 0xeb, 0xf7, 0xa5, 0xfa, 0x07, 0xfb, 0x0a, 0x81, 0x8a, 0x6b, + 0x82, 0x42, 0x23, 0xbf, 0x4f, 0xf0, 0xff, 0x33, 0x9a, 0x1a, 0x80, 0x18, + 0x80, 0x1a, 0xc8, 0x63, 0x00, 0x21, 0xf0, 0xb2, 0xf0, 0xf7, 0xfb, 0xfc, + 0x00, 0x2d, 0xc6, 0xd0, 0x02, 0x21, 0x00, 0xf0, 0x12, 0xf8, 0x00, 0xf0, + 0x0f, 0xf8, 0xec, 0xf7, 0x27, 0xfe, 0x01, 0xa9, 0x00, 0x91, 0x00, 0x23, + 0x82, 0x22, 0x20, 0x21, 0xea, 0xf7, 0x28, 0xfe, 0xb9, 0xe7, 0x00, 0x00, + 0x8c, 0x09, 0x00, 0x20, 0x28, 0xf1, 0x00, 0x20, 0x01, 0x21, 0x48, 0x46, + 0xec, 0xf7, 0x32, 0xbe, 0x78, 0x29, 0x00, 0x20, 0x64, 0x00, 0x00, 0x00, + 0x4c, 0x1f, 0x00, 0x20, 0x84, 0x00, 0x00, 0x00, 0xd4, 0x28, 0x00, 0x20, + 0x21, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x20, 0x5c, 0x00, 0x00, 0x00, + 0x84, 0xf3, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x1c, 0x1f, 0x00, 0x20, + 0x14, 0x00, 0x00, 0x00, 0x30, 0x1f, 0x00, 0x20, 0x08, 0x00, 0x00, 0x00, + 0x88, 0x02, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x19, 0xe0, 0x50, 0xf8, + 0x04, 0x1b, 0xcb, 0x07, 0x44, 0xbf, 0xa9, 0xf1, 0x01, 0x03, 0x59, 0x18, + 0x12, 0x1f, 0x00, 0x23, 0x04, 0x2a, 0x41, 0xf8, 0x04, 0x3b, 0xf9, 0xd2, + 0x5f, 0xea, 0x82, 0x7c, 0x0b, 0x46, 0x04, 0xd5, 0x4f, 0xf0, 0x00, 0x0c, + 0xa1, 0xf8, 0x00, 0xc0, 0x9b, 0x1c, 0xd1, 0x07, 0x44, 0xbf, 0x00, 0x21, + 0x19, 0x70, 0x50, 0xf8, 0x04, 0x2b, 0x00, 0x2a, 0xe1, 0xd1, 0x70, 0x47, + 0x80, 0xb5, 0x01, 0x29, 0x04, 0xd0, 0x02, 0x29, 0x08, 0xbf, 0xf2, 0xf7, + 0x8d, 0xf8, 0x01, 0xe0, 0xf2, 0xf7, 0xce, 0xf8, 0x00, 0x20, 0x02, 0xbd, + 0x10, 0xb5, 0x07, 0x4c, 0x02, 0x21, 0x21, 0x60, 0x00, 0x21, 0x61, 0x60, + 0xf2, 0xf7, 0xd9, 0xf8, 0x08, 0x21, 0x60, 0x60, 0x21, 0x60, 0x20, 0x46, + 0xeb, 0xf7, 0xbe, 0xff, 0xfe, 0xe7, 0x00, 0x00, 0x28, 0xf3, 0x00, 0x20, + 0x38, 0xb5, 0x0c, 0x4c, 0x0c, 0x49, 0x20, 0x68, 0xc9, 0x6a, 0x88, 0x42, + 0x34, 0xbf, 0x65, 0x79, 0x25, 0x79, 0x2a, 0x46, 0x7f, 0x21, 0x4f, 0xf4, + 0x9e, 0x60, 0xeb, 0xf7, 0x91, 0xfc, 0x94, 0xf9, 0x06, 0x00, 0x41, 0x19, + 0xc9, 0xb2, 0x4f, 0xf4, 0xe2, 0x60, 0xeb, 0xf7, 0x7f, 0xfc, 0x00, 0x20, + 0x32, 0xbd, 0x00, 0x00, 0x70, 0x29, 0x00, 0x20, 0x78, 0x29, 0x00, 0x20, + 0x49, 0xff, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x00, 0x68, 0x2c, 0x00, 0x20, + 0x00, 0x08, 0x00, 0x00, 0x68, 0x36, 0x00, 0x20, 0x00, 0x02, 0x00, 0x00, + 0x68, 0x76, 0x00, 0x20, 0x00, 0x06, 0x00, 0x00, 0x68, 0x4e, 0x00, 0x20, + 0x00, 0x06, 0x00, 0x00, 0x68, 0x54, 0x00, 0x20, 0x00, 0x06, 0x00, 0x00, + 0x68, 0x5a, 0x00, 0x20, 0x00, 0x06, 0x00, 0x00, 0x68, 0x60, 0x00, 0x20, + 0x00, 0x04, 0x00, 0x00, 0x68, 0x66, 0x00, 0x20, 0x00, 0x04, 0x00, 0x00, + 0x68, 0x6a, 0x00, 0x20, 0x00, 0x04, 0x00, 0x00, 0x68, 0x6e, 0x00, 0x20, + 0x00, 0x04, 0x00, 0x00, 0x68, 0x72, 0x00, 0x20, 0x00, 0x08, 0x00, 0x00, + 0x68, 0x3e, 0x00, 0x20, 0x00, 0x08, 0x00, 0x00, 0x68, 0x46, 0x00, 0x20, + 0xf0, 0x01, 0x00, 0x00, 0x68, 0x7c, 0x00, 0x20, 0xf0, 0x01, 0x00, 0x00, + 0x58, 0x7e, 0x00, 0x20, 0x70, 0x00, 0x00, 0x00, 0xd8, 0x81, 0x00, 0x20, + 0x70, 0x00, 0x00, 0x00, 0x48, 0x82, 0x00, 0x20, 0x00, 0x02, 0x00, 0x00, + 0x68, 0x78, 0x00, 0x20, 0x90, 0x01, 0x00, 0x00, 0x48, 0x80, 0x00, 0x20, + 0x00, 0x02, 0x00, 0x00, 0x68, 0x7a, 0x00, 0x20, 0x80, 0x36, 0x00, 0x00, + 0x20, 0xbd, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0xcb, 0xb7, 0xfe, 0xff, + 0xc8, 0x00, 0x00, 0x00, 0x72, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x20, + 0x59, 0x51, 0xff, 0xff, 0x0c, 0x00, 0x00, 0x00, 0x70, 0x89, 0xfe, 0xff, + 0x90, 0xbc, 0x00, 0x20, 0x84, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, + 0x9c, 0xbc, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x70, 0x47, + 0x80, 0xb5, 0xec, 0xf7, 0x11, 0xfd, 0xec, 0xf7, 0xe5, 0xfc, 0xbd, 0xe8, + 0x01, 0x40, 0xec, 0xf7, 0x18, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x25, 0xe0, 0x02, + 0xd4, 0x01, 0xbf, 0x00, 0x63, 0x00, 0x00, 0x05, 0x4b, 0x01, 0xc4, 0x07, + 0x32, 0x01, 0xf8, 0x04, 0x99, 0x00, 0xbc, 0x03, 0x24, 0x00, 0x30, 0x00, + 0x1e, 0x00, 0x17, 0x00, 0xcd, 0x00, 0xc4, 0x01, 0x80, 0x01, 0xc7, 0x00, + 0x69, 0x20, 0x10, 0x0b, 0xb6, 0x02, 0x22, 0x07, 0x56, 0x03, 0xd5, 0x05, + 0x72, 0x02, 0xe5, 0x03, 0x17, 0x20, 0x10, 0x0b, 0x26, 0x00, 0x1d, 0x00, + 0xe3, 0x00, 0xf0, 0x02, 0xc7, 0x01, 0xc1, 0x00, 0x65, 0x20, 0x10, 0x0b, + 0xbf, 0x00, 0x89, 0x07, 0xa8, 0x00, 0x04, 0x05, 0x56, 0x00, 0xe9, 0x03, + 0x27, 0x20, 0xf0, 0x04, 0x0f, 0x1f, 0x00, 0x18, 0x00, 0xcf, 0x00, 0x60, + 0x80, 0x04, 0x00, 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x52, 0xff, 0x01, + 0x30, 0x01, 0x00, 0x00, 0x64, 0x16, 0x50, 0x01, 0xdf, 0xa2, 0x05, 0x1e, + 0x10, 0x01, 0x03, 0x00, 0x0a, 0x0a, 0xf0, 0x31, 0x00, 0xb8, 0x0c, 0xf6, + 0x0d, 0x42, 0x15, 0x4f, 0x1b, 0xf9, 0x24, 0xb1, 0x2d, 0xb7, 0x39, 0xd5, + 0x44, 0xeb, 0x52, 0xfe, 0x5f, 0x8b, 0x6f, 0xe2, 0x7d, 0x14, 0x8e, 0xc9, + 0x9c, 0x9f, 0xac, 0xa8, 0xba, 0x0e, 0xc9, 0x5d, 0xd5, 0x45, 0xe1, 0xde, + 0xea, 0x5f, 0xf3, 0x79, 0xf9, 0xe7, 0xfd, 0xff, 0xff, 0x1f, 0xe0, 0x00, + 0x01, 0x12, 0x03, 0x71, 0x10, 0x0a, 0x0a, 0xd7, 0xa3, 0x3b, 0x00, 0x00, + 0x80, 0x40, 0xac, 0xc5, 0xa7, 0x38, 0x22, 0x20, 0x0f, 0x3f, 0x6f, 0x12, + 0x83, 0x3a, 0x17, 0xb7, 0xd1, 0x38, 0x95, 0xbf, 0xd6, 0x33, 0x0a, 0xd7, + 0x23, 0x3c, 0x04, 0x11, 0x20, 0x20, 0x5f, 0x3f, 0xed, 0xdf, 0x4b, 0x3e, + 0x33, 0x63, 0x94, 0x35, 0xdc, 0x6e, 0xc8, 0x37, 0x5e, 0x72, 0x0b, 0x37, + 0x1a, 0xd6, 0x38, 0x36, 0x46, 0xf6, 0x71, 0x35, 0x0f, 0xde, 0x8e, 0x34, + 0xc7, 0xb4, 0x6f, 0x33, 0x63, 0x2e, 0x2e, 0x31, 0x06, 0xb1, 0xe7, 0x31, + 0x88, 0x5d, 0x01, 0x33, 0xe2, 0x10, 0x70, 0x33, 0x5b, 0xb5, 0xaf, 0x33, + 0x34, 0x9f, 0xe3, 0x33, 0xb3, 0x7c, 0x07, 0x34, 0xdb, 0x33, 0x1d, 0x34, + 0x6c, 0x83, 0x31, 0x34, 0xa5, 0x95, 0x47, 0x34, 0xae, 0xb5, 0x64, 0x34, + 0xb7, 0xff, 0x8a, 0x34, 0x99, 0x7f, 0xc1, 0x34, 0x10, 0x6f, 0x2e, 0x35, + 0xa0, 0xd0, 0x56, 0x36, 0xbd, 0x37, 0x86, 0x35, 0x9e, 0x21, 0x8c, 0x21, + 0xee, 0x12, 0x06, 0x04, 0x12, 0x08, 0x04, 0x20, 0x02, 0xf9, 0x83, 0x01, + 0x3d, 0x04, 0xc1, 0xba, 0x45, 0x10, 0xf4, 0x01, 0x5c, 0xb6, 0x5c, 0x38, + 0x10, 0x21, 0x04, 0xf5, 0x85, 0x10, 0xf1, 0xff, 0x01, 0xf1, 0xff, 0x01, + 0xf1, 0xff, 0x01, 0xf1, 0x21, 0x01, 0xb0, 0x05, 0xff, 0x00, 0x07, 0x00, + 0x01, 0x00, 0x00, 0x04, 0x43, 0x90, 0x01, 0x04, 0x43, 0x70, 0x17, 0x04, + 0xc3, 0x32, 0x00, 0x04, 0x52, 0xc8, 0x04, 0x43, 0xe8, 0x03, 0x04, 0xd2, + 0x20, 0x04, 0x2d, 0xf0, 0x05, 0xf2, 0xff, 0x00, 0x01, 0xf1, 0xff, 0x01, + 0xf1, 0xff, 0x01, 0xf1, 0xff, 0x01, 0xf1, 0xff, 0x01, 0xf1, 0xff, 0x01, + 0xf1, 0xff, 0x01, 0xf1, 0xff, 0x01, 0xf1, 0xff, 0x01, 0xf1, 0xff, 0x01, + 0xf1, 0xff, 0x01, 0xf1, 0xff, 0x01, 0xf1, 0xff, 0x01, 0xf1, 0xff, 0x01, + 0xf1, 0xff, 0x01, 0xf1, 0xff, 0x01, 0xf1, 0xff, 0x01, 0xf1, 0xff, 0x01, + 0xf1, 0xff, 0x01, 0xf1, 0xff, 0x01, 0xf1, 0xff, 0x01, 0xf1, 0x20, 0x01, + 0xfc, 0x0d, 0x02, 0x01, 0x06, 0x07, 0x04, 0x05, 0x02, 0x03, 0x08, 0x09, + 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x91, 0x16, 0x2d, 0x76, 0x1c, 0x8f, + 0xa0, 0x0f, 0xc8, 0x16, 0x21, 0x04, 0x2d, 0x00, 0x17, 0x12, 0x5e, 0x05, + 0x33, 0x30, 0x75, 0x31, 0x1e, 0x20, 0xa6, 0x1c, 0x2e, 0x20, 0x17, 0x17, + 0xe0, 0x02, 0xff, 0x7f, 0x01, 0x01, 0x43, 0x12, 0x0c, 0x11, 0x80, 0x06, + 0x3f, 0x0c, 0xc8, 0x16, 0xf0, 0x00, 0x00, 0x00, 0x1d, 0x10, 0x0a, 0x3c, + 0x3c, 0xb3, 0x28, 0x00, 0x00, 0x0f, 0xe0, 0x0f, 0xe0, 0x00, 0x80, 0x0e, + 0x13, 0x00, 0xb1, 0x0e, 0x3c, 0x01, 0x2d, 0xe0, 0x2d, 0x94, 0x1b, 0x1c, + 0x01, 0x30, 0x00, 0xb1, 0xed, 0x1a, 0x30, 0x01, 0x31, 0xe0, 0x31, 0x0e, + 0x43, 0x23, 0x00, 0x84, 0x1e, 0x23, 0x56, 0x17, 0x50, 0x0e, 0x03, 0x00, + 0xb4, 0x2c, 0x10, 0x20, 0x0f, 0xaa, 0x0f, 0xaa, 0x00, 0x89, 0xb7, 0x2d, + 0x00, 0x30, 0x0a, 0x40, 0x01, 0x2e, 0x00, 0x24, 0x0a, 0xfd, 0x07, 0x50, + 0x17, 0x40, 0x03, 0x44, 0x00, 0x00, 0x50, 0x40, 0x04, 0x21, 0x0c, 0x12, + 0x58, 0x08, 0x70, 0x02, 0x58, 0x00, 0x00, 0x10, 0x18, 0xb2, 0x80, 0x18, + 0x92, 0x08, 0x0c, 0xf1, 0x46, 0x01, 0xf2, 0x02, 0x80, 0x5a, 0xf1, 0x36, + 0x14, 0x54, 0x06, 0x01, 0x02, 0x07, 0x08, 0x05, 0x06, 0x03, 0x04, 0xd2, + 0x62, 0x10, 0x1a, 0x6d, 0x5c, 0x1e, 0x2c, 0x02, 0xb9, 0x76, 0x01, 0x01, + 0x5c, 0x1e, 0xf1, 0x13, 0xdc, 0x12, 0x04, 0x25, 0x10, 0x03, 0xf0, 0x6d, + 0x01, 0x01, 0xd1, 0x34, 0x17, 0x68, 0x36, 0xe4, 0x42, 0x02, 0x14, 0x2d, + 0xf0, 0x18, 0x56, 0x01, 0xce, 0x21, 0x58, 0x25, 0xa0, 0xf3, 0x19, 0x05, + 0x71, 0x58, 0x22, 0x12, 0x25, 0x10, 0x02, 0x6e, 0x01, 0x01, 0x09, 0x34, + 0x40, 0x04, 0x68, 0x5a, 0x00, 0x20, 0x80, 0x01, 0x58, 0x21, 0x52, 0x22, + 0x02, 0x65, 0x11, 0x01, 0xf1, 0x0b, 0x58, 0xf2, 0x06, 0x01, 0x65, 0x12, + 0x13, 0x18, 0x62, 0x0c, 0x58, 0xc2, 0x60, 0x58, 0x56, 0x03, 0x02, 0x21, + 0x06, 0x21, 0x14, 0xf3, 0x19, 0xc5, 0x73, 0xb0, 0x12, 0x0e, 0x25, 0x12, + 0x18, 0x58, 0x12, 0xd3, 0x34, 0x17, 0x68, 0x66, 0x08, 0x86, 0x01, 0x08, + 0x32, 0x04, 0x0a, 0xf1, 0x0d, 0x58, 0xf1, 0x07, 0xb0, 0x2d, 0x70, 0x03, + 0x62, 0x24, 0x58, 0xc2, 0x6e, 0x58, 0x32, 0x03, 0xfe, 0x41, 0x58, 0x21, + 0x40, 0xf3, 0x19, 0x6d, 0x75, 0xb0, 0x2d, 0x30, 0x1e, 0x12, 0x30, 0x58, + 0x12, 0x71, 0x34, 0x83, 0x68, 0x6a, 0x58, 0x32, 0x90, 0x08, 0xf2, 0x10, + 0x06, 0x58, 0xf1, 0x07, 0xb0, 0x12, 0x07, 0x18, 0x62, 0x40, 0x58, 0xc2, + 0x72, 0x58, 0x32, 0x05, 0x1e, 0x85, 0xb8, 0xf3, 0x19, 0x09, 0x70, 0xb0, + 0x29, 0xa5, 0x12, 0x50, 0x58, 0x12, 0x0d, 0x34, 0xc7, 0x68, 0x4e, 0xb8, + 0xf0, 0x01, 0x10, 0x06, 0x00, 0x08, 0x58, 0xf1, 0x07, 0xb0, 0x12, 0x11, + 0x18, 0x62, 0x60, 0x58, 0xea, 0x54, 0x10, 0x72, 0x09, 0x58, 0x29, 0x72, + 0xfa, 0x1a, 0xfd, 0xc0, 0x21, 0x92, 0x12, 0x70, 0x58, 0x13, 0x01, 0x72, + 0x58, 0x8e, 0x3e, 0x18, 0x03, 0x2d, 0xf8, 0x1b, 0xf0, 0x01, 0x10, 0x04, + 0x00, 0x0a, 0x58, 0xf1, 0x07, 0xb0, 0x21, 0x92, 0x62, 0x80, 0x58, 0xc2, + 0x46, 0x58, 0xb0, 0x01, 0x03, 0x00, 0x0b, 0x58, 0xf3, 0x19, 0x9d, 0x74, + 0xb0, 0x21, 0x92, 0x12, 0x90, 0x58, 0x12, 0xa1, 0x34, 0x17, 0xcc, 0xe2, + 0x08, 0xa2, 0x00, 0xb0, 0xf2, 0x10, 0x0c, 0x58, 0xf1, 0x07, 0xb0, 0x21, + 0x92, 0x62, 0xa4, 0x58, 0xc2, 0xe4, 0x58, 0x70, 0x01, 0x03, 0x00, 0x0d, + 0x58, 0x21, 0x04, 0xf3, 0x19, 0xe5, 0x72, 0xb0, 0x21, 0x92, 0x12, 0xb8, + 0x58, 0x26, 0xe9, 0x08, 0x50, 0x02, 0x7c, 0x00, 0x20, 0x7c, 0x58, 0x32, + 0xc8, 0x08, 0xf2, 0x10, 0x0e, 0x58, 0xf1, 0x07, 0xb0, 0x21, 0x92, 0x52, + 0xcc, 0x58, 0xc3, 0x58, 0x7e, 0x58, 0x70, 0x01, 0x03, 0x00, 0x0f, 0x58, + 0x25, 0x08, 0xf3, 0x19, 0x11, 0x78, 0x58, 0x12, 0x14, 0x18, 0x12, 0xe0, + 0x58, 0x12, 0x15, 0x34, 0x50, 0x03, 0xd8, 0x81, 0x00, 0x20, 0x1c, 0x58, + 0x2d, 0x2c, 0x07, 0x3a, 0x04, 0xde, 0xf1, 0x25, 0x58, 0x12, 0x15, 0x18, + 0x52, 0xf4, 0x58, 0xc3, 0x48, 0x82, 0x58, 0x81, 0x01, 0x23, 0x80, 0xbf, + 0x04, 0x12, 0x29, 0x13, 0x27, 0x40, 0x7f, 0x1c, 0x1e, 0xff, 0x89, 0x07, + 0x1d, 0x54, 0x03, 0x42, 0x01, 0x04, 0x60, 0x02, 0x30, 0xf8, 0x30, 0xf8, + 0x2e, 0x12, 0x4b, 0x02, 0x12, 0x64, 0x02, 0x3d, 0xbc, 0x05, 0x1d, 0x69, + 0x05, 0x12, 0xde, 0x02, 0x6d, 0xc8, 0x05, 0x50, 0x05, 0x58, 0x02, 0x58, + 0x02, 0x01, 0x01, 0xa4, 0x02, 0x21, 0x1a, 0xf1, 0x01, 0x95, 0xa1, 0xa8, + 0x1c, 0x03, 0x15, 0x07, 0x00, 0x02, 0x64, 0x79, 0x06, 0x70, 0x05, 0x10, + 0x27, 0x00, 0x10, 0x0a, 0x00, 0x40, 0x1a, 0x28, 0x02, 0x05, 0x00, 0x5a, + 0x0f, 0x08, 0xbc, 0x05, 0x3f, 0x3e, 0x3f, 0x1e, 0x04, 0x00, 0xfa, 0xaf, + 0x06, 0x1a, 0x01, 0x1a, 0x11, 0x44, 0x23, 0x01, 0x2c, 0x49, 0xf0, 0x01, + 0xff, 0x02, 0x64, 0x00, 0x01, 0xf1, 0x07, 0x01, 0xf5, 0x07, 0xdc, 0x1e, + 0x09, 0xda, 0x03, 0x1e, 0x0b, 0x2e, 0x03, 0xf2, 0x04, 0x13, 0x02, 0x2d, + 0x00, 0x05, 0x1f, 0x01, 0x02, 0x0b, 0x08, 0xf4, 0x09, 0x11, 0x05, 0x0b, + 0x0e, 0x0c, 0x07, 0x08, 0x0a, 0x11, 0x09, 0x0f, 0x10, 0x73, 0x4c, 0x02, + 0x0a, 0x20, 0x0a, 0x20, 0x8a, 0x04, 0x55, 0xf0, 0x29, 0x08, 0x4a, 0x02, + 0xc0, 0x20, 0x01, 0x20, 0x7f, 0x0b, 0x13, 0x80, 0x01, 0x10, 0x00, 0xf0, + 0x84, 0x11, 0x14, 0xd3, 0x00, 0x00, 0x14, 0x40, 0x04, 0x2e, 0x33, 0x33, + 0x2b, 0x28, 0x1c, 0x06, 0xa0, 0x04, 0x2c, 0x2c, 0x37, 0x20, 0x20, 0x11, + 0x12, 0x51, 0x84, 0xf8, 0x06, 0x5a, 0xe1, 0xf5, 0x05, 0x43, 0x44, 0x02, + 0x00, 0x01, 0x06, 0x1e, 0xfc, 0x77, 0x03, 0x21, 0x04, 0x21, 0xe4, 0x2d, + 0x00, 0x06, 0x11, 0xb3, 0xf0, 0x04, 0x26, 0x07, 0x01, 0xf6, 0x01, 0x00, + 0xff, 0x84, 0xa1, 0x50, 0x5e, 0x0e, 0xf8, 0x05, 0xf0, 0x01, 0x1d, 0x01, + 0x00, 0x01, 0xd4, 0x4d, 0xe7, 0x07, 0x5e, 0x47, 0x97, 0x07, 0x5e, 0x48, + 0x47, 0x07, 0x5e, 0x53, 0xf7, 0x06, 0x30, 0x01, 0x54, 0x00, 0x2f, 0x08, + 0x1e, 0x59, 0x17, 0x0b, 0x11, 0x01, 0x63, 0x10, 0x59, 0x5b, 0x21, 0x64, + 0x10, 0x01, 0x01, 0x1e, 0xff, 0x37, 0x11, 0x82, 0x10, 0x16, 0xff, 0xf7, + 0xff, 0x13, 0x00, 0xdc, 0xff, 0x58, 0x00, 0x9d, 0xfe, 0x45, 0x42, 0x9c, + 0xfe, 0x5a, 0x00, 0xd9, 0xff, 0x17, 0x00, 0xf3, 0xff, 0x05, 0x1c, 0x21, + 0x96, 0x20, 0x02, 0xc8, 0x00, 0xb8, 0x0b, 0x50, 0x32, 0x80, 0x99, 0x30, + 0x03, 0x10, 0x00, 0x30, 0x1b, 0x0f, 0x04, 0x1c, 0x04, 0x58, 0x3e, 0x0f, + 0x00, 0xa0, 0xbb, 0x16, 0x05, 0x3c, 0x04, 0x09, 0x11, 0x02, 0x00, 0x20, + 0x02, 0x1a, 0x04, 0x3e, 0x80, 0xcc, 0x03, 0x37, 0x01, 0x00, 0x9a, 0x34, + 0x02, 0x01, 0x00, 0x2f, 0x02, 0xfa, 0x42, 0x01, 0xde, 0x1c, 0x0c, 0xff, + 0x01, 0xff, 0x02, 0x03, 0xff, 0x04, 0xff, 0x05, 0x06, 0xff, 0x07, 0x08, + 0xff, 0x63, 0x0a, 0x2e, 0xff, 0x64, 0x0a, 0x40, 0x28, 0xff, 0x10, 0x11, + 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0xff, 0x1b, 0x1c, + 0x1d, 0xff, 0x1e, 0xff, 0x1f, 0x20, 0xff, 0x21, 0x22, 0x23, 0x24, 0xff, + 0x25, 0x26, 0x27, 0x28, 0xff, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x9d, 0xbd, 0x11, 0xe2, 0x5c, 0x09, 0x0d, 0x1b, 0x2b, 0x34, + 0x37, 0x39, 0x00, 0x00, 0x28, 0x00, 0x3c, 0x20, 0x05, 0x20, 0x05, 0xa0, + 0x0f, 0x11, 0x3c, 0x3c, 0x14, 0x02, 0x01, 0x55, 0x03, 0x3d, 0x26, 0x04, + 0x13, 0x00, 0xf4, 0x06, 0xf8, 0x03, 0x46, 0xff, 0xe6, 0xdb, 0x2e, 0x12, + 0x2a, 0x96, 0x01, 0xb2, 0x12, 0x32, 0x02, 0x2e, 0x20, 0xcb, 0x0c, 0xff, + 0x0c, 0x02, 0x00, 0x9c, 0x23, 0xfd, 0x07, 0x90, 0x03, 0xf1, 0x03, 0x14, + 0xa1, 0x01, 0x03, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xe7, 0x0c, 0x37, 0xfb, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff +}; +unsigned int firmware_Mykonos_M3_bin_len = 98304; diff --git a/df_datalink_ge/src/hardware/mykonos/Mykonos_M3.h b/df_datalink_ge/src/hardware/mykonos/Mykonos_M3.h new file mode 100644 index 0000000..30215b8 --- /dev/null +++ b/df_datalink_ge/src/hardware/mykonos/Mykonos_M3.h @@ -0,0 +1,13 @@ +/** +SOFTWARE LICENSE AGREEMENT +20180301-AD937X-CTSLA +**/ + +// Version 5.2.2 +#ifndef SRC_MYKONOS_BIN_H_ +#define SRC_MYKONOS_BIN_H_ + +unsigned char firmware_Mykonos_M3_bin[]; +unsigned int firmware_Mykonos_M3_bin_len; + +#endif diff --git a/df_datalink_ge/src/hardware/mykonos/ad9528.c b/df_datalink_ge/src/hardware/mykonos/ad9528.c new file mode 100644 index 0000000..645acf6 --- /dev/null +++ b/df_datalink_ge/src/hardware/mykonos/ad9528.c @@ -0,0 +1,740 @@ +/** + * \file ad9528.c + * \brief Contains source code for configuring and initializing AD9528 clock device + */ + +/** +* \page Disclaimer Legal Disclaimer +* Copyright 2015-2017 Analog Devices Inc. +* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file. +* +*/ + +#include "ad9528.h" + +/** + * \brief Performs a hard reset on the AD9528 DUT + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is structure pointer to the AD9528 data structure containing settings + * \return Returns enum ADI_ERR, ADIERR_OK=pass, !ADIERR_OK=fail + */ +ADI_ERR AD9528_resetDevice(ad9528Device_t *device) +{ + /* toggle RESETB on device with matching spi chip select index */ + CMB_hardReset(device->spiSettings->chipSelectIndex); + return ADIERR_OK; +} + +/** + * \brief Sets the AD9528 device SPI settings (3wire/4wire, MSBFirst, etc). + * + * This function will use the settings in the device->spiSettings structure + * to set SPI stream mode, address auto increment direction, MSBFirst/LSBfirst, + * and 3wire/4wire mode. The AD9528 device always uses SPI MODE 0 (CPHA=0, CPOL=0). + * This function will update your device->spiSettings to set CHPA=0 and CPOL=0 and + * longInstructionWord =1 to use a 16bit instruction word. + * + * Dependencies + * - writes device->spiSettings->CPHA = 0 + * - writes device->spiSettings->CPOL = 0 + * - writes device->spiSettings->longInstructionWord = 1 + * + * - device->spiSettings->MSBFirst + * - device->spiSettings->enSpiStreaming + * - device->spiSettings->autoIncAddrUp + * - device->spiSettings->fourWireMode + * + * \param device is structure pointer to the AD9528 data structure containing settings + * + * \return Returns enum ADI_ERR, ADIERR_OK=pass, !ADIERR_OK=fail + */ +ADI_ERR AD9528_setSpiSettings(ad9528Device_t *device) +{ + //device->spiSettings->enSpiStreaming + uint8_t spiReg = 0; + + device->spiSettings->CPHA = 0; + device->spiSettings->CPOL = 0; + device->spiSettings->longInstructionWord = 1; + + if (device->spiSettings->MSBFirst == 0) + { + spiReg |= 0x42; /* SPI bit is 1=LSB first */ + } + + if (device->spiSettings->autoIncAddrUp > 0) + { + spiReg |= 0x24; + } + + if (device->spiSettings->fourWireMode > 0) + { + spiReg |= 0x18; + } + + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_ADI_SPI_CONFIG_A, spiReg); + + if (device->spiSettings->enSpiStreaming > 0) + { + /* Allow SPI streaming mode: SPI message ends when chip select deasserts */ + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_ADI_SPI_CONFIG_B, 0x00); + } + else + { + /* Force single instruction mode */ + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_ADI_SPI_CONFIG_B, 0x80); + } + + return ADIERR_OK; +} + + +/** + * \brief Helper function for ADI transceiver eval boards to init the AD9528 data structure + * + * This function inits the AD9528 device data structure with defaults that + * are known to work with the ADI AD9369 and AD9371 evaluation boards. NOTE: This function will + * modify the contents of the AD9528 device data structure. + * + * Dependencies + * - spi->chipSelectIndex + * - spi + * + * \param device Pointer to the AD9528 device data structure to initialize + * \param vcxoFrequency_Hz The VCXO frequency that is connected to the AD9528 + * \param refAFrequency_Hz The reference clock frequency being input into the AD9528 REFCLK A input + * \param outputDeviceClock_Hz Desired output clock frequency to the FPGA and transceiver device + * + * \return Returns enum ADI_ERR, 0=pass, >0 = fail +*/ +ADI_ERR AD9528_initDeviceDataStruct(ad9528Device_t *device, uint32_t vcxoFrequency_Hz, uint32_t refAFrequency_Hz, uint32_t outputDeviceClock_Hz) +{ +// uint16_t chDiv; +// uint8_t i = 0; +// +// uint32_t pll1PfdFreq_Hz = 0; +// uint8_t pll1Ndiv = 0; +// uint8_t validPll1DivSetting = 0; +// uint8_t refAdiv = 1; +// +// +// uint8_t pll2RfDiv = 3; /* Valid values 3,4,5 */ +// uint16_t pll2Ndiv = 1; /* Valid values 1-256 */ +// uint32_t pll2InputFreq_Hz = 0; +// uint64_t pll2VcoFreq_Hz = 0; +// uint16_t pll2NdivStart = 0; +// uint8_t validPll2DivSetting = 0; +// uint64_t chDivU64 = 0; +// +// static const uint64_t PLL2_MIN_VCO_FREQ_HZ = 3450000000ULL; +// static const uint64_t PLL2_MAX_VCO_FREQ_HZ = 4025000000ULL; +// /******************************************************************* +// * PLL1 Settings +// ******************************************************************* +// */ +// +// /* find valid PLL1 Ndiv and REFA div */ +// for (pll1Ndiv = 1; pll1Ndiv < 20; pll1Ndiv++) +// { +// pll1PfdFreq_Hz = vcxoFrequency_Hz / pll1Ndiv; +// +// if ((pll1PfdFreq_Hz <= 110000000) && (pll1PfdFreq_Hz >= 1000000) && +// (pll1PfdFreq_Hz <= refAFrequency_Hz) && +// (refAFrequency_Hz % pll1PfdFreq_Hz == 0) +// ) +// { +// validPll1DivSetting = 1; +// refAdiv = refAFrequency_Hz / pll1PfdFreq_Hz ; +// break; +// } +// } +// +// if (validPll1DivSetting == 0) +// { +// return ADIERR_INV_PARM; +// } +// +// device->pll1Settings->nDivider = pll1Ndiv; //This init function always runs PLL1 at 30.72MHz Pfd rate +// device->pll1Settings->refA_bufferCtrl = DIFFERENTIAL; //DISABLED = 0, SINGLE_ENDED, NEG_SINGLE_ENDED, DIFFERENTIAL +// device->pll1Settings->refA_Divider = refAdiv; +// device->pll1Settings->refA_Frequency_Hz = refAFrequency_Hz; +// device->pll1Settings->refB_bufferCtrl = DISABLED; //DISABLED = 0, SINGLE_ENDED, NEG_SINGLE_ENDED, DIFFERENTIAL +// device->pll1Settings->refB_Divider = 1; +// device->pll1Settings->refB_Frequency_Hz = 0; +// device->pll1Settings->vcxoBufferCtrl = NEG_SINGLE_ENDED; //DISABLED = 0, SINGLE_ENDED, NEG_SINGLE_ENDED, DIFFERENTIAL +// device->pll1Settings->vcxo_Frequency_Hz = vcxoFrequency_Hz; +// +// /******************************************************************* +// * PLL2 Settings +// ******************************************************************* +// */ +// +// /******************************************************************* +// * Output Distribution Settings +// * 9369CE02A uses the following clock outputs +// * OUT 1: FPGA REFCLK +// * OUT 3: FPGA SYSREF +// * OUT 12: DUT SYSREF +// * OUT 13: DUT REFCLK +// ******************************************************************* +// */ +// +// /* PLL 2 input clock can be several different things. Currently hard coded by this init funciton to use +// * PLL 1 output (VCXO Frequency) with no scaling +// */ +// pll2InputFreq_Hz = device->pll1Settings->vcxo_Frequency_Hz; +// validPll2DivSetting = 0; +// +// /* Sweep PLL2 Divider settings to find something that has a valid integer divide (3,4,5)*/ +// for (pll2RfDiv = 3; pll2RfDiv <= 5; pll2RfDiv++) +// { +// +// pll2NdivStart = (PLL2_MIN_VCO_FREQ_HZ / pll2RfDiv / pll2InputFreq_Hz); +// /* find valid PLL2 Ndiv (1-256) */ +// for (pll2Ndiv = pll2NdivStart; pll2Ndiv <= 256; pll2Ndiv++) +// { +// pll2VcoFreq_Hz = (pll2InputFreq_Hz * pll2RfDiv * pll2Ndiv); +// +// if (pll2VcoFreq_Hz < PLL2_MIN_VCO_FREQ_HZ) +// { +// /* Continue to next PLL2 N div */ +// continue; +// } +// else if (pll2VcoFreq_Hz > PLL2_MAX_VCO_FREQ_HZ) +// { +// /* Break to next PLL2 RF div */ +// break; +// } +// +// if (((pll2VcoFreq_Hz / pll2RfDiv) % outputDeviceClock_Hz) == 0) +// { +// +// device->pll2Settings->rfDivider = pll2RfDiv; +// device->pll2Settings->n2Divider = pll2Ndiv; +// device->pll2Settings->totalNdiv = pll2RfDiv * pll2Ndiv; +// chDivU64 = ((pll2VcoFreq_Hz / pll2RfDiv) / outputDeviceClock_Hz); +// +// if ((chDivU64 < 1) || (chDivU64 > 256)) +// { +// return ADIERR_INV_PARM; +// } +// else +// { +// chDiv = (uint16_t)(chDivU64); +// } +// +// validPll2DivSetting = 1; +// break; +// } +// } +// +// if (validPll2DivSetting == 1) +// { +// break; +// } +// } +// +// if (validPll2DivSetting == 0) +// { +// return ADIERR_INV_PARM; +// } +// +// device->outputSettings->outPowerDown = (uint16_t)(~0x300A); //enable outputs 13,12,3 and 1 +// +// for (i=0; i<14; i++){ +// device->outputSettings->outSource[i] = CHANNEL_DIV; //CHANNEL_DIV , PLL1_OUTPUT, SYSREF, INV_PLL1_OUTPUT +// device->outputSettings->outBufferCtrl[i] = LVDS; //LVDS, LVDS_BOOST, HSTL +// device->outputSettings->outChannelDiv[i] = chDiv; +// device->outputSettings->outFrequency_Hz[i] = outputDeviceClock_Hz; +// device->outputSettings->outAnalogDelay[i] = 0; +// device->outputSettings->outDigitalDelay[i] = 0; +// } +// +// +// device->outputSettings->outSource[3] = SYSREF; +// device->outputSettings->outSource[12] = SYSREF; +// +// +// device->sysrefSettings->sysrefDivide = 512; //SYSREF frequency = VCXO / 2 / sysrefDivde +// device->sysrefSettings->sysrefNshotMode = ONE_PULSE; //ONE_PULSE=0, TWO_PULSES=2, FOUR_PULSES=3, SIX_PULSES=4, EIGHT_PULSES=5 +// device->sysrefSettings->sysrefPatternMode = NSHOT; //NSHOT=0, CONTINUOUS=1, PRBS=2, STOP=3 +// device->sysrefSettings->sysrefPinBufferMode = DISABLED; //DISABLED = 0, SINGLE_ENDED, NEG_SINGLE_ENDED, DIFFERENTIAL +// device->sysrefSettings->sysrefPinEdgeMode = LEVEL_ACTIVE_HIGH; //LEVEL_ACTIVE_HIGH=0, LEVEL_ACTIVE_LOW=1, RISING_EDGE=2, FALLING_EDGE=3 +// device->sysrefSettings->sysrefRequestMethod = SPI; //SPI=0,PIN=1 +// device->sysrefSettings->sysrefSource = INTERNAL; //EXTERNAL=0, EXT_RESAMPLED=1, INTERNAL=2 + return ADIERR_OK; +} + +/** + * \brief Debug function to print out summary of AD9528 setup + * + * \param device AD9528 Device data structure describing setup of device. + * + * \return Returns enum ADI_ERR, 0=pass, >0 = fail +***********************************************************************************/ +ADI_ERR AD9528_reportClockRates(ad9528Device_t *device) +{ + + return ADIERR_OK; +} //debug function to help verify data structure is setup correctly. + +/** + * \brief Initializes the AD9528 by writing all SPI registers + * + * Initializes the AD9528 for use with the AD9369 transceiver. Designed to work with + * a reference clock of 122.88MHz. Reference clock is expected to be 30.72MHz. + * The output clocks from the AD9528 can run at 122.88M, 153.6M, 184.32M, 245.76M, or 307.2M. + * Typical setup: REFA frequency = 30.72, VCXO = 122.88MHz + * SYNC(SYSREF) pulses output at rate of 120kHz + * + * Dependencies + * - All parameters in device structure + * + * \param device is structure pointer to AD9528 clock device structure + * + * \return Returns enum ADI_ERR, 0=pass, >0 = fail + */ +ADI_ERR AD9528_initialize(ad9528Device_t *device) { //writes all registers to desired values, leaves clock outputs off, SYSREF output disabled. + uint8_t pll2_Adiv=0; + uint8_t pll2_Bdiv=0; + uint8_t reg108=0; + uint8_t reg109=0; + uint8_t i = 0; + uint8_t j = 0; + uint8_t reg508; + ADI_ERR retval = ADIERR_OK; + + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, ADIERR_OK, "\n// AD9528_initialize\n"); + + //CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_ADI_SPI_CONFIG_A, 0x18); //[4] and [3] =1 enable 4 wire SPI + //CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_ADI_SPI_CONFIG_B, 0x00); + retval = AD9528_setSpiSettings(device); + if (retval != ADIERR_OK) + { + return retval; + } + + /********************************************************************** + * Configure PLL1 + ********************************************************************** + */ + + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_REF_A_DIVIDER_LSB, + device->pll1Settings->refA_Divider & 0xFF); //REF A div[7:0] + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_REF_A_DIVIDER_MSB, + (device->pll1Settings->refA_Divider >> 8) & 0x03); //REF A div[9:8] + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_REF_B_DIVIDER_LSB, + device->pll1Settings->refB_Divider & 0xFF); //REF B div[7:0] + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_REF_B_DIVIDER_MSB, + (device->pll1Settings->refB_Divider >> 8) & 0x03); //REF B div[9:8] + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL1_N_DIV_LSB, + device->pll1Settings->nDivider & 0xFF); //PLL1 N div[7:0] + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL1_N_DIV_MSB, + (device->pll1Settings->nDivider >> 8) & 0x03); //PLL1 N div[9:8] + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL1_CHARGEPUMP, + 0x0A); //PLL1 Charge Pump control 1 + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL1_CP_CTRL2, + 0x03); //PLL1 Charge Pump control 2 + + switch (device->pll1Settings->refA_bufferCtrl){ + case DISABLED: + reg108 &= ~0x28; + reg109 &= ~0x01; + break; //clear all REFA enable bits + case SINGLE_ENDED: + reg108 |= 0x08; + reg109 &= ~0x01; + break; //Set REFA receiver enable, clear REFA SE negative input enable + case NEG_SINGLE_ENDED: + reg108 |= 0x08; + reg108 &= ~0x10; + reg109 |= 0x01; + break; //Disable REFA diff receiver, enable REFA receiver and use negative REFA input + case DIFFERENTIAL: + reg108 |= 0x28; + reg109 &= ~0x01; + break; + default: + reg108 |= 0x08; + reg109 &= ~0x01; + break; //default to single ended case + } + switch (device->pll1Settings->refB_bufferCtrl){ + case DISABLED: + reg108 &= ~0x50; + reg109 &= ~0x02; + break; //clear all REFB enable bits + case SINGLE_ENDED: + reg108 |= 0x10; + reg109 &= ~0x02; + break; //Set REFB receiver enable, clear REFB SE negative input enable + case NEG_SINGLE_ENDED: + reg108 |= 0x10; + reg108 &= ~0x40; + reg109 |= 0x02; + break; //Disable REFB diff receiver, enable REFB receiver and use negative REFB input + case DIFFERENTIAL: + reg108 |= 0x50; + reg109 &= ~0x02; + break; + default: + reg108 |= 0x10; + reg109 &= ~0x02; + break; //default to single ended case + } + switch (device->pll1Settings->vcxoBufferCtrl){ + case DISABLED: + reg108 &= ~0x03; + reg108 |= 0x04; + break; //power down VCXO input + case SINGLE_ENDED: + reg108 &= ~0x07; + break; //Clear VCXO receiver power down, defaults to Single ended mode + case NEG_SINGLE_ENDED: + reg108 &= ~0x07; + reg108 |= 0x02; + break; //Clear VCXO power down, enable Negative single ended mode[1] + case DIFFERENTIAL: + reg108 &= ~0x07; + reg108 |= 0x01; + break; //Clear VCXO power down, enable differential input buffer[0] + default: + reg108 &= ~0x07; + break; //default to positive single ended case + } + + + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_INPUT_RECEIVERS1, + reg108); //Input receiver settings (single ended or differential clock inputs) + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_INPUT_RECEIVERS2, + reg109); //Input receiver settings + + + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_INPUT_RECEIVERS3, + 0x0A); //Reference selection mode + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL1_FASTLOCK, + 0x00); //Disable Fast lock + + /********************************************************************** + * Configure PLL2 + ********************************************************************** + */ + pll2_Bdiv = device->pll2Settings->totalNdiv / 4; + pll2_Adiv = device->pll2Settings->totalNdiv % 4; + + if (pll2_Adiv > 3) { //A div valid range (0 to 3) + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, ADIERR_INV_PARM, "\n// AD9528 PLL2 A Divider out of range (0 to 3)\n"); + return ADIERR_INV_PARM; + } + if (pll2_Bdiv < 3 || pll2_Bdiv > 63) { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, ADIERR_INV_PARM, "\n// AD9528 PLL2 B Divider out of range (3 to 63)\n"); + return ADIERR_INV_PARM; + } + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL2_CHARGEPUMP, + 0xE6); //PLL2 Charge Pump[7:0] + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL2_N_DIV, + ((pll2_Adiv & 0x3) << 6) | (pll2_Bdiv & 0x3F)); //PLL2 A and B divider + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL2_CTRL, 0x03); //PLL2 control + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL2_VCO_CTRL, 0x01); //Manual VCO CAL + + if (device->pll2Settings->rfDivider < 3 || device->pll2Settings->rfDivider > 5) { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, ADIERR_INV_PARM, "\n// AD9528 PLL2 RF Divider out of range (3,4, or 5)\n"); + return ADIERR_INV_PARM; + } + + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL2_VCO_DIV, + device->pll2Settings->rfDivider); //VCO divider + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL2_LF_CTRL1, + 0x3A); //PLL2 Loop filter [7:0] + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL2_LF_CTRL2, + 0x00); //PLL2 Loop filter [8] + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL2_RDIV, + 0x00); //R divider + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL2_REPLICA_CHDIV, + (device->pll2Settings->totalNdiv / device->pll2Settings->rfDivider) + -1 ); //Replica channel divider: Ndivider = rfDivider * R divider + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_PLL2_REPLICA_DIV_PHASE, + 0x00); //Replica Channel Divider phase + + /********************************************************************** + * Configure Output Distribution + ********************************************************************** + */ + for (i=0; i<14; i=i+1){ + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_CH_OUT0_CTRL1 + j, + ((device->outputSettings->outSource[i] & 0x7) << 5) | + (device->outputSettings->outAnalogDelay[i] & 0x1F)); + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_CH_OUT0_CTRL2 + j, + ((device->outputSettings->outBufferCtrl[i] & 0x3) << 6) | + (device->outputSettings->outDigitalDelay[i] & 0x3F)); + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_CH_OUT0_CHDIV + j, + device->outputSettings->outChannelDiv[i]-1); + j = j+3; + } + + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_OUTPUT_SYNC, 0x00); //Sync outputs + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_MASK_SYNC1, 0x00); //Mask SYNC[7:0] + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_MASK_SYNC2, 0x00); //Mask SYNC[13:8] + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_EN_OUTPUT_PATH_SEL1, + 0x00); //Bypass SYSREF resample [6:0], bit0:Enable VCXO to feed output distrubution + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_EN_OUTPUT_PATH_SEL2, + 0x00); //Bypass SYSREF resample [13:7] + + /********************************************************************** + * Configure SYSREF operation + ********************************************************************** + */ + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_SYSERF_DIV_LSB, + device->sysrefSettings->sysrefDivide & 0xFF); //SYSREF divider [7:0] + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_SYSERF_DIV_MSB, + (device->sysrefSettings->sysrefDivide >> 8) & 0xFF); //SYSREF divider [7:0] + + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_SYSREF_CTRL3, + ((device->sysrefSettings->sysrefRequestMethod & 0x1) << 7) | + ((device->sysrefSettings->sysrefPinEdgeMode & 0x3) << 5) ); + + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_SYSREF_CTRL4, + ((device->sysrefSettings->sysrefSource & 0x03) << 6) | + ((device->sysrefSettings->sysrefPatternMode & 0x3) << 4 ) | + ((device->sysrefSettings->sysrefNshotMode & 0x7) << 1) ); + + if(device->sysrefSettings->sysrefPinBufferMode == DISABLED) + { + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_SYSREF_CTRL5, + 0x04); //power down input buffer for external SYSREF + } + else if(device->sysrefSettings->sysrefPinBufferMode == SINGLE_ENDED) + { + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_SYSREF_CTRL5, + 0x00); //enable positive singled ended input + } + else if(device->sysrefSettings->sysrefPinBufferMode == NEG_SINGLE_ENDED) + { + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_SYSREF_CTRL5, + 0x02); //enable negative singled ended input + } + else if(device->sysrefSettings->sysrefPinBufferMode == DIFFERENTIAL) + { + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_SYSREF_CTRL5, + 0x01); //enable differential input buffer + } + else + { + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_SYSREF_CTRL5, + 0x04); //power down input buffer for external SYSREF + } + + /********************************************************************** + * Power down control + ********************************************************************** + */ + + if (device->pll1Settings->bypassPll1 > 0) + { + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_POWERDOWN_CTRL, + 0x14);// power up PLL2 and output distribution, power down PLL1 + } + else + { + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_POWERDOWN_CTRL, + 0x10);// power up PLL1, PLL2 and output distribution + } + + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_CH_POWERDOWN1, + device->outputSettings->outPowerDown & 0xFF); //power down out[7:0] + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_CH_POWERDOWN2, + ((device->outputSettings->outPowerDown >> 8) & 0x3F)); //power down out[13:8] + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_LDO_ENABLES1, + 0xFF); //LDO enable per output channel [7:0] + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_LDO_ENABLES2, + 0xFF); //LDO enable per output channel [15:8] + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_STATUS0_CTRL, + 0x07); //STATUS 0 outputs REFA present + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_STATUS1_CTRL, + 0x01); //STATUS 1 outputs PLL1 and PLL2 locked + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_STATUS_OE, + 0x0C);// Make Status0 and Status1 outputs after reset. + + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_IO_UPDATE, + 0x01); //IO update to make all these settings valid in the 9528 + + CMB_setTimeout_ms(1000); + do{ + CMB_SPIReadByte(device->spiSettings, AD9528_ADDR_STATUS_READBACK0, ®508); + if(CMB_hasTimeoutExpired() > 0) + { + return ADIERR_FAILED; + } + }while((reg508 & 0xA2) != 0xA2); + + return ADIERR_OK; +} + +/// Send a SPI message to request a SYSREF pulse or continuous SYSREF from the AD9528. +/*******************************************************************************//** + * Requests a SYSREF from the AD9528. It will use whatever settings for SYSREF + * that are current configured in the AD9528. This could be a single pulse, + * multiple pulses, or continuous pulses. + * Dependencies + * - device->spiSettings + * - device->sysrefSettings->sysrefPatternMode + * + * \param device is structure pointer to AD9528 clock device structure + * \param enableSYSREF If NSHOT SYSREF mode, this parameter is ignored. If PRBS/CONTINUOUS SYSREF mode, 1= enable SYSREF, 0= disable SYSREF. + * + * \return Returns enum ADI_ERR, 0=pass, >0 = fail + ***********************************************************************************/ +ADI_ERR AD9528_requestSysref(ad9528Device_t *device, uint8_t enableSYSREF){ + uint8_t _enableSYSREF=0; + + if (device->sysrefSettings->sysrefPatternMode == NSHOT || enableSYSREF > 0) + { + _enableSYSREF = 1; + } + else + { + _enableSYSREF = 0; + } + + CMB_SPIWriteField(device->spiSettings, AD9528_ADDR_SYSREF_CTRL4, _enableSYSREF, 0x01, 0x00); //Set SPI SYSREF request bit + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_IO_UPDATE, 0x01); //IO update to make all these settings valid in the 9528 + + return ADIERR_OK; +} + +/// Allow changing the 9528 SYSREF frequency and pattern mode(CONTINUOUS, PRBS vs NSHOT mode) +/*******************************************************************************//** + * NOTE: this function will update the device structure with the parameter values passed + * into this function. The device->sysrefSettings->sysrefPatternMode, device->sysrefSettings->sysrefNshotMode, + * and device->sysrefSettings->sysrefDivide values will be updated in the device structure. + * + * Dependencies + * - device->spiSettings + * + * \param device is structure pointer to AD9528 clock device structure + * \param divideFromPll1Out Sets the SYSREF pulse frequency. SYSREF frequency = PLL1_VCXO frequency/divideFromPll1Out + * \param sysrefPatternMode Valid settings: NSHOT, CONTINUOUS, PRBS, STOP + * \param nShotPulses Valid settings: ONE_PULSE=0, TWO_PULSES=2, FOUR_PULSES=3, SIX_PULSES=4, EIGHT_PULSES=5 + * + * \return Returns enum ADI_ERR, 0=pass, >0 = fail + ***********************************************************************************/ +ADI_ERR AD9528_setupSYSREF(ad9528Device_t *device, uint16_t divideFromPll1Out, sysrefPatternMode_t sysrefPatternMode, sysrefNshotMode_t nShotPulses) +{ + uint8_t reg403=0; + + device->sysrefSettings->sysrefPatternMode = sysrefPatternMode; + device->sysrefSettings->sysrefNshotMode = nShotPulses; + device->sysrefSettings->sysrefDivide = divideFromPll1Out >> 1; //SYSREF frequency is (PLL1)VCXO frequency / 2 / device->sysrefSettings->sysrefDivide + + CMB_SPIReadByte(device->spiSettings, AD9528_ADDR_SYSREF_CTRL4, ®403); + + reg403 = reg403 & ~0x01; //clear bit 0 to stop a continuous sysref if it is on. + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_SYSREF_CTRL4, reg403); + + reg403 = reg403 & ~0x3E; //clear bits for pattern mode and Nshot mode bitfields + reg403 = reg403 | ((sysrefPatternMode & 0x3) << 4) | ((nShotPulses & 0x7) << 1); + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_SYSREF_CTRL4, reg403); //update internal sysref pattern mode and Nshot mode (number of pulses) + + //SYSREF request bit x403[0] is left 0. The next call to AD9528_requestSysref will start the SYSREF + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_IO_UPDATE, 0x01); //IO update to make all these settings valid in the 9528 + + + return ADIERR_OK; +} + +/// Update the AD9528 clock outputs that are enabled. +/*******************************************************************************//** + * NOTE: this function will update the device structure with the parameter values passed + * into this function. The device->sysrefSettings->sysrefPatternMode, device->sysrefSettings->sysrefNshotMode, + * and device->sysrefSettings->sysrefDivide values will be updated in the device structure. + * + * Dependencies + * - device->spiSettings + * + * \param device is structure pointer to AD9528 clock device structure + * \param clkEnable Sets which clock outputs are enabled. Bit per clock output. bit0 = out0, etc. + * + * \return Returns enum ADI_ERR, 0=pass, >0 = fail + ***********************************************************************************/ +ADI_ERR AD9528_enableClockOutputs(ad9528Device_t *device, uint16_t clkEnable) +{ //clkEnable: bit per clock output + + device->outputSettings->outPowerDown = ~clkEnable; + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_CH_POWERDOWN1, device->outputSettings->outPowerDown & 0xFF); //power down out[7:0] + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_CH_POWERDOWN2, ((device->outputSettings->outPowerDown >> 8) & 0x3F)); //power down out[13:8] + + CMB_SPIWriteByte(device->spiSettings, AD9528_ADDR_IO_UPDATE, 0x01); //IO update to make all these settings valid in the 9528 + return ADIERR_OK; +} + +/// Waits for PLL1 and PLL2 to lock and the REFA and VCXO clocks to be present +/*******************************************************************************//** + * Waits until Reference A clock and VCXO clock input to be detected (present), + * and PLL1 and PLL2 to lock. Will timeout after 1 second and return ADIERR_FAILED. + * If clock are detected and PLLs locked, returns ADIERR_OK. + * + * Dependencies + * - device->spiSettings + * + * \param device is structure pointer to AD9528 clock device structure + * + * \return Returns enum ADI_ERR, 0=pass, >0 = fail + ***********************************************************************************/ +ADI_ERR AD9528_waitForPllLock(ad9528Device_t *device) +{ + uint8_t reg508; + + CMB_setTimeout_ms(1000); + do{ + CMB_SPIReadByte(device->spiSettings, AD9528_ADDR_STATUS_READBACK0, ®508); + if(CMB_hasTimeoutExpired() > 0) + { + return ADIERR_FAILED; + } + }while((reg508 & 0x27) != 0x27); + + return ADIERR_OK; +} + +/// Reads the Lock Status of the PLLs and present detect of the reference clocks +/*******************************************************************************//** + * NOTE: This is a non blocking function that reads a register to see if PLL1 + * and PLL2 are locked and Reference clock A and the VCXO input clock are + * detected (present). If the *status parameter is not NULL, the status will + * be returned. If *status is NULL, the error return value will denote if + * the PllStatus is locked or not with ADIERR_OK or ADIERR_FAILED. + * + * Dependencies + * - device->spiSettings + * + * \param device is structure pointer to AD9528 clock device structure + * + * \return Returns enum ADI_ERR, 0=pass, >0 = fail + ***********************************************************************************/ +ADI_ERR AD9528_readPllStatus(ad9528Device_t *device, uint8_t *status) +{ + uint8_t reg508; + + //bit5 is VCXO clock detected + //bit2 is REFCLK A detected + //bit1 is PLL2 lock detect + //bit0 is PLL1 lock detect + + /* read twice to refresh status bits */ + CMB_SPIReadByte(device->spiSettings, AD9528_ADDR_STATUS_READBACK0, ®508); + CMB_SPIReadByte(device->spiSettings, AD9528_ADDR_STATUS_READBACK0, ®508); + /* if status is a valid pointer, return the PLL status */ + if (status > 0) + { + *status = reg508; + } + + /* PLLs 1 and 2 are locked and VCXO and REFA detected if reg508 has bits 5,2,1 and 0 set */ + if((reg508 & 0x27) == 0x27) + return ADIERR_OK; + else + return ADIERR_FAILED; +} diff --git a/df_datalink_ge/src/hardware/mykonos/ad9528.h b/df_datalink_ge/src/hardware/mykonos/ad9528.h new file mode 100644 index 0000000..b7e6cfe --- /dev/null +++ b/df_datalink_ge/src/hardware/mykonos/ad9528.h @@ -0,0 +1,44 @@ +/** + * \file ad9528.h + * \brief Contains function declarations and ad9528Device_t structure typedef for ad9528.c + */ + +/** +* \page Disclaimer Legal Disclaimer +* Copyright 2015-2017 Analog Devices Inc. +* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file. +* +*/ + +#ifndef _AD9528_LIB_H_ +#define _AD9528_LIB_H_ + +#include +#include "../common.h" +#include "t_ad9528.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define CLEMENTE_TDD_AD9528_CLKOUT_INDEX 13 + +//Helper function to setup the 9528 device data structure specifically for the ADI transceiver evaluation cards +ADI_ERR AD9528_initDeviceDataStruct(ad9528Device_t *device, uint32_t vcxoFrequency_Hz, uint32_t refAFrequency_Hz, uint32_t outputDeviceClock_Hz); +ADI_ERR AD9528_reportClockRates(ad9528Device_t *device); //debug function to help verify data structure is setup correctly. + +//AD9528 API functions +ADI_ERR AD9528_resetDevice(ad9528Device_t *device); +ADI_ERR AD9528_setSpiSettings(ad9528Device_t *device); +ADI_ERR AD9528_initialize(ad9528Device_t *device); //writes all registers to desired values, leaves clock outputs off. +ADI_ERR AD9528_waitForPllLock(ad9528Device_t *device); +ADI_ERR AD9528_readPllStatus(ad9528Device_t *device, uint8_t *status); +ADI_ERR AD9528_enableClockOutputs(ad9528Device_t *device, uint16_t clkEnable); //clkEnable: bit per clock output +ADI_ERR AD9528_setupSYSREF(ad9528Device_t *device, uint16_t divideFromPll1Out, sysrefPatternMode_t sysrefPatternMode, sysrefNshotMode_t nShotPulses); +ADI_ERR AD9528_requestSysref(ad9528Device_t *device, uint8_t enableSYSREF); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/df_datalink_ge/src/hardware/mykonos/mykonos.c b/df_datalink_ge/src/hardware/mykonos/mykonos.c new file mode 100644 index 0000000..c8db0e3 --- /dev/null +++ b/df_datalink_ge/src/hardware/mykonos/mykonos.c @@ -0,0 +1,18444 @@ +/** + *\file mykonos.c + * + *\brief Contains Mykonos APIs for transceiver configuration and control + * + * Mykonos API version: 1.5.2.3566 + */ + +/** + * \mainpage Overview + * + * This document is intended for use by software engineering professionals and + * includes detailed information regarding the data types and function calls + * which comprise the Mykonos ANSI C API. + * References to "Mykonos" in the API refer to the Analog Devices development name for the AD9371 family of devices. + * + */ + +/** + * \page Use Suggested Use + * The purpose of this API library is to add abstraction for the low level + * SPI control and calculations necessary to control the Mykonos family of transceiver devices + * + * Add the included source code as required to your baseband processor software build. Please reference the integration document + * as well for further instructions. + */ + +/** +* \page Disclaimer Legal Disclaimer +* Copyright 2015-2017 Analog Devices Inc. +* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file. +* +*/ + +#include +#include +#include "../common.h" +#include "mykonos.h" +#include "mykonos_gpio.h" +#include "mykonos_macros.h" +#include "mykonos_user.h" + +/* Private helper functions local to this file */ +static mykonosErr_t MYKONOS_calculateScaledDeviceClk_kHz(mykonosDevice_t *device, uint32_t *scaledRefClk_kHz, uint8_t *deviceClkDiv); +static mykonosErr_t MYKONOS_calculateDigitalClocks(mykonosDevice_t *device, uint32_t *hsDigClk_kHz, uint32_t *hsDigClkDiv4or5_kHz); +static mykonosErr_t enableDpdTracking(mykonosDevice_t *device, uint8_t tx1Enable, uint8_t tx2Enable); +static mykonosErr_t enableClgcTracking(mykonosDevice_t *device, uint8_t tx1Enable, uint8_t tx2Enable); + +/** + * \brief Verifies the Tx profile members are valid (in range) in the init structure + * + * If the Tx profile IQ data rate = 0, it is assumed that the Tx profile is + * not used. If Tx IQ data rate > 0, and Tx profile members are out of range, + * + * \pre This function is private and is not called directly by the user. + * + * Dependencies + * - device->tx->txProfile + * + * \param device Structure pointer to Mykonos device data structure + * \param txProfile txProfile settings to be verified + * \param txHsDigClk_kHz Return value of the calculated HS Dig Clock required by the Tx profile + * + * \retval MYKONOS_ERR_TXPROFILE_IQRATE Profile IQ rate out of range + * \retval MYKONOS_ERR_TXPROFILE_RFBW Tx Profile RF bandwidth out of range + * \retval MYKONOS_ERR_TXPROFILE_FILTER_INTERPOLATION Filter interpolation not valid + * \retval MYKONOS_ERR_TXPROFILE_FIR_INT FIR filter not valid + * \retval MYKONOS_ERR_OK All profile members are valid + */ +static mykonosErr_t mykVerifyTxProfile(mykonosDevice_t *device, mykonosTxProfile_t *txProfile, uint32_t *txHsDigClk_kHz) +{ + mykonosErr_t retVal = MYKONOS_ERR_OK; + + *txHsDigClk_kHz = 0; + + /********************************/ + /* Check for a valid Tx profile */ + /********************************/ + + if ((txProfile->iqRate_kHz < MIN_TX_IQRATE_KHZ) || (txProfile->iqRate_kHz > MAX_TX_IQRATE_KHZ)) + { + return MYKONOS_ERR_TXPROFILE_IQRATE; + } + + if ((txProfile->rfBandwidth_Hz < MIN_TX_RFBW_HZ) || (txProfile->rfBandwidth_Hz > MAX_TX_RFBW_HZ)) + { + return MYKONOS_ERR_TXPROFILE_RFBW; + } + + if ((txProfile->thb1Interpolation != 1) && (txProfile->thb1Interpolation != 2)) + { + return MYKONOS_ERR_TXPROFILE_FILTER_INTERPOLATION; + } + + if ((txProfile->thb2Interpolation != 1) && (txProfile->thb2Interpolation != 2)) + { + return MYKONOS_ERR_TXPROFILE_FILTER_INTERPOLATION; + } + + if ((txProfile->txFirInterpolation != 1) && (txProfile->txFirInterpolation != 2) && (txProfile->txFirInterpolation != 4)) + { + return MYKONOS_ERR_TXPROFILE_FILTER_INTERPOLATION; + } + + if ((txProfile->txFir->coefs == NULL) && (txProfile->txFirInterpolation != 1)) + { + return MYKONOS_ERR_TXPROFILE_FIR_COEFS; + } + + if ((txProfile->dacDiv != DACDIV_2) && (txProfile->dacDiv != DACDIV_2p5) && (txProfile->dacDiv != DACDIV_4)) + { + return MYKONOS_ERR_TXPROFILE_DACDIV; + } + + *txHsDigClk_kHz = (txProfile->iqRate_kHz * txProfile->txFirInterpolation * txProfile->thb1Interpolation * txProfile->thb2Interpolation * (uint32_t)txProfile->dacDiv); + + device->profilesValid |= TX_PROFILE_VALID; + + return retVal; +} + +/** + * \brief Verifies the Rx profile members are valid (in range) and calculates HS Dig Clock require for the Rx Profile + * + * Private helper function to verify the Rx profile members are valid (in range) + * and calculates HS Dig Clock require for the Rx Profile + * If the Rx profile IQ data rate = 0, it is assumed that the Rx profile is + * not used. If Rx IQ data rate > 0, and Rx profile members are out of range. + * + * \pre This function is private and is not called directly by the user. + * + * Dependencies + * - device->rx->rxProfile + * + * \param device Structure pointer to Talise device data structure + * \param rxChannel receiver channel to be checked + * \param rxProfile rxProfile settings to be verified + * \param rxHsDigClk_kHz Return value of the calculated HS Dig Clock required by the Rx profile + * + * \retval MYKONOS_ERR_RXPROFILE_RXCHANNEL Rx channel is not valid. + * \retval MYKONOS_ERR_RXPROFILE_IQRATE out of range IQ rate + * \retval MYKONOS_ERR_RXPROFILE_RFBW out of range RF bandwidth + * \retval MYKONOS_ERR_RXPROFILE_FILTER_DECIMATION not valid filter decimation setting + * \retval MYKONOS_ERR_RXPROFILE_FIR_COEFS FIR filter not valid + * \retval MYKONOS_ERR_RXPROFILE_ADCDIV not valid ADC divider + * \retval MYKONOS_ERR_OK all profile members are valid + */ +static mykonosErr_t mykVerifyRxProfile(mykonosDevice_t *device, mykonosRxProfType_t rxChannel, mykonosRxProfile_t *rxProfile, uint32_t *rxHsDigClk_kHz) +{ + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint32_t minBwHz = 0; + uint32_t maxBwHz = 0; + + *rxHsDigClk_kHz = 0; + + switch (rxChannel) + { + case MYK_RX_PROFILE: + minBwHz = MIN_RX_RFBW_HZ; + maxBwHz = MAX_RX_RFBW_HZ; + break; + case MYK_OBS_PROFILE: + minBwHz = MIN_ORX_RFBW_HZ; + maxBwHz = MAX_ORX_RFBW_HZ; + break; + case MYK_SNIFFER_PROFILE: + minBwHz = MIN_SNIFFER_RFBW_HZ; + maxBwHz = MAX_SNIFFER_RFBW_HZ; + break; + + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RXPROFILE_RXCHANNEL, + getMykonosErrorMessage(MYKONOS_ERR_RXPROFILE_RXCHANNEL)); + return MYKONOS_ERR_RXPROFILE_RXCHANNEL; + } + + /********************************/ + /* Check for a valid Rx profile */ + /********************************/ + if ((rxProfile->iqRate_kHz < MIN_RX_IQRATE_KHZ) || (rxProfile->iqRate_kHz > MAX_RX_IQRATE_KHZ)) + { + return MYKONOS_ERR_RXPROFILE_IQRATE; + } + + /* check for Rx/Obs or Sniffer BW */ + if ((rxProfile->rfBandwidth_Hz < minBwHz) || (rxProfile->rfBandwidth_Hz > maxBwHz)) + { + return MYKONOS_ERR_RXPROFILE_RFBW; + } + + if ((rxProfile->rhb1Decimation != 1) && (rxProfile->rhb1Decimation != 2)) + { + return MYKONOS_ERR_RXPROFILE_FILTER_DECIMATION; + } + + if ((rxProfile->rxDec5Decimation != 4) && (rxProfile->rxDec5Decimation != 5)) + { + return MYKONOS_ERR_RXPROFILE_FILTER_DECIMATION; + } + + if ((rxProfile->rxFirDecimation != 1) && (rxProfile->rxFirDecimation != 2) && (rxProfile->rxFirDecimation != 4)) + { + return MYKONOS_ERR_RXPROFILE_FILTER_DECIMATION; + } + + if ((rxProfile->rxFir->coefs == NULL) && (rxProfile->rxFirDecimation != 1)) + { + return MYKONOS_ERR_RXPROFILE_FIR_COEFS; + } + + if ((rxProfile->adcDiv != 1) && (rxProfile->adcDiv != 2)) + { + return MYKONOS_ERR_RXPROFILE_ADCDIV; + } + + *rxHsDigClk_kHz = (rxProfile->iqRate_kHz * rxProfile->rxFirDecimation * rxProfile->rhb1Decimation * rxProfile->rxDec5Decimation * rxProfile->adcDiv); + + switch (rxChannel) + { + case MYK_RX_PROFILE: + device->profilesValid |= RX_PROFILE_VALID; + break; + case MYK_OBS_PROFILE: + device->profilesValid |= ORX_PROFILE_VALID; + break; + /*case MYK_SNIFFER_PROFILE:*/ + default: + device->profilesValid |= SNIFF_PROFILE_VALID; + break; + } + + return retVal; +} + +/** + * \brief Performs a hard reset on the MYKONOS DUT (Toggles RESETB pin on device) + * + * Toggles the Mykonos devices RESETB pin. Only resets the device with + * the SPI chip select indicated in the device->spiSettings structure. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device Pointer to Mykonos device data structure containing settings + * + * \return Returns enum mykonosErr_t, MYKONOS_ERR_OK=pass, !MYKONOS_ERR_OK=fail + */ +mykonosErr_t MYKONOS_resetDevice(mykonosDevice_t *device) +{ + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_resetDevice()\n"); +#endif + + /* toggle RESETB on device with matching spi chip select index */ + CMB_hardReset(device->spiSettings->chipSelectIndex); + return MYKONOS_ERR_OK; +} + +/** + * \brief Reads back the silicon revision for the Mykonos Device + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device Pointer to Mykonos device data structure containing settings + * \param revision Return value of the Mykonos silicon revision + * + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_getDeviceRev(mykonosDevice_t *device, uint8_t *revision) +{ +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getDeviceRev()\n"); +#endif + + CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_PRODUCT_ID, revision, 0x07, 0); + + return MYKONOS_ERR_OK; +} + +/** + * \brief Reads back the Product ID for the Mykonos Device + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device Pointer to Mykonos device data structure containing settings + * \param productId Return value of the Mykonos product Id + * + * \retval MYKONOS_ERR_GETPRODUCTID__NULL_PARAM recovery action for bad parameter check + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_getProductId(mykonosDevice_t *device, uint8_t *productId) +{ + mykonosErr_t retVal = MYKONOS_ERR_OK; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getProductId()\n"); +#endif + + if (productId == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETPRODUCTID_NULL_PARAM, + getMykonosErrorMessage(MYKONOS_ERR_GETPRODUCTID_NULL_PARAM)); + return MYKONOS_ERR_GETPRODUCTID_NULL_PARAM; + } + + CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_PRODUCT_ID, productId, 0xF8, 3); + + return retVal; +} + +/** + * \brief Get API version number + * + * This function reads back the version number of the API + * + * \param device Pointer to the Mykonos data structure + * \param siVer A pointer to the current silicon version number. + * \param majorVer A pointer to the current major version number. + * \param minorVer A pointer to the current minor version number. + * \param buildVer A pointer to the current build version number. + * + * \retval MYKONOS_ERR_GET_API_VERSION_NULL_PARAM Null parameter passed to the function. + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_getApiVersion(mykonosDevice_t *device, uint32_t *siVer, uint32_t *majorVer, uint32_t *minorVer, uint32_t *buildVer) +{ + mykonosErr_t retVal = MYKONOS_ERR_OK; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getApiVersion()\n"); +#endif + + if ((siVer == NULL) || (majorVer == NULL) || (minorVer == NULL) || (buildVer == NULL)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GET_API_VERSION_NULL_PARAM, + getMykonosErrorMessage(MYKONOS_ERR_GET_API_VERSION_NULL_PARAM)); + return MYKONOS_ERR_GET_API_VERSION_NULL_PARAM; + } + + *siVer = (uint32_t)MYKONOS_CURRENT_SI_VERSION; + *majorVer = (uint32_t)MYKONOS_CURRENT_MAJOR_VERSION; + *minorVer = (uint32_t)MYKONOS_CURRENT_MINOR_VERSION; + *buildVer = (uint32_t)MYKONOS_CURRENT_BUILD_VERSION; + return retVal; +} + +/** + * \brief Sets the Mykonos device SPI settings (3wire/4wire, MSBFirst, etc). + * + * This function will use the settings in the device->spiSettings structure + * to set SPI stream mode, address auto increment direction, MSBFirst/LSBfirst, + * and 3wire/4wire mode. The Mykonos device always uses SPI MODE 0 (CPHA=0, CPOL=0). + * This function will update your device->spiSettings to set CHPA=0 and CPOL=0 and + * longInstructionWord =1 to use a 16bit instruction word. + * + * Dependencies + * - writes device->spiSettings->CPHA = 0 + * - writes device->spiSettings->CPOL = 0 + * - writes device->spiSettings->longInstructionWord = 1 + * + * - device->spiSettings->MSBFirst + * - device->spiSettings->enSpiStreaming + * - device->spiSettings->autoIncAddrUp + * - device->spiSettings->fourWireMode + * + * \param device Pointer to Mykonos device data structure containing settings + * + * \return Returns enum mykonosErr_t, MYKONOS_ERR_OK=pass, !MYKONOS_ERR_OK=fail + */ +mykonosErr_t MYKONOS_setSpiSettings(mykonosDevice_t *device) +{ + //device->spiSettings->enSpiStreaming + uint8_t spiReg = 0; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setSpiSettings()\n"); +#endif + + device->spiSettings->CPHA = 0; + device->spiSettings->CPOL = 0; + device->spiSettings->longInstructionWord = 1; + + if (device->spiSettings->MSBFirst == 0) + { + spiReg |= 0x42; /* SPI bit is 1=LSB first */ + } + + if (device->spiSettings->autoIncAddrUp > 0) + { + spiReg |= 0x24; + } + + if (device->spiSettings->fourWireMode > 0) + { + spiReg |= 0x18; + } + + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CONFIGURATION_CONTROL_0, spiReg); + + if (device->spiSettings->enSpiStreaming > 0) + { + /* Allow SPI streaming mode: SPI message ends when chip select deasserts */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_SPI_CONFIGURATION_CONTROL_1, 0x00); + } + else + { + /* Force single instruction mode */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_SPI_CONFIGURATION_CONTROL_1, 0x80); + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief Verifies the integrity of the Mykonos device data structure. + * + * The Mykonos device data structure has many pointers to other structures. The + * main purpose of this function to verify that the necessary pointers within the + * device data structure have non zero pointers. The focus is on the Rx/Tx/ObsRx + * profiles and FIR filters where if a channel is disabled, it may be valid for + * some pointers to be NULL. This function updates device->profileValid to remember + * which profile pointers are valid. + * profileValid[3:0] = {SnifferProfileValid, ObsRxProfileValid, RxProfileValid, TxProfileValid}; + * + * Dependencies + * - device (all variables) + * + * \param device Pointer to Mykonos device data structure containing settings + * + * \return Returns enum mykonosErr_t, MYKONOS_ERR_OK=pass, !MYKONOS_ERR_OK=fail + */ +mykonosErr_t MYKONOS_verifyDeviceDataStructure(mykonosDevice_t *device) +{ + if (device == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, 0, MYKONOS_ERR_CHECKDEVSTRUCT_NULLDEVPOINTER, getMykonosErrorMessage(MYKONOS_ERR_CHECKDEVSTRUCT_NULLDEVPOINTER)); + return MYKONOS_ERR_CHECKDEVSTRUCT_NULLDEVPOINTER; + } + + device->profilesValid = 0; /* Reset */ + + if (device->spiSettings == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, 0, MYKONOS_ERR_CHECKDEVSTRUCT_SPI, getMykonosErrorMessage(MYKONOS_ERR_CHECKDEVSTRUCT_SPI)); + return MYKONOS_ERR_CHECKDEVSTRUCT_SPI; + } + + /* place this writeToLog after verifying the spiSettings structure is not NULL */ +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_verifyDeviceDataStructure()\n"); +#endif + + /************************************************************************** + * Check Rx stucture pointers + ************************************************************************** + */ + if (device->rx == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CHECKDEVSTRUCT_RX, getMykonosErrorMessage(MYKONOS_ERR_CHECKDEVSTRUCT_RX)); + return MYKONOS_ERR_CHECKDEVSTRUCT_RX; + } + else + { + if (device->rx->rxChannels == RXOFF) + {/* If no Rx channel enabled, ok to have null pointers for rx gain control, framer, and Rx profile/Rx FIR Filter */ + } + else + { + if ((device->rx->framer == NULL) || (device->rx->rxGainCtrl == NULL) || (device->rx->rxProfile == NULL)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CHECKDEVSTRUCT_RXSUB, + getMykonosErrorMessage(MYKONOS_ERR_CHECKDEVSTRUCT_RXSUB)); + return MYKONOS_ERR_CHECKDEVSTRUCT_RXSUB; + } + + if ((device->rx->rxProfile->rxFir == NULL) && (device->rx->rxProfile->rxFirDecimation != 1)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CHECKDEVSTRUCT_RXFIR, + getMykonosErrorMessage(MYKONOS_ERR_CHECKDEVSTRUCT_RXFIR)); + return MYKONOS_ERR_CHECKDEVSTRUCT_RXFIR; + } + } + } + + /************************************************************************** + * Check Tx stucture pointers + ************************************************************************** + */ + if (device->tx == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CHECKDEVSTRUCT_TX, getMykonosErrorMessage(MYKONOS_ERR_CHECKDEVSTRUCT_TX)); + return MYKONOS_ERR_CHECKDEVSTRUCT_TX; + } + else + { + if (device->tx->txChannels == TXOFF) + {/* If no Tx channel enabled, ok to have null pointers for deframer, and Tx profile/Tx FIR filter */ + } + else + { + if ((device->tx->deframer == NULL) || (device->tx->txProfile == NULL)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CHECKDEVSTRUCT_TXSUB, + getMykonosErrorMessage(MYKONOS_ERR_CHECKDEVSTRUCT_TXSUB)); + return MYKONOS_ERR_CHECKDEVSTRUCT_TXSUB; + } + + if ((device->tx->txProfile->txFir == NULL) && (device->tx->txProfile->txFirInterpolation != 1)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CHECKDEVSTRUCT_TXFIR, + getMykonosErrorMessage(MYKONOS_ERR_CHECKDEVSTRUCT_TXFIR)); + return MYKONOS_ERR_CHECKDEVSTRUCT_TXFIR; + } + } + } + + /************************************************************************** + * Check ObsRx stucture pointers + ************************************************************************** + */ + if (device->obsRx == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CHECKDEVSTRUCT_OBSRX, + getMykonosErrorMessage(MYKONOS_ERR_CHECKDEVSTRUCT_OBSRX)); + return MYKONOS_ERR_CHECKDEVSTRUCT_OBSRX; + } + else + { + if (device->obsRx->obsRxChannelsEnable == MYK_OBS_RXOFF) + {/* If no ObsRx channel enabled, ok to have null pointers for ObsRx gain control, framer, and ObsRx profile/FIR Filter */ + } + else + { + if ((device->obsRx->framer == NULL)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CHECKDEVSTRUCT_OBSRXFRAMER, + getMykonosErrorMessage(MYKONOS_ERR_CHECKDEVSTRUCT_OBSRXFRAMER)); + return MYKONOS_ERR_CHECKDEVSTRUCT_OBSRXFRAMER; + } + + if (device->obsRx->snifferProfile != NULL) + { + if (device->obsRx->snifferGainCtrl == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CHECKDEVSTRUCT_SNIFFERGAINCTRL, + getMykonosErrorMessage(MYKONOS_ERR_CHECKDEVSTRUCT_SNIFFERGAINCTRL)); + return MYKONOS_ERR_CHECKDEVSTRUCT_SNIFFERGAINCTRL; + } + + if ((device->obsRx->snifferProfile->rxFir == NULL) && (device->obsRx->snifferProfile->rxFirDecimation != 1)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CHECKDEVSTRUCT_SNIFFERFIR, + getMykonosErrorMessage(MYKONOS_ERR_CHECKDEVSTRUCT_SNIFFERFIR)); + return MYKONOS_ERR_CHECKDEVSTRUCT_SNIFFERFIR; + } + } + + if (device->obsRx->orxProfile != NULL) + { + if (device->obsRx->orxGainCtrl == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CHECKDEVSTRUCT_ORXGAINCTRL, + getMykonosErrorMessage(MYKONOS_ERR_CHECKDEVSTRUCT_ORXGAINCTRL)); + return MYKONOS_ERR_CHECKDEVSTRUCT_ORXGAINCTRL; + } + + if ((device->obsRx->orxProfile->rxFir == NULL) && (device->obsRx->orxProfile->rxFirDecimation != 1)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CHECKDEVSTRUCT_ORXFIR, + getMykonosErrorMessage(MYKONOS_ERR_CHECKDEVSTRUCT_ORXFIR)); + return MYKONOS_ERR_CHECKDEVSTRUCT_ORXFIR; + } + } + } + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief Initializes the Mykonos device based on the desired device settings. + * + * This function initializes the mykonos device, setting up the CLKPLL, digital clocks, + * JESD204b settings, FIR Filters, digital filtering. It does not load the ARM + * or perform any of the ARM init calibrations. It also sets the Rx Manual gain indexes and + * TxAttenuation settings to the initial values found in the device data structure. It leaves the + * Mykonos in a state ready for multichip sync (which can bring up the JESD204 links), the + * ARM to be loaded, and the init calibartions run. + * + * Dependencies + * - device (all variables) + * + * \param device Pointer to Mykonos device data structure containing settings + * + * \return Returns enum mykonosErr_t, MYKONOS_ERR_OK=pass, !MYKONOS_ERR_OK=fail + */ +mykonosErr_t MYKONOS_initialize(mykonosDevice_t *device) +{ + uint8_t txChannelSettings = 0; + uint8_t rxChannelSettings = 0; + uint8_t orxChannelSettings = 0; + uint8_t sniffChannelSettings = 0; + uint8_t adcDacClockRateSelect = 0; + uint8_t enableDpd = 0; + uint8_t obsRxRealIf = 0; + uint8_t enRxHighRejDec5 = 0; + uint8_t rxRealIfData = 0; + uint8_t txSyncb = 0x00; + uint8_t rxSyncb = 0x00; + uint8_t orxSyncb = 0x00; + mykonosErr_t retVal = MYKONOS_ERR_OK; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_initialize()\n"); +#endif + + retVal = MYKONOS_verifyDeviceDataStructure(device); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* Verify Rx/Tx and ObsRx profiles are valid combinations */ + retVal = MYKONOS_verifyProfiles(device); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* Set 3 or 4-wire SPI mode, MSBFirst/LSBfirst in device, pushes CPOL=0, CPHA=0, longInstWord=1 into device->spiSettings */ + retVal = MYKONOS_setSpiSettings(device); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* Increase SPI_DO drive strength */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DIGITAL_IO_CONTROL, 0x10); + + /* Enable Reference clock - Set REFCLK pad common mode voltage */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_REF_PAD_CONFIG2, 0x07); + + /* Set Mykonos IO pin settings, GPIO direction, enable relevant LVDS pads */ + /* Enable SYSREF LVDS input pad + 100ohm internal termination */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_SYSREF_PAD_CONFIG, 0x12); //Enable SYSREF input buffer + + if ((device->tx > 0) && (device->tx->txProfile > 0)) + { + /* Check for LVDS/CMOS mode */ + if (device->tx->deframer->txSyncbMode > 0) + { + txSyncb = 0xF0; + } + else + { + txSyncb = 0x02; + } + + /* Enable SYNCOUTB output buffer */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_TX1_SYNC_PAD_CONFIG, txSyncb); + } + + /* Look at each framer and enable the RXSYNCB used for each framer. + * It is possible that they use the same RXSYNCB pin */ + if ((device->rx > 0) && (device->rx->framer > 0)) + { + /* Check for LVDS/CMOS mode */ + if (device->rx->framer->rxSyncbMode > 0) + { + rxSyncb = 0x00; + } + else + { + rxSyncb = 0x12; + } + + if (device->rx->framer->obsRxSyncbSelect == 0) + { + /* Enable SYNCINB0 LVDS/CMOS input buffer */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RX1_SYNC_CONFIG, rxSyncb); + } + else + { + /* Enable SYNCINB1 LVDS/CMOS input buffer */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RX2_SYNC_CONFIG, rxSyncb); + } + } + if ((device->obsRx > 0) && (device->obsRx->framer > 0)) + { + /* Check for LVDS/CMOS mode */ + if (device->obsRx->framer->rxSyncbMode > 0) + { + orxSyncb = 0x00; + } + else + { + orxSyncb = 0x12; + } + + if (device->obsRx->framer->obsRxSyncbSelect == 0) + { + /* Check for rxSyncb and orxSyncb when using the same RXSYNCB */ + if ((orxSyncb != rxSyncb) && (device->rx->framer->obsRxSyncbSelect == 0)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_RXSYNCB_ORXSYNCB_MODE, + getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_RXSYNCB_ORXSYNCB_MODE)); + return MYKONOS_ERR_INIT_INV_RXSYNCB_ORXSYNCB_MODE; + } + + /* Enable SYNCINB0 LVDS input buffer */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RX1_SYNC_CONFIG, orxSyncb); + } + else + { + /* Check for rxSyncb and orxSyncb when using the same ORXSYNCB */ + if ((orxSyncb != rxSyncb) && (device->rx->framer->obsRxSyncbSelect == 1)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_RXSYNCB_ORXSYNCB_MODE, + getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_RXSYNCB_ORXSYNCB_MODE)); + return MYKONOS_ERR_INIT_INV_RXSYNCB_ORXSYNCB_MODE; + } + + /* Enable SYNCINB1 LVDS input buffer */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RX2_SYNC_CONFIG, orxSyncb); + } + } + + /* Set number of device clock cycles per microsecond [round(freq/2) - 1] */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_REFERENCE_CLOCK_CYCLES, (uint8_t)((((device->clocks->deviceClock_kHz / 1000) + 1) >> 1) - 1)); + + /* Set profile specific digital clock dividers */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CONFIGURATION_CONTROL_1, 0x04); /* Negate Rx2 so phase matches Rx1 */ + + if (device->profilesValid & TX_PROFILE_VALID) + { + txChannelSettings = (((uint8_t)device->tx->txChannels & 0x3) << 6); + switch (device->tx->txProfile->thb2Interpolation) + { + case 1: + break; /* keep bit as 0 in bitfield */ + case 2: + txChannelSettings |= 0x20; + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_TXHB2_INTERPOLATION, + getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_TXHB2_INTERPOLATION)); + return MYKONOS_ERR_INIT_INV_TXHB2_INTERPOLATION; + } + + switch (device->tx->txProfile->thb1Interpolation) + { + case 1: + break; /* keep bit as 0 in bitfield */ + case 2: + txChannelSettings |= 0x10; + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_TXHB1_INTERPOLATION, + getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_TXHB1_INTERPOLATION)); + return MYKONOS_ERR_INIT_INV_TXHB1_INTERPOLATION; + } + + if (device->tx->txProfile->txFir == NULL) + { + /* If invalid pointer to FIR filter, Bypass programmable FIR, keep txChannelSettings[1:0] == 0 */ + } + else + { + switch (device->tx->txProfile->txFirInterpolation) + { + case 1: + txChannelSettings |= 0x01; + break; + case 2: + txChannelSettings |= 0x02; + break; + case 4: + txChannelSettings |= 0x03; + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_TXFIR_INTERPOLATION, + getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_TXFIR_INTERPOLATION)); + return MYKONOS_ERR_INIT_INV_TXFIR_INTERPOLATION; + } + } + + switch (device->tx->txProfile->dacDiv) + { + case DACDIV_2: + break; /* Keep bit [1]=0 */ + case DACDIV_2p5: + break; /* Keep bit [1]=0, div 2.5 is set when Rx DEC5 filter enabled*/ + case DACDIV_4: + adcDacClockRateSelect |= 2; + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_DACDIV, getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_DACDIV)); + return MYKONOS_ERR_INIT_INV_DACDIV; + } + } + + if (device->profilesValid & RX_PROFILE_VALID) + { + rxChannelSettings = (((uint8_t)device->rx->rxChannels & 0x3) << 6); + switch (device->rx->rxProfile->rxDec5Decimation) + { + case 4: + break; /* keep bit as 0 in bitfield */ + case 5: + rxChannelSettings |= 0x04; + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_RXDEC5_DECIMATION, + getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_RXDEC5_DECIMATION)); + return MYKONOS_ERR_INIT_INV_RXDEC5_DECIMATION; + } + + switch (device->rx->rxProfile->rhb1Decimation) + { + case 1: + break; /* keep bit as 0 in bitfield */ + case 2: + rxChannelSettings |= 0x10; + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_RXHB1_DECIMATION, + getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_RXHB1_DECIMATION)); + return MYKONOS_ERR_INIT_INV_RXHB1_DECIMATION; + } + + if (device->rx->rxProfile->rxFir == NULL) + { + /* If invalid pointer to FIR filter, Bypass programmable FIR, keep rxChannelSettings[1:0] == 0 */ + } + else + { + switch (device->rx->rxProfile->rxFirDecimation) + { + case 1: + rxChannelSettings |= 0x01; + break; + case 2: + rxChannelSettings |= 0x02; + break; + case 4: + rxChannelSettings |= 0x03; + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_RXFIR_DECIMATION, + getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_RXFIR_DECIMATION)); + return MYKONOS_ERR_INIT_INV_RXFIR_DECIMATION; + } + } + + switch (device->rx->rxProfile->adcDiv) + { + case 1: + adcDacClockRateSelect |= 0; + break; + case 2: + adcDacClockRateSelect |= 1; + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_ADCDIV, getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_ADCDIV)); + return MYKONOS_ERR_INIT_INV_ADCDIV; + } + + rxRealIfData = (device->rx->realIfData > 0) ? 1 : 0; + enRxHighRejDec5 = (device->rx->rxProfile->enHighRejDec5 > 0) ? 1 : 0; + } + else if (device->profilesValid & ORX_PROFILE_VALID) + { + /* if Rx profile not valid, but ORX profile valid, set RX ADC divider and dec5 to match orx profile setting */ + /* ARM clock is derived from Rx clocking, so Rx ADC div needs to be set */ + switch (device->obsRx->orxProfile->rxDec5Decimation) + { + case 4: + break; /* keep bit as 0 in bitfield */ + case 5: + rxChannelSettings |= 0x04; + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_RXDEC5_DECIMATION, + getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_RXDEC5_DECIMATION)); + return MYKONOS_ERR_INIT_INV_RXDEC5_DECIMATION; + } + + switch (device->obsRx->orxProfile->adcDiv) + { + case 1: + adcDacClockRateSelect |= 0; + break; + case 2: + adcDacClockRateSelect |= 1; + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_ADCDIV, getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_ADCDIV)); + return MYKONOS_ERR_INIT_INV_ADCDIV; + } + } + else if (device->profilesValid & SNIFF_PROFILE_VALID) + { + /* if Rx profile not valid, and ORX profile not valid, set RX ADC divider and dec5 to match sniffer profile setting */ + /* ARM clock is derived from Rx clocking, so Rx ADC div needs to be set */ + switch (device->obsRx->snifferProfile->rxDec5Decimation) + { + case 4: + break; /* keep bit as 0 in bitfield */ + case 5: + rxChannelSettings |= 0x04; + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_RXDEC5_DECIMATION, + getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_RXDEC5_DECIMATION)); + return MYKONOS_ERR_INIT_INV_RXDEC5_DECIMATION; + } + + switch (device->obsRx->snifferProfile->adcDiv) + { + case 1: + adcDacClockRateSelect |= 0; + break; + case 2: + adcDacClockRateSelect |= 1; + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_ADCDIV, getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_ADCDIV)); + return MYKONOS_ERR_INIT_INV_ADCDIV; + } + } + + /* determine ObsRx ADC Div setting */ + if (device->profilesValid & ORX_PROFILE_VALID) + { + switch (device->obsRx->orxProfile->adcDiv) + { + case 1: + break; /* Keep bit[4]=0 */ + case 2: + adcDacClockRateSelect |= 0x10; + break; /* Set bit[4]=1 */ + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_OBSRX_ADCDIV, + getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_OBSRX_ADCDIV)); + return MYKONOS_ERR_INIT_INV_OBSRX_ADCDIV; + } + } + else if (device->profilesValid & SNIFF_PROFILE_VALID) + { + switch (device->obsRx->snifferProfile->adcDiv) + { + case 1: + break; /* Keep bit[4]=0 */ + case 2: + adcDacClockRateSelect |= 0x10; + break; /* Set bit[4]=1 */ + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_OBSRX_ADCDIV, + getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_OBSRX_ADCDIV)); + return MYKONOS_ERR_INIT_INV_OBSRX_ADCDIV; + } + } + else if (device->profilesValid & RX_PROFILE_VALID) + { /* if OBSRX profiles are not valid, set obsRx ADC div to match Rx ADC divider */ + switch (device->rx->rxProfile->adcDiv) + { + case 1: + break; /* Keep bit[4]=0 */ + case 2: + adcDacClockRateSelect |= 0x10; + break; /* Set bit[4]=1 */ + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_OBSRX_ADCDIV, + getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_OBSRX_ADCDIV)); + return MYKONOS_ERR_INIT_INV_OBSRX_ADCDIV; + } + } + + /* Determine ORx and Sniffer channel settings */ + if (device->obsRx != NULL) + { + /* verify pointers in data structure are valid (non-zero) */ + if (device->profilesValid & (ORX_PROFILE_VALID | SNIFF_PROFILE_VALID)) + { + if (device->obsRx->realIfData > 0) + { + obsRxRealIf = 1; + } + } + + /* TODO: verify that the decimation matches the given IQ rate in the data structure */ + + /* Set Sniffer profile (digital filter enables) if sniffer profile enabled (valid pointer) */ + if (device->profilesValid & SNIFF_PROFILE_VALID) + { + sniffChannelSettings = 0; + switch (device->obsRx->snifferProfile->rhb1Decimation) + { + case 1: + break; + case 2: + sniffChannelSettings |= 0x10; + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_SNIFFER_RHB1, + getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_SNIFFER_RHB1)); + return MYKONOS_ERR_INIT_INV_SNIFFER_RHB1; + } + + if (device->obsRx->snifferProfile->rxFir != NULL) + { + + switch (device->obsRx->snifferProfile->rxFirDecimation) + { + case 1: + sniffChannelSettings |= 0x01; + break; + case 2: + sniffChannelSettings |= 0x02; + break; + case 4: + sniffChannelSettings |= 0x03; + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_SNIFFER_RFIR_DEC, + getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_SNIFFER_RFIR_DEC)); + return MYKONOS_ERR_INIT_INV_SNIFFER_RFIR_DEC; + } + } + } + + /* Set ORx profile (digital filter enables) if ORx profile enabled (valid pointer) */ + if (device->profilesValid & ORX_PROFILE_VALID) + { + orxChannelSettings = 0; + switch (device->obsRx->orxProfile->rhb1Decimation) + { + case 1: + break; + case 2: + orxChannelSettings |= 0x10; + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_ORX_RHB1, + getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_ORX_RHB1)); + return MYKONOS_ERR_INIT_INV_ORX_RHB1; + } + + if (device->obsRx->orxProfile->rxFir != NULL) + {/* if pointer to orx rxFIR is valid */ + + switch (device->obsRx->orxProfile->rxFirDecimation) + { + case 1: + orxChannelSettings |= 0x01; + break; + case 2: + orxChannelSettings |= 0x02; + break; + case 4: + orxChannelSettings |= 0x03; + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_ORX_RFIR_DEC, + getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_ORX_RFIR_DEC)); + return MYKONOS_ERR_INIT_INV_ORX_RFIR_DEC; + } + } + } + } + + /************************************************************************ + * Set channel config settings for Rx/Tx/oRx and Sniffer channels + *********************************************************************** + */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CONFIGURATION_CONTROL_2, txChannelSettings); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CONFIGURATION_CONTROL_4, rxChannelSettings); + + /* Set option to use new high rejection DEC5 filters in main Rx1/Rx2 path. */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CONFIGURATION_CONTROL_5, ((uint8_t)(rxRealIfData << 2) | (enRxHighRejDec5 ? 3 : 0))); + + if (rxRealIfData > 0) + { + /* Set Rx1 NCO frequency */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RX_NCO_CH1_FTW_BYTE_3, 0x40); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RX_NCO_CH1_FTW_BYTE_2, 0x00); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RX_NCO_CH1_FTW_BYTE_1, 0x01); + + /* Set Rx2 NCO frequency */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RX_NCO_CH2_FTW_BYTE_3, 0x40); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RX_NCO_CH2_FTW_BYTE_2, 0x00); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RX_NCO_CH2_FTW_BYTE_1, 0x01); + + /* Enable NCO for Rx1 and Rx2 to shift data from zero IF to real IF */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_RX_NCO_CONTROL, 3, 0x03, 0); + } + + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_DPD_SNIFFER_CONFIGURATION_CONTROL_2, obsRxRealIf, 0x40, 6); + + /* if sniffer profile disabled, Sniffer config reg is set to default = 0x80 */ + sniffChannelSettings |= 0x80; /* use PFIR coef set B = bit[7]=1*/ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_SNIFFER_CONFIGURATION_CONTROL, sniffChannelSettings); + + /* if orx profile not valid, SPI reg for orx config is set to default = 0x00 */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DPD_CONFIGURATION_CONTROL, orxChannelSettings); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_LOOPBACK_CONFIGURATION_CONTROL, orxChannelSettings); + + /* Set ADC divider, DAC divider, and ObsRx/sniffer dividers */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_CLOCK_CONTROL_1, adcDacClockRateSelect, 0x13, 0); + + /* Disable ORx digital DC offset - bad default SPI setting for ObsRx DC offset */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DIGITAL_DC_OFFSET_CH3_DPD_M_SHIFT, 0x60); + + /* Necessary write for ARM init cals to work */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_SNIFF_RXLOGEN_BYTE1, 0x0E); + + /* Increase Sniffer LNA gain */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_SNRX_LNA_BIAS_C, 0x0F); + + /* Set the CLKPLL with the frequency from the device data structure */ + retVal = MYKONOS_initDigitalClocks(device); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* Wait for CLKPLL CP Cal done and CLKPLL Lock or throw error message */ + CMB_wait_ms(500); + retVal = MYKONOS_waitForEvent(device, CLKPLLCP, 1000000); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + retVal = MYKONOS_waitForEvent(device, CLKPLL_LOCK, 1000000); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* Enable digital clocks - this is gated by the CLKPLL being locked */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLOCK_CONTROL_0, 0x14); + + /* Set the Tx PFIR synchronization clock */ + retVal = MYKONOS_setTxPfirSyncClk(device); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* Set the Rx PFIR synchronization clock */ + retVal = MYKONOS_setRxPfirSyncClk(device); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + if (device->profilesValid & TX_PROFILE_VALID) + { + /* Set pre TxPFIR Half band filter interpolation */ + if (device->tx->txProfile->txInputHbInterpolation == 1) + { + /* disable TX input half band ([3:2]=00) - but allow DPD to still be enabled for tx profiles with wide BW [1] */ + enableDpd = (device->tx->txProfile->enableDpdDataPath > 0) ? 1 : 0; + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_TX_FILTER_CONFIGURATION, enableDpd, 0x0E, 1); + } + else if (device->tx->txProfile->txInputHbInterpolation == 2) + { + if (device->tx->txProfile->iqRate_kHz > 160000) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_TXINPUTHB0_INV_RATE, + getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_TXINPUTHB0_INV_RATE)); + return MYKONOS_ERR_INIT_INV_TXINPUTHB0_INV_RATE; + } + + /* enable TX input half band[2]=1, and Enable DPD[1]=1*/ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_TX_FILTER_CONFIGURATION, 3, 0x0E, 1); + } + else if (device->tx->txProfile->txInputHbInterpolation == 4) + { + if (device->tx->txProfile->iqRate_kHz > 80000) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_TXINPUTHB_INV_RATE, + getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_TXINPUTHB_INV_RATE)); + return MYKONOS_ERR_INIT_INV_TXINPUTHB_INV_RATE; + } + + /* enable TX input HB0[3]=1 and Tx input HB[2]=1, and Enable DPD[1]=1*/ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_TX_FILTER_CONFIGURATION, 7, 0x0E, 1); + } + else + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_TXINPUTHB_PARM, + getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_TXINPUTHB_PARM)); + return MYKONOS_ERR_INIT_INV_TXINPUTHB_PARM; + } + + /* Enable SPI Tx Atten mode */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_TX_TPC_CONFIG, 0x01, 0x03, 0); + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_TX_TPC_CONFIG, 0x01, 0x0C, 2); + + /* Set Tx1 Atten step size */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_TX_INCR_DECR_WORD, device->tx->txAttenStepSize, 0x60, 5); + + /* Set Tx2 Atten step size */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_TX_TPC_CONFIG, device->tx->txAttenStepSize, 0x60, 5); + } + else + { + /* Power down DACs */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_TX_PD_OVERIDE_7_0, 3, 0x0C, 2); + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_TX_PD_OVERRIDE_CONTROL_7_0, 3, 0x0C, 2); + } + + /* Set RxFE LO Common mode */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RXFE1_LOCM, 0xF0); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RXFE2_LOCM, 0xF0); + + /* Set Rxloopback LO Common mode */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RXLOOPBACK1_CNTRL_1, 0xFF); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RXLOOPBACK2_CNTRL_1, 0xFF); + + /* Setup MGC or AGC Rx gain control */ + if ((retVal = MYKONOS_setupRxAgc(device)) != MYKONOS_ERR_OK) + { + return retVal; + } + + /* Default Rx to use manual gain control until AGC enabled by user */ + if ((retVal = MYKONOS_setRxGainControlMode(device, MGC)) != MYKONOS_ERR_OK) + { + return retVal; + } + + + if ((retVal = MYKONOS_setupObsRxAgc(device)) != MYKONOS_ERR_OK) + { + return retVal; + } + + /* Default ObsRx to use manual gain control until AGC enabled by user */ + if ((retVal = MYKONOS_setObsRxGainControlMode(device, MGC)) != MYKONOS_ERR_OK) + { + return retVal; + } + + /* Disable GPIO select bits by setting to b11 */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_CONFIGURATION_CONTROL_1, 3, 0x30, 4); + + /* Extra settings for ARM calibrations */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DIGITAL_DC_OFFSET_SHIFT, 0x11); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RX_LOOPBACK1_CNTRL_4, 0x04); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RX_LOOPBACK2_CNTRL_4, 0x04); + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_ORX_SNRX_CFG_2, 0x20, 0x20, 0); + + /* Extra settings for ADC initialisation */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RX_ADC_FLASH_DELAY, 0x28); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RX_ADC_FLASH_CTRL, 0x0E); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ORX_ADC_FLASH_DELAY, 0x28); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ORX_ADC_FLASH_CTRL, 0x0E); + + /* Move to Alert ENSM state */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ENSM_CONFIG_7_0, 0x05); + + return MYKONOS_ERR_OK; +} + +/** + * \brief Verifies the init structure profiles are valid combinations + * + * This function checks that the Rx/Tx/ORx/Sniffer profiles have valid clock rates in + * order to operate together. Rx/Tx and ORx/Sniffer share a common high speed digital + * clock. If an invalid combination of profiles is detected, an error will be + * returned. If a profile in the init structure is unused, the user should zero + * out all members of that particular profile structure. If a Rx/Tx/ORx/Sniffer profile + * has an IQ rate = 0, it is assumed that the profile is disabled. + * + * \pre This function is private and is not called directly by the user. + * + * This function uses mykVerifyTxProfile() and mykVerifyRxProfile() as helper functions. + * + * Dependencies + * - device->spiSettings + * - device->spiSettings->chipSelectIndex + * + * \param device Structure pointer to Mykonos device data structure + * + * \retval MYKONOS_ERR_PROFILES_HSDIGCLK profiles loaded are not valid + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_verifyProfiles(mykonosDevice_t *device) +{ + mykonosErr_t retVal = MYKONOS_ERR_OK; + + uint32_t rxHsDigClk_kHz = 0; + uint32_t orxHsDigClk_kHz = 0; + uint32_t snifferHsDigClk_kHz = 0; + uint32_t txHsDigClk_kHz = 0; + + mykonosRxProfile_t *rxProfile = NULL; + mykonosTxProfile_t *txProfile = NULL; + mykonosRxProfile_t *orxProfile = NULL; + mykonosRxProfile_t *snifferProfile = NULL; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_verifyProfiles()\n"); +#endif + + device->profilesValid = 0; + + /* Check all loaded profiles */ + if (device->tx->txChannels != TXOFF) + { + txProfile = device->tx->txProfile; + retVal = mykVerifyTxProfile(device, txProfile, &txHsDigClk_kHz); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + } + + if (device->rx->rxChannels != RXOFF) + { + rxProfile = device->rx->rxProfile; + retVal = mykVerifyRxProfile(device, MYK_RX_PROFILE, rxProfile, &rxHsDigClk_kHz); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + } + + if (device->obsRx->obsRxChannelsEnable != MYK_OBS_RXOFF) + { + if ((uint32_t)device->obsRx->obsRxChannelsEnable & (uint32_t)MYK_ORX1_ORX2) + { + orxProfile = device->obsRx->orxProfile; + retVal = mykVerifyRxProfile(device, MYK_OBS_PROFILE, orxProfile, &orxHsDigClk_kHz); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + } + + if ((uint32_t)device->obsRx->obsRxChannelsEnable & (uint32_t)MYK_SNRXA_B_C) + { + snifferProfile = device->obsRx->snifferProfile; + retVal = mykVerifyRxProfile(device, MYK_SNIFFER_PROFILE, snifferProfile, &snifferHsDigClk_kHz); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + } + } + + return retVal; +} + +/** + * \brief Write indirect registers (Programmable FIRs, Rx gain tables, JESD204B settings). Must be done after Multi Chip Sync + * + * The BBP should never need to call this function. It is called automatically by the initArm function. + * This function is a continuation of the MYKONOS_initialize() function. This part of initialization must be done after + * the BBP has completed Multi chip Sync. These registers include FIR filters, Rx gain tables, and JESD204B framer/deframer + * config registers. + * + * Dependencies + * - device->spiSettings + * - device->spiSettings->chipSelectIndex + * + * \param device Pointer to the Mykonos device data structure containing settings + * an error. + * \return Returns enum mykonosErr_t, MYKONOS_ERR_OK=pass, !MYKONOS_ERR_OK=fail + */ +mykonosErr_t MYKONOS_initSubRegisterTables(mykonosDevice_t *device) +{ + mykonosErr_t retVal = MYKONOS_ERR_OK; + + /* ------------------------------------------------------------------------------------------- */ + /* Program submap register tables after digital clocks are up and running and Multi Chip Sync */ + /* has been completed by BBP */ + if (device->profilesValid & TX_PROFILE_VALID) + { + if (device->tx->txProfile->txFir != NULL) + { + retVal = MYKONOS_programFir(device, TX1TX2_FIR, device->tx->txProfile->txFir); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + } + } + + if (device->profilesValid & RX_PROFILE_VALID) + { + if (device->rx->rxProfile->rxFir != NULL) + { + retVal = MYKONOS_programFir(device, RX1RX2_FIR, device->rx->rxProfile->rxFir); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* Load Rx gain table */ + retVal = MYKONOS_programRxGainTable(device, &RxGainTable[0][0], (sizeof(RxGainTable) >> 2), RX1_RX2_GT); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + retVal = MYKONOS_setRx1ManualGain(device, device->rx->rxGainCtrl->rx1GainIndex); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + retVal = MYKONOS_setRx2ManualGain(device, device->rx->rxGainCtrl->rx2GainIndex); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* Enable Digital gain for Rx and ObsRx gain tables */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DIGITAL_GAIN_CONFIG, 0x80); + } + } + + if (device->profilesValid & SNIFF_PROFILE_VALID) + { + if (device->obsRx->snifferProfile->rxFir != NULL) + { + retVal = MYKONOS_programFir(device, OBSRX_B_FIR, device->obsRx->snifferProfile->rxFir); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* Load Sniffer Rx gain table */ + retVal = MYKONOS_programRxGainTable(device, &SnRxGainTable[0][0], (sizeof(SnRxGainTable) >> 2), SNRX_GT); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + retVal = MYKONOS_setObsRxManualGain(device, OBS_SNIFFER_A, device->obsRx->snifferGainCtrl->gainIndex); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + } + } + + if (device->profilesValid & ORX_PROFILE_VALID) + { + if (device->obsRx->orxProfile->rxFir != NULL) + {/* if pointer to orx rxFIR is valid */ + retVal = MYKONOS_programFir(device, OBSRX_A_FIR, device->obsRx->orxProfile->rxFir); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* Load ORx gain table */ + retVal = MYKONOS_programRxGainTable(device, &ORxGainTable[0][0], (sizeof(ORxGainTable) >> 2), ORX_GT); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + retVal = MYKONOS_setObsRxManualGain(device, OBS_RX1_TXLO, device->obsRx->orxGainCtrl->orx1GainIndex); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + retVal = MYKONOS_setObsRxManualGain(device, OBS_RX2_TXLO, device->obsRx->orxGainCtrl->orx2GainIndex); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + } + } + + /* Load Loopback Gain Table for ARM calibrations */ + { + uint8_t loopBackGainTable[6][4] = { + /* Order: {FE table, External Ctl, Digital Gain/Atten, Enable Atten} */ + {0, 0, 0, 0}, /* Gain index 255 */ + {7, 0, 0, 0}, /* Gain index 254 */ + {13, 0, 1, 1}, /* Gain index 253 */ + {18, 0, 3, 1}, /* Gain index 252 */ + {23, 0, 3, 1}, /* Gain index 251 */ + {28, 0, 0, 0} /* Gain index 250 */ + }; + retVal = MYKONOS_programRxGainTable(device, &loopBackGainTable[0][0], (sizeof(loopBackGainTable) >> 2), LOOPBACK_GT); + } + + /* Enable Digital gain for ORx/Sniffer/Loopback gain table */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DPD_SNIFFER_DIGITAL_GAIN_CONFIG, 0x80); + + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RCAL_CONTROL, 0x07);/* Set RCAL code to nominal */ + + /* If Valid Rx Profile or valid ObsRx profile, setup serializers */ + if ((device->profilesValid & RX_PROFILE_VALID) || (device->profilesValid & (ORX_PROFILE_VALID | SNIFF_PROFILE_VALID))) + { + retVal = MYKONOS_setupSerializers(device); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + } + + if ((device->rx->rxChannels != RXOFF) && (device->profilesValid & RX_PROFILE_VALID)) + { + retVal = MYKONOS_setupJesd204bFramer(device); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + } + + if ((device->obsRx->obsRxChannelsEnable != MYK_OBS_RXOFF) && (device->profilesValid & (ORX_PROFILE_VALID | SNIFF_PROFILE_VALID))) + { + retVal = MYKONOS_setupJesd204bObsRxFramer(device); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + } + + if ((device->tx->txChannels != TXOFF) && (device->profilesValid & TX_PROFILE_VALID)) + { + retVal = MYKONOS_setupDeserializers(device); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + retVal = MYKONOS_setupJesd204bDeframer(device); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + retVal = MYKONOS_setTx1Attenuation(device, device->tx->tx1Atten_mdB); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + retVal = MYKONOS_setTx2Attenuation(device, device->tx->tx2Atten_mdB); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief Performs a blocking wait for a Mykonos calibration or Pll Lock + * + * Dependencies + * - device->spiSettings + * - device->spiSettings->chipSelectIndex + * + * \param device Pointer to the Mykonos device data structure containing settings + * \param waitEvent the enum value of the event to wait for + * \param timeout_us If timeout_us time has passed, function will return with + * an error. + * \return Returns enum mykonosErr_t, MYKONOS_ERR_OK=pass, !MYKONOS_ERR_OK=fail + */ +mykonosErr_t MYKONOS_waitForEvent(mykonosDevice_t *device, waitEvent_t waitEvent, uint32_t timeout_us) +{ + uint16_t spiAddr = 0; + uint8_t spiBit = 0; + uint8_t doneBitLevel = 0; + uint8_t data = 0; + mykonosErr_t errCode = MYKONOS_ERR_OK; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_waitForEvent()\n"); +#endif + + switch (waitEvent) + { + case CALPLL_LOCK:/* wait for x17F[7]=1 */ + spiAddr = MYKONOS_ADDR_CALPLL_SDM_CONTROL; + spiBit = 7; + doneBitLevel = 1; + errCode = MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_CALPLL_LOCK; + break; + case CLKPLLCP: /* wait for x154[5]=1 */ + spiAddr = MYKONOS_ADDR_CLK_SYNTH_CAL_STAT; + spiBit = 5; + doneBitLevel = 1; + errCode = MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_CLKPLLCP; + break; + case CLKPLL_LOCK: /* wait for x157[0]=1 */ + spiAddr = MYKONOS_ADDR_CLK_SYNTH_VCO_BAND_BYTE1; + spiBit = 0; + doneBitLevel = 1; + errCode = MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_CLKPLL_LOCK; + break; + case RF_RXPLLCP:/* wait for x254[5]=1 */ + spiAddr = MYKONOS_ADDR_RXSYNTH_CP_CAL_STAT; + spiBit = 5; + doneBitLevel = 1; + errCode = MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_RXPLLCP; + break; + case RF_RXPLL_LOCK: /* wait for x257[0]=1 */ + spiAddr = MYKONOS_ADDR_RXSYNTH_VCO_BAND_BYTE1; + spiBit = 0; + doneBitLevel = 1; + errCode = MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_RXPLL_LOCK; + break; + case RF_TXPLLCP: /* wait for x2C4[5]=1 */ + spiAddr = MYKONOS_ADDR_TXSYNTH_CP_CAL_STAT; + spiBit = 5; + doneBitLevel = 1; + errCode = MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_TXPLLCP; + break; + case RF_TXPLL_LOCK: /* wait for x2C7[0]=1 */ + spiAddr = MYKONOS_ADDR_TXSYNTH_VCO_BAND_BYTE1; + spiBit = 0; + doneBitLevel = 1; + errCode = MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_TXPLL_LOCK; + break; + case RF_SNIFFERPLLCP: /* wait for x354[7]=1 */ + spiAddr = MYKONOS_ADDR_SNIFF_RXSYNTH_CP_CAL_STAT; + spiBit = 5; + doneBitLevel = 1; + errCode = MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_SNIFFPLLCP; + break; + case RF_SNIFFERPLL_LOCK: /* wait for x357[0]=1 */ + spiAddr = MYKONOS_ADDR_SNIFF_RXSYNTH_VCO_BAND_BYTE1; + spiBit = 0; + doneBitLevel = 1; + errCode = MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_SNIFFPLL_LOCK; + break; + case RXBBF_CALDONE: /* wait for x1B2[5]=0 */ + spiAddr = MYKONOS_ADDR_CALIBRATION_CONTROL; + spiBit = 5; + doneBitLevel = 0; + errCode = MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_RXBBFCALDONE; + break; + case TXBBF_CALDONE:/* wait for x1B2[0]=0 */ + spiAddr = MYKONOS_ADDR_CALIBRATION_CONTROL; + spiBit = 0; + doneBitLevel = 0; + errCode = MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_TXBBFCALDONE; + break; + case RX_RFDC_CALDONE: /* wait for x1B2[1]=0 */ + spiAddr = MYKONOS_ADDR_CALIBRATION_CONTROL; + spiBit = 1; + doneBitLevel = 0; + errCode = MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_RFDCCALDONE; + break; + case RX_ADCTUNER_CALDONE:/* wait for x1B2[7]=0 */ + spiAddr = MYKONOS_ADDR_CALIBRATION_CONTROL; + spiBit = 7; + doneBitLevel = 0; + errCode = MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_ADCTUNECALDONE; + break; + case RX1_ADCPROFILE:/* wait for x5DD[5]=0 */ + spiAddr = MYKONOS_ADDR_RX_ADC1_PRFL; + spiBit = 5; + doneBitLevel = 0; + errCode = MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_RX1ADCPROFILE; + break; + case RX2_ADCPROFILE:/* wait for x5DE[5]=0 */ + spiAddr = MYKONOS_ADDR_RX_ADC2_PRFL; + spiBit = 5; + doneBitLevel = 0; + errCode = MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_RX2ADCPROFILE; + break; + case ORX_ADCPROFILE:/* wait for x5DF[5]=0 */ + spiAddr = MYKONOS_ADDR_ORX_ADC_PRFL; + spiBit = 5; + doneBitLevel = 0; + errCode = MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_ORXADCPROFILE; + break; + case RCAL_CALDONE: /* wait for x1B2[6]=0 */ + spiAddr = MYKONOS_ADDR_CALIBRATION_CONTROL; + spiBit = 6; + doneBitLevel = 0; + errCode = MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_RCALDONE; + break; + case ARMBUSY:/* wait for xD30[7]=0 */ + spiAddr = MYKONOS_ADDR_ARM_CMD; + spiBit = 7; + doneBitLevel = 0; + errCode = MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_ARMBUSY; + break; + case INITARM_DONE: + spiAddr = MYKONOS_ADDR_ARM_CMD; + spiBit = 7; + doneBitLevel = 0; + errCode = MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_INITARMDONE; + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_WAITFOREVENT_INV_PARM, + getMykonosErrorMessage(MYKONOS_ERR_WAITFOREVENT_INV_PARM)); + return MYKONOS_ERR_WAITFOREVENT_INV_PARM; + } + + CMB_setTimeout_us(timeout_us); /* timeout after desired time */ + + do + { + CMB_SPIReadByte(device->spiSettings, spiAddr, &data); + + /* For SW verification tests, allow API to think all cals are complete*/ +#ifdef MYK_CALS_DONE_SWDEBUG + if (doneBitLevel == 0) + { + data = 0x00; + } + else + { + data = 0xFF; + } +#endif + + if ((uint32_t)CMB_hasTimeoutExpired() > 0) + { + CMB_writeToLog(ADIHAL_LOG_WARNING, device->spiSettings->chipSelectIndex, errCode, getMykonosErrorMessage(errCode)); + return errCode; + } + } while (((data >> spiBit) & 0x01) != doneBitLevel); + + return MYKONOS_ERR_OK; +} + +/** + * \brief Performs a readback with no wait for a Mykonos calibration or Pll Lock + * + * Dependencies + * - device->spiSettings + * - device->spiSettings->chipSelectIndex + * + * \param device Pointer to the Mykonos device data structure containing settings + * \param waitEvent the enum value of the event to wait for + * \param eventDone Return value: 1= calibration event is complete. 0 = Event is still pending + * \return Returns enum mykonosErr_t, MYKONOS_ERR_OK=pass, !MYKONOS_ERR_OK=fail + */ +mykonosErr_t MYKONOS_readEventStatus(mykonosDevice_t *device, waitEvent_t waitEvent, uint8_t *eventDone) +{ + uint16_t spiAddr = 0; + uint8_t data = 0; + uint8_t spiBit = 0; + uint8_t doneBitLevel = 0; + + switch (waitEvent) + { + case CALPLL_LOCK:/* wait for x17F[7]=1 */ + spiAddr = MYKONOS_ADDR_CALPLL_SDM_CONTROL; + spiBit = 7; + doneBitLevel = 1; + break; + case CLKPLLCP: /* wait for x154[5]=1 */ + spiAddr = MYKONOS_ADDR_CLK_SYNTH_CAL_STAT; + spiBit = 5; + doneBitLevel = 1; + break; + case CLKPLL_LOCK: /* wait for x157[0]=1 */ + spiAddr = MYKONOS_ADDR_CLK_SYNTH_VCO_BAND_BYTE1; + spiBit = 0; + doneBitLevel = 1; + break; + case RF_RXPLLCP:/* wait for x254[5]=1 */ + spiAddr = MYKONOS_ADDR_RXSYNTH_CP_CAL_STAT; + spiBit = 5; + doneBitLevel = 1; + break; + case RF_RXPLL_LOCK: /* wait for x257[0]=1 */ + spiAddr = MYKONOS_ADDR_RXSYNTH_VCO_BAND_BYTE1; + spiBit = 0; + doneBitLevel = 1; + break; + case RF_TXPLLCP: /* wait for x2C4[5]=1 */ + spiAddr = MYKONOS_ADDR_TXSYNTH_CP_CAL_STAT; + spiBit = 5; + doneBitLevel = 1; + break; + case RF_TXPLL_LOCK: /* wait for x2C7[0]=1 */ + spiAddr = MYKONOS_ADDR_TXSYNTH_VCO_BAND_BYTE1; + spiBit = 0; + doneBitLevel = 1; + break; + case RF_SNIFFERPLLCP: /* wait for x354[7]=1 */ + spiAddr = MYKONOS_ADDR_SNIFF_RXSYNTH_CP_CAL_STAT; + spiBit = 5; + doneBitLevel = 1; + break; + case RF_SNIFFERPLL_LOCK: /* wait for x357[0]=1 */ + spiAddr = MYKONOS_ADDR_SNIFF_RXSYNTH_VCO_BAND_BYTE1; + spiBit = 0; + doneBitLevel = 1; + break; + case RXBBF_CALDONE: /* wait for x1B2[5]=0 */ + spiAddr = MYKONOS_ADDR_CALIBRATION_CONTROL; + spiBit = 5; + doneBitLevel = 0; + break; + case TXBBF_CALDONE:/* wait for x1B2[0]=0 */ + spiAddr = MYKONOS_ADDR_CALIBRATION_CONTROL; + spiBit = 0; + doneBitLevel = 0; + break; + case RX_RFDC_CALDONE: /* wait for x1B2[1]=0 */ + spiAddr = MYKONOS_ADDR_CALIBRATION_CONTROL; + spiBit = 1; + doneBitLevel = 0; + break; + case RX_ADCTUNER_CALDONE:/* wait for x1B2[7]=0 */ + spiAddr = MYKONOS_ADDR_CALIBRATION_CONTROL; + spiBit = 7; + doneBitLevel = 0; + break; + case RX1_ADCPROFILE:/* wait for x5DD[5]=0 */ + spiAddr = MYKONOS_ADDR_RX_ADC1_PRFL; + spiBit = 5; + doneBitLevel = 0; + break; + case RX2_ADCPROFILE:/* wait for x5DE[5]=0 */ + spiAddr = MYKONOS_ADDR_RX_ADC2_PRFL; + spiBit = 5; + doneBitLevel = 0; + break; + case ORX_ADCPROFILE:/* wait for x5DF[5]=0 */ + spiAddr = MYKONOS_ADDR_ORX_ADC_PRFL; + spiBit = 5; + doneBitLevel = 0; + break; + case RCAL_CALDONE: /* wait for x1B2[6]=0 */ + spiAddr = MYKONOS_ADDR_CALIBRATION_CONTROL; + spiBit = 6; + doneBitLevel = 0; + break; + case ARMBUSY:/* wait for xD30[7]=0 */ + spiAddr = MYKONOS_ADDR_ARM_CMD; + spiBit = 7; + doneBitLevel = 0; + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_WAITFOREVENT_INV_PARM, + getMykonosErrorMessage(MYKONOS_ERR_WAITFOREVENT_INV_PARM)); + return MYKONOS_ERR_WAITFOREVENT_INV_PARM; + } + + CMB_SPIReadByte(device->spiSettings, spiAddr, &data); + + if (doneBitLevel) + { + *eventDone = (data >> spiBit) & 0x01; + } + else + { + *eventDone = (~(data >> spiBit) & 0x01); + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief Sets the CLKPLL output frequency. + * + * This code updates the Synth and Loop filter settings based on a VCO + * frequency LUT. The VCO frequency break points for the Synth LUT can be + * found in an array called vcoFreqArrayMhz. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - device->spiSettings + * - device->deviceClock_kHz + * - device->rxSettings->rxProfile->vcoFreq_kHz + * - device->rxSettings->rxProfile->clkPllHsDiv + * - device->rxSettings->rxProfile->clkPllVcoDiv + * + * \param device is structure pointer to the MYKONOS data structure containing settings + * + * \return Returns enum MYKONOS_ERR, MYKONOS_ERR_OK=pass, !MYKONOS_ERR_OK=fail + */ +mykonosErr_t MYKONOS_initDigitalClocks(mykonosDevice_t *device) +{ + /* RF Synth variables */ + /* pull Synth and Loop filter values from a Look Up Table */ + uint8_t vcoOutLvl; + uint8_t vcoVaractor; /* [3:0] */ + uint8_t vcoBiasRef; /* [2:0] */ + uint8_t vcoBiasTcf; /* [1:0] */ + uint8_t vcoCalOffset; /* [3:0] */ + uint8_t vcoVaractorRef; /* [3:0] */ + uint8_t loopFilterIcp; /* Icp[5:0] */ + uint8_t loopFilterC2C1; /* C2[3:0],C1[3:0] */ + uint8_t loopFilterR1C3; /* R1[3:0],C3[3:0] */ + uint8_t loopFilterR3; /* R3[3:0] */ + uint8_t vcoIndex; + uint8_t i; + + /* RF PLL variables */ + uint16_t integerWord; + uint32_t fractionalWord; + uint32_t fractionalRemainder; + uint32_t scaledRefClk_Hz; + + /* common */ + uint64_t hsDigClk_Hz = 0; + uint32_t scaledRefClk_kHz = 0; + uint8_t deviceClkDiv = 0; + mykonosErr_t retVal = MYKONOS_ERR_OK; + + uint8_t clockControl2 = 0; + uint8_t sdmSettings = 0; + uint8_t hsDiv = 4; + uint8_t vcoDiv = 0; + uint8_t vcoDivTimes10 = 10; + + /******************RF Synth Section************************/ + static const uint8_t icp_46p08[53] = {15, 15, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 27, 27, 28, 29, 30, 31, 32, 33, 32, 33, 32, 33, 33, 34, 27, 28, 29, + 29, 30, 39, 29, 30, 31, 31, 30, 31, 31, 32, 30, 31, 31, 32, 32, 31, 31, 32, 32, 33}; + + static const uint8_t icp_61p44[53] = {13, 13, 13, 14, 15, 16, 16, 17, 18, 19, 20, 21, 22, 22, 23, 24, 24, 25, 25, 26, 27, 28, 29, 28, 29, 28, 29, 29, 30, 24, 25, 25, + 26, 26, 35, 33, 34, 35, 35, 26, 27, 27, 28, 27, 27, 27, 28, 28, 27, 27, 28, 28, 29}; + + static const uint8_t icp_76p8[53] = {7, 7, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15, 16, 15, 16, 15, 16, 16, 17, 13, 14, 14, 14, 15, + 19, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 15, 15, 15, 16, 16}; + + static const uint32_t vcoFreqArray_kHz[53] = {12605000UL, 12245000UL, 11906000UL, 11588000UL, 11288000UL, 11007000UL, 10742000UL, 10492000UL, 10258000UL, 10036000UL, + 9827800UL, 9631100UL, 9445300UL, 9269800UL, 9103600UL, 8946300UL, 8797000UL, 8655300UL, 8520600UL, 8392300UL, 8269900UL, 8153100UL, 8041400UL, 7934400UL, + 7831800UL, 7733200UL, 7638400UL, 7547100UL, 7459000UL, 7374000UL, 7291900UL, 7212400UL, 7135500UL, 7061000UL, 6988700UL, 6918600UL, 6850600UL, 6784600UL, + 6720500UL, 6658200UL, 6597800UL, 6539200UL, 6482300UL, 6427000UL, 6373400UL, 6321400UL, 6270900UL, 6222000UL, 6174500UL, 6128400UL, 6083600UL, 6040100UL, + 5997700UL}; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_initDigitalClocks()\n"); +#endif + + retVal = MYKONOS_calculateScaledDeviceClk_kHz(device, &scaledRefClk_kHz, &deviceClkDiv); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + hsDiv = device->clocks->clkPllHsDiv; + vcoDiv = device->clocks->clkPllVcoDiv; + + switch (hsDiv) + { + case 4: + hsDiv = 4; /* clockControl2[3:2] = 00 */ + break; + case 5: + hsDiv = 5; + clockControl2 |= 0x04; /* Set bit[2]=1 */ + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CLKPLL_INV_HSDIV, getMykonosErrorMessage(MYKONOS_ERR_CLKPLL_INV_HSDIV)); + return MYKONOS_ERR_CLKPLL_INV_HSDIV; + } + + switch (vcoDiv) + { + case VCODIV_1: + vcoDivTimes10 = 10; /* clockControl2[1:0] = 00 */ + break; + case VCODIV_1p5: + vcoDivTimes10 = 15; + clockControl2 |= 0x01; + break; + case VCODIV_2: + vcoDivTimes10 = 20; + clockControl2 |= 0x02; + break; + case VCODIV_3: + vcoDivTimes10 = 30; + clockControl2 |= 0x03; + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CLKPLL_INV_VCODIV, getMykonosErrorMessage(MYKONOS_ERR_CLKPLL_INV_VCODIV)); + return MYKONOS_ERR_CLKPLL_INV_VCODIV; + } + + clockControl2 |= ((deviceClkDiv & 3) << 4); + + /* find vco table index based on vco frequency */ + for (i = 0; device->clocks->clkPllVcoFreq_kHz < vcoFreqArray_kHz[i]; i++) + { + /* Intentionally blank, for loop exits when condition met, index i used below */ + } + vcoIndex = i + 1; + + if (vcoIndex < 1 || vcoIndex > 53) + { + /* vco index out of range */ + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETCLKPLL_INV_VCOINDEX, + getMykonosErrorMessage(MYKONOS_ERR_SETCLKPLL_INV_VCOINDEX)); + return MYKONOS_ERR_SETCLKPLL_INV_VCOINDEX; + } + + /* valid for all refclk frequencies */ + vcoOutLvl = (vcoIndex <= 16) ? 13 : (vcoIndex <= 23) ? 12 : (vcoIndex <= 25) ? + 11 : (vcoIndex <= 35) ? 10 : (vcoIndex <= 39) ? 9 : (vcoIndex <= 43) ? + 8 : (vcoIndex <= 48) ? 7 : 6; + vcoVaractor = (vcoIndex <= 29 || vcoIndex == 35) ? 1 : 2; + vcoBiasRef = (vcoIndex <= 7 ) ? 4 : (vcoIndex <= 16) ? 6 : 7; + vcoBiasTcf = (vcoIndex <= 25 || (vcoIndex > 26 && vcoIndex <= 29) || + (vcoIndex > 37 && vcoIndex <= 39)) || (vcoIndex > 40 && vcoIndex <= 43) ? + 2 : 3; + + vcoVaractorRef = (vcoIndex <= 29) ? 12 : (vcoIndex == 35) ? 14 : 13; + + if ((scaledRefClk_kHz >= 40000) && (scaledRefClk_kHz < 53760)) + { /* Settings designed for 46.08 MHz PLL REFCLK */ + vcoCalOffset = (vcoIndex == 11 || (vcoIndex > 35 && vcoIndex <= 37) || (vcoIndex > 29 && vcoIndex <= 34)|| vcoIndex == 40 || vcoIndex == 44) ? + 14 :(vcoIndex <= 10 || vcoIndex > 44) ? + 15 : ((vcoIndex > 12 && vcoIndex <= 22) || (vcoIndex > 23 && vcoIndex <= 23) || (vcoIndex > 26 && vcoIndex <= 29) || (vcoIndex > 23 && vcoIndex <= 25) || vcoIndex == 35) ? + 12 : 13; + + loopFilterIcp = icp_46p08[vcoIndex - 1]; + loopFilterC2C1 = 0xF9; /* C2=0xF0 */ + loopFilterR1C3 = 0xD5; + loopFilterR3 = 0x0E; + } + else if ((scaledRefClk_kHz >= 53760) && (scaledRefClk_kHz < 69120)) + { /* Settings designed for 61.44 MHz PLL REFCLK */ + vcoCalOffset = (vcoIndex == 11 || (vcoIndex > 29 && vcoIndex <= 34) || vcoIndex == 40 || vcoIndex == 44) ? + 14 :(vcoIndex <= 10 || vcoIndex > 44) ? + 15 : ((vcoIndex > 12 && vcoIndex <= 22) || (vcoIndex > 23 && vcoIndex <= 25) || (vcoIndex > 26 && vcoIndex <= 29) || (vcoIndex > 34 && vcoIndex <= 37)) ? + 12 : (vcoIndex > 37 && vcoIndex <= 39) ? 11 : 13; + + vcoVaractor = (vcoIndex > 35 && vcoIndex <= 39) ? 1 : vcoVaractor; + vcoBiasRef = (vcoIndex > 4 && vcoIndex <= 7) ? 5 : vcoBiasRef; + vcoVaractorRef = (vcoIndex > 35 && vcoIndex <= 39) ? 14 : vcoVaractorRef; + loopFilterIcp = icp_61p44[vcoIndex-1]; + loopFilterC2C1 = ((vcoIndex > 2 && vcoIndex <= 6) || (vcoIndex > 8 && vcoIndex <= 13) || (vcoIndex > 14)) ? 0xFD : 0xFC; /* C2=0xF0 */ + loopFilterR1C3 = 0xC5; + loopFilterR3 = (vcoIndex <= 2 || (vcoIndex > 6 && vcoIndex <= 8) || vcoIndex == 14) ? 14 : 13 ; + } + else if ((scaledRefClk_kHz >= 69120) && (scaledRefClk_kHz <= 80000)) + { /* Settings designed for 76.8 MHz PLL REFCLK */ + vcoCalOffset = (vcoIndex == 11 || (vcoIndex > 35 && vcoIndex <= 37) || (vcoIndex > 29 && vcoIndex <= 34)|| vcoIndex == 40 || vcoIndex == 44) ? + 14 :(vcoIndex <= 10 || vcoIndex > 44) ? + 15 : ((vcoIndex > 12 && vcoIndex <= 22) || (vcoIndex > 23 && vcoIndex <= 23) || (vcoIndex > 26 && vcoIndex <= 29) || (vcoIndex > 23 && vcoIndex <= 25) || vcoIndex == 35) ? + 12 : 13; + + loopFilterIcp = icp_76p8[vcoIndex-1]; + loopFilterC2C1 = (vcoIndex == 20 ) ? 0xF7 : (vcoIndex == 4 || vcoIndex == 6 || vcoIndex == 8 ) ? 0xE6: 0xF6; /*C2=0xF0, C1=6 or 7 */ + loopFilterR1C3 = (vcoIndex == 4 ) ? 0xE4 : 0xD5; + loopFilterR3 = 0x0E; + } + else + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETRFPLL_INV_REFCLK, getMykonosErrorMessage(MYKONOS_ERR_SETRFPLL_INV_REFCLK)); + return MYKONOS_ERR_SETRFPLL_INV_REFCLK; /* invalid ref clk */ + } + + /* Hold CLKPLL digital logic in reset */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLOCK_CONTROL_4, 0x00); + + /* Set reference clock scaler + HSdiv + VCOdiv */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLOCK_CONTROL_2, clockControl2); + + /*Set VCO cal time */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_CAL_CONTROL, 0x02); + + /* Write Synth Setting regs */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_F_VCOTN_BYTE1, ((vcoCalOffset & 0x0F) << 3)); /* Set VCO Cal offset[3:0] */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_BYTE1, (0xC0 | (vcoVaractor & 0x0F))); /* Init ALC[3:0], VCO varactor[3:0] */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_BYTE2, (0x40 | (vcoOutLvl & 0x0F))); /* VCO output level */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_BYTE9, (((vcoBiasTcf & 0x03) << 3) | (vcoBiasRef & 0x07))); /* Set VCO Bias Tcf[1:0] and VCO Bias Ref[2:0] */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_VCO_CAL_REF, 0x30); /* Set VCO cal time (compare length) + Set VCO Cal Ref Tcf[2:0]=0 */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_VCO_VAR_CTL1, 0x70); /* Set VCO Varactor Ref Tcf[2:0] and VCO Varactor Offset[3:0] */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_VCO_VAR_CTL2, (vcoVaractorRef & 0x0F)); /* Set VCO Varactor Reference[3:0] */ + + /* Write Loop filter */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_BYTE3, (0x80 | (loopFilterIcp & 0x03F))); /* Set Loop Filter Icp[5:0] */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_BYTE6, loopFilterC2C1); /* Set Loop Filter C2[3:0] and C1[3:0] */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_BYTE7, loopFilterR1C3); /* Set Loop Filter R1[3:0] and C3[3:0] */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_LF_R3, (loopFilterR3 & 0x0F)); /*Set Loop Filter R3[3:0] */ + + /* Calculate PLL integer and fractional words with integer math */ + scaledRefClk_Hz = scaledRefClk_kHz * 1000; + hsDigClk_Hz = (((uint64_t)(device->clocks->clkPllVcoFreq_kHz) * 10000) / vcoDivTimes10) / hsDiv; + integerWord = (uint16_t)(hsDigClk_Hz / scaledRefClk_Hz); + fractionalRemainder = hsDigClk_Hz % scaledRefClk_Hz; + + /* +1 >> 1 is rounding (add .5) */ + fractionalWord = ((uint32_t)((((uint64_t)fractionalRemainder * 4177920) / (uint64_t)scaledRefClk_Hz) + 1) >> 1); + + /* if fractionalWord rounded up and == PLL modulus, fix it */ + if (fractionalWord == 2088960) + { + fractionalWord = 0; + integerWord = integerWord + 1; + } + + if (fractionalWord > 0) + { /* in normal case, the fractional word should be zero and SDM bypassed */ + CMB_writeToLog(ADIHAL_LOG_WARNING, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETCLKPLL_INV_FRACWORD, + getMykonosErrorMessage(MYKONOS_ERR_SETCLKPLL_INV_FRACWORD)); + /* down graded to warning, do not return error code */ + //return MYKONOS_ERR_SETCLKPLL_INV_FRACWORD; + sdmSettings = 0x20; + } + else + { + /* Bypass SDM */ + sdmSettings = 0xE0; + } + + /* Set PLL fractional word[22:0] */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_DIVIDER_FRAC_BYTE0, (fractionalWord & 0xFF)); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_DIVIDER_FRAC_BYTE1, ((fractionalWord >> 8) & 0xFF)); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_DIVIDER_FRAC_BYTE2, ((fractionalWord >> 16) & 0x7F)); + + /* Write PLL integer word [7:0] */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_DIVIDER_INT_BYTE1, (sdmSettings | ((integerWord >> 8) & 0x7))); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_DIVIDER_INT_BYTE0, (integerWord & 0xFF)); + + /* Release PLL from reset, and set start VCO cal bit to 0 */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLOCK_CONTROL_4, 0x80); + + /* Power up CLKPLL */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLOCK_CONTROL_0, 0x00); + CMB_wait_ms(200); /* Allow PLL time to power up */ + + /* Enable Charge pump cal after Charge Pump current set (Icp[5:0]) */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_BYTE5, 0x84); + + /* Start VCO Cal */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLOCK_CONTROL_4, 0x81); + + return MYKONOS_ERR_OK; +} + +/** + * \brief Sets the RF PLL local oscillator frequency (RF carrier frequency). + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - device->spiSettings + * + * \param device is structure pointer to the MYKONOS data structure containing settings + * \param pllName Name of the PLL to configure + * \param rfPllLoFrequency_Hz Desired RF LO frequency + * + * \return MYKONOS_ERR_OK Function completed successfully + * \return MYKONOS_ERR_SETRFPLL_ARMERROR ARM Command to set RF PLL frequency failed + */ +mykonosErr_t MYKONOS_setRfPllFrequency(mykonosDevice_t *device, mykonosRfPllName_t pllName, uint64_t rfPllLoFrequency_Hz) +{ + const uint8_t SETCMD_OPCODE = 0x0A; + const uint8_t SET_PLL_FREQUENCY = 0x63; + + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint8_t armData[8] = {0}; + uint8_t extData[2] = {0}; + uint32_t timeoutMs = 0; + uint8_t cmdStatusByte = 0; + + armData[0] = (uint8_t)(rfPllLoFrequency_Hz & 0xFF); + armData[1] = (uint8_t)((rfPllLoFrequency_Hz >> 8) & 0xFF); + armData[2] = (uint8_t)((rfPllLoFrequency_Hz >> 16) & 0xFF); + armData[3] = (uint8_t)((rfPllLoFrequency_Hz >> 24) & 0xFF); + armData[4] = (uint8_t)((rfPllLoFrequency_Hz >> 32) & 0xFF); + armData[5] = (uint8_t)((rfPllLoFrequency_Hz >> 40) & 0xFF); + armData[6] = (uint8_t)((rfPllLoFrequency_Hz >> 48) & 0xFF); + armData[7] = (uint8_t)((rfPllLoFrequency_Hz >> 56) & 0xFF); + + /* write 64-bit frequency to ARM memory */ + retVal = MYKONOS_writeArmMem(device, MYKONOS_ADDR_ARM_START_DATA_ADDR, &armData[0], 8); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + extData[0] = SET_PLL_FREQUENCY; + + switch (pllName) + { + case RX_PLL: + extData[1] = 0x00; + break; + case TX_PLL: + extData[1] = 0x01; + break; + case SNIFFER_PLL: + extData[1] = 0x02; + break; + default: + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETRFPLL_INV_PLLNAME, + getMykonosErrorMessage(MYKONOS_ERR_SETRFPLL_INV_PLLNAME)); + return MYKONOS_ERR_SETRFPLL_INV_PLLNAME; + } + } + + retVal = MYKONOS_sendArmCommand(device, SETCMD_OPCODE, &extData[0], sizeof(extData)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + timeoutMs = 1000; + retVal = MYKONOS_waitArmCmdStatus(device, SETCMD_OPCODE, timeoutMs, &cmdStatusByte); + if (retVal != MYKONOS_ERR_OK) + { + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETRFPLL_ARMERROR, getMykonosErrorMessage(MYKONOS_ERR_SETRFPLL_ARMERROR)); + return MYKONOS_ERR_SETRFPLL_ARMERROR; + } + + return retVal; + } + + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETRFPLL_ARMERROR, getMykonosErrorMessage(MYKONOS_ERR_SETRFPLL_ARMERROR)); + return MYKONOS_ERR_SETRFPLL_ARMERROR; + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief Gets the RF PLL local oscillator frequency (RF carrier frequency). + * + * This function is used to get the RF PLL's frequency. It can get the RX PLL, TX PLL + * Sniffer PLL, and CLKPLL. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - device->spiSettings + * - device->clocks->deviceClock_kHz + * + * \param device is structure pointer to the MYKONOS data structure containing settings + * \param pllName Name of the PLL for which to read the frequency + * \param rfPllLoFrequency_Hz RF LO frequency currently set for the PLL specified + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_GET_PLLFREQ_INV_REFCLKDIV Invalid CLKPLL reference clock divider read from Mykonos device + * \retval MYKONOS_ERR_GET_PLLFREQ_INV_HSDIV Invalid CLKPLL high speed clock divider read from Mykonos device + * \retval MYKONOS_ERR_GETRFPLL_INV_PLLNAME Invalid PLL name, can not get PLL frequency. Use PLL name ENUM. + * \retval MYKONOS_ERR_GETRFPLL_ARMERROR ARM Command to get RF PLL frequency failed + * \retval MYKONOS_ERR_GETRFPLL_NULLPARAM rfPllLoFrequency_Hz function parameter pointer is NULL + */ +mykonosErr_t MYKONOS_getRfPllFrequency(mykonosDevice_t *device, mykonosRfPllName_t pllName, uint64_t *rfPllLoFrequency_Hz) +{ + const uint8_t RFPLL_LO_FREQUENCY = 0x63; + + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint8_t armData[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + uint8_t extData[2] = {0, 0}; + uint32_t timeoutMs = 0; + uint8_t cmdStatusByte = 0; + uint8_t getClkPllFrequency = 0; + + uint32_t clkPllIntWord = 0; + uint32_t clkPllFracWord = 0; + uint8_t clkPllRefClkDiv = 0; + uint8_t hsDiv = 0; + uint8_t vcoDivTimes10 = 0; + uint8_t hsDivReg = 0; + uint8_t vcoDivReg = 0; + uint8_t clkPllIntWord7_0 = 0; + uint8_t clkPllIntWord10_8 = 0; + uint8_t clkPllFracWord7_0 = 0; + uint8_t clkPllFracWord15_8 = 0; + uint8_t clkPllFracWord22_16 = 0; + uint64_t refclk_Hz = 0; + + extData[0] = RFPLL_LO_FREQUENCY; + + switch (pllName) + { + case CLK_PLL: + getClkPllFrequency = 1; + break; + case RX_PLL: + extData[1] = 0x00; + break; + case TX_PLL: + extData[1] = 0x01; + break; + case SNIFFER_PLL: + extData[1] = 0x02; + break; + default: + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETRFPLL_INV_PLLNAME, + getMykonosErrorMessage(MYKONOS_ERR_GETRFPLL_INV_PLLNAME)); + return MYKONOS_ERR_GETRFPLL_INV_PLLNAME; + } + } + + if (getClkPllFrequency > 0) + { + CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_CLOCK_CONTROL_2, &hsDivReg, 0x0C, 2); + CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_CLOCK_CONTROL_2, &vcoDivReg, 0x03, 0); + CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_CLOCK_CONTROL_2, &clkPllRefClkDiv, 0x70, 4); + + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_DIVIDER_INT_BYTE0, &clkPllIntWord7_0); + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_DIVIDER_INT_BYTE1, &clkPllIntWord10_8); + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_DIVIDER_FRAC_BYTE0, &clkPllFracWord7_0); + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_DIVIDER_FRAC_BYTE1, &clkPllFracWord15_8); + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_DIVIDER_FRAC_BYTE2, &clkPllFracWord22_16); + + clkPllIntWord = (((uint32_t)(clkPllIntWord10_8 & 0x7) << 8) | clkPllIntWord7_0); + clkPllFracWord = (((uint32_t)(clkPllFracWord22_16 & 0x7F) << 16) | ((uint32_t)(clkPllFracWord15_8) << 8) | clkPllFracWord7_0); + + switch (clkPllRefClkDiv) + { + case 0: + refclk_Hz = ((uint64_t)device->clocks->deviceClock_kHz * 1000); + break; + case 1: + refclk_Hz = (((uint64_t)device->clocks->deviceClock_kHz * 1000) >> 1); + break; /* div 2 */ + case 2: + refclk_Hz = (((uint64_t)device->clocks->deviceClock_kHz * 1000) >> 2); + break; /* div 4 */ + case 3: + refclk_Hz = (((uint64_t)device->clocks->deviceClock_kHz * 1000) << 1); + break; /* times 2 */ + default: + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GET_PLLFREQ_INV_REFCLKDIV, + getMykonosErrorMessage(MYKONOS_ERR_GET_PLLFREQ_INV_REFCLKDIV)); + return MYKONOS_ERR_GET_PLLFREQ_INV_REFCLKDIV; + } + } + + switch (vcoDivReg) + { + case 0: + vcoDivTimes10 = 10; + break; + case 1: + vcoDivTimes10 = 15; + break; + case 2: + vcoDivTimes10 = 20; + break; + case 3: + vcoDivTimes10 = 30; + break; + default: + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GET_PLLFREQ_INV_VCODIV, + getMykonosErrorMessage(MYKONOS_ERR_GET_PLLFREQ_INV_VCODIV)); + return MYKONOS_ERR_GET_PLLFREQ_INV_VCODIV; + } + } + + switch (hsDivReg) + { + case 0: + hsDiv = 4; + break; + case 1: + hsDiv = 5; + break; + default: + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GET_PLLFREQ_INV_HSDIV, + getMykonosErrorMessage(MYKONOS_ERR_GET_PLLFREQ_INV_HSDIV)); + return MYKONOS_ERR_GET_PLLFREQ_INV_HSDIV; + } + } + + /* round to nearest Hz for fractional word (fractional modulus = 2088960) */ + *rfPllLoFrequency_Hz = (uint64_t)(((refclk_Hz * clkPllIntWord) + (((refclk_Hz * clkPllFracWord / 1044480) + 1) >> 1)) * hsDiv * vcoDivTimes10 / 10); + } + else + { + retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_GET_OPCODE, &extData[0], sizeof(extData)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + timeoutMs = 1000; + retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_GET_OPCODE, timeoutMs, &cmdStatusByte); + if (retVal != MYKONOS_ERR_OK) + { + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETRFPLL_ARMERROR, + getMykonosErrorMessage(MYKONOS_ERR_GETRFPLL_ARMERROR)); + return MYKONOS_ERR_GETRFPLL_ARMERROR; + } + + return retVal; + } + + /* read 64-bit frequency from ARM memory */ + retVal = MYKONOS_readArmMem(device, MYKONOS_ADDR_ARM_START_DATA_ADDR, &armData[0], 8, 1); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETRFPLL_ARMERROR, getMykonosErrorMessage(MYKONOS_ERR_GETRFPLL_ARMERROR)); + return MYKONOS_ERR_GETRFPLL_ARMERROR; + } + + if (rfPllLoFrequency_Hz == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETRFPLL_NULLPARAM, + getMykonosErrorMessage(MYKONOS_ERR_GETRFPLL_NULLPARAM)); + return MYKONOS_ERR_GETRFPLL_NULLPARAM; + } + + *rfPllLoFrequency_Hz = (uint64_t)((uint64_t)(armData[0])) | ((uint64_t)(armData[1]) << 8) | ((uint64_t)(armData[2]) << 16) | ((uint64_t)(armData[3]) << 24) + | ((uint64_t)(armData[4]) << 32) | ((uint64_t)(armData[5]) << 40) | ((uint64_t)(armData[6]) << 48) | ((uint64_t)(armData[7]) << 56); + } + return MYKONOS_ERR_OK; +} + +/** + * \brief Checks if the PLLs are locked + * + * This function updates the pllLockStatus pointer with a lock status it per + * PLL. + * pllLockStatus[0] = CLKPLL Locked + * pllLockStatus[1] = RX_PLL Locked + * pllLockStatus[2] = TX_PLL Locked + * pllLockStatus[3] = SNIFFER_PLL Locked + * pllLockStatus[4] = CAL_PLL Locked + * + * \param device the Mykonos device data structure + * \param pllLockStatus Lock status bit per PLL + * + * \return Returns enum MYKONOS_ERR, MYKONOS_ERR_OK=pass, !MYKONOS_ERR_OK=fail + */ +mykonosErr_t MYKONOS_checkPllsLockStatus(mykonosDevice_t *device, uint8_t *pllLockStatus) +{ + uint8_t readData = 0; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_checkPllsLockStatus()\n"); +#endif + + if (pllLockStatus == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CHECK_PLL_LOCK_NULL_PARM, + getMykonosErrorMessage(MYKONOS_ERR_CHECK_PLL_LOCK_NULL_PARM)); + return MYKONOS_ERR_CHECK_PLL_LOCK_NULL_PARM; + } + + *pllLockStatus = 0; + + CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_VCO_BAND_BYTE1, &readData, 0x01, 0); + *pllLockStatus = readData; + + CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_RXSYNTH_VCO_BAND_BYTE1, &readData, 0x01, 0); + *pllLockStatus = *pllLockStatus | (uint8_t)(readData << 1); + + CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_TXSYNTH_VCO_BAND_BYTE1, &readData, 0x01, 0); + *pllLockStatus = *pllLockStatus | (uint8_t)(readData << 2); + + CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_SNIFF_RXSYNTH_VCO_BAND_BYTE1, &readData, 0x01, 0); + *pllLockStatus = *pllLockStatus | (uint8_t)(readData << 3); + + CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_CALPLL_SDM_CONTROL, &readData, 0x80, 7); + *pllLockStatus = *pllLockStatus | (uint8_t)(readData << 4); + + return MYKONOS_ERR_OK; +} + +/* + ***************************************************************************** + * Shared Data path functions + ***************************************************************************** + */ + +/** + * \brief Sets the digital Tx PFIR SYNC clock divider. + * + * This function is a helper function. It is called automatically in + * MYKONOS_initialize() and should not need to be called by the BBIC. + * + * This function sets the digital clock divider that is used to synchronize the + * Tx PFIR each time the Tx channel power up. The Sync clock must + * be set equal to or slower than the FIR processing clock. + * + * Dependencies + * - device->spiSettings + * - device->spiSettings->chipSelectIndex + * - device->profilesValid + * - device->tx->txProfile->txFir + * - device->tx->txProfile->txFir->numFirCoefs + * - device->tx->txProfile->txFirInterpolation + * - device->tx->txProfile->iqRate_kHz + * + * \param device Pointer to the Mykonos data structure + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_TXFIR_INV_NUMTAPS_PARM: Invalid number of Tx FIR coefficients + * \retval MYKONOS_ERR_TXFIR_INV_NUMROWS Invalid number of PFIR coefficient rows + * \retval MYKONOS_ERR_TXFIR_TAPSEXCEEDED Too many Tx PFIR taps for the IQ sample rate. FIR processing clock can not run fast enough to handle the number of taps + */ +mykonosErr_t MYKONOS_setTxPfirSyncClk(mykonosDevice_t *device) +{ + const uint8_t numTapMultiple = 16; + const uint8_t maxNumTaps = 96; + uint8_t effectiveRows = 0; + uint8_t numRows = 0; + uint32_t dpClk_kHz = 0; + uint32_t syncClk_kHz = 0; + uint32_t hsDigClkDiv4or5_kHz = 0; + uint8_t syncDiv = 0; + mykonosErr_t retval = MYKONOS_ERR_OK; + + if (((device->profilesValid & TX_PROFILE_VALID) > 0) && (device->tx->txProfile->txFir != NULL)) + { + /* Calculate number of FIR rows for number of Taps */ + if ((device->tx->txProfile->txFir->numFirCoefs % numTapMultiple == 0) && (device->tx->txProfile->txFir->numFirCoefs > 0) + && (device->tx->txProfile->txFir->numFirCoefs <= maxNumTaps)) + { + numRows = (device->tx->txProfile->txFir->numFirCoefs / numTapMultiple); + } + else + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_TXFIR_INV_NUMTAPS_PARM, + getMykonosErrorMessage(MYKONOS_ERR_TXFIR_INV_NUMTAPS_PARM)); + return MYKONOS_ERR_TXFIR_INV_NUMTAPS_PARM; + } + + effectiveRows = ((numRows + (device->tx->txProfile->txFirInterpolation - 1)) / device->tx->txProfile->txFirInterpolation); + + /* round up to next power of 2 */ + switch (effectiveRows) + { + case 1: + effectiveRows = 1; + break; + case 2: + effectiveRows = 2; + break; + case 3: /* fall through */ + case 4: + effectiveRows = 4; + break; + case 5: /* fall through */ + case 6: /* fall through */ + case 7: /* fall through */ + case 8: + effectiveRows = 8; + break; + default: + { + /* invalid number of FIR taps */ + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_TXFIR_INV_NUMROWS, + getMykonosErrorMessage(MYKONOS_ERR_TXFIR_INV_NUMROWS)); + return MYKONOS_ERR_TXFIR_INV_NUMROWS; + } + } + + dpClk_kHz = (device->tx->txProfile->iqRate_kHz * device->tx->txProfile->txInputHbInterpolation * device->tx->txProfile->txFirInterpolation * effectiveRows); + + /* FIR DPCLK can only run at max of 500MHz */ + if (dpClk_kHz > 500000) + { + /* Max number of Tx PFIR taps exceeded for Tx Profile */ + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_TXFIR_TAPSEXCEEDED, + getMykonosErrorMessage(MYKONOS_ERR_TXFIR_TAPSEXCEEDED)); + return MYKONOS_ERR_TXFIR_TAPSEXCEEDED; + } + + /* SYNC CLOCK is the PFIR output rate / 2 */ + syncClk_kHz = device->tx->txProfile->iqRate_kHz * device->tx->txProfile->txFirInterpolation / 2; + if ((retval = MYKONOS_calculateDigitalClocks(device, NULL, &hsDigClkDiv4or5_kHz)) != MYKONOS_ERR_OK) + { + return retval; + } + + /* Select correct divider setting for SYNCCLK - must be == syncClk_kHz or slower */ + for (syncDiv = 0; syncDiv < 5; syncDiv++) + { + if ((hsDigClkDiv4or5_kHz / (uint32_t)(4 << syncDiv)) <= syncClk_kHz) + { + break; + } + } + + /* Write Tx PFIR SYNC Clock divider */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_CLOCK_CONTROL_5, syncDiv, 0x70, 4); + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief Sets the digital Rx PFIR SYNC clock divider. + * + * This function is a helper function. It is called automatically in + * MYKONOS_initialize() and should not need to be called by the BBIC. + * + * This function sets the digital clock divider that is used to synchronize the + * Rx/ORx/Sniffer PFIRs each time the channels power up. The Sync clock must + * be set equal to or slower than the slowest Rx/ORx/Sniffer PFIR processing + * clock. + * + * Dependencies + * - device->spiSettings + * - device->spiSettings->chipSelectIndex + * - device->profilesValid + * - device->rx->rxProfile->rxFir + * - device->rx->rxProfile->rxFir->numFirCoefs + * - device->rx->rxProfile->iqRate_kHz + * - device->obsRx->orxProfile->rxFir + * - device->obsRx->orxProfile->rxFir->numFirCoefs + * - device->obsRx->orxProfile->iqRate_kHz + * - device->obsRx->snifferProfile->rxFir + * - device->obsRx->snifferProfile->rxFir->numFirCoefs + * - device->obsRx->snifferProfile->iqRate_kHz + * + * \param device Pointer to the Mykonos data structure + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_RXFIR_TAPSEXCEEDED ERROR: the number of Rx FIR taps exceeds the number of taps accommodated by the FIR processing clock + * \retval MYKONOS_ERR_ORXFIR_TAPSEXCEEDED ERROR: the number of ORx FIR Taps exceeds the number of taps accommodated by the FIR processing clock + * \retval MYKONOS_ERR_SNRXFIR_TAPSEXCEEDED ERROR: the number of sniffer FIR taps exceeds the number of taps accommodated by the FIR processing clock + */ +mykonosErr_t MYKONOS_setRxPfirSyncClk(mykonosDevice_t *device) +{ + uint32_t rxDpClk_kHz = 0; + uint32_t orxDpClk_kHz = 0; + uint32_t snRxDpClk_kHz = 0; + uint32_t slowestIqRate_kHz = 0; + uint32_t syncClk_kHz = 0; + uint8_t effectiveRxNumRows = 0; + uint8_t effectiveOrxNumRows = 0; + uint8_t effectiveSnrxNumRows = 0; + + uint32_t hsDigClkDiv4or5_kHz = 0; + uint8_t syncDiv = 0; + mykonosErr_t retval = MYKONOS_ERR_OK; + + /** + * Calculate Rx SYNC Clock divider for Rx PFIR. Same Rx SYNC Clock is used + * for Rx, ORx, and Sniffer PFIRs, and must be slow enough to handle the slowest + * PFIR rate. + **/ + + if (((device->profilesValid & RX_PROFILE_VALID) > 0) && (device->rx->rxProfile->rxFir != NULL)) + { + switch (device->rx->rxProfile->rxFir->numFirCoefs) + { + case 24: + effectiveRxNumRows = 1; + break; + case 48: + effectiveRxNumRows = 2; + break; + case 72: + effectiveRxNumRows = 4; + break; + default: + break; + } + + rxDpClk_kHz = device->rx->rxProfile->iqRate_kHz * effectiveRxNumRows; + + if (rxDpClk_kHz > 500000) + { + /* Max number of Rx PFIR taps exceeded for Profile */ + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RXFIR_TAPSEXCEEDED, + getMykonosErrorMessage(MYKONOS_ERR_RXFIR_TAPSEXCEEDED)); + return MYKONOS_ERR_RXFIR_TAPSEXCEEDED; + } + + slowestIqRate_kHz = device->rx->rxProfile->iqRate_kHz; + } + + if (((device->profilesValid & ORX_PROFILE_VALID) > 0) && (device->obsRx->orxProfile->rxFir != NULL)) + { + switch (device->obsRx->orxProfile->rxFir->numFirCoefs) + { + case 24: + effectiveOrxNumRows = 1; + break; + case 48: + effectiveOrxNumRows = 2; + break; + case 72: + effectiveOrxNumRows = 4; + break; + default: + break; + } + + orxDpClk_kHz = device->obsRx->orxProfile->iqRate_kHz * effectiveOrxNumRows; + + if (orxDpClk_kHz > 500000) + { + /* Max number of ORx PFIR taps exceeded for Profile */ + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_ORXFIR_TAPSEXCEEDED, + getMykonosErrorMessage(MYKONOS_ERR_ORXFIR_TAPSEXCEEDED)); + return MYKONOS_ERR_ORXFIR_TAPSEXCEEDED; + } + + if ((slowestIqRate_kHz == 0) || (slowestIqRate_kHz > device->obsRx->orxProfile->iqRate_kHz)) + { + slowestIqRate_kHz = device->obsRx->orxProfile->iqRate_kHz; + + } + } + + if (((device->profilesValid & SNIFF_PROFILE_VALID) > 0) && (device->obsRx->snifferProfile->rxFir != NULL)) + { + switch (device->obsRx->snifferProfile->rxFir->numFirCoefs) + { + case 24: + effectiveSnrxNumRows = 1; + break; + case 48: + effectiveSnrxNumRows = 2; + break; + case 72: + effectiveSnrxNumRows = 4; + break; + default: + break; + } + + snRxDpClk_kHz = device->obsRx->snifferProfile->iqRate_kHz * effectiveSnrxNumRows; + + if (snRxDpClk_kHz > 500000) + { + /* Max number of ORx PFIR taps exceeded for Profile */ + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SNRXFIR_TAPSEXCEEDED, + getMykonosErrorMessage(MYKONOS_ERR_SNRXFIR_TAPSEXCEEDED)); + return MYKONOS_ERR_SNRXFIR_TAPSEXCEEDED; + } + + if ((slowestIqRate_kHz == 0) || (slowestIqRate_kHz > device->obsRx->snifferProfile->iqRate_kHz)) + { + slowestIqRate_kHz = device->obsRx->snifferProfile->iqRate_kHz; + } + } + + /* SYNC CLOCK should be FIR output rate / 2 */ + syncClk_kHz = (slowestIqRate_kHz / 2); + if ((retval = MYKONOS_calculateDigitalClocks(device, NULL, &hsDigClkDiv4or5_kHz)) != MYKONOS_ERR_OK) + { + return retval; + } + + /* Select correct divider setting for SYNCCLK - must be == syncClk_kHz or slower */ + for (syncDiv = 0; syncDiv < 5; syncDiv++) + { + if ((hsDigClkDiv4or5_kHz / (uint32_t)(4 << syncDiv)) <= syncClk_kHz) + { + break; + } + } + + /* Write Rx PFIR SYNC Clock divider */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_CLOCK_CONTROL_5, syncDiv, 0x07, 0); + + return MYKONOS_ERR_OK; +} + +/** + * \brief Configures one or more FIR filters in the device + * + * The device stores up to 6 FIR filters (2Rx, 2Obs Rx/Sniffer, and 2Tx). + * Rx filters can have 24, 48, or 72 taps. Tx filters can have 16, 32, + * 48, 64, 80, or 96 taps. + * + * Dependencies + * - device->spiSettings + * - device->spiSettings->chipSelectIndex + * + * \param device Pointer to the Mykonos data structure + * \param filterToProgram Name of the desired filter to program + * \param firFilter Pointer to the filter to write into the device + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_PROGRAMFIR_NULL_PARM ERROR: firFilter parameter is a NULL pointer + * \retval MYKONOS_ERR_PROGRAMFIR_COEFS_NULL ERROR: firFilter->coefs is a NULL pointer + * \retval MYKONOS_ERR_PROGRAMFIR_INV_FIRNAME_PARM ERROR: Invalid FIR filter name in filterToProgram parameter + * \retval MYKONOS_ERR_PROGRAMFIR_INV_NUMTAPS_PARM ERROR: Invalid number of taps for the filter + * \retval MYKONOS_ERR_RXFIR_INV_GAIN_PARM ERROR: Rx FIR filter has invalid gain setting + * \retval MYKONOS_ERR_OBSRXFIR_INV_GAIN_PARM ERROR: OBSRX_A (ORX) FIR filter has invalid gain setting + * \retval MYKONOS_ERR_SRXFIR_INV_GAIN_PARM ERROR: OBSRX_B (Sniffer) FIR filter has invalid gain setting + * \retval MYKONOS_ERR_TXFIR_INV_GAIN_PARM ERROR: Tx FIR filter has invalid gain setting + */ +mykonosErr_t MYKONOS_programFir(mykonosDevice_t *device, mykonosfirName_t filterToProgram, mykonosFir_t *firFilter) +{ + uint8_t filterSelect = 0; + uint8_t i = 0; + uint8_t numTapsReg = 0; + uint8_t numTapMultiple = 24; /* Rx=24, Tx=16 */ + uint8_t maxNumTaps = 72; /* Rx=72, Tx=96 */ + uint8_t filterGain = 0; + +#if MYK_ENABLE_SPIWRITEARRAY == 1 + uint32_t addrIndex = 0; + uint32_t dataIndex = 0; + uint32_t spiBufferSize = ((MYK_SPIWRITEARRAY_BUFFERSIZE / 6) * 6); /* Make buffer size a multiple of 6 */ + uint16_t addrArray[MYK_SPIWRITEARRAY_BUFFERSIZE] = {0}; + uint8_t dataArray[MYK_SPIWRITEARRAY_BUFFERSIZE] = {0}; +#endif + + const uint8_t COEF_WRITE_EN = 0x40; + const uint8_t PROGRAM_CLK_EN = 0x80; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_programFir()\n"); +#endif + + if (firFilter == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_PROGRAMFIR_NULL_PARM, + getMykonosErrorMessage(MYKONOS_ERR_PROGRAMFIR_NULL_PARM)); + return MYKONOS_ERR_PROGRAMFIR_NULL_PARM; + } + + if (firFilter->coefs == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_PROGRAMFIR_COEFS_NULL, + getMykonosErrorMessage(MYKONOS_ERR_PROGRAMFIR_COEFS_NULL)); + return MYKONOS_ERR_PROGRAMFIR_COEFS_NULL; + } + + switch (filterToProgram) + { + case TX1_FIR: + filterSelect = 0x01; + numTapMultiple = 16; + maxNumTaps = 96; + break; + case TX2_FIR: + filterSelect = 0x02; + numTapMultiple = 16; + maxNumTaps = 96; + break; + case TX1TX2_FIR: + filterSelect = 0x03; + numTapMultiple = 16; + maxNumTaps = 96; + break; + case RX1_FIR: + filterSelect = 0x04; + numTapMultiple = 24; + maxNumTaps = 72; + break; + case RX2_FIR: + filterSelect = 0x08; + numTapMultiple = 24; + maxNumTaps = 72; + break; + case RX1RX2_FIR: + filterSelect = 0x0C; + numTapMultiple = 24; + maxNumTaps = 72; + break; + case OBSRX_A_FIR: + filterSelect = 0x10; + numTapMultiple = 24; + maxNumTaps = 72; + break; + case OBSRX_B_FIR: + filterSelect = 0x20; + numTapMultiple = 24; + maxNumTaps = 72; + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_PROGRAMFIR_INV_FIRNAME_PARM, + getMykonosErrorMessage(MYKONOS_ERR_PROGRAMFIR_INV_FIRNAME_PARM)); + return MYKONOS_ERR_PROGRAMFIR_INV_FIRNAME_PARM; + } + + /* Calculate register value for number of Taps */ + if ((firFilter->numFirCoefs % numTapMultiple == 0) && (firFilter->numFirCoefs > 0) && (firFilter->numFirCoefs <= maxNumTaps)) + { + numTapsReg = (firFilter->numFirCoefs / numTapMultiple) - 1; + } + else + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_PROGRAMFIR_INV_NUMTAPS_PARM, + getMykonosErrorMessage(MYKONOS_ERR_PROGRAMFIR_INV_NUMTAPS_PARM)); + return MYKONOS_ERR_PROGRAMFIR_INV_NUMTAPS_PARM; + } + + /* Select which FIR filter to program coeffs for */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PFIR_COEFF_CTL, (PROGRAM_CLK_EN | filterSelect)); //select filter and enable the programming clock + +#if (MYK_ENABLE_SPIWRITEARRAY == 0) + + /* write filter coefficients */ + for (i = 0; i < firFilter->numFirCoefs; i++) + { + /* Write Low byte of 16bit coefficient */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PFIR_COEFF_ADDR, (i * 2)); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PFIR_COEFF_DATA, (firFilter->coefs[i] & 0xFF)); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PFIR_COEFF_CTL, (PROGRAM_CLK_EN | COEF_WRITE_EN | filterSelect)); /* write enable (self clearing) */ + + /* Write High Byte of 16bit coefficient */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PFIR_COEFF_ADDR, ((i * 2) + 1)); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PFIR_COEFF_DATA, ((firFilter->coefs[i] >> 8) & 0xFF)); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PFIR_COEFF_CTL, (PROGRAM_CLK_EN | COEF_WRITE_EN | filterSelect));/* write enable (self clearing) */ + } + +#elif (MYK_ENABLE_SPIWRITEARRAY == 1) + + addrIndex = 0; + dataIndex = 0; + for (i = 0; i < firFilter->numFirCoefs; i++) + { + addrArray[addrIndex++] = MYKONOS_ADDR_PFIR_COEFF_ADDR; + addrArray[addrIndex++] = MYKONOS_ADDR_PFIR_COEFF_DATA; + addrArray[addrIndex++] = MYKONOS_ADDR_PFIR_COEFF_CTL; + addrArray[addrIndex++] = MYKONOS_ADDR_PFIR_COEFF_ADDR; + addrArray[addrIndex++] = MYKONOS_ADDR_PFIR_COEFF_DATA; + addrArray[addrIndex++] = MYKONOS_ADDR_PFIR_COEFF_CTL; + + dataArray[dataIndex++] = (uint8_t)(i * 2); + dataArray[dataIndex++] = (firFilter->coefs[i] & 0xFF); + dataArray[dataIndex++] = (PROGRAM_CLK_EN | COEF_WRITE_EN | filterSelect); + dataArray[dataIndex++] = (uint8_t)((i * 2) + 1); + dataArray[dataIndex++] = (((uint16_t)firFilter->coefs[i] >> 8) & 0xFF); + dataArray[dataIndex++] = (PROGRAM_CLK_EN | COEF_WRITE_EN | filterSelect); + + /* Send full buffer size when possible */ + /* spiBufferSize set to multiple of 6 at top of function */ + if (addrIndex >= spiBufferSize) + { + CMB_SPIWriteBytes(device->spiSettings, &addrArray[0], &dataArray[0], addrIndex); + dataIndex = 0; + addrIndex = 0; + } + } + + if (addrIndex > 0) + { + CMB_SPIWriteBytes(device->spiSettings, &addrArray[0], &dataArray[0], addrIndex); + } + +#endif + + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PFIR_COEFF_CTL, filterSelect); /* clear Program clock enable */ + /* write filter gain and #taps */ + if (filterToProgram == RX1_FIR || filterToProgram == RX2_FIR || filterToProgram == RX1RX2_FIR) + { + /* Write Rx FIR #taps */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_RX_FILTER_CONFIGURATION, numTapsReg, 0x60, 5); + + /* Set Rx filter gain */ + switch (firFilter->gain_dB) + { + case -12: + filterGain = 0x00; + break; + case -6: + filterGain = 0x01; + break; + case 0: + filterGain = 0x02; + break; + case 6: + filterGain = 0x03; + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RXFIR_INV_GAIN_PARM, + getMykonosErrorMessage(MYKONOS_ERR_RXFIR_INV_GAIN_PARM)); + return MYKONOS_ERR_RXFIR_INV_GAIN_PARM; + } + + /* Write Rx filter gain */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_RX_FILTER_GAIN, filterGain, 0x03, 0); + } + else if (filterToProgram == OBSRX_A_FIR) + { + /* Write Obs Rx FIR A #taps */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_RX_FILTER_CONFIGURATION, numTapsReg, 0x06, 1); + + /* Set Rx filter gain */ + switch (firFilter->gain_dB) + { + case -12: + filterGain = 0x00; + break; + case -6: + filterGain = 0x01; + break; + case 0: + filterGain = 0x02; + break; + case 6: + filterGain = 0x03; + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OBSRXFIR_INV_GAIN_PARM, + getMykonosErrorMessage(MYKONOS_ERR_OBSRXFIR_INV_GAIN_PARM)); + return MYKONOS_ERR_OBSRXFIR_INV_GAIN_PARM; + } + + /* Write Obs Rx filter gain */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_DPD_SNIFFER_RX_FILTER_GAIN, filterGain, 0x03, 0); + } + else if (filterToProgram == OBSRX_B_FIR) + { + /* Write Obs Rx FIR B #taps */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_RX_FILTER_CONFIGURATION, numTapsReg, 0x18, 3); + + /* Set Rx filter gain */ + switch (firFilter->gain_dB) + { + case -12: + filterGain = 0x00; + break; + case -6: + filterGain = 0x01; + break; + case 0: + filterGain = 0x02; + break; + case 6: + filterGain = 0x03; + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SRXFIR_INV_GAIN_PARM, + getMykonosErrorMessage(MYKONOS_ERR_SRXFIR_INV_GAIN_PARM)); + return MYKONOS_ERR_SRXFIR_INV_GAIN_PARM; + } + + /* Write Obs Rx filter gain */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_DPD_SNIFFER_RX_FILTER_GAIN, filterGain, 0x60, 5); + } + else if (filterToProgram == TX1_FIR || filterToProgram == TX2_FIR || filterToProgram == TX1TX2_FIR) + { + /* Write number of Taps */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_TX_FILTER_CONFIGURATION, numTapsReg, 0xE0, 5); + + switch (firFilter->gain_dB) + { + case 0: + filterGain = 0; + break; + case 6: + filterGain = 1; + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_TXFIR_INV_GAIN_PARM, + getMykonosErrorMessage(MYKONOS_ERR_TXFIR_INV_GAIN_PARM)); + return MYKONOS_ERR_TXFIR_INV_GAIN_PARM; + } + + /* Write Tx Filter gain */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_TX_FILTER_CONFIGURATION, filterGain, 0x01, 0); + + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief Reads the FIR filter programmed into the device + * + * The device stores up to 6 FIR filters (2Rx, 2Obs Rx/Sniffer, and 2Tx). + * Rx filters can have 24, 48, or 72 taps. Tx filters can have 16, 32, + * 48, 64, 80, or 96 taps. + * + * Dependencies + * - device->spiSettings + * - device->spiSettings->chipSelectIndex + * + * \param device Pointer to the Mykonos data structure + * \param filterToRead Name of the desired filter to be read + * \param firFilter Pointer to the filter to be read from the device + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_READFIR_NULL_PARM ERROR: firFilter parameter is a NULL pointer + * \retval MYKONOS_ERR_READFIR_COEFS_NULL ERROR: firFilter->coefs is a NULL pointer + * \retval MYKONOS_ERR_READFIR_INV_FIRNAME_PARM ERROR: Invalid FIR filter name in filterToRead parameter + * \retval MYKONOS_ERR_READFIR_INV_NUMTAPS_PARM ERROR: Invalid number of taps for the filter + * \retval MYKONOS_ERR_RXFIR_INV_GAIN_PARM ERROR: Rx FIR filter has invalid gain setting + * \retval MYKONOS_ERR_OBSRXFIR_INV_GAIN_PARM ERROR: OBSRX_A (ORX) FIR filter has invalid gain setting + * \retval MYKONOS_ERR_SRXFIR_INV_GAIN_PARM ERROR: OBSRX_B (Sniffer) FIR filter has invalid gain setting + * \retval MYKONOS_ERR_TXFIR_INV_GAIN_PARM ERROR: Tx FIR filter has invalid gain setting + */ +mykonosErr_t MYKONOS_readFir(mykonosDevice_t *device, mykonosfirName_t filterToRead, mykonosFir_t *firFilter) +{ + uint8_t filterSelect = 0; + uint8_t i = 0; + uint8_t numTapsReg = 0; + uint8_t numTapMultiple = 24; + uint8_t maxNumTaps = 72; + uint8_t filterGain = 0; + uint8_t msbRead = 0; + uint8_t lsbRead = 0; + + const uint8_t PROGRAM_CLK_EN = 0x80; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_readFir()\n"); +#endif + + if (firFilter == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_READFIR_NULL_PARM, getMykonosErrorMessage(MYKONOS_ERR_READFIR_NULL_PARM)); + return MYKONOS_ERR_READFIR_NULL_PARM; + } + + if (firFilter->coefs == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_READFIR_COEFS_NULL, getMykonosErrorMessage(MYKONOS_ERR_READFIR_COEFS_NULL)); + return MYKONOS_ERR_READFIR_COEFS_NULL; + } + + switch (filterToRead) + { + case TX1_FIR: + filterSelect = 0x01; + numTapMultiple = 16; + maxNumTaps = 96; + break; + case TX2_FIR: + filterSelect = 0x02; + numTapMultiple = 16; + maxNumTaps = 96; + break; + case TX1TX2_FIR: + filterSelect = 0x03; + numTapMultiple = 16; + maxNumTaps = 96; + break; + case RX1_FIR: + filterSelect = 0x04; + numTapMultiple = 24; + maxNumTaps = 72; + break; + case RX2_FIR: + filterSelect = 0x08; + numTapMultiple = 24; + maxNumTaps = 72; + break; + case RX1RX2_FIR: + filterSelect = 0x0C; + numTapMultiple = 24; + maxNumTaps = 72; + break; + case OBSRX_A_FIR: + filterSelect = 0x10; + numTapMultiple = 24; + maxNumTaps = 72; + break; + case OBSRX_B_FIR: + filterSelect = 0x20; + numTapMultiple = 24; + maxNumTaps = 72; + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_READFIR_INV_FIRNAME_PARM, + getMykonosErrorMessage(MYKONOS_ERR_READFIR_INV_FIRNAME_PARM)); + return MYKONOS_ERR_READFIR_INV_FIRNAME_PARM; + } + + /* clear Program clock enable */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PFIR_COEFF_CTL, filterSelect); + + /* Read filter gain and #taps */ + if (filterToRead == RX1_FIR || filterToRead == RX2_FIR || filterToRead == RX1RX2_FIR) + { + /* Read Rx FIR #taps */ + CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_RX_FILTER_CONFIGURATION, &numTapsReg, 0x60, 5); + + firFilter->numFirCoefs = (uint8_t)((numTapsReg + 1) * numTapMultiple); + + /* Read Rx filter gain */ + CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_RX_FILTER_GAIN, &filterGain, 0x03, 0); + + switch (filterGain) + { + case 0x00: + firFilter->gain_dB = -12; + break; + case 0x01: + firFilter->gain_dB = -6; + break; + case 0x02: + firFilter->gain_dB = 0; + break; + case 0x03: + firFilter->gain_dB = 6; + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RXFIR_INV_GAIN_PARM, + getMykonosErrorMessage(MYKONOS_ERR_RXFIR_INV_GAIN_PARM)); + return MYKONOS_ERR_RXFIR_INV_GAIN_PARM; + } + } + else if (filterToRead == OBSRX_A_FIR) + { + /* Read Obs Rx FIR A #taps */ + CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_RX_FILTER_CONFIGURATION, &numTapsReg, 0x60, 1); + + firFilter->numFirCoefs = (uint8_t)((numTapsReg + 1) * numTapMultiple); + + /* Read Obs Rx FIR A gain */ + CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_DPD_SNIFFER_RX_FILTER_GAIN, &filterGain, 0x03, 0); + + switch (filterGain) + { + case 0x00: + firFilter->gain_dB = -12; + break; + case 0x01: + firFilter->gain_dB = -6; + break; + case 0x02: + firFilter->gain_dB = 0; + break; + case 0x03: + firFilter->gain_dB = 6; + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OBSRXFIR_INV_GAIN_PARM, + getMykonosErrorMessage(MYKONOS_ERR_OBSRXFIR_INV_GAIN_PARM)); + return MYKONOS_ERR_OBSRXFIR_INV_GAIN_PARM; + } + } + else if (filterToRead == OBSRX_B_FIR) + { + /* Read Obs Rx FIR B #taps */ + CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_RX_FILTER_CONFIGURATION, &numTapsReg, 0x18, 3); + + firFilter->numFirCoefs = (uint8_t)((numTapsReg + 1) * numTapMultiple); + + /* Read Obs Rx FIR B gain */ + CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_DPD_SNIFFER_RX_FILTER_GAIN, &filterGain, 0x60, 5); + + switch (filterGain) + { + case 0x00: + firFilter->gain_dB = -12; + break; + case 0x01: + firFilter->gain_dB = -6; + break; + case 0x02: + firFilter->gain_dB = 0; + break; + case 0x03: + firFilter->gain_dB = 6; + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SRXFIR_INV_GAIN_PARM, + getMykonosErrorMessage(MYKONOS_ERR_SRXFIR_INV_GAIN_PARM)); + return MYKONOS_ERR_SRXFIR_INV_GAIN_PARM; + } + } + else if (filterToRead == TX1_FIR || filterToRead == TX2_FIR || filterToRead == TX1TX2_FIR) + { + /* Read number of Taps */ + CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_TX_FILTER_CONFIGURATION, &numTapsReg, 0xE0, 5); + + firFilter->numFirCoefs = (uint8_t)((numTapsReg + 1) * numTapMultiple); + + /* Read Tx Filter gain */ + CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_TX_FILTER_CONFIGURATION, &filterGain, 0x01, 0); + + switch (filterGain) + { + case 0: + firFilter->gain_dB = 0; + break; + case 1: + firFilter->gain_dB = 6; + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_TXFIR_INV_GAIN_PARM, + getMykonosErrorMessage(MYKONOS_ERR_TXFIR_INV_GAIN_PARM)); + return MYKONOS_ERR_TXFIR_INV_GAIN_PARM; + } + } + + /* Select which FIR filter to read the coeffs for */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PFIR_COEFF_CTL, (PROGRAM_CLK_EN | filterSelect)); //select filter and enable the programming clock + + if (firFilter->numFirCoefs > maxNumTaps) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_READFIR_INV_NUMTAPS_PARM, + getMykonosErrorMessage(MYKONOS_ERR_READFIR_INV_NUMTAPS_PARM)); + return MYKONOS_ERR_READFIR_INV_NUMTAPS_PARM; + } + + /* write filter coefficients */ + for (i = 0; i < firFilter->numFirCoefs; i++) + { + /* Write Low byte of 16bit coefficient */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PFIR_COEFF_ADDR, (uint8_t)(i * 2)); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PFIR_COEFF_CTL, (PROGRAM_CLK_EN | filterSelect)); /* write enable (self clearing) */ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_PFIR_COEFF_DATA, &lsbRead); + + /* Write High Byte of 16bit coefficient */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PFIR_COEFF_ADDR, (uint8_t)((i * 2) + 1)); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PFIR_COEFF_CTL, (PROGRAM_CLK_EN | filterSelect));/* write enable (self clearing) */ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_PFIR_COEFF_DATA, &msbRead); + + firFilter->coefs[i] = (int16_t)((lsbRead & 0xFF) | ((msbRead << 8) & 0xFF00)); + } + + return MYKONOS_ERR_OK; +} + +/* + ***************************************************************************** + * Rx Data path functions + ***************************************************************************** + */ +/*! + * \brief Programs the gain table settings for either Rx1, Rx2, Rx1 + Rx2, ORx, or SnRx receiver types + * + * The gain table for a receiver type is set with the parameters passed by uint8_t gainTablePtr array. + * gainTablePtr is a 4 x n array, where there are four (4) elements per index, and the array + * length (n) is dependent upon receiver type. The (n) value is conveyed by numGainIndexesInTable. + * All gain tables have a maximum index of 255 when used with this function. The minimum gain index is + * application dependent. + * + * Where for Rx1, Rx2, and ObsRx: + * [A, B, C, D]: A = Front End Gain, B = External Control, C = Digital Attenuation/Gain, D = Attenuation/Gain select + * + * Where for SnRx: + * [A, B, C, D]: A = Front End Gain, B = LNA Bypass, C = Digital Attenuation/Gain, D = Attenuation/Gain select + * + * The gain table starting address changes with each receiver type. This function accounts for this change as well as the + * difference between byte [B] for {Rx1, Rx2, ObsRx} and SnRx receiver array values and programs the correct registers. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device Pointer to the Mykonos data structure + * \param gainTablePtr Pointer to 4 x n array containing gain table program values + * \param numGainIndexesInTable The number of 'n' indices in 4 x n array. A range check is performed to ensure the maximum is not exceeded. + * \param rxChannel mykonosGainTable_t enum type to select either Rx1, Rx2, Rx1 + Rx2, ORx, or SnRx gain table for programming. A + * channel check is performed to ensure a valid selection. + * + * \return Returns enum MYKONOS_ERR, MYKONOS_ERR_OK if successful, MYKONOS_ERR_RXGAINTABLE_INV_CHANNEL if invalid channel is selected, MYKONOS_ERR_RXGAINTABLE_INV_GAIN_INDEX_RANGE + * if numGainIndexesInTable exceeds range for selected receiver gain table + */ +mykonosErr_t MYKONOS_programRxGainTable(mykonosDevice_t *device, uint8_t *gainTablePtr, uint8_t numGainIndexesInTable, mykonosGainTable_t rxChannel) +{ + uint8_t ctlReg = 0; + uint8_t ch3CtlReg = 0; + uint16_t rxFEGainAddr = 0; + uint16_t rxExtCtlLnaAddr = 0; + uint16_t rxDigGainAttenAddr = 0; + uint16_t rx2FEGainAddr = 0; + uint16_t rx2ExtCtlAddr = 0; + uint16_t rx2DigGainAttenAddr = 0; + uint8_t minGainIndex = 0; + uint8_t startIndex = 0; + int16_t i = 0; + uint16_t tableRowIndex = 0; + uint8_t retFlag = 0; + +#if MYK_ENABLE_SPIWRITEARRAY + uint32_t addrIndex = 0; + uint32_t dataIndex = 0; + uint32_t spiBufferSize = (((MYK_SPIWRITEARRAY_BUFFERSIZE / 9) - 1) * 9); + uint16_t addrArray[MYK_SPIWRITEARRAY_BUFFERSIZE] = {0}; + uint8_t dataArray[MYK_SPIWRITEARRAY_BUFFERSIZE] = {0}; +#endif + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_programRxGainTable()\n"); +#endif + + if (gainTablePtr == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_PROGRAM_RXGAIN_TABLE_NULL_PARM, + getMykonosErrorMessage(MYKONOS_ERR_PROGRAM_RXGAIN_TABLE_NULL_PARM)); + return MYKONOS_ERR_PROGRAM_RXGAIN_TABLE_NULL_PARM; + } + + /* checking range of numGainIndexesInTable against maximums and for valid rxChannel selection */ + switch (rxChannel) + { + case RX1_GT: + /* Rx1 max gain index = 255, check is out of range of uint8_t */ + break; + case RX2_GT: + /* Rx1 max gain index = 255, check is out of range of uint8_t */ + break; + case RX1_RX2_GT: + /* Rx1 max gain index = 255, check is out of range of uint8_t */ + break; + case ORX_GT: + if (numGainIndexesInTable > MAX_ORX_GAIN_TABLE_NUMINDEXES) + { + retFlag = 1; + } + break; + case SNRX_GT: + if (numGainIndexesInTable > MAX_SNRX_GAIN_TABLE_NUMINDEXES) + { + retFlag = 1; + } + break; + case LOOPBACK_GT: + if (numGainIndexesInTable > MAX_LOOPBACK_GAIN_TABLE_NUMINDEXES) + { + retFlag = 1; + } + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RXGAINTABLE_INV_CHANNEL, + getMykonosErrorMessage(MYKONOS_ERR_RXGAINTABLE_INV_CHANNEL)); + return MYKONOS_ERR_RXGAINTABLE_INV_CHANNEL; + } + + if (retFlag) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RXGAINTABLE_INV_GAIN_INDEX_RANGE, + getMykonosErrorMessage(MYKONOS_ERR_RXGAINTABLE_INV_GAIN_INDEX_RANGE)); + return MYKONOS_ERR_RXGAINTABLE_INV_GAIN_INDEX_RANGE; + } + else + { + /* calculating minimum gain index value */ + minGainIndex = MAX_GAIN_TABLE_INDEX - numGainIndexesInTable + 1; + } + + /* forming control register words based on channel select, assigning starting index, and register addressing, also updating max and min gain table indices in structure */ + switch (rxChannel) + { + case RX1_GT: + ctlReg = ((uint8_t)rxChannel << 3) | 0x05; + startIndex = START_RX_GAIN_INDEX; + rxFEGainAddr = MYKONOS_ADDR_GAIN_TABLE_RX1_FE_GAIN; + rxExtCtlLnaAddr = MYKONOS_ADDR_GAIN_TABLE_RX1_EXT_CTL; + rxDigGainAttenAddr = MYKONOS_ADDR_GAIN_TABLE_RX1_DIG_GAIN; + device->rx->rxGainCtrl->rx1MaxGainIndex = MAX_GAIN_TABLE_INDEX; + device->rx->rxGainCtrl->rx1MinGainIndex = minGainIndex; + break; + case RX2_GT: + ctlReg = ((uint8_t)rxChannel << 3) | 0x05; + startIndex = START_RX_GAIN_INDEX; + rxFEGainAddr = MYKONOS_ADDR_GAIN_TABLE_RX2_FE_GAIN; + rxExtCtlLnaAddr = MYKONOS_ADDR_GAIN_TABLE_RX2_EXT_CTL; + rxDigGainAttenAddr = MYKONOS_ADDR_GAIN_TABLE_RX2_DIG_GAIN; + device->rx->rxGainCtrl->rx2MaxGainIndex = MAX_GAIN_TABLE_INDEX; + device->rx->rxGainCtrl->rx2MinGainIndex = minGainIndex; + break; + case RX1_RX2_GT: + ctlReg = ((uint8_t)rxChannel << 3) | 0x05; + startIndex = START_RX_GAIN_INDEX; + rxFEGainAddr = MYKONOS_ADDR_GAIN_TABLE_RX1_FE_GAIN; + rx2FEGainAddr = MYKONOS_ADDR_GAIN_TABLE_RX2_FE_GAIN; + rxExtCtlLnaAddr = MYKONOS_ADDR_GAIN_TABLE_RX1_EXT_CTL; + rx2ExtCtlAddr = MYKONOS_ADDR_GAIN_TABLE_RX2_EXT_CTL; + rxDigGainAttenAddr = MYKONOS_ADDR_GAIN_TABLE_RX1_DIG_GAIN; + rx2DigGainAttenAddr = MYKONOS_ADDR_GAIN_TABLE_RX2_DIG_GAIN; + device->rx->rxGainCtrl->rx1MaxGainIndex = MAX_GAIN_TABLE_INDEX; + device->rx->rxGainCtrl->rx1MinGainIndex = minGainIndex; + device->rx->rxGainCtrl->rx2MaxGainIndex = MAX_GAIN_TABLE_INDEX; + device->rx->rxGainCtrl->rx2MinGainIndex = minGainIndex; + break; + case ORX_GT: + ctlReg = 0x05; + ch3CtlReg = 0x08; + startIndex = START_ORX_GAIN_INDEX; + rxFEGainAddr = MYKONOS_ADDR_GAIN_TABLE_RX3_FE_GAIN; + rxExtCtlLnaAddr = MYKONOS_ADDR_GAIN_TABLE_RX3_LNA_ENAB; + rxDigGainAttenAddr = MYKONOS_ADDR_GAIN_TABLE_RX3_DIG_GAIN; + device->obsRx->orxGainCtrl->maxGainIndex = MAX_GAIN_TABLE_INDEX; + device->obsRx->orxGainCtrl->minGainIndex = minGainIndex; + break; + case SNRX_GT: + ctlReg = 0x05; + ch3CtlReg = 0x00; + startIndex = START_SNRX_GAIN_INDEX; + rxFEGainAddr = MYKONOS_ADDR_GAIN_TABLE_RX3_FE_GAIN; + rxExtCtlLnaAddr = MYKONOS_ADDR_GAIN_TABLE_RX3_LNA_ENAB; + rxDigGainAttenAddr = MYKONOS_ADDR_GAIN_TABLE_RX3_DIG_GAIN; + device->obsRx->snifferGainCtrl->maxGainIndex = MAX_GAIN_TABLE_INDEX; + device->obsRx->snifferGainCtrl->minGainIndex = minGainIndex; + break; + /*case LOOPBACK_GT: Loopback is only for ARM calibrations */ + default: + ctlReg = 0x05; + ch3CtlReg = 0x10; + startIndex = START_LOOPBACK_GAIN_INDEX; + rxFEGainAddr = MYKONOS_ADDR_GAIN_TABLE_RX3_FE_GAIN; + rxExtCtlLnaAddr = MYKONOS_ADDR_GAIN_TABLE_RX3_LNA_ENAB; + rxDigGainAttenAddr = MYKONOS_ADDR_GAIN_TABLE_RX3_DIG_GAIN; + break; + } + + /* starting the gain table clock and read from gain table address bits */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_GAIN_TABLE_CONFIGURATION, ctlReg); + + /* if ORx or Sniffer are selected also writing channel 3 readback bits for ObsRx or Sniffer selection */ + if (rxChannel > RX1_RX2_GT) + { + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CH3_GAIN_TABLE_CONFIGURATION, ch3CtlReg); + } + + /* programming a table selected by rxChannel enum type */ + +#if MYK_ENABLE_SPIWRITEARRAY == 0 + + for(i = startIndex; i >= ((startIndex + 1) - numGainIndexesInTable); i--) + { + tableRowIndex = (uint16_t)(startIndex - i) << 2; + + /* set current gain table index (address) */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_GAIN_TABLE_ADDR, i); + + /* Set Rx Front End gain[5:0] */ + CMB_SPIWriteByte(device->spiSettings, rxFEGainAddr, gainTablePtr[tableRowIndex]); + + /* Set external control [5:0] OR LNA bypass if rxChannel == SNRX_GT */ + if (rxChannel == SNRX_GT) + { + CMB_SPIWriteByte(device->spiSettings, rxExtCtlLnaAddr, gainTablePtr[tableRowIndex + 1] << 4); + } + else + { + CMB_SPIWriteByte(device->spiSettings, rxExtCtlLnaAddr, gainTablePtr[tableRowIndex + 1]); + } + + /* Set digital attenuation/gain[6:0] and set/clear attenuation bit */ + CMB_SPIWriteByte(device->spiSettings, rxDigGainAttenAddr, (gainTablePtr[tableRowIndex + 3] << 7) | gainTablePtr[tableRowIndex + 2]); + + /* repeating gain table settings if Rx1 and Rx2 are selected for Rx2 configuration */ + if (rxChannel == RX1_RX2_GT) + { + /* Set Rx Front End gain[5:0] */ + CMB_SPIWriteByte(device->spiSettings, rx2FEGainAddr, gainTablePtr[tableRowIndex]); + + /* Set external control [5:0] */ + CMB_SPIWriteByte(device->spiSettings, rx2ExtCtlAddr, gainTablePtr[tableRowIndex + 1]); + + /* Set digital attenuation/gain[6:0] */ + CMB_SPIWriteByte(device->spiSettings, rx2DigGainAttenAddr, (gainTablePtr[tableRowIndex + 3] << 7) | gainTablePtr[tableRowIndex + 2]); + } + + /* setting the write enable depending on rxChannel choice */ + if (rxChannel == ORX_GT) + { + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CH3_GAIN_TABLE_CONFIGURATION, ch3CtlReg | 0x02); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_GAIN_TABLE_CONFIGURATION, ctlReg | 0x02); + } + else if (rxChannel == SNRX_GT) + { + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CH3_GAIN_TABLE_CONFIGURATION, ch3CtlReg | 0x01); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_GAIN_TABLE_CONFIGURATION, ctlReg | 0x02); + } + else if (rxChannel == LOOPBACK_GT) + { + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CH3_GAIN_TABLE_CONFIGURATION, ch3CtlReg | 0x04); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_GAIN_TABLE_CONFIGURATION, ctlReg | 0x02); + } + else + { + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_GAIN_TABLE_CONFIGURATION, ctlReg | 0x02); + } + } + +#elif MYK_ENABLE_SPIWRITEARRAY == 1 +//#elif 0 + + addrIndex = 0; + dataIndex = 0; + for(i = startIndex; i >= ((startIndex + 1) - numGainIndexesInTable); i--) + { + tableRowIndex = (uint16_t)(startIndex - (uint8_t)i) << 2; + + /* set current gain table index (address) */ + addrArray[addrIndex++] = MYKONOS_ADDR_GAIN_TABLE_ADDR; + dataArray[dataIndex++] = (uint8_t)i; + + /* Set Rx Front End gain[5:0] */ + addrArray[addrIndex++] = rxFEGainAddr; + dataArray[dataIndex++] = gainTablePtr[tableRowIndex]; + + /* Set external control [5:0] OR LNA bypass if rxChannel == SNRX_GT */ + addrArray[addrIndex++] = rxExtCtlLnaAddr; + dataArray[dataIndex++] = (rxChannel == SNRX_GT) ? (uint8_t)(gainTablePtr[tableRowIndex + 1] << 4) : (gainTablePtr[tableRowIndex + 1]); + + /* Set digital attenuation/gain[6:0] and set/clear attenuation bit */ + addrArray[addrIndex++] = rxDigGainAttenAddr; + dataArray[dataIndex++] = ((uint8_t)(gainTablePtr[tableRowIndex + 3] << 7) | gainTablePtr[tableRowIndex + 2]); + + /* repeating gain table settings if Rx1 and Rx2 are selected for Rx2 configuration */ + if (rxChannel == RX1_RX2_GT) + { + /* Set Rx Front End gain[5:0] */ + addrArray[addrIndex++] = rx2FEGainAddr; + dataArray[dataIndex++] = gainTablePtr[tableRowIndex]; + + /* Set external control [5:0] */ + addrArray[addrIndex++] = rx2ExtCtlAddr; + dataArray[dataIndex++] = gainTablePtr[tableRowIndex + 1]; + + /* Set digital attenuation/gain[6:0] */ + addrArray[addrIndex++] = rx2DigGainAttenAddr; + dataArray[dataIndex++] = ((uint8_t)(gainTablePtr[tableRowIndex + 3] << 7) | gainTablePtr[tableRowIndex + 2]); + } + + /* setting the write enable depending on rxChannel choice */ + if (rxChannel == ORX_GT) + { + addrArray[addrIndex++] = MYKONOS_ADDR_CH3_GAIN_TABLE_CONFIGURATION; + dataArray[dataIndex++] = (ch3CtlReg | 0x02); + addrArray[addrIndex++] = MYKONOS_ADDR_GAIN_TABLE_CONFIGURATION; + dataArray[dataIndex++] = (ctlReg | 0x02); + } + else if (rxChannel == SNRX_GT) + { + addrArray[addrIndex++] = MYKONOS_ADDR_CH3_GAIN_TABLE_CONFIGURATION; + dataArray[dataIndex++] = (ch3CtlReg | 0x01); + addrArray[addrIndex++] = MYKONOS_ADDR_GAIN_TABLE_CONFIGURATION; + dataArray[dataIndex++] = (ctlReg | 0x02); + } + else if (rxChannel == LOOPBACK_GT) + { + addrArray[addrIndex++] = MYKONOS_ADDR_CH3_GAIN_TABLE_CONFIGURATION; + dataArray[dataIndex++] = (ch3CtlReg | 0x04); + addrArray[addrIndex++] = MYKONOS_ADDR_GAIN_TABLE_CONFIGURATION; + dataArray[dataIndex++] = (ctlReg | 0x02); + } + else + { + addrArray[addrIndex++] = MYKONOS_ADDR_GAIN_TABLE_CONFIGURATION; + dataArray[dataIndex++] = (ctlReg | 0x02); + } + + if (addrIndex >= spiBufferSize) + { + CMB_SPIWriteBytes(device->spiSettings, &addrArray[0], &dataArray[0], addrIndex); + dataIndex = 0; + addrIndex = 0; + } + } + + if (addrIndex > 0) + { + CMB_SPIWriteBytes(device->spiSettings, &addrArray[0], &dataArray[0], addrIndex); + } + +#endif + + /* clearing the channel 3 gain table configuration register if selected and stopping the gain table clock */ + if (rxChannel > RX1_RX2_GT) + { + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CH3_GAIN_TABLE_CONFIGURATION, 0x00); + } + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_GAIN_TABLE_CONFIGURATION, 0x08); + + return MYKONOS_ERR_OK; +} + +/** + * \brief Sets the Rx1 Manual Gain Index + * + * If the value passed in the gainIndex parameter is within range of the gain table minimum and + * maximum indexes, the Rx1 gain index will be updated in the device data structure + * and written to the transceiver. Else, an error will be returned. The maximum index is 255 + * and the minimum index is application specific. + * + * Dependencies + * - device->spiSettings + * - device->rxSettings->rxGainControl->rx1GainIndex + * - device->rxSettings->rxGainControl->rx1MaxGainIndex + * - device->rxSettings->rxGainControl->rx1MinGainIndex + * + * \param device Pointer to the Mykonos data structure + * \param gainIndex Desired Rx1 gain index + * + * \return Returns enum MYKONOS_ERR, MYKONOS_ERR_OK=pass, !MYKONOS_ERR_OK=fail + */ +mykonosErr_t MYKONOS_setRx1ManualGain(mykonosDevice_t *device, uint8_t gainIndex) +{ + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setRx1ManualGain()\n"); +#endif + + if ((gainIndex < device->rx->rxGainCtrl->rx1MinGainIndex) || (gainIndex > device->rx->rxGainCtrl->rx1MaxGainIndex)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETRX1GAIN_INV_GAIN_PARM, + getMykonosErrorMessage(MYKONOS_ERR_SETRX1GAIN_INV_GAIN_PARM)); + return MYKONOS_ERR_SETRX1GAIN_INV_GAIN_PARM; + + } + else + { + /* If the desired gain index is in range of the gain table, update the + * value in the device data structure, and write to device. + */ + device->rx->rxGainCtrl->rx1GainIndex = gainIndex; + + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_MANUAL_GAIN_INDEX_CH_1, gainIndex); + + return MYKONOS_ERR_OK; + } +} + +/** + * \brief Sets the Rx2 Manual Gain index + * + * If the value passed in the gainIndex parameter is within range of the gain table minimum and + * maximum indexes, the Rx2 gain index will be updated in the device data structure + * and written to the transceiver. Else, an error will be returned. The maximum index is 255 + * and the minimum index is application specific. + * + * Dependencies + * - device->spiSettings + * - device->rxTxSettings->rxGainControl->rx2GainIndex + * - device->rxTxSettings->rxGainControl->rx2MaxGainIndex + * - device->rxTxSettings->rxGainControl->rx2MinGainIndex + * + * \param device Pointer to the Mykonos data structure + * \param gainIndex Desired Rx2 gain index + * + * \return Returns enum MYKONOS_ERR, MYKONOS_ERR_OK=pass, !MYKONOS_ERR_OK=fail + */ +mykonosErr_t MYKONOS_setRx2ManualGain(mykonosDevice_t *device, uint8_t gainIndex) +{ + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setRx2ManualGain()\n"); +#endif + + if ((gainIndex < device->rx->rxGainCtrl->rx2MinGainIndex) || (gainIndex > device->rx->rxGainCtrl->rx2MaxGainIndex)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETRX2GAIN_INV_GAIN_PARM, + getMykonosErrorMessage(MYKONOS_ERR_SETRX2GAIN_INV_GAIN_PARM)); + return MYKONOS_ERR_SETRX2GAIN_INV_GAIN_PARM; + + } + else + { + /* If the desired gain index is in range of the gain table, update the + * value in the device data structure, and write to device. + */ + device->rx->rxGainCtrl->rx2GainIndex = gainIndex; + + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_MANUAL_GAIN_INDEX_CH_2, gainIndex); + + return MYKONOS_ERR_OK; + } +} + +/** + * \brief Reads the Rx1 Gain Index for Manual or AGC gain control mode + * + * This function reads the Rx1 gain index for manual or AGC modes. If the + * *rx1GainIndex pointer is nonzero, the read back gain index will + * be returned in the parameter. If the *rx1GainIndex pointer + * is NULL, the device data structure will be updated with the new read back value + * + * Dependencies + * - device->spiSettings + * - device->rxTxSettings->rxGainControl->rx1GainIndex + * + * \param device Pointer to the Mykonos data structure + * \param rx1GainIndex uint8_t Pointer to the Rx1 gain index value + * + * \return Returns enum MYKONOS_ERR, MYKONOS_ERR_OK=pass, !MYKONOS_ERR_OK=fail + */ +mykonosErr_t MYKONOS_getRx1Gain(mykonosDevice_t *device, uint8_t *rx1GainIndex) +{ + uint8_t readData = 0; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getRx1Gain()\n"); +#endif + + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GAIN_CTL_CHANNEL_1, &readData); + + /* + * If rx1GainIndex address is not NULL, return the Rx1 gain index in the + * rx1GainIndex function parameter + */ + if (rx1GainIndex != NULL) + { + *rx1GainIndex = readData; + } + + /* + * set the current Rx1 gain in the device data structure + */ + if (device->profilesValid & RX_PROFILE_VALID) + { + device->rx->rxGainCtrl->rx1GainIndex = readData; + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief Reads the Rx2 Gain Index for Manual or AGC gain control mode + * + * This function reads the Rx2 gain index for manual or AGC modes. If the + * *rx1GainIndex pointer is nonzero, the read back gain index will + * be returned in the parameter. If the *rx1GainIndex pointer + * is NULL, the device data structure will be updated with the new read back value + * + * Dependencies + * - device->spiSettings + * - device->rxTxSettings->rxGainControl->rx2GainIndex + * + * \param device Pointer to the Mykonos data structure + * \param rx2GainIndex Desired Rx2 gain index + * + * \return Returns enum MYKONOS_ERR, MYKONOS_ERR_OK=pass, !MYKONOS_ERR_OK=fail + */ +mykonosErr_t MYKONOS_getRx2Gain(mykonosDevice_t *device, uint8_t *rx2GainIndex) +{ + uint8_t readData = 0; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getRx2Gain()\n"); +#endif + + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GAIN_CTL_CHANNEL_2, &readData); + + /* + * If rx1GainIndex address is not NULL, return the Rx1 gain index in the + * rx1GainIndex function parameter + */ + if (rx2GainIndex != NULL) + { + *rx2GainIndex = readData; + } + + /* + * set the current Rx2 gain in the device data structure + */ + if (device->profilesValid & RX_PROFILE_VALID) + { + device->rx->rxGainCtrl->rx2GainIndex = readData; + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief Sets up the device Rx Automatic Gain Control (AGC) registers. + * + * Three data structures (mykonosAgcCfg_t, mykonosPeakDetAgcCfg_t, mykonosPowerMeasAgcCfg_t) + * must be instantiated prior to calling this function. Valid ranges for data structure members + * must also be provided. + * + * + * Dependencies: + * - device->spiSettings + * - device->spiSettings->chipSelectIndex + * - device->rx->rxAgcCtrl->agcRx1MaxGainIndex + * - device->rx->rxAgcCtrl->agcRx1MinGainIndex + * - device->rx->rxAgcCtrl->agcRx2MaxGainIndex + * - device->rx->rxAgcCtrl->agcRx2MinGainIndex + * - device->rx->rxAgcCtrl->agcObsRxMaxGainIndex + * - device->rx->rxAgcCtrl->agcObsRxMinGainIndex + * - device->rx->rxAgcCtrl->agcObsRxSelect + * - device->rx->rxAgcCtrl->agcPeakThresholdMode + * - device->rx->rxAgcCtrl->agcLowThsPreventGainIncrease + * - device->rx->rxAgcCtrl->agcGainUpdateCounter + * - device->rx->rxAgcCtrl->agcSlowLoopSettlingDelay + * - device->rx->rxAgcCtrl->agcPeakWaitTime + * - device->rx->rxAgcCtrl->agcResetOnRxEnable + * - device->rx->rxAgcCtrl->agcEnableSyncPulseForGainCounter + * - device->rx->rxAgcCtrl->peakAgc->apdHighThresh + * - device->rx->rxAgcCtrl->peakAgc->apdLowThresh + * - device->rx->rxAgcCtrl->peakAgc->hb2HighThresh + * - device->rx->rxAgcCtrl->peakAgc->hb2LowThresh + * - device->rx->rxAgcCtrl->peakAgc->hb2VeryLowThresh + * - device->rx->rxAgcCtrl->peakAgc->apdHighThreshExceededCnt + * - device->rx->rxAgcCtrl->peakAgc->apdLowThreshExceededCnt + * - device->rx->rxAgcCtrl->peakAgc->hb2HighThreshExceededCnt + * - device->rx->rxAgcCtrl->peakAgc->hb2LowThreshExceededCnt + * - device->rx->rxAgcCtrl->peakAgc->hb2VeryLowThreshExceededCnt + * - device->rx->rxAgcCtrl->peakAgc->apdHighGainStepAttack + * - device->rx->rxAgcCtrl->peakAgc->apdLowGainStepRecovery + * - device->rx->rxAgcCtrl->peakAgc->hb2HighGainStepAttack + * - device->rx->rxAgcCtrl->peakAgc->hb2LowGainStepRecovery + * - device->rx->rxAgcCtrl->peakAgc->hb2VeryLowGainStepRecovery + * - device->rx->rxAgcCtrl->peakAgc->apdFastAttack + * - device->rx->rxAgcCtrl->peakAgc->hb2FastAttack + * - device->rx->rxAgcCtrl->peakAgc->hb2OverloadDetectEnable + * - device->rx->rxAgcCtrl->peakAgc->hb2OverloadDurationCnt + * - device->rx->rxAgcCtrl->peakAgc->hb2OverloadThreshCnt + * - device->rx->rxAgcCtrl->powerAgc->pmdUpperHighThresh + * - device->rx->rxAgcCtrl->powerAgc->pmdUpperLowThresh + * - device->rx->rxAgcCtrl->powerAgc->pmdLowerHighThresh + * - device->rx->rxAgcCtrl->powerAgc->pmdLowerLowThresh + * - device->rx->rxAgcCtrl->powerAgc->pmdUpperHighGainStepAttack + * - device->rx->rxAgcCtrl->powerAgc->pmdUpperLowGainStepAttack + * - device->rx->rxAgcCtrl->powerAgc->pmdLowerHighGainStepRecovery + * - device->rx->rxAgcCtrl->powerAgc->pmdLowerLowGainStepRecovery + * - device->rx->rxAgcCtrl->powerAgc->pmdMeasDuration + * - device->rx->rxAgcCtrl->powerAgc->pmdMeasConfig + * + * \param device is structure pointer to the Mykonos data structure containing settings + * The pointer to the Mykonos AGC data structure containing settings is checked for a null pointer + * to ensure it has been initialized. If not an error is thrown. + * + * \retval Returns MYKONOS_ERR=pass, !MYKONOS_ERR=fail + * \retval MYKONOS_ERR_INV_AGC_RX_STRUCT_INIT + * \retval MYKONOS_ERR_INV_AGC_RX_PEAK_STRUCT_INIT + * \retval MYKONOS_ERR_INV_AGC_RX_PWR_STRUCT_INIT + * \retval MYKONOS_ERR_INV_AGC_RX1_MAX_GAIN_INDEX + * \retval MYKONOS_ERR_INV_AGC_RX1_MIN_GAIN_INDEX + * \retval MYKONOS_ERR_INV_AGC_RX2_MAX_GAIN_INDEX + * \retval MYKONOS_ERR_INV_AGC_RX2_MIN_GAIN_INDEX + * \retval MYKONOS_ERR_INV_AGC_RX_GAIN_UPDATE_TIME_PARM + * \retval MYKONOS_ERR_INV_AGC_RX_PEAK_WAIT_TIME_PARM + * \retval MYKONOS_ERR_INV_AGC_RX_SLOW_LOOP_SETTLING_DELAY + * \retval MYKONOS_ERR_INV_AGC_PMD_MEAS_DURATION + * \retval MYKONOS_ERR_INV_AGC_PMD_MEAS_CONFIG + * \retval MYKONOS_ERR_INV_AGC_RX_LOW_THS_PREV_GAIN_INC + * \retval MYKONOS_ERR_INV_AGC_RX_PEAK_THRESH_MODE + * \retval MYKONOS_ERR_INV_AGC_RX_RESET_ON_RX_ENABLE + * \retval MYKONOS_ERR_INV_AGC_RX_ENABLE_SYNC_PULSE_GAIN_COUNTER + * \retval MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_HIGH_THRESH + * \retval MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_LOW_THRESH + * \retval MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_LOW_THRESH + * \retval MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_HIGH_THRESH + * \retval MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_HIGH_GAIN_STEP + * \retval MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_LOW_GAIN_STEP + * \retval MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_LOW_GAIN_STEP + * \retval MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_LOW_GAIN_STEP + * \retval MYKONOS_ERR_INV_AGC_RX_PKDET_FAST_ATTACK_VALUE + * \retval MYKONOS_ERR_INV_AGC_RX_APD_HIGH_THRESH_PARM + * \retval MYKONOS_ERR_INV_AGC_RX_APD_LOW_THRESH_PARM + * \retval MYKONOS_ERR_INV_AGC_RX_HB2_HIGH_THRESH_PARM + * \retval MYKONOS_ERR_INV_AGC_RX_HB2_LOW_THRESH_PARM + * \retval MYKONOS_ERR_INV_AGC_RX_HB2_VERY_LOW_THRESH_PARM + * \retval MYKONOS_ERR_INV_AGC_RX_APD_HIGH_GAIN_STEP_PARM + * \retval MYKONOS_ERR_INV_AGC_RX_APD_LOW_GAIN_STEP_PARM + * \retval MYKONOS_ERR_INV_AGC_RX_HB2_HIGH_GAIN_STEP_PARM + * \retval MYKONOS_ERR_INV_AGC_RX_HB2_LOW_GAIN_STEP_PARM + * \retval MYKONOS_ERR_INV_AGC_RX_HB2_VERY_LOW_GAIN_STEP_PARM + * \retval MYKONOS_ERR_INV_AGC_RX_HB2_OVLD_ENABLE + * \retval MYKONOS_ERR_INV_AGC_RX_HB2_OVLD_DUR_CNT + * \retval MYKONOS_ERR_INV_AGC_RX_HB2_OVLD_THRESH_CNT + */ +mykonosErr_t MYKONOS_setupRxAgc(mykonosDevice_t *device) +{ + uint8_t decPowerConfig = 0; + uint8_t lower1ThreshGainStepRegValue = 0; + uint8_t powerThresholdsRegValue = 0; + uint8_t hb2OvldCfgRegValue = 0; + uint8_t agcGainUpdateCtr[3] = {0}; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setRxAgc()\n"); +#endif + + /* Check mykonosAgcCfg_t device->rx->rxAgcCtrl pointer for initialization */ + if (device->rx->rxAgcCtrl == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_STRUCT_INIT, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_STRUCT_INIT)); + return MYKONOS_ERR_INV_AGC_RX_STRUCT_INIT; + } + + /* Check mykonosPeakDetAgcCfg_t device->rx->rxAgcCtrl->peakAgc pointer for initialization */ + if (device->rx->rxAgcCtrl->peakAgc == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_PEAK_STRUCT_INIT, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_PEAK_STRUCT_INIT)); + return MYKONOS_ERR_INV_AGC_RX_PEAK_STRUCT_INIT; + } + + /* Check mykonosPowerMeasAgcCfg_t device->rx->rxAgcCtrl->powerAgc pointer for initialization */ + if (device->rx->rxAgcCtrl->powerAgc == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_PWR_STRUCT_INIT, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_PWR_STRUCT_INIT)); + return MYKONOS_ERR_INV_AGC_RX_PWR_STRUCT_INIT; + } + + /* Range check agcRx1MaxGainIndex versus gain table limits */ + if ((device->rx->rxAgcCtrl->agcRx1MaxGainIndex > device->rx->rxGainCtrl->rx1MaxGainIndex) + || (device->rx->rxAgcCtrl->agcRx1MaxGainIndex < device->rx->rxAgcCtrl->agcRx1MinGainIndex)) + + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX1_MAX_GAIN_INDEX, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX1_MAX_GAIN_INDEX)); + return MYKONOS_ERR_INV_AGC_RX1_MAX_GAIN_INDEX; + } + else + { + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_RX1_MAX_GAIN_INDEX, device->rx->rxAgcCtrl->agcRx1MaxGainIndex); + } + + /* Range check agcRx1MinGainIndex versus gain table limits */ + if ((device->rx->rxAgcCtrl->agcRx1MinGainIndex < device->rx->rxGainCtrl->rx1MinGainIndex) + || (device->rx->rxAgcCtrl->agcRx1MaxGainIndex < device->rx->rxAgcCtrl->agcRx1MinGainIndex)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX1_MIN_GAIN_INDEX, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX1_MIN_GAIN_INDEX)); + return MYKONOS_ERR_INV_AGC_RX1_MIN_GAIN_INDEX; + } + else + { + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_RX1_MIN_GAIN_INDEX, device->rx->rxAgcCtrl->agcRx1MinGainIndex); + } + + /* Range check agcRx2MaxGainIndex versus gain table limits */ + if ((device->rx->rxAgcCtrl->agcRx2MaxGainIndex > device->rx->rxGainCtrl->rx2MaxGainIndex) + || (device->rx->rxAgcCtrl->agcRx2MaxGainIndex < device->rx->rxAgcCtrl->agcRx2MinGainIndex)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX2_MAX_GAIN_INDEX, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX2_MAX_GAIN_INDEX)); + return MYKONOS_ERR_INV_AGC_RX2_MAX_GAIN_INDEX; + } + else + { + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_RX2_MAX_GAIN_INDEX, device->rx->rxAgcCtrl->agcRx2MaxGainIndex); + } + + /* Range check agcRx2MinGainIndex versus gain table limits */ + if ((device->rx->rxAgcCtrl->agcRx2MinGainIndex < device->rx->rxGainCtrl->rx2MinGainIndex) + || (device->rx->rxAgcCtrl->agcRx2MaxGainIndex < device->rx->rxAgcCtrl->agcRx2MinGainIndex)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX2_MIN_GAIN_INDEX, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX2_MIN_GAIN_INDEX)); + return MYKONOS_ERR_INV_AGC_RX2_MIN_GAIN_INDEX; + } + else + { + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_RX2_MIN_GAIN_INDEX, device->rx->rxAgcCtrl->agcRx2MinGainIndex); + } + + /* Range check for agcGainUpdateCounter (22-bit) */ + if ((device->rx->rxAgcCtrl->agcGainUpdateCounter > 0x3FFFFF) || (device->rx->rxAgcCtrl->agcGainUpdateCounter < 1)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_GAIN_UPDATE_TIME_PARM, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_GAIN_UPDATE_TIME_PARM)); + return MYKONOS_ERR_INV_AGC_RX_GAIN_UPDATE_TIME_PARM; + } + else + { + /* Split agcGainUpdateCounter into three values */ + agcGainUpdateCtr[0] = (uint8_t)(device->rx->rxAgcCtrl->agcGainUpdateCounter); + agcGainUpdateCtr[1] = (uint8_t)(device->rx->rxAgcCtrl->agcGainUpdateCounter >> 8); + agcGainUpdateCtr[2] = (uint8_t)(device->rx->rxAgcCtrl->agcGainUpdateCounter >> 16); + + /* Write two bytes directly due. Third word has its upper two bits masked off. */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_GAIN_UPDATE_CNT_1, agcGainUpdateCtr[0]); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_GAIN_UPDATE_CNT_2, agcGainUpdateCtr[1]); + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_GAIN_UPDATE_CNT_3, agcGainUpdateCtr[2], 0x3F, 0); + } + + /* Range check on agcPeakWaitTime (5-bit) */ + if (device->rx->rxAgcCtrl->agcPeakWaitTime > 0x1F || device->rx->rxAgcCtrl->agcPeakWaitTime < 0x02) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_PEAK_WAIT_TIME_PARM, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_PEAK_WAIT_TIME_PARM)); + return MYKONOS_ERR_INV_AGC_RX_PEAK_WAIT_TIME_PARM; + } + else + { + /* Write agcPeakWaitTime */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_CFG_2, device->rx->rxAgcCtrl->agcPeakWaitTime, 0x1F, 0); + } + + /* Set MYKONOS_ADDR_AGC_CFG_2 bits [6:5] = b11 to enable AGC counters for MGC mode - needed for ARM cals to work correctly */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_CFG_2, 3, 0x60, 5); + + /* Range check for agcSlowLoopSettlingDelay (7-bit) */ + if (device->rx->rxAgcCtrl->agcSlowLoopSettlingDelay > 0x7F) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_SLOW_LOOP_SETTLING_DELAY, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_SLOW_LOOP_SETTLING_DELAY)); + return MYKONOS_ERR_INV_AGC_RX_SLOW_LOOP_SETTLING_DELAY; + } + else + { + /* Write agcSlowLoopSettlingDelay */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_LOOP_CFG, device->rx->rxAgcCtrl->agcSlowLoopSettlingDelay, 0x7F, 0); + } + + /* Range check for pmdMeasDuration */ + if ((uint32_t)(1 << (3 + device->rx->rxAgcCtrl->powerAgc->pmdMeasDuration)) >= (device->rx->rxAgcCtrl->agcGainUpdateCounter)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_PMD_MEAS_DURATION, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_PMD_MEAS_DURATION)); + return MYKONOS_ERR_INV_AGC_PMD_MEAS_DURATION; + } + else + { + /* Write pmdMeasDuration */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_DEC_POWER_CONFIG_2, device->rx->rxAgcCtrl->powerAgc->pmdMeasDuration, 0x0F, 0); + } + + /* Range check for pmdMeasConfig */ + if (device->rx->rxAgcCtrl->powerAgc->pmdMeasConfig > 0x3) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_PMD_MEAS_CONFIG, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_PMD_MEAS_CONFIG)); + return MYKONOS_ERR_INV_AGC_PMD_MEAS_CONFIG; + } + else + { + if (device->rx->rxAgcCtrl->powerAgc->pmdMeasConfig == 0) + { + decPowerConfig = 0x0; /* Dec Pwr measurement disable */ + } + else if (device->rx->rxAgcCtrl->powerAgc->pmdMeasConfig == 1) + { + decPowerConfig = 0x3; /* Dec Pwr measurement enable, HB2 for decPwr measurement */ + } + else if (device->rx->rxAgcCtrl->powerAgc->pmdMeasConfig == 2) + { + decPowerConfig = 0x5; /* Dec Pwr measurement enable, RFIR for decPwr measurement */ + } + else if (device->rx->rxAgcCtrl->powerAgc->pmdMeasConfig == 3) + { + decPowerConfig = 0x11; /* Dec Pwr measurement enable, BBDC2 for decPwr measurement */ + } + /* Write pmdMeasConfig */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_DEC_POWER_CONFIG_1, decPowerConfig); + } + + /* Range check agcLowThsPreventGainIncrease (1-bit) */ + if (device->rx->rxAgcCtrl->agcLowThsPreventGainIncrease > 1) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_LOW_THS_PREV_GAIN_INC, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_LOW_THS_PREV_GAIN_INC)); + return MYKONOS_ERR_INV_AGC_RX_LOW_THS_PREV_GAIN_INC; + } + else + { + /* Write agcLowThsPreventGainIncrease */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_LOCK_LEV_THRSH, device->rx->rxAgcCtrl->agcLowThsPreventGainIncrease, 0x80, 7); + } + + /* Range check agcPeakThresholdMode (1-bit), */ + if (device->rx->rxAgcCtrl->agcPeakThresholdMode > 1) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_PEAK_THRESH_MODE, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_PEAK_THRESH_MODE)); + return MYKONOS_ERR_INV_AGC_RX_PEAK_THRESH_MODE; + } + else + { + /* Save to lower1ThreshGainStepRegValue register variable */ + lower1ThreshGainStepRegValue |= (uint8_t)(device->rx->rxAgcCtrl->agcPeakThresholdMode << 5); + } + + /* Range check agcResetOnRxEnable (1-bit) */ + if (device->rx->rxAgcCtrl->agcResetOnRxEnable > 1) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_LOW_THS_PREV_GAIN_INC, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_LOW_THS_PREV_GAIN_INC)); + return MYKONOS_ERR_INV_AGC_RX_RESET_ON_RX_ENABLE; + } + else + { + /* Write agcResetOnRxEnable */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_GAIN_UPDATE_CNT_3, (uint8_t)(device->rx->rxAgcCtrl->agcResetOnRxEnable << 7), 0x80, 0); + } + + /* Range check agcEnableSyncPulseForGainCounter (1-bit) */ + if (device->rx->rxAgcCtrl->agcEnableSyncPulseForGainCounter > 1) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_ENABLE_SYNC_PULSE_GAIN_COUNTER, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_ENABLE_SYNC_PULSE_GAIN_COUNTER)); + return MYKONOS_ERR_INV_AGC_RX_ENABLE_SYNC_PULSE_GAIN_COUNTER; + } + else + { + /* Write agcEnableSyncPulseForGainCounter */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_LOOP_CFG, (uint8_t)(device->rx->rxAgcCtrl->agcEnableSyncPulseForGainCounter << 7), 0x80, 0); + } + + /* WRITE REGISTERS FOR THE AGC POWER MEASUREMENT DETECTOR (PMD) STRUCTURE */ + + /* Range check pmdLowerHighThresh (7-bit) vs 0x7F and pmdUpperLowThresh */ + if ((device->rx->rxAgcCtrl->powerAgc->pmdLowerHighThresh <= device->rx->rxAgcCtrl->powerAgc->pmdUpperLowThresh) + || device->rx->rxAgcCtrl->powerAgc->pmdLowerHighThresh > 0x7F) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_HIGH_THRESH, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_HIGH_THRESH)); + return MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_HIGH_THRESH; + } + else + { + /* Write pmdLowerHighThresh */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_LOCK_LEV_THRSH, device->rx->rxAgcCtrl->powerAgc->pmdLowerHighThresh, 0x7F, 0); + } + + /* Range check pmdUpperLowThresh (7-bit): Comparison to pmdLowerHigh done earlier */ + if (device->rx->rxAgcCtrl->powerAgc->pmdUpperLowThresh > 0x7F) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_LOW_THRESH, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_LOW_THRESH)); + return MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_LOW_THRESH; + } + else + { + /* Write pmdUpperLowThresh */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_LOCK_LEVEL, device->rx->rxAgcCtrl->powerAgc->pmdUpperLowThresh); + } + + /* Range check pmdLowerLowThresh (4-bit) */ + if (device->rx->rxAgcCtrl->powerAgc->pmdLowerLowThresh > 0xF) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_LOW_THRESH, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_LOW_THRESH)); + return MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_LOW_THRESH; + } + else + { + /* Write pmdUpperLowThresh to temp variable */ + powerThresholdsRegValue |= device->rx->rxAgcCtrl->powerAgc->pmdLowerLowThresh; + } + + /* Range check pmdUpperHighThresh (4-bit) */ + if (device->rx->rxAgcCtrl->powerAgc->pmdUpperHighThresh > 0xF) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_HIGH_THRESH, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_HIGH_THRESH)); + return MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_HIGH_THRESH; + } + else + { + /* Write pmdUpperHighThresh to temp var, then to register */ + powerThresholdsRegValue |= (uint8_t)(device->rx->rxAgcCtrl->powerAgc->pmdUpperHighThresh << 4); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_POWER_THRSH, powerThresholdsRegValue); + } + + /* Range check pmdUpperHighGainStepAttack (5-bit) */ + if (device->rx->rxAgcCtrl->powerAgc->pmdUpperHighGainStepAttack > 0x1F) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_HIGH_GAIN_STEP, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_HIGH_GAIN_STEP)); + return MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_HIGH_GAIN_STEP; + } + else + { + /* Write pmdUpperHighGainStepAttack */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_UPPER1_THRSH_GAIN_STEP, device->rx->rxAgcCtrl->powerAgc->pmdUpperHighGainStepAttack, 0x1F, 0); + } + + /* Range check pmdLowerLowGainStepRecovery (5-bit) */ + if (device->rx->rxAgcCtrl->powerAgc->pmdLowerLowGainStepRecovery > 0x1F) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_LOW_GAIN_STEP, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_LOW_GAIN_STEP)); + return MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_LOW_GAIN_STEP; + } + else + { + /* Write pmdLowerLowGainStepRecovery to temp var, then to register */ + lower1ThreshGainStepRegValue |= (device->rx->rxAgcCtrl->powerAgc->pmdLowerLowGainStepRecovery); + } + + /* Range check pmdUpperLowGainStepRecovery (5-bit) */ + if (device->rx->rxAgcCtrl->powerAgc->pmdUpperLowGainStepAttack > 0x1F) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_LOW_GAIN_STEP, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_LOW_GAIN_STEP)); + return MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_LOW_GAIN_STEP; + } + else + { + /* Write pmdLowerLowGainStepRecovery to temp var, then to register */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_UPPER0_THRSH_GAIN_STEP, device->rx->rxAgcCtrl->powerAgc->pmdUpperLowGainStepAttack); + } + + /* Range check pmdLowerHighGainStepRecovery (5-bit) */ + if (device->rx->rxAgcCtrl->powerAgc->pmdLowerHighGainStepRecovery > 0x1F) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_HIGH_GAIN_STEP, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_HIGH_GAIN_STEP)); + return MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_HIGH_GAIN_STEP; + } + else + { + /* Write pmdLowerLowGainStepRecovery to temp var, then to register */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_LOWER0_THRSH_GAIN_STEP, device->rx->rxAgcCtrl->powerAgc->pmdLowerHighGainStepRecovery); + } + + /* WRITE REGISTERS FOR THE AGC PEAK DETECTOR (APD/HB2) STRUCTURE */ + + /* Range check apdFastAttack and hb2FastAttack (1-bit) */ + if (device->rx->rxAgcCtrl->peakAgc->apdFastAttack > 0x1 || device->rx->rxAgcCtrl->peakAgc->hb2FastAttack > 0x1) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_PKDET_FAST_ATTACK_VALUE, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_PKDET_FAST_ATTACK_VALUE)); + return MYKONOS_ERR_INV_AGC_RX_PKDET_FAST_ATTACK_VALUE; + } + else + { + /* Write pmdLowerLowGainStepRecovery to temp var, then to register */ + lower1ThreshGainStepRegValue |= (uint8_t)(device->rx->rxAgcCtrl->peakAgc->apdFastAttack << 7); + lower1ThreshGainStepRegValue |= (uint8_t)(device->rx->rxAgcCtrl->peakAgc->hb2FastAttack << 6); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_LOWER1_THRSH_GAIN_STEP, lower1ThreshGainStepRegValue); + } + + /* Range check apdHighThresh */ + if ((device->rx->rxAgcCtrl->peakAgc->apdHighThresh > 0x3F) || (device->rx->rxAgcCtrl->peakAgc->apdHighThresh <= device->rx->rxAgcCtrl->peakAgc->apdLowThresh)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_APD_HIGH_THRESH_PARM, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_APD_HIGH_THRESH_PARM)); + return MYKONOS_ERR_INV_AGC_RX_APD_HIGH_THRESH_PARM; + } + else + { + /* Write apdHighThresh */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_ULB_THRSH, device->rx->rxAgcCtrl->peakAgc->apdHighThresh, 0X3F, 0); + } + + /* Range check apdLowThresh */ + if ((device->rx->rxAgcCtrl->peakAgc->apdLowThresh > 0x3F) || (device->rx->rxAgcCtrl->peakAgc->apdHighThresh < device->rx->rxAgcCtrl->peakAgc->apdLowThresh)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_APD_LOW_THRESH_PARM, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_APD_LOW_THRESH_PARM)); + return MYKONOS_ERR_INV_AGC_RX_APD_LOW_THRESH_PARM; + } + else + { + /* write apdLowThresh */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_LLB_THRSH, device->rx->rxAgcCtrl->peakAgc->apdLowThresh, 0x3F, 0); + } + + /* Range check hb2HighThresh */ + if (device->rx->rxAgcCtrl->peakAgc->hb2HighThresh < device->rx->rxAgcCtrl->peakAgc->hb2LowThresh) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_HB2_HIGH_THRESH_PARM, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_HB2_HIGH_THRESH_PARM)); + return MYKONOS_ERR_INV_AGC_RX_HB2_HIGH_THRESH_PARM; + } + else + { + /* write hb2HighThresh */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OVRLD_PD_DEC_OVRLD_UPPER_THRSH, device->rx->rxAgcCtrl->peakAgc->hb2HighThresh); + } + + /* Range check hb2LowThresh */ + if (device->rx->rxAgcCtrl->peakAgc->hb2LowThresh > device->rx->rxAgcCtrl->peakAgc->hb2HighThresh) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_HB2_LOW_THRESH_PARM, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_HB2_LOW_THRESH_PARM)); + return MYKONOS_ERR_INV_AGC_RX_HB2_LOW_THRESH_PARM; + } + else + { + /* write hb2LowThresh */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OVRLD_PD_DEC_OVRLD_LOWER_THRSH, device->rx->rxAgcCtrl->peakAgc->hb2LowThresh); + } + + /* Range check hb2VeryLowThresh */ + if (device->rx->rxAgcCtrl->peakAgc->hb2VeryLowThresh > device->rx->rxAgcCtrl->peakAgc->hb2LowThresh) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_HB2_VERY_LOW_THRESH_PARM, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_HB2_VERY_LOW_THRESH_PARM)); + return MYKONOS_ERR_INV_AGC_RX_HB2_VERY_LOW_THRESH_PARM; + } + else + { + /* write hb2VeryLowThresh */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OVRLD_PD_DEC_VERYLOW_THRSH, device->rx->rxAgcCtrl->peakAgc->hb2VeryLowThresh); + } + + /* Write threshold counter values for apdHigh/apdLow/hb2High/hb2Low/hb2VeryLow */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_ULB_CNT_THRSH, device->rx->rxAgcCtrl->peakAgc->apdHighThreshExceededCnt); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_LLB_CNT_THRSH, device->rx->rxAgcCtrl->peakAgc->apdLowThreshExceededCnt); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_HIGH_OVRG_CNT_THRSH, device->rx->rxAgcCtrl->peakAgc->hb2HighThreshExceededCnt); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_LOW_OVRG_CNT_THRSH, device->rx->rxAgcCtrl->peakAgc->hb2LowThreshExceededCnt); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_VERYLOW_OVRG_CNT_THRSH, device->rx->rxAgcCtrl->peakAgc->hb2VeryLowThreshExceededCnt); + + /* Range check on apdHighGainStepAttack (5-bit) */ + if (device->rx->rxAgcCtrl->peakAgc->apdHighGainStepAttack > 0x1F) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_APD_HIGH_GAIN_STEP_PARM, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_APD_HIGH_GAIN_STEP_PARM)); + return MYKONOS_ERR_INV_AGC_RX_APD_HIGH_GAIN_STEP_PARM; + } + else + { + /* Write apdHighGainStepAttack */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_OVRG_GAIN_STEP_1, device->rx->rxAgcCtrl->peakAgc->apdHighGainStepAttack); + } + + /* Range check on apdLowGainStepRecovery (5-bit) */ + if (device->rx->rxAgcCtrl->peakAgc->apdLowGainStepRecovery > 0x1F) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_APD_LOW_GAIN_STEP_PARM, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_APD_LOW_GAIN_STEP_PARM)); + return MYKONOS_ERR_INV_AGC_RX_APD_LOW_GAIN_STEP_PARM; + } + else + { + /* Write apdLowGainStepRecovery */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_OVRG_GAIN_STEP_4, device->rx->rxAgcCtrl->peakAgc->apdLowGainStepRecovery); + } + + /* Range check on hb2HighGainStepAttack (5-bit) */ + if (device->rx->rxAgcCtrl->peakAgc->hb2HighGainStepAttack > 0x1F) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_HB2_HIGH_GAIN_STEP_PARM, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_HB2_HIGH_GAIN_STEP_PARM)); + return MYKONOS_ERR_INV_AGC_RX_HB2_HIGH_GAIN_STEP_PARM; + } + else + { + /* Write hb2HighGainStepAttack */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_OVRG_GAIN_STEP_2, device->rx->rxAgcCtrl->peakAgc->hb2HighGainStepAttack); + } + + /* Range check on hb2LowGainStepRecovery (5-bit) */ + if (device->rx->rxAgcCtrl->peakAgc->hb2LowGainStepRecovery > 0x1F) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_HB2_LOW_GAIN_STEP_PARM, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_HB2_LOW_GAIN_STEP_PARM)); + return MYKONOS_ERR_INV_AGC_RX_HB2_LOW_GAIN_STEP_PARM; + } + else + { + /* Write hb2LowGainStepRecovery */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_OVRG_GAIN_STEP_5, device->rx->rxAgcCtrl->peakAgc->hb2LowGainStepRecovery); + } + + /* Range check on hb2VeryLowGainStepRecovery (5-bit) */ + if (device->rx->rxAgcCtrl->peakAgc->hb2VeryLowGainStepRecovery > 0x1F) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_HB2_VERY_LOW_GAIN_STEP_PARM, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_HB2_VERY_LOW_GAIN_STEP_PARM)); + return MYKONOS_ERR_INV_AGC_RX_HB2_VERY_LOW_GAIN_STEP_PARM; + } + else + { + /* Write hb2VeryLowGainStepRecovery */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_OVRG_GAIN_STEP_6, device->rx->rxAgcCtrl->peakAgc->hb2VeryLowGainStepRecovery); + } + + /* Range Check on hb2OverloadDetectEnable */ + if (device->rx->rxAgcCtrl->peakAgc->hb2OverloadDetectEnable > 0x1) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_HB2_OVLD_ENABLE, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_HB2_OVLD_ENABLE)); + return MYKONOS_ERR_INV_AGC_RX_HB2_OVLD_ENABLE; + } + + /* Range Check on hb2OverloadDetectEnable */ + if (device->rx->rxAgcCtrl->peakAgc->hb2OverloadDurationCnt > 0x7) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_HB2_OVLD_DUR_CNT, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_HB2_OVLD_DUR_CNT)); + return MYKONOS_ERR_INV_AGC_RX_HB2_OVLD_DUR_CNT; + } + + /* Range Check on hb2OverloadDetectEnable */ + if (device->rx->rxAgcCtrl->peakAgc->hb2OverloadThreshCnt > 0xF) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_HB2_OVLD_THRESH_CNT, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_HB2_OVLD_THRESH_CNT)); + return MYKONOS_ERR_INV_AGC_RX_HB2_OVLD_THRESH_CNT; + } + else + { + /* Write the hb2OvldCfgRegValue, the combination of hb2OverloadThreshCnt, hb2OverloadDurationCnt, and hb2OverloadDetectEnable */ + hb2OvldCfgRegValue = (device->rx->rxAgcCtrl->peakAgc->hb2OverloadThreshCnt) |(uint8_t)(device->rx->rxAgcCtrl->peakAgc->hb2OverloadDurationCnt << 4) + | (uint8_t)(device->rx->rxAgcCtrl->peakAgc->hb2OverloadDetectEnable << 7); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OVRLD_PD_DEC_OVRLD_CFG, hb2OvldCfgRegValue); + } + + /* Hard-coded value for the ADC overload configuration. Sets the HB2 offset to -6dB.*/ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OVRLD_ADC_OVRLD_CFG, 0x18); + /* Hard-coded value for APD decay setting. Setting allows for the quickest settling time of peak detector */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_RX_BLOCK_DET_DECAY, 0x0); + + /* performing a soft reset */ + return MYKONOS_resetRxAgc(device); +} + +/** + * \brief This function resets the AGC state machine + * + * Calling this function resets all state machines within the gain control and maximum gain. + * + * Dependencies: + * - device->spiSettings + * + * \param device is structure pointer to the Mykonos data structure containing the device SPI settings + * + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_resetRxAgc(mykonosDevice_t *device) +{ + const uint8_t AGC_RESET = 0x80; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_resetRxAgc()\n"); +#endif + + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_CFG_2, 1, AGC_RESET, 7); + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_CFG_2, 0, AGC_RESET, 7); + + return MYKONOS_ERR_OK; + +} + +/** + * \brief This function sets the min/max gain indexes for AGC in the main RX channel + * + * Allows to change min/max gain index on runtime. + * If RX1_RX2 selected, then the maxGainIndex/minGainIndex value will be applied to both channels. + * If only Rx1 selected, then only Rx1 min/max gain indices will be updated, along with their device data structure values. + * If only Rx2 selected, then only Rx2 min/max gain indices will be updated, along with their device data structure values. + * + * Dependencies: + * - device->spiSettings + * - device->rx->rxAgcCtrl + * + * \param device is structure pointer to the Mykonos data structure containing the device SPI settings + * \param rxChannelSelect RX channel for setting the max and min gain index settings + * \param maxGainIndex Max gain index setting + * \param minGainIndex Min gain index setting + * + * \retval MYKONOS_ERR_SET_RX_MAX_GAIN_INDEX Max gain index bigger than max gain index loaded table. + * \retval MYKONOS_ERR_SET_RX_MIN_GAIN_INDEX Min gain index lower than min gain index loaded table. + * \retval MYKONOS_ERR_AGC_MIN_MAX_CHANNEL Wrong RX channel selected + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_setRxAgcMinMaxGainIndex(mykonosDevice_t *device, mykonosRxChannels_t rxChannelSelect, uint8_t maxGainIndex, uint8_t minGainIndex) +{ + const uint8_t MIN_GAIN_INDEX = 1 + MAX_GAIN_TABLE_INDEX - (sizeof(RxGainTable) / sizeof(RxGainTable[0])); + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setRxAgcMinMaxGainIndex()\n"); +#endif + + /* Check for maxGainIndex */ + if (maxGainIndex > MAX_GAIN_TABLE_INDEX) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SET_RX_MAX_GAIN_INDEX, + getMykonosErrorMessage(MYKONOS_ERR_SET_RX_MAX_GAIN_INDEX)); + return MYKONOS_ERR_SET_RX_MAX_GAIN_INDEX; + } + + /* Check for minGainIndex */ + if (minGainIndex < MIN_GAIN_INDEX) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SET_RX_MIN_GAIN_INDEX, + getMykonosErrorMessage(MYKONOS_ERR_SET_RX_MIN_GAIN_INDEX)); + return MYKONOS_ERR_SET_RX_MIN_GAIN_INDEX; + } + + if ((uint32_t)rxChannelSelect & (uint32_t)RX1) + { + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_RX1_MAX_GAIN_INDEX, maxGainIndex); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_RX1_MIN_GAIN_INDEX, minGainIndex); + device->rx->rxAgcCtrl->agcRx1MaxGainIndex = maxGainIndex; + device->rx->rxAgcCtrl->agcRx1MinGainIndex = minGainIndex; + } + + if ((uint32_t)rxChannelSelect & (uint32_t)RX2) + { + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_RX2_MAX_GAIN_INDEX, maxGainIndex); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_RX2_MIN_GAIN_INDEX, minGainIndex); + device->rx->rxAgcCtrl->agcRx2MaxGainIndex = maxGainIndex; + device->rx->rxAgcCtrl->agcRx2MinGainIndex = minGainIndex; + } + + /* Check for invalid Rx channel */ + if (!((uint32_t)rxChannelSelect & (uint32_t)RX1_RX2)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_AGC_MIN_MAX_RX_CHANNEL, + getMykonosErrorMessage(MYKONOS_ERR_AGC_MIN_MAX_RX_CHANNEL)); + return MYKONOS_ERR_AGC_MIN_MAX_RX_CHANNEL; + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief This function sets the min/max gain indexes for AGC in the observation channel + * + * Allows to change min/max gain index on runtime. + * + * Dependencies: + * - device->spiSettings + * - device->rx->rxAgcCtrl + * + * \param device is structure pointer to the Mykonos data structure containing the device SPI settings + * \param obsRxChannelSelect Observation channel for setting the max and min gain index settings + * \param maxGainIndex Max gain index setting + * \param minGainIndex Min gain index setting + * + * \retval MYKONOS_ERR_SET_ORX_MAX_GAIN_INDEX_CHANNEL Wrong read back channel. + * \retval MYKONOS_ERR_SET_ORX_MAX_GAIN_INDEX Max gain index bigger than max gain index loaded table. + * \retval MYKONOS_ERR_SET_ORX_MIN_GAIN_INDEX Min gain index lower than min gain index loaded table. + * \retval MYKONOS_ERR_AGC_MIN_MAX_ORX_CHANNEL Wrong observation channel selected + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_setObsRxAgcMinMaxGainIndex(mykonosDevice_t *device, mykonosObsRxChannels_t obsRxChannelSelect, uint8_t maxGainIndex, uint8_t minGainIndex) +{ + uint8_t rdObsActive = 0x00; + uint8_t obsActive = 0x00; + uint8_t obsCheck = 0x00; + uint8_t minGainIndexCheck = 0x00; + uint8_t maxGainIndexCheck = 0x00; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setObsRxAgcMinMaxGainIndex()\n"); +#endif + + /* Read active channel */ + CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_AGC_ORX_SNRX_ACTIVE, &rdObsActive, 0x03, 0); + + /* Check active channel and set min/max checks */ + switch (rdObsActive) + { + case 0x00: + case 0x01: + /*sniffer*/ + maxGainIndexCheck = MAX_GAIN_TABLE_INDEX; + minGainIndexCheck = MAX_GAIN_TABLE_INDEX - (sizeof(SnRxGainTable) / sizeof(SnRxGainTable[0])); + obsActive = (uint32_t)OBS_SNIFFER | (uint32_t)OBS_SNIFFER_A | (uint32_t)OBS_SNIFFER_B | (uint32_t)OBS_SNIFFER_C; + break; + case 0x02: + case 0x03: + /*observation 1*/ + maxGainIndexCheck = MAX_GAIN_TABLE_INDEX; + minGainIndexCheck = MAX_GAIN_TABLE_INDEX - (sizeof(ORxGainTable) / sizeof(ORxGainTable[0])); + obsActive = (uint32_t)OBS_RX1_TXLO | (uint32_t)OBS_RX1_SNIFFERLO | (uint32_t)OBS_RX2_TXLO | (uint32_t)OBS_RX2_SNIFFERLO; + break; + + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SET_ORX_MAX_GAIN_INDEX_CHANNEL, + getMykonosErrorMessage(MYKONOS_ERR_SET_ORX_MAX_GAIN_INDEX_CHANNEL)); + return MYKONOS_ERR_SET_ORX_MAX_GAIN_INDEX_CHANNEL; + } + + /* Check for maxGainIndex */ + if ((maxGainIndex > maxGainIndexCheck) || (maxGainIndex < minGainIndexCheck)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SET_ORX_MAX_GAIN_INDEX, + getMykonosErrorMessage(MYKONOS_ERR_SET_ORX_MAX_GAIN_INDEX)); + return MYKONOS_ERR_SET_ORX_MAX_GAIN_INDEX; + } + + /* Check for minGainIndex */ + if ((minGainIndex < minGainIndexCheck) || (minGainIndex > maxGainIndexCheck)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SET_ORX_MIN_GAIN_INDEX, + getMykonosErrorMessage(MYKONOS_ERR_SET_ORX_MIN_GAIN_INDEX)); + return MYKONOS_ERR_SET_ORX_MIN_GAIN_INDEX; + } + + device->obsRx->orxAgcCtrl->agcObsRxMaxGainIndex = maxGainIndex; + device->obsRx->orxAgcCtrl->agcObsRxMinGainIndex = minGainIndex; + + switch (obsRxChannelSelect) + { + case OBS_SNIFFER: + case OBS_SNIFFER_A: + case OBS_SNIFFER_B: + case OBS_SNIFFER_C: + obsCheck = (uint32_t)OBS_SNIFFER | (uint32_t)OBS_SNIFFER_A | (uint32_t)OBS_SNIFFER_B | (uint32_t)OBS_SNIFFER_C; + maxGainIndex = maxGainIndex - MAX_SNRX_GAIN_TABLE_NUMINDEXES; + minGainIndex = minGainIndex - MAX_SNRX_GAIN_TABLE_NUMINDEXES; + break; + + case OBS_RX1_TXLO: + case OBS_RX2_TXLO: + case OBS_RX1_SNIFFERLO: + case OBS_RX2_SNIFFERLO: + obsCheck = (uint32_t)OBS_RX1_TXLO | (uint32_t)OBS_RX1_SNIFFERLO | (uint32_t)OBS_RX2_TXLO | (uint32_t)OBS_RX2_SNIFFERLO; + maxGainIndex = maxGainIndex - MAX_ORX_GAIN_TABLE_NUMINDEXES; + minGainIndex = minGainIndex - MAX_ORX_GAIN_TABLE_NUMINDEXES; + break; + + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_AGC_MIN_MAX_ORX_CHANNEL, + getMykonosErrorMessage(MYKONOS_ERR_AGC_MIN_MAX_ORX_CHANNEL)); + return MYKONOS_ERR_AGC_MIN_MAX_ORX_CHANNEL; + } + + if (obsCheck == obsActive) + { + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_ORX_SNRX_MAX_GAIN_INDEX, maxGainIndex); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_ORX_SNRX_MIN_GAIN_INDEX, minGainIndex); + } + else + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_AGC_MIN_MAX_ORX_CHANNEL, + getMykonosErrorMessage(MYKONOS_ERR_AGC_MIN_MAX_ORX_CHANNEL)); + return MYKONOS_ERR_AGC_MIN_MAX_ORX_CHANNEL; + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief This function sets the Temperature gain compensation for Rx1 channel + * + * The temperature gain compensation control allow for a +3000mdB to -3000mdB digital gain + * in the data path. + * The resolution of the temperature compensation gain is 250mdB. + * + * Dependencies: + * - device->spiSettings + * + * \param device is structure pointer to the Mykonos data structure containing the device SPI settings + * \param rx1TempCompGain_mdB gain compensation for Rx1, the range is from -3000mdB to +3000mdB in steps of 250mdB + * + * \retval MYKONOS_ERR_RX1_TEMP_GAIN_COMP_RANGE The temp gain compensation is outside range (-3000mdB to 3000mdB) + * \retval MYKONOS_ERR_RX1_TEMP_GAIN_COMP_STEP Not valid temp gain compensation, step size is 250mdB + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_setRx1TempGainComp(mykonosDevice_t *device, int16_t rx1TempCompGain_mdB) +{ + int8_t tempGainComp = 0x00; + + const int16_t LOW_LIMIT_GAIN_COMP = -3000; + const int16_t HIGH_LIMIT_GAIN_COMP = 3000; + const int16_t GAIN_COMP_STEP = 250; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setRx1TempGainComp()\n"); +#endif + + /* Check for Gain compensation range */ + if ((rx1TempCompGain_mdB > HIGH_LIMIT_GAIN_COMP) || (rx1TempCompGain_mdB < LOW_LIMIT_GAIN_COMP)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RX1_TEMP_GAIN_COMP_RANGE, + getMykonosErrorMessage(MYKONOS_ERR_RX1_TEMP_GAIN_COMP_RANGE)); + return MYKONOS_ERR_RX1_TEMP_GAIN_COMP_RANGE; + } + + /* Check for Gain compensation steps */ + if (rx1TempCompGain_mdB % GAIN_COMP_STEP) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RX1_TEMP_GAIN_COMP_STEP, + getMykonosErrorMessage(MYKONOS_ERR_RX1_TEMP_GAIN_COMP_STEP)); + return MYKONOS_ERR_RX1_TEMP_GAIN_COMP_STEP; + } + + /* Prepare register write */ + tempGainComp = (rx1TempCompGain_mdB / GAIN_COMP_STEP) & 0x1F; + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RX1_TEMP_GAIN_COMP, (uint8_t)tempGainComp); + + return MYKONOS_ERR_OK; +} + +/** + * \brief This function gets the Temperature gain compensation for Rx1 + * + * Dependencies: + * - device->spiSettings + * + * \param device is structure pointer to the Mykonos data structure containing the device SPI settings + * \param rx1TempCompGain_mdB Which will be populated with the Temperature Gain Compensation in mdB value for Rx1 channel. + * + * \retval MYKONOS_ERR_RX1_TEMP_GAIN_COMP_NULL rx1TempCompGain_mdB pointer is null. + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_getRx1TempGainComp(mykonosDevice_t *device, int16_t *rx1TempCompGain_mdB) +{ + uint8_t tempGainComp = 0x00; + int8_t tempGainCompDB = 0x00; + + const int16_t GAIN_COMP_STEP = 250; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getRx1TempGainComp()\n"); +#endif + + /* Check for null passed parameter */ + if (rx1TempCompGain_mdB == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RX1_TEMP_GAIN_COMP_NULL, + getMykonosErrorMessage(MYKONOS_ERR_RX1_TEMP_GAIN_COMP_NULL)); + return MYKONOS_ERR_RX1_TEMP_GAIN_COMP_NULL; + } + + /* Read Temperature Gain Compensation */ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_RX1_TEMP_GAIN_COMP, &tempGainComp); + + /* Convert to dB and prepare the signed return */ + tempGainCompDB = tempGainComp & 0x1F; + if (tempGainCompDB & 0x10) + { + tempGainCompDB = ((((~((uint8_t)tempGainCompDB)) & 0x0F) + 1) * (-1)); + } + + /* Assign value to the passed pointer */ + *rx1TempCompGain_mdB = tempGainCompDB * GAIN_COMP_STEP; + + return MYKONOS_ERR_OK; +} + +/** + * \brief This function sets the Temperature gain compensation for Rx2 channel + * + * The temperature gain compensation control allow for a +3000mdB to -3000mdB digital gain + * in the data path. + * The resolution of the temperature compensation gain is 250mdB. + * + * Dependencies: + * - device->spiSettings + * + * \param device is structure pointer to the Mykonos data structure containing the device SPI settings + * \param rx2TempCompGain_mdB gain compensation for Rx1, + * the range is from -3000mdB to +3000mdB in steps of 250mdB + * + * \retval MYKONOS_ERR_RX2_TEMP_GAIN_COMP_RANGE The temp gain compensation is outside range (-3000mdB to 3000mdB) + * \retval MYKONOS_ERR_RX2_TEMP_GAIN_COMP_STEP Not valid temp gain compensation, step size is 250mdB + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_setRx2TempGainComp(mykonosDevice_t *device, int16_t rx2TempCompGain_mdB) +{ + int8_t tempGainComp = 0x00; + + const int16_t LOW_LIMIT_GAIN_COMP = -3000; + const int16_t HIGH_LIMIT_GAIN_COMP = 3000; + const int16_t GAIN_COMP_STEP = 250; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setRx2TempGainComp()\n"); +#endif + + /* Check for Gain compensation range */ + if ((rx2TempCompGain_mdB > HIGH_LIMIT_GAIN_COMP) || (rx2TempCompGain_mdB < LOW_LIMIT_GAIN_COMP)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RX2_TEMP_GAIN_COMP_RANGE, + getMykonosErrorMessage(MYKONOS_ERR_RX2_TEMP_GAIN_COMP_RANGE)); + return MYKONOS_ERR_RX2_TEMP_GAIN_COMP_RANGE; + } + + /* Check for Gain compensation range */ + if (rx2TempCompGain_mdB % GAIN_COMP_STEP) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RX2_TEMP_GAIN_COMP_STEP, + getMykonosErrorMessage(MYKONOS_ERR_RX2_TEMP_GAIN_COMP_STEP)); + return MYKONOS_ERR_RX2_TEMP_GAIN_COMP_STEP; + } + + /* Prepare register write */ + tempGainComp = (rx2TempCompGain_mdB / GAIN_COMP_STEP) & 0x1F; + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RX2_TEMP_GAIN_COMP, (uint8_t)tempGainComp); + + return MYKONOS_ERR_OK; +} + +/** + * \brief This function gets the Temperature gain compensation for Rx2 + * + * Dependencies: + * - device->spiSettings + * + * \param device is structure pointer to the Mykonos data structure containing the device SPI settings + * \param rx2TempCompGain_mdB Which will be populated with the Temperature Gain Compensation in mdB value for Rx2 channel. + * + * \retval MYKONOS_ERR_RX2_TEMP_GAIN_COMP_NULL rx2TempCompGain_mdB pointer is null. + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_getRx2TempGainComp(mykonosDevice_t *device, int16_t *rx2TempCompGain_mdB) +{ + uint8_t tempGainComp = 0x00; + int8_t tempGainCompDB = 0x00; + + const int16_t GAIN_COMP_STEP = 250; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getRx2TempGainComp()\n"); +#endif + + /* Check for null passed parameter */ + if (rx2TempCompGain_mdB == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RX2_TEMP_GAIN_COMP_NULL, + getMykonosErrorMessage(MYKONOS_ERR_RX2_TEMP_GAIN_COMP_NULL)); + return MYKONOS_ERR_RX2_TEMP_GAIN_COMP_NULL; + } + + /* Read programmed Temperature Gain Compensation */ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_RX2_TEMP_GAIN_COMP, &tempGainComp); + + /* Convert to dB and prepare the signed return */ + tempGainCompDB = tempGainComp & 0x1F; + if (tempGainCompDB & 0x10) + { + tempGainCompDB = (((~((uint8_t)tempGainCompDB)) & 0x0F) + 1) * (-1); + } + + /* Assign value to the passed pointer */ + *rx2TempCompGain_mdB = tempGainCompDB * GAIN_COMP_STEP; + + return MYKONOS_ERR_OK; +} + +/** + * \brief This function sets the Temperature gain compensation for the observation channel + * + * The temperature gain compensation control allow for a +3000mdB to -3000mdB digital gain + * in the data path. + * The resolution of the temperature compensation gain is 250mdB. + * + * Dependencies: + * - device->spiSettings + * + * \param device is structure pointer to the Mykonos data structure containing the device SPI settings + * \param obsRxTempCompGain_mdB gain compensation for observation channel, + * the range is from -3000mdB to +3000mdB in steps of 250mdB + * + * \retval MYKONOS_ERR_OBS_RX_TEMP_GAIN_COMP_RANGE The temp gain compensation is outside range (-3000mdB to 3000mdB) + * \retval MYKONOS_ERR_OBS_RX_TEMP_GAIN_COMP_STEP Not valid temp gain compensation, step size is 250mdB + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_setObsRxTempGainComp(mykonosDevice_t *device, int16_t obsRxTempCompGain_mdB) +{ + int8_t tempGainComp = 0x00; + + const int16_t LOW_LIMIT_GAIN_COMP = -3000; + const int16_t HIGH_LIMIT_GAIN_COMP = 3000; + const int16_t GAIN_COMP_STEP = 250; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setObsRxTempGainComp()\n"); +#endif + + /* Check for Gain compensation range */ + if ((obsRxTempCompGain_mdB > HIGH_LIMIT_GAIN_COMP) || (obsRxTempCompGain_mdB < LOW_LIMIT_GAIN_COMP)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OBS_RX_TEMP_GAIN_COMP_RANGE, + getMykonosErrorMessage(MYKONOS_ERR_OBS_RX_TEMP_GAIN_COMP_RANGE)); + return MYKONOS_ERR_OBS_RX_TEMP_GAIN_COMP_RANGE; + } + + /* Check for Gain compensation range */ + if (obsRxTempCompGain_mdB % GAIN_COMP_STEP) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OBS_RX_TEMP_GAIN_COMP_STEP, + getMykonosErrorMessage(MYKONOS_ERR_OBS_RX_TEMP_GAIN_COMP_STEP)); + return MYKONOS_ERR_OBS_RX_TEMP_GAIN_COMP_STEP; + } + + /* Prepare register write */ + tempGainComp = (obsRxTempCompGain_mdB / GAIN_COMP_STEP) & 0x1F; + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OBS_TEMP_GAIN_COMP, (uint8_t)tempGainComp); + + return MYKONOS_ERR_OK; +} + +/** + * \brief This function gets the Temperature gain compensation for the observation channel + * + * + * Dependencies: + * - device->spiSettings + * + * \param device is structure pointer to the Mykonos data structure containing the device SPI settings + * \param obsRxTempCompGain_mdB Which will be populated with the Temperature Gain Compensation in mdB value for the observation channel. + * + * \retval MYKONOS_ERR_OBS_RX_TEMP_GAIN_COMP_NULL obsRxTempCompGain_mdB pointer is null. + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_getObsRxTempGainComp(mykonosDevice_t *device, int16_t *obsRxTempCompGain_mdB) +{ + uint8_t tempGainComp = 0x00; + int8_t tempGainCompDB = 0x00; + + const int16_t GAIN_COMP_STEP = 250; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getObsRxTempGainComp()\n"); +#endif + + /* Check for null passed parameter */ + if (obsRxTempCompGain_mdB == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OBS_RX_TEMP_GAIN_COMP_NULL, + getMykonosErrorMessage(MYKONOS_ERR_OBS_RX_TEMP_GAIN_COMP_NULL)); + return MYKONOS_ERR_OBS_RX_TEMP_GAIN_COMP_NULL; + } + + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_OBS_TEMP_GAIN_COMP, &tempGainComp); + + /* Convert to dB and prepare the signed return */ + tempGainCompDB = tempGainComp & 0x1F; + if (tempGainCompDB & 0x10) + { + tempGainCompDB = (((~((uint8_t)tempGainCompDB)) & 0x0F) + 1) * (-1); + } + + /* Assign value to the passed pointer */ + *obsRxTempCompGain_mdB = tempGainCompDB * GAIN_COMP_STEP; + + return MYKONOS_ERR_OK; +} + +/** + * \brief Enables or disables the Rx slow loop gain counter to use the sync pulse + * + * Dependencies: + * - device->spiSettings + * + * \param device is structure pointer to the Mykonos data structure containing the device SPI settings + * \param enable is a uint8_t data type where '0' = disable Rx gain counter from using sync pulse, '1' = enable Rx gain. All other values will throw an error. + * counter to use the sync pulse. This value is written back to the device data structure for storage. + * + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_enableRxGainCtrSyncPulse(mykonosDevice_t *device, uint8_t enable) +{ + const uint8_t syncPulseBitMask = 0x80; + uint8_t enableBit = 0; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setRxGainCtrSyncPulse()\n"); +#endif + + /* read, modify, write Rx gain counter sync pulse enable bit */ + enableBit = (enable > 0) ? 1 : 0; + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_LOOP_CFG, enableBit, syncPulseBitMask, 7); + + return MYKONOS_ERR_OK; +} + +/** + * \brief Configures the Rx gain control mode + * + * Dependencies: + * - device->spiSettings + * - device->spiSettings->chipSelectIndex + * - device->rx->rxGainCtrl->gainMode + * + * \param device is structure pointer to the Mykonos data structure containing settings + * \param mode is a mykonosGainMode_t enumerated gain control mode type where: + * Manual Gain = MGC, Automatic Gain Control = AGC, and hybrid mode = HYBRID + * + * When the mode enumerated type is passed, the Rx1 and Rx2 gain mode is set to this value and the + * Rx gainMode structure member is updated with the new value + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_INV_RX_GAIN_MODE_PARM Invalid AGC mode pass in function mode paramter + */ +mykonosErr_t MYKONOS_setRxGainControlMode(mykonosDevice_t *device, mykonosGainMode_t mode) +{ + uint8_t rxGainCfgReg = 0; + + const uint8_t RX_GAIN_TYPE_MASK = 0x1F; + const uint8_t RX_GAIN_HYBRID_MASK = 0x10; + const uint8_t RX_GAIN_TYPE_SHIFT = 0x02; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setRxGainControlMode()\n"); +#endif + + /* read AGC type for Rx1 and Rx2 for modify, write */ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_AGC_CFG_1, &rxGainCfgReg); + rxGainCfgReg &= ~RX_GAIN_TYPE_MASK; + + /* performing AGC type check */ + switch (mode) + { + case MGC: + rxGainCfgReg &= ~RX_GAIN_HYBRID_MASK; + break; + case AGC: + rxGainCfgReg &= ~RX_GAIN_HYBRID_MASK; + break; + case HYBRID: + rxGainCfgReg |= RX_GAIN_HYBRID_MASK; + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_RX_GAIN_MODE_PARM, + getMykonosErrorMessage(MYKONOS_ERR_INV_RX_GAIN_MODE_PARM)); + return MYKONOS_ERR_INV_RX_GAIN_MODE_PARM; + } + + /* modify, write AGC type for Rx1 and Rx2 */ + rxGainCfgReg |= (uint8_t)mode; + rxGainCfgReg |= (uint8_t)((uint8_t)mode << RX_GAIN_TYPE_SHIFT); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_CFG_1, rxGainCfgReg); + + /* writing mode setting to data structure */ + if ((device->profilesValid & RX_PROFILE_VALID) > 0) + { + device->rx->rxGainCtrl->gainMode = mode; + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief Performs a power measurement in the Rx1 digital data path. + * + * Due to interdependencies between the AGC and power measurement the power measurement duration and + * where the measurement is taken is variable. + * The location of the power measurement is given by device->rx->rxAgcCtrl->rxPwrAgc->pmdMeasConfig + * The number of samples the power measurement uses is given by 8*2^(device->rx->rxAgcCtrl->rxPwrAgc->pmdMeasDuration) at the IQ rate, + * if measured at RFIR output. This number of samples must be less than the agcGainUpdateCounter. + * If the receiver is disabled during the power measurement, this function returns a 0 value for rx1DecPower_mdBFS + * + * The resolution of this function is 0.25dB. + * The dynamic range of this function is 40dB. Signals lower than 40dBFS may not be measured accurately. + * + * Dependencies + * - device->spiSettings + * - device->rx->rxAgcCtrl->rxPwrAgc->pmdMeasConfig + * - device->rx->rxAgcCtrl->rxPwrAgc->pmdMeasDuration + * + * \param device Pointer to the Mykonos data structure + * \param rx1DecPower_mdBFS Pointer to store the Rx1 decimated power return. Value returned in mdBFS + * + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_getRx1DecPower(mykonosDevice_t *device, uint16_t *rx1DecPower_mdBFS) +{ + uint8_t rx1DecPower_dBFS = 0; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getRx1DecPower()\n"); +#endif + + /* read Rx1 Dec Power Measurement */ + if (rx1DecPower_mdBFS != NULL) + { + CMB_SPIReadByte(device->spiSettings, MYKONOS_CH1_DECIMATED_PWR, &rx1DecPower_dBFS); + *rx1DecPower_mdBFS = (uint16_t)(rx1DecPower_dBFS * 250); /* 250 = 1000 * 0.25dB */ + } + else + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GET_RX1_DEC_POWER_NULL_PARM, + getMykonosErrorMessage(MYKONOS_ERR_GET_RX1_DEC_POWER_NULL_PARM)); + return MYKONOS_ERR_GET_RX1_DEC_POWER_NULL_PARM; + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief Performs a power measurement in the Rx2 digital data path. + * + * Due to interdependencies between the AGC and power measurement the power measurement duration and + * where the measurement is taken is variable. + * The location of the power measurement is given by device->rx->rxAgcCtrl->rxPwrAgc->pmdMeasConfig + * The number of samples the power measurement uses is given by 8*2^(device->rx->rxAgcCtrl->rxPwrAgc->pmdMeasDuration) at the IQ rate, + * if measured at RFIR output. This number of samples must be less than the agcGainUpdateCounter. + * If the receiver is disabled during the power measurement, this function returns a 0 value for rx2DecPower_mdBFS + * + * The resolution of this function is 0.25dB. + * The dynamic range of this function is 40dB. Signals lower than 40dBFS may not be measured accurately. + * + * Dependencies + * - device->spiSettings + * + * \param device Pointer to the Mykonos data structure + * \param rx2DecPower_mdBFS Pointer to store the Rx1 decimated power return. Value returned in mdBFS + * + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_getRx2DecPower(mykonosDevice_t *device, uint16_t *rx2DecPower_mdBFS) +{ + uint8_t rx2DecPower_dBFS = 0; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getRx2DecPower()\n"); +#endif + + /* read Rx2 Dec Power Measurement */ + if (rx2DecPower_mdBFS != NULL) + { + CMB_SPIReadByte(device->spiSettings, MYKONOS_CH2_DECIMATED_PWR, &rx2DecPower_dBFS); + *rx2DecPower_mdBFS = (uint16_t)(rx2DecPower_dBFS * 250); /* 250 = 1000 * 0.25dB */ + } + else + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GET_RX2_DEC_POWER_NULL_PARM, + getMykonosErrorMessage(MYKONOS_ERR_GET_RX2_DEC_POWER_NULL_PARM)); + return MYKONOS_ERR_GET_RX2_DEC_POWER_NULL_PARM; + } + + return MYKONOS_ERR_OK; +} + +/* + ***************************************************************************** + * Observation Rx Data path functions + ***************************************************************************** + */ + +/** + * \brief Sets the default Obs Rx channel to enter when device moves from + * radioOff to radioOn + * + * By default, the observation receiver remains powered down when the device + * moves into the radioOn state. If the BBIC prefers a particular ObsRx + * channel to be enabled, this function can be called in radioOff to set + * the default channel to power up when the device moves to radioOn. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - device->obsRx->defaultObsRxChannel + * + * \param device is structure pointer to the Mykonos data structure containing settings + * \param defaultObsRxCh is mykonosObsRxChannels_t enum type which selects the desired observation receive path to power up + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_SETDEFOBSRXPATH_NULL_OBSRX_STRUCT Observation profile not valid, device->obsRx structure is NULL + * \retval MYKONOS_ERR_SETDEFOBSRXPATH_NULL_DEF_OBSRX_STRUCT Invalid defaultObsRxCh function parameter + */ +mykonosErr_t MYKONOS_setDefaultObsRxPath(mykonosDevice_t *device, mykonosObsRxChannels_t defaultObsRxCh) +{ + uint8_t orxEntryMode[1] = {0}; + uint16_t byteOffset = 0; + mykonosErr_t retVal = MYKONOS_ERR_OK; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setDefaultObsRxPath()\n"); +#endif + + if (device->obsRx == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETDEFOBSRXPATH_NULL_DEF_OBSRX_STRUCT, + getMykonosErrorMessage(MYKONOS_ERR_SETDEFOBSRXPATH_NULL_DEF_OBSRX_STRUCT)); + return MYKONOS_ERR_SETDEFOBSRXPATH_NULL_DEF_OBSRX_STRUCT; + } + + if (((defaultObsRxCh > OBS_RX2_SNIFFERLO) && (defaultObsRxCh != OBS_SNIFFER_A) && (defaultObsRxCh != OBS_SNIFFER_B) && (defaultObsRxCh != OBS_SNIFFER_C))) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_PU_OBSRXPATH_INV_PARAM, + getMykonosErrorMessage(MYKONOS_ERR_PU_OBSRXPATH_INV_PARAM)); + return MYKONOS_ERR_PU_OBSRXPATH_INV_PARAM; + } + + device->obsRx->defaultObsRxChannel = defaultObsRxCh; + orxEntryMode[0] = ((uint8_t)device->obsRx->defaultObsRxChannel & 0xFF); + + byteOffset = 6; + retVal = MYKONOS_writeArmConfig(device, MYKONOS_ARM_OBJECTID_RADIO_CONTROL, byteOffset, &orxEntryMode[0], 1); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief Powers up or down the Observation Rx signal chain in the radioOn state + * + * When the ARM radio control is in ARM command mode, this + * function allows the user to selectively power up or down the desired ObsRx + * data path. If this function is called when the ARM is expecting GPIO pin + * control of the ObsRx path source, an error will be returned. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is structure pointer to the Mykonos data structure containing settings + * \param obsRxCh is mykonosObsRxChannels_t enum type which selects the desired observation receive path to power up + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_PU_OBSRXPATH_INV_PARAM Invalid obsRxCh function parameter + * \retval MYKONOS_ERR_PU_OBSRXPATH_ARMERROR ARM returned an error while trying to set the ObsRx Path source + */ +mykonosErr_t MYKONOS_setObsRxPathSource(mykonosDevice_t *device, mykonosObsRxChannels_t obsRxCh) +{ + uint8_t cmdStatByte = 0; + uint32_t timeoutMs = 0; + uint8_t payload[2] = {0, 0}; + mykonosErr_t retVal = MYKONOS_ERR_OK; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setObsRxPathSource()\n"); +#endif + + if (((obsRxCh > OBS_RX2_SNIFFERLO) && (obsRxCh != OBS_SNIFFER_A) && (obsRxCh != OBS_SNIFFER_B) && (obsRxCh != OBS_SNIFFER_C))) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_PU_OBSRXPATH_INV_PARAM, + getMykonosErrorMessage(MYKONOS_ERR_PU_OBSRXPATH_INV_PARAM)); + return MYKONOS_ERR_PU_OBSRXPATH_INV_PARAM; + } + + payload[0] = MYKONOS_ARM_OBJECTID_ORX_MODE; + payload[1] = (uint8_t)(obsRxCh); + + retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_SET_OPCODE, &payload[0], sizeof(payload)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + timeoutMs = 1000; /* wait max of 1sec for command to complete */ + retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_SET_OPCODE, timeoutMs, &cmdStatByte); + if (retVal != MYKONOS_ERR_OK) + { + if (cmdStatByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_PU_OBSRXPATH_ARMERROR, + getMykonosErrorMessage(MYKONOS_ERR_PU_OBSRXPATH_ARMERROR)); + return MYKONOS_ERR_PU_OBSRXPATH_ARMERROR; + } + + return retVal; + } + + /* Verify ARM command did not return an error */ + if (cmdStatByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_PU_OBSRXPATH_ARMERROR, + getMykonosErrorMessage(MYKONOS_ERR_PU_OBSRXPATH_ARMERROR)); + return MYKONOS_ERR_PU_OBSRXPATH_ARMERROR; + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief Reads back the currently enabled Observation Rx channel in the + * radioOn state + * + * In pin mode, the pin could change asynchronous to reading back the + * current enable ObsRx path. Calling this function while in radioOff will + * return OBS_RXOFF since all radio channels are powered down. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is structure pointer to the Mykonos data structure containing settings + * \param obsRxCh Parameter to return enum of the current observation receive + * path powered up + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_PU_GETOBSRXPATH_ARMERROR ARM returned an error while trying to get the ObsRx Path source + */ +mykonosErr_t MYKONOS_getObsRxPathSource(mykonosDevice_t *device, mykonosObsRxChannels_t *obsRxCh) +{ + uint8_t extData[1] = {MYKONOS_ARM_OBJECTID_ORX_MODE}; + uint8_t cmdStatusByte = 0; + uint8_t armData[1] = {0}; + uint32_t timeoutMs = 0; + mykonosErr_t retVal = MYKONOS_ERR_OK; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getObsRxPathSource()\n"); +#endif + + retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_GET_OPCODE, &extData[0], sizeof(extData)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + timeoutMs = 1000; + retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_GET_OPCODE, timeoutMs, &cmdStatusByte); + if (retVal != MYKONOS_ERR_OK) + { + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_PU_GETOBSRXPATH_ARMERROR, + getMykonosErrorMessage(MYKONOS_ERR_PU_GETOBSRXPATH_ARMERROR)); + return MYKONOS_ERR_PU_GETOBSRXPATH_ARMERROR; + } + + return retVal; + } + + /* read 64-bit frequency from ARM memory */ + retVal = MYKONOS_readArmMem(device, MYKONOS_ADDR_ARM_START_DATA_ADDR, &armData[0], 1, 1); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_PU_GETOBSRXPATH_ARMERROR, + getMykonosErrorMessage(MYKONOS_ERR_PU_GETOBSRXPATH_ARMERROR)); + return MYKONOS_ERR_PU_GETOBSRXPATH_ARMERROR; + } + + *obsRxCh = (mykonosObsRxChannels_t)(armData[0]); + + return MYKONOS_ERR_OK; +} + +/** + * \brief Sets the Rx gain of the ObsRx channel + * + * The ObsRx channel can have different RF inputs (ORx1/ORx2/SnRx A,B,C) + * This function sets the ObsRx gain index independently for ORx1/ORx2, or SnRx. + * SnRx A, B, and C share the same gain index. Please note that ORx1/ORx2 share a gain + * table, as does SnRx A, B, and C. The maximum index is 255 + * and the minimum index is application specific. + * + * Dependencies + * - device->spiSettings + * - device->obsRx->orxGainCtrl->maxGainIndex + * - device->obsRx->orxGainCtrl->minGainIndex + * - device->obsRx->orxGainCtrl->orx1GainIndex + * - device->obsRx->orxGainCtrl->orx2GainIndex + * - device->obsRx->snifferGainCtrl->maxGainIndex + * - device->obsRx->snifferGainCtrl->minGainIndex + * - device->obsRx->snifferGainCtrl->gainIndex + * + * \param device Pointer to the Mykonos device data structure + * \param obsRxCh is an enum type mykonosObsRxChannels_t to identify the desired RF input for gain change + * \param gainIndex Desired manual gain table index to set + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_SETORXGAIN_INV_ORX1GAIN Invalid gain requested for ORx1: outside gain table min/max index + * \retval MYKONOS_ERR_SETORXGAIN_INV_ORX2GAIN Invalid gain requested for ORx2: outside gain table min/max index + * \retval MYKONOS_ERR_SETORXGAIN_INV_SNRXGAIN Invalid gain requested for Sniffer: outside gain table min/max index + * \retval MYKONOS_ERR_SETORXGAIN_INV_CHANNEL Function parameter obsRxCh has an invalid enum value + */ +mykonosErr_t MYKONOS_setObsRxManualGain(mykonosDevice_t *device, mykonosObsRxChannels_t obsRxCh, uint8_t gainIndex) +{ + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setObsRxManualGain()\n"); +#endif + + if ((obsRxCh == OBS_RX1_TXLO) || (obsRxCh == OBS_RX1_SNIFFERLO)) + { + if (gainIndex <= device->obsRx->orxGainCtrl->maxGainIndex && gainIndex >= device->obsRx->orxGainCtrl->minGainIndex) + { + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_ORX1_MANUAL_GAIN_INDEX, (gainIndex - MIN_ORX_GAIN_TABLE_INDEX)); + device->obsRx->orxGainCtrl->orx1GainIndex = gainIndex; + } + else + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETORXGAIN_INV_ORX1GAIN, + getMykonosErrorMessage(MYKONOS_ERR_SETORXGAIN_INV_ORX1GAIN)); + return MYKONOS_ERR_SETORXGAIN_INV_ORX1GAIN; + } + } + else if ((obsRxCh == OBS_RX2_TXLO) || (obsRxCh == OBS_RX2_SNIFFERLO)) + { + if (gainIndex <= device->obsRx->orxGainCtrl->maxGainIndex && gainIndex >= device->obsRx->orxGainCtrl->minGainIndex) + { + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_ORX2_MANUAL_GAIN_INDEX, (gainIndex - MIN_ORX_GAIN_TABLE_INDEX)); + device->obsRx->orxGainCtrl->orx2GainIndex = gainIndex; + } + else + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETORXGAIN_INV_ORX2GAIN, + getMykonosErrorMessage(MYKONOS_ERR_SETORXGAIN_INV_ORX2GAIN)); + return MYKONOS_ERR_SETORXGAIN_INV_ORX2GAIN; + } + + } + else if (obsRxCh == OBS_SNIFFER_A || obsRxCh == OBS_SNIFFER_B || obsRxCh == OBS_SNIFFER_C || obsRxCh == OBS_SNIFFER) + { + if (gainIndex <= device->obsRx->snifferGainCtrl->maxGainIndex && gainIndex >= device->obsRx->snifferGainCtrl->minGainIndex) + { + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SNRX_MANUAL_GAIN_INDEX, (gainIndex - MIN_SNRX_GAIN_TABLE_INDEX)); + device->obsRx->snifferGainCtrl->gainIndex = gainIndex; + } + else + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETORXGAIN_INV_SNRXGAIN, + getMykonosErrorMessage(MYKONOS_ERR_SETORXGAIN_INV_SNRXGAIN)); + return MYKONOS_ERR_SETORXGAIN_INV_SNRXGAIN; + } + } + else + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETORXGAIN_INV_CHANNEL, + getMykonosErrorMessage(MYKONOS_ERR_SETORXGAIN_INV_CHANNEL)); + return MYKONOS_ERR_SETORXGAIN_INV_CHANNEL; + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief Gets the gain index of the currently enabled ObsRx channel + * + * The ObsRx data path can have multiple RF sources. This function will + * read back the gain index of the currently enabled RF source. If the ObsRx + * data path is disabled, an error is returned. If the functions uint8_t *gainIndex + * parameter is a valid pointer, the gain index is returned at the pointers + * address. Else, if the uint8_t *gainIndex pointer is NULL, the gainIndex read back + * is stored in the device data structure. + * + * NOTE: if the observation source is chosen by ORX_MODE pins, it is possible that + * the readback value will be incorrect if the obsRx channel changes while this function + * reads the gain. + * + * Dependencies + * - device->spiSettings + * - device->profilesValid + * - device->obsRx->orxGainCtrl->orx1GainIndex + * - device->obsRx->orxGainCtrl->orx2GainIndex + * - device->obsRx->snifferGainCtrl->gainIndex + * + * \param device Pointer to the Mykonos device data structure + * \param gainIndex Return value of the current gain index for the currently enabled ObsRx channel. + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_GETORX1GAIN_INV_POINTER The ObsRx profile is not valid in the device data structure + * \retval MYKONOS_ERR_GETORX2GAIN_INV_POINTER The ObsRx profile is not valid in the device data structure + * \retval MYKONOS_ERR_GETSNIFFGAIN_INV_POINTER The sniffer profile is not valid in the device data structure + * \retval MYKONOS_ERR_GETOBSRXGAIN_CH_DISABLED The observation receiver is currently disabled, can not read back gain index. + */ +mykonosErr_t MYKONOS_getObsRxGain(mykonosDevice_t *device, uint8_t *gainIndex) +{ + /* Potential issue, if ARM is using loopback path when this function is called, it will likely readback loopback gain */ + uint8_t readObsRxPathEnabled = 0; + uint8_t readObsRxGain = 0; + + const uint8_t ORX1_EN = 0x01; + const uint8_t ORX2_EN = 0x02; + const uint8_t SNRX_EN = 0x04; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getObsRxGain()\n"); +#endif + + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_DPD_SNIFFER_CONFIGURATION_CONTROL_1, &readObsRxPathEnabled); + + /* If obsRx channel enabled, then read gain index */ + if (readObsRxPathEnabled > 0) + { + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GAIN_CTL_ORX_SNRX_GAIN, &readObsRxGain); + + switch (readObsRxPathEnabled) + { + case 0x01: + readObsRxGain += MIN_ORX_GAIN_TABLE_INDEX; + break; + case 0x02: + readObsRxGain += MIN_ORX_GAIN_TABLE_INDEX; + break; + case 0x04: + readObsRxGain += MIN_SNRX_GAIN_TABLE_INDEX; + break; + default: + break; + } + + if (gainIndex != NULL) + { + *gainIndex = readObsRxGain; + } + + /* Store the gain index in the device's gain control data structure. */ + + if (readObsRxPathEnabled == ORX1_EN) + { + /* verify valid data structure pointers */ + if (device->profilesValid & ORX_PROFILE_VALID) + { + device->obsRx->orxGainCtrl->orx1GainIndex = readObsRxGain; + } + else + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETORX1GAIN_INV_POINTER, + getMykonosErrorMessage(MYKONOS_ERR_GETORX1GAIN_INV_POINTER)); + return MYKONOS_ERR_GETORX1GAIN_INV_POINTER; + } + + } + else if (readObsRxPathEnabled == ORX2_EN) + { + /* verify valid pointers */ + if (device->profilesValid & ORX_PROFILE_VALID) + { + device->obsRx->orxGainCtrl->orx2GainIndex = readObsRxGain; + } + else + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETORX2GAIN_INV_POINTER, + getMykonosErrorMessage(MYKONOS_ERR_GETORX2GAIN_INV_POINTER)); + return MYKONOS_ERR_GETORX2GAIN_INV_POINTER; + } + + } + else if (readObsRxPathEnabled == SNRX_EN) + { + /* verify valid pointers */ + if (device->profilesValid & SNIFF_PROFILE_VALID) + { + device->obsRx->snifferGainCtrl->gainIndex = readObsRxGain; + } + else + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETSNIFFGAIN_INV_POINTER, + getMykonosErrorMessage(MYKONOS_ERR_GETSNIFFGAIN_INV_POINTER)); + return MYKONOS_ERR_GETSNIFFGAIN_INV_POINTER; + } + } + else + { + /* ignore gain index for Tx loopback input into obsRx channel */ + } + } + else + { + CMB_writeToLog(ADIHAL_LOG_WARNING, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETOBSRXGAIN_CH_DISABLED, + getMykonosErrorMessage(MYKONOS_ERR_GETOBSRXGAIN_CH_DISABLED)); + return MYKONOS_ERR_GETOBSRXGAIN_CH_DISABLED; + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief Sets up the device ObsRx Automatic Gain Control (AGC) registers. + * + * Three data structures (of types mykonosAgcCfg_t, mykonosPeakDetAgcCfg_t, mykonosPowerMeasAgcCfg_t) + * must be instantiated prior to calling this function. Valid ranges for data structure members + * must also be provided. + * + * + * Dependencies: + * - device->spiSettings + * - device->spiSettings->chipSelectIndex + * - device->obsRx->orxAgcCtrl->agcRx1MaxGainIndex + * - device->obsRx->orxAgcCtrl->agcRx1MinGainIndex + * - device->obsRx->orxAgcCtrl->agcRx2MaxGainIndex + * - device->obsRx->orxAgcCtrl->agcRx2MinGainIndex + * - device->obsRx->orxAgcCtrl->agcObsRxMaxGainIndex + * - device->obsRx->orxAgcCtrl->agcObsRxMinGainIndex + * - device->obsRx->orxAgcCtrl->agcObsRxSelect + * - device->obsRx->orxAgcCtrl->agcPeakThresholdMode + * - device->obsRx->orxAgcCtrl->agcLowThsPreventGainIncrease + * - device->obsRx->orxAgcCtrl->agcGainUpdateCounter + * - device->obsRx->orxAgcCtrl->agcSlowLoopSettlingDelay + * - device->obsRx->orxAgcCtrl->agcPeakWaitTime + * - device->obsRx->orxAgcCtrl->agcResetOnRxEnable + * - device->obsRx->orxAgcCtrl->agcEnableSyncPulseForGainCounter + * - device->obsRx->orxAgcCtrl->peakAgc->apdHighThresh + * - device->obsRx->orxAgcCtrl->peakAgc->apdLowThresh + * - device->obsRx->orxAgcCtrl->peakAgc->hb2HighThresh + * - device->obsRx->orxAgcCtrl->peakAgc->hb2LowThresh + * - device->obsRx->orxAgcCtrl->peakAgc->hb2VeryLowThresh + * - device->obsRx->orxAgcCtrl->peakAgc->apdHighThreshExceededCnt + * - device->obsRx->orxAgcCtrl->peakAgc->apdLowThreshExceededCnt + * - device->obsRx->orxAgcCtrl->peakAgc->hb2HighThreshExceededCnt + * - device->obsRx->orxAgcCtrl->peakAgc->hb2LowThreshExceededCnt + * - device->obsRx->orxAgcCtrl->peakAgc->hb2VeryLowThreshExceededCnt + * - device->obsRx->orxAgcCtrl->peakAgc->apdHighGainStepAttack + * - device->obsRx->orxAgcCtrl->peakAgc->apdLowGainStepRecovery + * - device->obsRx->orxAgcCtrl->peakAgc->hb2HighGainStepAttack + * - device->obsRx->orxAgcCtrl->peakAgc->hb2LowGainStepRecovery + * - device->obsRx->orxAgcCtrl->peakAgc->hb2VeryLowGainStepRecovery + * - device->obsRx->orxAgcCtrl->peakAgc->apdFastAttack + * - device->obsRx->orxAgcCtrl->peakAgc->hb2FastAttack + * - device->obsRx->orxAgcCtrl->peakAgc->hb2OverloadDetectEnable + * - device->obsRx->orxAgcCtrl->peakAgc->hb2OverloadDurationCnt + * - device->obsRx->orxAgcCtrl->peakAgc->hb2OverloadThreshCnt + * - device->obsRx->orxAgcCtrl->powerAgc->pmdUpperHighThresh + * - device->obsRx->orxAgcCtrl->powerAgc->pmdUpperLowThresh + * - device->obsRx->orxAgcCtrl->powerAgc->pmdLowerHighThresh + * - device->obsRx->orxAgcCtrl->powerAgc->pmdLowerLowThresh + * - device->obsRx->orxAgcCtrl->powerAgc->pmdUpperHighGainStepAttack + * - device->obsRx->orxAgcCtrl->powerAgc->pmdUpperLowGainStepAttack + * - device->obsRx->orxAgcCtrl->powerAgc->pmdLowerHighGainStepRecovery + * - device->obsRx->orxAgcCtrl->powerAgc->pmdLowerLowGainStepRecovery + * - device->obsRx->orxAgcCtrl->powerAgc->pmdMeasDuration + * - device->obsRx->orxAgcCtrl->powerAgc->pmdMeasConfig + * + * \param device is structure pointer to the Mykonos data structure containing settings + * The pointer to the Mykonos AGC data structure containing settings is checked for a null pointer + * to ensure it has been initialized. If not an error is thrown. + * + * \retval Returns MYKONOS_ERR=pass, !MYKONOS_ERR=fail + * \retval MYKONOS_ERR_INV_AGC_OBSRX_STRUCT_INIT + * \retval MYKONOS_ERR_INV_AGC_OBSRX_PEAK_STRUCT_INIT + * \retval MYKONOS_ERR_INV_AGC_OBSRX_PWR_STRUCT_INIT + * \retval MYKONOS_ERR_INV_AGC_OBSRX_MAX_GAIN_INDEX + * \retval MYKONOS_ERR_INV_AGC_OBSRX_MIN_GAIN_INDEX + * \retval MYKONOS_ERR_INV_AGC_OBSRX_SELECT + * \retval MYKONOS_ERR_INV_AGC_OBSRX_GAIN_UPDATE_TIME_PARM + * \retval MYKONOS_ERR_INV_AGC_OBSRX_PEAK_WAIT_TIME_PARM + * \retval MYKONOS_ERR_INV_AGC_OBSRX_SLOW_LOOP_SETTLING_DELAY + * \retval MYKONOS_ERR_INV_AGC_OBSRX_PMD_MEAS_DURATION + * \retval MYKONOS_ERR_INV_AGC_OBSRX_PMD_MEAS_CONFIG + * \retval MYKONOS_ERR_INV_AGC_OBSRX_LOW_THS_PREV_GAIN_INC + * \retval MYKONOS_ERR_INV_AGC_OBSRX_PEAK_THRESH_MODE + * \retval MYKONOS_ERR_INV_AGC_OBSRX_RESET_ON_RX_ENABLE + * \retval MYKONOS_ERR_INV_AGC_OBSRX_ENABLE_SYNC_PULSE_GAIN_COUNTER + * \retval MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_HIGH_THRESH + * \retval MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_LOW_THRESH + * \retval MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_LOW_THRESH + * \retval MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_HIGH_THRESH + * \retval MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_HIGH_GAIN_STEP + * \retval MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_LOW_GAIN_STEP + * \retval MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_LOW_GAIN_STEP + * \retval MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_HIGH_GAIN_STEP + * \retval MYKONOS_ERR_INV_AGC_OBSRX_PKDET_FAST_ATTACK_VALUE + * \retval MYKONOS_ERR_INV_AGC_OBSRX_APD_HIGH_THRESH_PARM + * \retval MYKONOS_ERR_INV_AGC_OBSRX_APD_LOW_THRESH_PARM + * \retval MYKONOS_ERR_INV_AGC_OBSRX_HB2_HIGH_THRESH_PARM + * \retval MYKONOS_ERR_INV_AGC_OBSRX_HB2_LOW_THRESH_PARM + * \retval MYKONOS_ERR_INV_AGC_OBSRX_HB2_VERY_LOW_THRESH_PARM + * \retval MYKONOS_ERR_INV_AGC_OBSRX_APD_HIGH_GAIN_STEP_PARM + * \retval MYKONOS_ERR_INV_AGC_OBSRX_APD_LOW_GAIN_STEP_PARM + * \retval MYKONOS_ERR_INV_AGC_OBSRX_HB2_HIGH_GAIN_STEP_PARM + * \retval MYKONOS_ERR_INV_AGC_OBSRX_HB2_LOW_GAIN_STEP_PARM + * \retval MYKONOS_ERR_INV_AGC_OBSRX_HB2_VERY_LOW_GAIN_STEP_PARM + * \retval MYKONOS_ERR_INV_AGC_OBSRX_HB2_OVLD_ENABLE + * \retval MYKONOS_ERR_INV_AGC_OBSRX_HB2_OVLD_DUR_CNT + * \retval MYKONOS_ERR_INV_AGC_OBSRX_HB2_OVLD_THRESH_CNT + */ +mykonosErr_t MYKONOS_setupObsRxAgc(mykonosDevice_t *device) +{ + /* Current configuration does not support AGC on ORx channel */ + uint8_t decPowerConfig = 0; + uint8_t lower1ThreshGainStepRegValue = 0; + uint8_t powerThresholdsRegValue = 0; + uint8_t hb2OvldCfgRegValue = 0; + uint8_t agcGainUpdateCtr[3] = {0}; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setupObsRxAgc()\n"); +#endif + + /* Check mykonosAgcCfg_t device->obsRx->orxAgcCtrl pointer for initialization */ + if (device->obsRx->orxAgcCtrl == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_STRUCT_INIT, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_STRUCT_INIT)); + return MYKONOS_ERR_INV_AGC_OBSRX_STRUCT_INIT; + } + + /* Check mykonosPeakDetAgcCfg_t device->orx->orxAgcCtrl->peakAgc pointer for initialization */ + if (device->obsRx->orxAgcCtrl->peakAgc == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_PEAK_STRUCT_INIT, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_PEAK_STRUCT_INIT)); + return MYKONOS_ERR_INV_AGC_OBSRX_PEAK_STRUCT_INIT; + } + + /* Check mykonosPowerMeasAgcCfg_t device->obsRx->orxAgcCtrl->powerAgc pointer for initialization */ + if (device->obsRx->orxAgcCtrl->powerAgc == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_PWR_STRUCT_INIT, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_PWR_STRUCT_INIT)); + return MYKONOS_ERR_INV_AGC_OBSRX_PWR_STRUCT_INIT; + } + + /* Range check agcObsRxMaxGainIndex versus gain table limits and agcObsRxMinGainIndex */ + if ((device->obsRx->orxAgcCtrl->agcObsRxMaxGainIndex > device->obsRx->snifferGainCtrl->maxGainIndex) || + (device->obsRx->orxAgcCtrl->agcObsRxMaxGainIndex < device->obsRx->orxAgcCtrl->agcObsRxMinGainIndex)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_MAX_GAIN_INDEX, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_MAX_GAIN_INDEX)); + return MYKONOS_ERR_INV_AGC_OBSRX_MAX_GAIN_INDEX; + } + else + { + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_ORX_SNRX_MAX_GAIN_INDEX, + (device->obsRx->orxAgcCtrl->agcObsRxMaxGainIndex - MAX_SNRX_GAIN_TABLE_NUMINDEXES)); + } + + /* Range check agcObsRxMinGainIndex versus gain table limits and agcObsRxMaxGainIndex */ + if ((device->obsRx->orxAgcCtrl->agcObsRxMinGainIndex < device->obsRx->snifferGainCtrl->minGainIndex) || + (device->obsRx->orxAgcCtrl->agcObsRxMaxGainIndex < device->obsRx->orxAgcCtrl->agcObsRxMinGainIndex)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_MIN_GAIN_INDEX, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_MIN_GAIN_INDEX)); + return MYKONOS_ERR_INV_AGC_OBSRX_MIN_GAIN_INDEX; + } + else + { + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_ORX_SNRX_MIN_GAIN_INDEX, + (device->obsRx->orxAgcCtrl->agcObsRxMinGainIndex - MAX_SNRX_GAIN_TABLE_NUMINDEXES)); + } + + /* Range check agcObsRxSelect. Sniffer only support. Sniffer is selected if value is 0 or 1. 2 or 3 select ORx1/ORx2 respectively */ + if (device->obsRx->orxAgcCtrl->agcObsRxSelect > 1) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_SELECT, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_SELECT)); + return MYKONOS_ERR_INV_AGC_OBSRX_SELECT; + } + else + { + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_ORX_SNRX_ACTIVE, device->obsRx->orxAgcCtrl->agcObsRxSelect); + } + + /* Range check for agcGainUpdateCounter (22-bit) */ + if ((device->obsRx->orxAgcCtrl->agcGainUpdateCounter > 0x3FFFFF) || + (device->obsRx->orxAgcCtrl->agcGainUpdateCounter < 1)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_GAIN_UPDATE_TIME_PARM, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_GAIN_UPDATE_TIME_PARM)); + return MYKONOS_ERR_INV_AGC_OBSRX_GAIN_UPDATE_TIME_PARM; + } + else + { + /* Split agcGainUpdateCounter into three values */ + agcGainUpdateCtr[0] = (uint8_t)(device->obsRx->orxAgcCtrl->agcGainUpdateCounter); + agcGainUpdateCtr[1] = (uint8_t)(device->obsRx->orxAgcCtrl->agcGainUpdateCounter >> 8); + agcGainUpdateCtr[2] = (uint8_t)(device->obsRx->orxAgcCtrl->agcGainUpdateCounter >> 16); + + /* Write two bytes directly due. Third word has its upper two bits masked off. */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_GAIN_UPDATE_CTR_1, agcGainUpdateCtr[0]); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_GAIN_UPDATE_CTR_2, agcGainUpdateCtr[1]); + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_GAIN_UPDATE_CTR_3, agcGainUpdateCtr[2], 0x3F, 0); + } + + /* Range check on agcPeakWaitTime (5-bit) */ + if ((device->obsRx->orxAgcCtrl->agcPeakWaitTime > 0x1F) || + (device->obsRx->orxAgcCtrl->agcPeakWaitTime < 0x02)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_PEAK_WAIT_TIME_PARM, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_PEAK_WAIT_TIME_PARM)); + return MYKONOS_ERR_INV_AGC_OBSRX_PEAK_WAIT_TIME_PARM; + } + else + { + /* Write agcPeakWaitTime */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_ORX_SNRX_CFG_2, device->obsRx->orxAgcCtrl->agcPeakWaitTime, 0x1F, 0); + } + + /* Range check for agcSlowLoopSettlingDelay (7-bit) */ + if (device->obsRx->orxAgcCtrl->agcSlowLoopSettlingDelay > 0x7F) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_SLOW_LOOP_SETTLING_DELAY, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_SLOW_LOOP_SETTLING_DELAY)); + return MYKONOS_ERR_INV_AGC_OBSRX_SLOW_LOOP_SETTLING_DELAY; + } + else + { + /* Write agcSlowLoopSettlingDelay */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_LOOP_CFG, device->obsRx->orxAgcCtrl->agcSlowLoopSettlingDelay, 0x7F, 0); + } + + /* Range check for pmdMeasDuration */ + if ((uint32_t)(1 << (3 + device->obsRx->orxAgcCtrl->powerAgc->pmdMeasDuration)) >= (device->obsRx->orxAgcCtrl->agcGainUpdateCounter)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_PMD_MEAS_DURATION, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_PMD_MEAS_DURATION)); + return MYKONOS_ERR_INV_AGC_OBSRX_PMD_MEAS_DURATION; + } + else + { + /* Write pmdMeasDuration */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_SNIFFER_DEC_POWER_CONFIG_2, device->obsRx->orxAgcCtrl->powerAgc->pmdMeasDuration, 0x0F, 0); + } + + /* Range check for pmdMeasConfig */ + if (device->obsRx->orxAgcCtrl->powerAgc->pmdMeasConfig > 0x3) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_PMD_MEAS_CONFIG, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_PMD_MEAS_CONFIG)); + return MYKONOS_ERR_INV_AGC_OBSRX_PMD_MEAS_CONFIG; + } + else + { + if (device->obsRx->orxAgcCtrl->powerAgc->pmdMeasConfig == 0) + { + decPowerConfig = 0x0; /* Dec Pwr measurement disable */ + } + else if (device->obsRx->orxAgcCtrl->powerAgc->pmdMeasConfig == 1) + { + decPowerConfig = 0x3; /* Dec Pwr measurement enable, HB2 for decPwr measurement */ + } + else if (device->obsRx->orxAgcCtrl->powerAgc->pmdMeasConfig == 2) + { + decPowerConfig = 0x5; /* Dec Pwr measurement enable, RFIR for decPwr measurement */ + } + else if (device->obsRx->orxAgcCtrl->powerAgc->pmdMeasConfig == 3) + { + decPowerConfig = 0x11; /* Dec Pwr measurement enable, BBDC2 for decPwr measurement */ + } + /* Write pmdMeasConfig */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_SNIFFER_DEC_POWER_CONFIG_1, decPowerConfig); + } + + /* Range check agcLowThsPreventGainIncrease (1-bit) */ + if (device->obsRx->orxAgcCtrl->agcLowThsPreventGainIncrease > 1) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_LOW_THS_PREV_GAIN_INC, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_LOW_THS_PREV_GAIN_INC)); + return MYKONOS_ERR_INV_AGC_OBSRX_LOW_THS_PREV_GAIN_INC; + } + else + { + /* Write agcLowThsPreventGainIncrease */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_LOCK_LEV_THRSH, device->obsRx->orxAgcCtrl->agcLowThsPreventGainIncrease, 0x80, 7); + } + + /* Range check agcPeakThresholdMode (1-bit), */ + if (device->obsRx->orxAgcCtrl->agcPeakThresholdMode > 1) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_PEAK_THRESH_MODE, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_PEAK_THRESH_MODE)); + return MYKONOS_ERR_INV_AGC_OBSRX_PEAK_THRESH_MODE; + } + else + { + /* Save to lower1ThreshGainStepRegValue register variable */ + lower1ThreshGainStepRegValue |= (uint8_t)(device->obsRx->orxAgcCtrl->agcPeakThresholdMode << 5); + } + + /* Range check agcResetOnRxEnable (1-bit) */ + if (device->obsRx->orxAgcCtrl->agcResetOnRxEnable > 1) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_RESET_ON_RX_ENABLE, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_RESET_ON_RX_ENABLE)); + return MYKONOS_ERR_INV_AGC_OBSRX_RESET_ON_RX_ENABLE; + } + else + { + /* Write agcResetOnRxEnable */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_GAIN_UPDATE_CTR_3, (uint8_t)(device->obsRx->orxAgcCtrl->agcResetOnRxEnable << 7), 0x80, 0); + } + + /* Range check agcEnableSyncPulseForGainCounter (1-bit) */ + if (device->obsRx->orxAgcCtrl->agcEnableSyncPulseForGainCounter > 1) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_ENABLE_SYNC_PULSE_GAIN_COUNTER, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_ENABLE_SYNC_PULSE_GAIN_COUNTER)); + return MYKONOS_ERR_INV_AGC_OBSRX_ENABLE_SYNC_PULSE_GAIN_COUNTER; + } + else + { + /* Write agcEnableSyncPulseForGainCounter */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_LOOP_CFG, (uint8_t)(device->obsRx->orxAgcCtrl->agcEnableSyncPulseForGainCounter << 7), 0x80, 0); + } + + /* WRITE REGISTERS FOR THE AGC POWER MEASUREMENT DETECTOR (PMD) STRUCTURE */ + + /* Range check pmdLowerHighThresh (7-bit) vs 0x7F and pmdUpperLowThresh */ + if ((device->obsRx->orxAgcCtrl->powerAgc->pmdLowerHighThresh <= device->obsRx->orxAgcCtrl->powerAgc->pmdUpperLowThresh) || + device->obsRx->orxAgcCtrl->powerAgc->pmdLowerHighThresh > 0x7F) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_HIGH_THRESH, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_HIGH_THRESH)); + return MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_HIGH_THRESH; + } + else + { + /* Write pmdLowerHighThresh */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_LOCK_LEV_THRSH, device->obsRx->orxAgcCtrl->powerAgc->pmdLowerHighThresh, 0x7F, 0); + } + + /* Range check pmdUpperLowThresh (7-bit): Comparison to pmdLowerHigh done earlier */ + if (device->obsRx->orxAgcCtrl->powerAgc->pmdUpperLowThresh > 0x7F) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_LOW_THRESH, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_LOW_THRESH)); + return MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_LOW_THRESH; + } + else + { + /* Write pmdUpperLowThresh */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_ORX_SNRX_LOCK_LEVEL, device->obsRx->orxAgcCtrl->powerAgc->pmdUpperLowThresh); + } + + /* Range check pmdLowerLowThresh (4-bit) */ + if (device->obsRx->orxAgcCtrl->powerAgc->pmdLowerLowThresh > 0xF) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_LOW_THRESH, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_LOW_THRESH)); + return MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_LOW_THRESH; + } + else + { + /* Write pmdUpperLowThresh to temp variable */ + powerThresholdsRegValue |= device->obsRx->orxAgcCtrl->powerAgc->pmdLowerLowThresh; + } + + /* Range check pmdUpperHighThresh (4-bit) */ + if (device->obsRx->orxAgcCtrl->powerAgc->pmdUpperHighThresh > 0xF) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_HIGH_THRESH, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_HIGH_THRESH)); + return MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_HIGH_THRESH; + } + else + { + /* Write pmdUpperHighThresh to temp var, then to register */ + powerThresholdsRegValue |= (uint8_t)(device->obsRx->orxAgcCtrl->powerAgc->pmdUpperHighThresh << 4); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_POWER_THRSH, powerThresholdsRegValue); + } + + /* Range check pmdUpperHighGainStepAttack (5-bit) */ + if (device->obsRx->orxAgcCtrl->powerAgc->pmdUpperHighGainStepAttack > 0x1F) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_HIGH_GAIN_STEP, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_HIGH_GAIN_STEP)); + return MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_HIGH_GAIN_STEP; + } + else + { + /* Write pmdUpperHighGainStepAttack */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_UPPER1_THRSH_GAIN_STEP, device->obsRx->orxAgcCtrl->powerAgc->pmdUpperHighGainStepAttack, 0x1F, 0); + } + + /* Range check pmdLowerLowGainStepRecovery (5-bit) */ + if (device->obsRx->orxAgcCtrl->powerAgc->pmdLowerLowGainStepRecovery > 0x1F) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_LOW_GAIN_STEP, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_LOW_GAIN_STEP)); + return MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_LOW_GAIN_STEP; + } + else + { + /* Write pmdLowerLowGainStepRecovery to temp var, then to register */ + lower1ThreshGainStepRegValue |= (uint8_t)(device->obsRx->orxAgcCtrl->powerAgc->pmdLowerLowGainStepRecovery); + } + + /* Range check pmdUpperLowGainStepRecovery (5-bit) */ + if (device->obsRx->orxAgcCtrl->powerAgc->pmdUpperLowGainStepAttack > 0x1F) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_LOW_GAIN_STEP, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_LOW_GAIN_STEP)); + return MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_LOW_GAIN_STEP; + } + else + { + /* Write pmdUpperLowGainStepRecovery to register */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_UPPER0_THRSH_GAIN_STEP, device->obsRx->orxAgcCtrl->powerAgc->pmdUpperLowGainStepAttack); + } + + /* Range check pmdLowerHighGainStepRecovery (5-bit) */ + if (device->obsRx->orxAgcCtrl->powerAgc->pmdLowerHighGainStepRecovery > 0x1F) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_HIGH_GAIN_STEP, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_HIGH_GAIN_STEP)); + return MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_HIGH_GAIN_STEP; + } + else + { + /* Write pmdLowerLowGainStepRecovery to temp var, then to register */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_LOWER0_THRSH_GAIN_STEP, device->obsRx->orxAgcCtrl->powerAgc->pmdLowerHighGainStepRecovery); + } + + /* WRITE REGISTERS FOR THE AGC PEAK DETECTOR (APD/HB2) STRUCTURE */ + + /* Range check apdFastAttack and hb2FastAttack (1-bit) */ + if ((device->obsRx->orxAgcCtrl->peakAgc->apdFastAttack > 0x1) || + (device->obsRx->orxAgcCtrl->peakAgc->hb2FastAttack > 0x1)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_PKDET_FAST_ATTACK_VALUE, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_PKDET_FAST_ATTACK_VALUE)); + return MYKONOS_ERR_INV_AGC_OBSRX_PKDET_FAST_ATTACK_VALUE; + } + else + { + /* Write pmdLowerLowGainStepRecovery to temp var, then to register */ + lower1ThreshGainStepRegValue |= (uint8_t)(device->obsRx->orxAgcCtrl->peakAgc->apdFastAttack << 7); + lower1ThreshGainStepRegValue |= (uint8_t)(device->obsRx->orxAgcCtrl->peakAgc->hb2FastAttack << 6); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_LOWER1_THRSH_GAIN_STEP, lower1ThreshGainStepRegValue); + } + + /* Range check apdHighThresh */ + if ((device->obsRx->orxAgcCtrl->peakAgc->apdHighThresh > 0x3F) || + (device->obsRx->orxAgcCtrl->peakAgc->apdHighThresh <= device->obsRx->orxAgcCtrl->peakAgc->apdLowThresh)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_APD_HIGH_THRESH_PARM, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_APD_HIGH_THRESH_PARM)); + return MYKONOS_ERR_INV_AGC_OBSRX_APD_HIGH_THRESH_PARM; + } + else + { + /* Write apdHighThresh */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_ORX_SNRX_ULB_THRSH, device->obsRx->orxAgcCtrl->peakAgc->apdHighThresh, 0X3F, 0); + } + + /* Range check apdLowThresh */ + if ((device->obsRx->orxAgcCtrl->peakAgc->apdLowThresh > 0x3F) || + (device->obsRx->orxAgcCtrl->peakAgc->apdHighThresh < device->obsRx->orxAgcCtrl->peakAgc->apdLowThresh)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_APD_LOW_THRESH_PARM, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_APD_LOW_THRESH_PARM)); + return MYKONOS_ERR_INV_AGC_OBSRX_APD_LOW_THRESH_PARM; + } + else + { + /* write apdLowThresh */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_ORX_SNRX_LLB_THRSH, device->obsRx->orxAgcCtrl->peakAgc->apdLowThresh, 0x3F, 0); + } + + /* Range check hb2HighThresh */ + if (device->obsRx->orxAgcCtrl->peakAgc->hb2HighThresh < device->obsRx->orxAgcCtrl->peakAgc->hb2LowThresh) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_HB2_HIGH_THRESH_PARM, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_HB2_HIGH_THRESH_PARM)); + return MYKONOS_ERR_INV_AGC_OBSRX_HB2_HIGH_THRESH_PARM; + } + else + { + /* write hb2HighThresh */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ORX_SNRX_OVRLD_PD_DEC_OVRLD_UPPER_THRSH, device->obsRx->orxAgcCtrl->peakAgc->hb2HighThresh); + } + + /* Range check hb2LowThresh */ + if (device->obsRx->orxAgcCtrl->peakAgc->hb2LowThresh > device->obsRx->orxAgcCtrl->peakAgc->hb2HighThresh) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_HB2_LOW_THRESH_PARM, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_HB2_LOW_THRESH_PARM)); + return MYKONOS_ERR_INV_AGC_OBSRX_HB2_LOW_THRESH_PARM; + } + else + { + /* write hb2LowThresh */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ORX_SNRX_OVRLD_PD_DEC_OVRLD_LOWER_THRSH, device->obsRx->orxAgcCtrl->peakAgc->hb2LowThresh); + } + + /* Range check hb2VeryLowThresh */ + if (device->obsRx->orxAgcCtrl->peakAgc->hb2VeryLowThresh > device->obsRx->orxAgcCtrl->peakAgc->hb2LowThresh) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_HB2_VERY_LOW_THRESH_PARM, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_HB2_VERY_LOW_THRESH_PARM)); + return MYKONOS_ERR_INV_AGC_OBSRX_HB2_VERY_LOW_THRESH_PARM; + } + else + { + /* write hb2VeryLowThresh */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ORX_SNRX_OVRLD_PD_DEC_OVRLD_VERYLOW_THRSH, device->obsRx->orxAgcCtrl->peakAgc->hb2VeryLowThresh); + } + + /* Write threshold counter values for apdHigh/apdLow/hb2High/hb2Low/hb2VeryLow */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_ULB_CNT_THRSH, device->obsRx->orxAgcCtrl->peakAgc->apdHighThreshExceededCnt); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_LLB_CNT_THRSH, device->obsRx->orxAgcCtrl->peakAgc->apdLowThreshExceededCnt); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_ADC_HIGH_OVRG_CNT_THRSH, device->obsRx->orxAgcCtrl->peakAgc->hb2HighThreshExceededCnt); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_ADC_LOW_OVRG_CNT_THRSH, device->obsRx->orxAgcCtrl->peakAgc->hb2LowThreshExceededCnt); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_ADC_VERYLOW_OVRG_CNT_THRSH, device->obsRx->orxAgcCtrl->peakAgc->hb2VeryLowThreshExceededCnt); + + /* Range check on apdHighGainStepAttack (5-bit) */ + if (device->obsRx->orxAgcCtrl->peakAgc->apdHighGainStepAttack > 0x1F) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_APD_HIGH_GAIN_STEP_PARM, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_APD_HIGH_GAIN_STEP_PARM)); + return MYKONOS_ERR_INV_AGC_OBSRX_APD_HIGH_GAIN_STEP_PARM; + } + else + { + /* Write apdHighGainStepAttack */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_ORX_SNRX_OVRG_GAIN_STEP_1, device->obsRx->orxAgcCtrl->peakAgc->apdHighGainStepAttack); + } + + /* Range check on apdLowGainStepRecovery (5-bit) */ + if (device->obsRx->orxAgcCtrl->peakAgc->apdLowGainStepRecovery > 0x1F) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_APD_LOW_GAIN_STEP_PARM, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_APD_LOW_GAIN_STEP_PARM)); + return MYKONOS_ERR_INV_AGC_OBSRX_APD_LOW_GAIN_STEP_PARM; + } + else + { + /* Write apdLowGainStepRecovery */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_ORX_SNRX_OVRG_GAIN_STEP_4, device->obsRx->orxAgcCtrl->peakAgc->apdLowGainStepRecovery); + } + + /* Range check on hb2HighGainStepAttack (5-bit) */ + if (device->obsRx->orxAgcCtrl->peakAgc->hb2HighGainStepAttack > 0x1F) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_HB2_HIGH_GAIN_STEP_PARM, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_HB2_HIGH_GAIN_STEP_PARM)); + return MYKONOS_ERR_INV_AGC_OBSRX_HB2_HIGH_GAIN_STEP_PARM; + } + else + { + /* Write hb2HighGainStepAttack */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_ORX_SNRX_OVRG_GAIN_STEP_2, device->obsRx->orxAgcCtrl->peakAgc->hb2HighGainStepAttack); + } + + /* Range check on hb2LowGainStepRecovery (5-bit) */ + if (device->obsRx->orxAgcCtrl->peakAgc->hb2LowGainStepRecovery > 0x1F) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_HB2_LOW_GAIN_STEP_PARM, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_HB2_LOW_GAIN_STEP_PARM)); + return MYKONOS_ERR_INV_AGC_OBSRX_HB2_LOW_GAIN_STEP_PARM; + } + else + { + /* Write hb2LowGainStepRecovery */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_ORX_SNRX_OVRG_GAIN_STEP_5, device->obsRx->orxAgcCtrl->peakAgc->hb2LowGainStepRecovery); + } + + /* Range check on hb2VeryLowGainStepRecovery (5-bit) */ + if (device->obsRx->orxAgcCtrl->peakAgc->hb2VeryLowGainStepRecovery > 0x1F) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_HB2_VERY_LOW_GAIN_STEP_PARM, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_HB2_VERY_LOW_GAIN_STEP_PARM)); + return MYKONOS_ERR_INV_AGC_OBSRX_HB2_VERY_LOW_GAIN_STEP_PARM; + } + else + { + /* Write hb2VeryLowGainStepRecovery */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_ORX_SNRX_OVRG_GAIN_STEP_6, device->obsRx->orxAgcCtrl->peakAgc->hb2VeryLowGainStepRecovery); + } + + /* Range Check on hb2OverloadDetectEnable */ + if (device->obsRx->orxAgcCtrl->peakAgc->hb2OverloadDetectEnable > 0x1) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_HB2_OVLD_ENABLE, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_HB2_OVLD_ENABLE)); + return MYKONOS_ERR_INV_AGC_OBSRX_HB2_OVLD_ENABLE; + } + + /* Range Check on hb2OverloadDetectEnable */ + if (device->obsRx->orxAgcCtrl->peakAgc->hb2OverloadDurationCnt > 0x7) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_HB2_OVLD_DUR_CNT, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_HB2_OVLD_DUR_CNT)); + return MYKONOS_ERR_INV_AGC_OBSRX_HB2_OVLD_DUR_CNT; + } + + /* Range Check on hb2OverloadDetectEnable */ + if (device->obsRx->orxAgcCtrl->peakAgc->hb2OverloadThreshCnt > 0xF) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_HB2_OVLD_THRESH_CNT, + getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_HB2_OVLD_THRESH_CNT)); + return MYKONOS_ERR_INV_AGC_OBSRX_HB2_OVLD_THRESH_CNT; + } + else + { + /* Write the hb2OvldCfgRegValue, the combination of hb2OverloadThreshCnt, hb2OverloadDurationCnt, and hb2OverloadDetectEnable */ + hb2OvldCfgRegValue = (device->obsRx->orxAgcCtrl->peakAgc->hb2OverloadThreshCnt) | + (uint8_t)(device->obsRx->orxAgcCtrl->peakAgc->hb2OverloadDurationCnt << 4) | + (uint8_t)(device->obsRx->orxAgcCtrl->peakAgc->hb2OverloadDetectEnable << 7); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ORX_SNRX_OVRLD_PD_DEC_OVRLD_CFG, hb2OvldCfgRegValue); + } + + /* Hard-coded value for the ADC overload configuration. Sets the HB2 offset to -6dB.*/ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ORX_SNRX_OVRLD_ADC_OVRLD_CFG, 0x18); + /* Hard-coded value for APD decay setting. Setting allows for the quickest settling time of peak detector */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_ORX_SNRX_BLOCK_DET_DECAY, 0x0); + + /* performing a soft reset */ + return MYKONOS_resetRxAgc(device); +} + +/** + * \brief Enables or disables the ObsRx slow loop gain counter to use the sync pulse + * + * Dependencies: + * - device->spiSettings + * + * \param device is structure pointer to the Mykonos data structure containing the device SPI settings + * \param enable is a uint8_t data type where '0' = disable ObsRx gain counter from using sync pulse, '1' = enable ObsRx gain. All other values will throw an error. + * counter to use the sync pulse. This value is written back to the device data structure for storage. + * + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_enableObsRxGainCtrSyncPulse(mykonosDevice_t *device, uint8_t enable) +{ + const uint8_t syncPulseBitMask = 0x80; + uint8_t enableBit = 0; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_enableObsRxGainCtrSyncPulse()\n"); +#endif + + enableBit = (enable > 0) ? 1 : 0; + + /* read, modify, write ObsRx gain counter sync pulse enable bit */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_LOOP_CFG, enableBit, syncPulseBitMask, 7); + + return MYKONOS_ERR_OK; +} + +/** + * \brief Configures the ObsRx gain control mode + * + * Dependencies: + * - device->spiSettings + * - device->obsRx->orxGainCtrl->gainMode + * + * \param device is structure pointer to the Mykonos data structure containing settings + * \param mode is a mykonosGainMode_t enumerated gain control mode type + * + * When the mode enumerated type is passed, the ObsRx gain mode is set to this value and the + * ObsRX agcType mykonosAgcCfg_t structure member is updated with the new value + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_INV_ORX_GAIN_MODE_PARM Invalid Observation Rx Gain control mode selected (use mykonosGainMode_t ENUM values) + */ +mykonosErr_t MYKONOS_setObsRxGainControlMode(mykonosDevice_t *device, mykonosGainMode_t mode) +{ + const uint8_t ORX_GAIN_TYPE_MASK = 0x3; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setObsRxGainControlMode()\n"); +#endif + + /* performing gain type check */ + switch (mode) + { + case MGC: + break; + case AGC: + break; + case HYBRID: + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_ORX_GAIN_MODE_PARM, + getMykonosErrorMessage(MYKONOS_ERR_INV_ORX_GAIN_MODE_PARM)); + return MYKONOS_ERR_INV_ORX_GAIN_MODE_PARM; + } + + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_ORX_SNRX_CFG_1, mode, ORX_GAIN_TYPE_MASK, 0); + + /* writing mode setting to data structure */ + if ((device->profilesValid & ORX_PROFILE_VALID) > 0) + { + device->obsRx->orxGainCtrl->gainMode = mode; + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief Performs a power measurement in the ObsRx digital data path. + * + * Due to interdependencies between the AGC and power measurement the power measurement duration and + * where the measurement is taken is variable. + * The location of the power measurement is given by device->obsRx->obsRxAgcCtrl->obsRxPwrAgc->pmdMeasConfig + * The number of samples the power measurement uses is given by 8*2^(device->obsRx->obsRxAgcCtrl->obsRxPwrAgc->pmdMeasConfig) at the IQ rate, + * if measured at RFIR output. This number of samples must be less than the agcGainUpdateCounter. + * If the receiver is disabled during the power measurement, this function returns a 0 value for rx2DecPower_mdBFS + * + * The resolution of this function is 0.25dB. + * The dynamic range of this function is 40dB. Signals lower than 40dBFS may not be measured accurately. + * + * Dependencies + * - device->spiSettings + * - device->obsRx->obsRxAgcCtrl->obsRxPwrAgc->pmdMeasConfig + * - device->obsRx->obsRxAgcCtrl->obsRxPwrAgc->pmdMeasConfig + * + * \param device Pointer to the Mykonos data structure + * \param obsRxDecPower_mdBFS Pointer to store the Rx1 decimated power return. Value returned in mdBFS + * + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_getObsRxDecPower(mykonosDevice_t *device, uint16_t *obsRxDecPower_mdBFS) +{ + uint8_t obsRxDecPower_dBFS = 0; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getObsRxDecPower()\n"); +#endif + + /* read ObsRx Dec Power Measurement */ + if (obsRxDecPower_mdBFS != NULL) + { + CMB_SPIReadByte(device->spiSettings, MYKONOS_SNIFFER_DECIMATED_PWR, &obsRxDecPower_dBFS); + *obsRxDecPower_mdBFS = (uint16_t)(obsRxDecPower_dBFS * 250); /* 250 = 1000 * 0.25dB */ + } + else + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GET_OBSRX_DEC_POWER_NULL_PARM, + getMykonosErrorMessage(MYKONOS_ERR_GET_OBSRX_DEC_POWER_NULL_PARM)); + return MYKONOS_ERR_GET_OBSRX_DEC_POWER_NULL_PARM; + } + + return MYKONOS_ERR_OK; +} + +/* + ***************************************************************************** + * Tx Data path functions + ***************************************************************************** + */ + +/** + * \brief Sets the Tx1 RF output Attenuation + * + * Dependencies + * - device->spiSettings + * - device->spiSettings->chipSelectIndex + * - device->tx->txAttenStepSize + * + * \param device Pointer to the Mykonos device's data structure + * \param tx1Attenuation_mdB The desired TxAttenuation in milli-dB (Range: 0 to 41950 mdB) + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_SETTX1ATTEN_INV_PARM tx1Attenuation_mdB parameter is out of range (0 - 41950) + * \retval MYKONOS_ERR_SETTX1ATTEN_INV_STEPSIZE_PARM device->tx->txAttenStepSize is not a valid enum value + */ +mykonosErr_t MYKONOS_setTx1Attenuation(mykonosDevice_t *device, uint16_t tx1Attenuation_mdB) +{ + uint16_t data = 0; + uint16_t attenStepSizeDiv = 50; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setTx1Attenuation()\n"); +#endif + + /* check input parameter is in valid range */ + if (tx1Attenuation_mdB > 41950) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETTX1ATTEN_INV_PARM, + getMykonosErrorMessage(MYKONOS_ERR_SETTX1ATTEN_INV_PARM)); + return MYKONOS_ERR_SETTX1ATTEN_INV_PARM; + } + + switch (device->tx->txAttenStepSize) + { + case TXATTEN_0P05_DB: + attenStepSizeDiv = 50; + break; + case TXATTEN_0P1_DB: + attenStepSizeDiv = 100; + break; + case TXATTEN_0P2_DB: + attenStepSizeDiv = 200; + break; + case TXATTEN_0P4_DB: + attenStepSizeDiv = 400; + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETTX1ATTEN_INV_STEPSIZE_PARM, + getMykonosErrorMessage(MYKONOS_ERR_SETTX1ATTEN_INV_STEPSIZE_PARM)); + return MYKONOS_ERR_SETTX1ATTEN_INV_STEPSIZE_PARM; + + } + + data = (tx1Attenuation_mdB / attenStepSizeDiv); + + /* Write MSB bits followed by LSB bits, TxAtten updates when [7:0] written */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_TX1_ATTENUATION_1, ((data >> 8) & 0x03)); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_TX1_ATTENUATION_0, (data & 0xFF)); + + return MYKONOS_ERR_OK; +} + +/** + * \brief Sets the Tx2 RF output Attenuation (Step size is 0.05dB.) + * + * Dependencies + * - device->spiSettings + * - device->spiSettings->chipSelectIndex + * - device->tx->txAttenStepSize + * + * \param device Pointer to the Mykonos device's data structure + * \param tx2Attenuation_mdB The desired TxAttenuation in milli-dB + * (Range: 0 to 41950 mdB) + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_SETTX2ATTEN_INV_PARM tx2Attenuation_mdB parameter is out of range (0 - 41950) + * \retval MYKONOS_ERR_SETTX2ATTEN_INV_STEPSIZE_PARM device->tx->txAttenStepSize is not a valid enum value + */ +mykonosErr_t MYKONOS_setTx2Attenuation(mykonosDevice_t *device, uint16_t tx2Attenuation_mdB) +{ + uint16_t attenStepSizeDiv = 50; + uint16_t data = 0; + //const uint8_t SPI_TXATTEN_MODE = 0x01; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setTx2Attenuation()\n"); +#endif + + /* check input parameter is in valid range */ + if (tx2Attenuation_mdB > 41950) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETTX2ATTEN_INV_PARM, + getMykonosErrorMessage(MYKONOS_ERR_SETTX2ATTEN_INV_PARM)); + return MYKONOS_ERR_SETTX2ATTEN_INV_PARM; + } + + switch (device->tx->txAttenStepSize) + { + case TXATTEN_0P05_DB: + attenStepSizeDiv = 50; + break; + case TXATTEN_0P1_DB: + attenStepSizeDiv = 100; + break; + case TXATTEN_0P2_DB: + attenStepSizeDiv = 200; + break; + case TXATTEN_0P4_DB: + attenStepSizeDiv = 400; + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETTX2ATTEN_INV_STEPSIZE_PARM, + getMykonosErrorMessage(MYKONOS_ERR_SETTX2ATTEN_INV_STEPSIZE_PARM)); + return MYKONOS_ERR_SETTX2ATTEN_INV_STEPSIZE_PARM; + } + + data = (tx2Attenuation_mdB / attenStepSizeDiv); + + /* Write MSB bits followed by LSB bits, TxAtten updates when [7:0] written */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_TX2_ATTENUATION_1, ((data >> 8) & 0x03)); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_TX2_ATTENUATION_0, (data & 0xFF)); + + return MYKONOS_ERR_OK; +} + +/** + * \brief Reads back the Tx1 RF output Attenuation + * + * This function reads back the TxAttenuation setting currently applied to the transmit chain. + * The function will work with SPI mode or pin controlled TxAtten mode using the increment/decrement GPIO + * pins. For the readback value to be valid the Tx data path must be powered up. If the Tx data path + * is powered down or radioOff state, the last TxAtten setting while the Tx was powered up will be + * read back. + * + * Dependencies + * - device->spiSettings + * - device->spiSettings->chipSelectIndex + * + * \param device Pointer to the Mykonos device's data structure + * \param tx1Attenuation_mdB The readback value of the Tx1 Attenuation in milli-dB (Range: 0 to 41950 mdB) + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_GETTX1ATTEN_NULL_PARM tx1Attenuation_mdB return parameter has NULL pointer + */ +mykonosErr_t MYKONOS_getTx1Attenuation(mykonosDevice_t *device, uint16_t *tx1Attenuation_mdB) +{ + uint8_t txAttenLsb = 0; + uint8_t txAttenMsb = 0; + uint16_t attenStepSizeDiv = 50; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getTx1Attenuation()\n"); +#endif + + /* check return parameter pointer is not NULL pointer */ + if (tx1Attenuation_mdB == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETTX1ATTEN_NULL_PARM, + getMykonosErrorMessage(MYKONOS_ERR_GETTX1ATTEN_NULL_PARM)); + return MYKONOS_ERR_GETTX1ATTEN_NULL_PARM; + } + + /* Write TxAtten read back reg to update readback values, then read Tx1Atten */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_TX1_ATTENUATION_1_READBACK, 0x00); + CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_TX1_ATTENUATION_0_READBACK, &txAttenLsb, 0xFF, 0); + CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_TX1_ATTENUATION_1_READBACK, &txAttenMsb, 0x03, 0); + + /* Readback word always reads back with 0.05dB resolution */ + *tx1Attenuation_mdB = (uint16_t)(((uint16_t)(txAttenLsb) | ((uint16_t)(txAttenMsb) << 8)) * attenStepSizeDiv); + + return MYKONOS_ERR_OK; +} + +/** + * \brief Reads back the Tx2 RF output Attenuation + * + * This function reads back the TxAttenuation setting currently applied to the transmit chain. + * The function will work with SPI mode or pin controlled TxAtten mode using the increment/decrement GPIO + * pins. For the readback value to be valid the Tx data path must be powered up. If the Tx data path + * is powered down or radioOff state, the last TxAtten setting while the Tx was powered up will be + * read back. + * + * Dependencies + * - device->spiSettings + * - device->spiSettings->chipSelectIndex + * + * \param device Pointer to the Mykonos device's data structure + * \param tx2Attenuation_mdB The readback value of the Tx2 Attenuation in milli-dB (Range: 0 to 41950 mdB) + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_GETTX2ATTEN_NULL_PARM tx2Attenuation_mdB return parameter pointer is NULL + */ +mykonosErr_t MYKONOS_getTx2Attenuation(mykonosDevice_t *device, uint16_t *tx2Attenuation_mdB) +{ + uint8_t txAttenLsb = 0; + uint8_t txAttenMsb = 0; + uint16_t attenStepSizeDiv = 50; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getTx2Attenuation()\n"); +#endif + + /* check return parameter pointer is not NULL pointer */ + if (tx2Attenuation_mdB == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETTX2ATTEN_NULL_PARM, + getMykonosErrorMessage(MYKONOS_ERR_GETTX2ATTEN_NULL_PARM)); + return MYKONOS_ERR_GETTX2ATTEN_NULL_PARM; + } + + /* Write TxAtten read back reg to update readback values, then read Tx1Atten */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_TX2_ATTENUATION_1_READBACK, 0x00); + CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_TX2_ATTENUATION_0_READBACK, &txAttenLsb, 0xFF, 0); + CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_TX2_ATTENUATION_1_READBACK, &txAttenMsb, 0x03, 0); + + /* Readback word always reads back with 0.05dB resolution */ + *tx2Attenuation_mdB = (uint16_t)(((uint16_t)(txAttenLsb) | ((uint16_t)(txAttenMsb) << 8)) * attenStepSizeDiv); + + return MYKONOS_ERR_OK; +} + +/** + * \brief Checks the Tx Filter over-range bit assignments for digital clipping in the Tx data path + * + * Dependencies + * - device->spiSettings + * + * txFilterStatus bit-field assignments are: + * txFilterStatus[0] = TFIR Ch1 Overflow + * txFilterStatus[1] = HB1 Ch1 Overflow + * txFilterStatus[2] = HB2 Ch1 Overflow + * txFilterStatus[3] = QEC Ch1 Overflow + * txFilterStatus[4] = TFIR Ch2 Overflow + * txFilterStatus[5] = HB1 Ch2 Overflow + * txFilterStatus[6] = HB2 Ch2 Overflow + * txFilterStatus[7] = QEC Ch2 Overflow + * + * \param device Pointer to the Mykonos device's data structure + * \param txFilterStatus is an 8-bit Tx filter over-range status bit-field + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_GET_TXFILTEROVRG_NULL_PARM Function txFilterStatus parameter pointer is NULL + */ +mykonosErr_t MYKONOS_getTxFilterOverRangeStatus(mykonosDevice_t *device, uint8_t *txFilterStatus) +{ + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getTxFilterOverRangeStatus()\n"); +#endif + + if (txFilterStatus == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GET_TXFILTEROVRG_NULL_PARM, + getMykonosErrorMessage(MYKONOS_ERR_GET_TXFILTEROVRG_NULL_PARM)); + return MYKONOS_ERR_GET_TXFILTEROVRG_NULL_PARM; + } + + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_TX_FILTER_OVERFLOW, txFilterStatus); + return MYKONOS_ERR_OK; +} + +/** + * \brief Enables/Disables the Tx NCO test tone + * + * This function enables/disables a digital numerically controlled oscillator + * in the Mykonos Digital to create a test CW tone on Tx1 and Tx2 RF outputs. + * + * The TxAttenuation is forced in this function to max analog output power, but + * the digital attenuation is backed off 6dB to make sure the digital filter + * does not clip and cause spurs in the tx spectrum. + * + * Dependencies + * - device->spiSettings + * - device->profilesValid + * - device->tx->txProfile->iqRate_kHz + * + * \param device Pointer to the Mykonos device's data structure + * \param enable 0 = Disable Tx NCO, 1 = Enable Tx NCO on both transmitters + * \param tx1ToneFreq_kHz Signed frequency in kHz of the desired Tx1 tone + * \param tx2ToneFreq_kHz Signed frequency in kHz of the desired Tx2 tone + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_ENTXNCO_TXPROFILE_INVALID Can not enable Tx NCO when Tx Profile is not enabled/valid + * \retval MYKONOS_ERR_ENTXNCO_TX1_FREQ_INVALID Tx1 NCO Tone frequency out of range (-IQrate/2 to IQrate/2) + * \retval MYKONOS_ERR_ENTXNCO_TX2_FREQ_INVALID Tx2 NCO Tone frequency out of range (-IQrate/2 to IQrate/2) + */ +mykonosErr_t MYKONOS_enableTxNco(mykonosDevice_t *device, uint8_t enable, int32_t tx1ToneFreq_kHz, int32_t tx2ToneFreq_kHz) +{ + int16_t tx1NcoTuneWord = 0; + int16_t tx2NcoTuneWord = 0; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_enableTxNco()\n"); +#endif + + if (enable > 0) + { + if ((device->profilesValid & TX_PROFILE_VALID) == 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_ENTXNCO_TXPROFILE_INVALID, + getMykonosErrorMessage(MYKONOS_ERR_ENTXNCO_TXPROFILE_INVALID)); + return MYKONOS_ERR_ENTXNCO_TXPROFILE_INVALID; + } + + if ((tx1ToneFreq_kHz > ((int32_t)(device->tx->txProfile->iqRate_kHz) / 2)) || (tx1ToneFreq_kHz < ((int32_t)(device->tx->txProfile->iqRate_kHz) * -1 / 2))) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_ENTXNCO_TX1_FREQ_INVALID, + getMykonosErrorMessage(MYKONOS_ERR_ENTXNCO_TX1_FREQ_INVALID)); + return MYKONOS_ERR_ENTXNCO_TX1_FREQ_INVALID; + } + + if ((tx2ToneFreq_kHz > ((int32_t)(device->tx->txProfile->iqRate_kHz) / 2)) || (tx2ToneFreq_kHz < ((int32_t)(device->tx->txProfile->iqRate_kHz) * -1 / 2))) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_ENTXNCO_TX2_FREQ_INVALID, + getMykonosErrorMessage(MYKONOS_ERR_ENTXNCO_TX2_FREQ_INVALID)); + return MYKONOS_ERR_ENTXNCO_TX2_FREQ_INVALID; + } + + /* Force Tx output power to max analog output power, but 6dB digital */ + /* backoff to prevent the NCO from clipping the Tx PFIR filter */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_TX1_GAIN_0, 0x78); + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_TX1_GAIN_1, 0x00, 0x3F, 0); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_TX1_GAIN_2, 0x0); + + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_TX2_GAIN_0, 0x78); + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_TX2_GAIN_1, 0x00, 0x3F, 0); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_TX2_GAIN_2, 0x0); + + /* Enable manual Tx output power mode */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_TX_TPC_CONFIG, 0x0A, 0x0F, 0); + + /* Set Tx NCO tuning words */ + tx1NcoTuneWord = (int16_t)(((int64_t)(tx1ToneFreq_kHz) << 16) / device->tx->txProfile->iqRate_kHz * -1); + tx2NcoTuneWord = (int16_t)(((int64_t)(tx2ToneFreq_kHz) << 16) / device->tx->txProfile->iqRate_kHz * -1); + + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_TX_ABBF_FREQ_CAL_NCO_I_MSB, (uint8_t)((uint16_t)tx1NcoTuneWord >> 8)); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_TX_ABBF_FREQ_CAL_NCO_I_LSB, (tx1NcoTuneWord & 0xFF)); + + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_TX_ABBF_FREQ_CAL_NCO_Q_MSB, (uint8_t)((uint16_t)tx2NcoTuneWord >> 8)); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_TX_ABBF_FREQ_CAL_NCO_Q_LSB, (tx2NcoTuneWord & 0xFF)); + + /* Enable Tx NCO - set [7] = 1 */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_DIGITAL_TEST_BYTE_0, 1, 0x80, 7); + } + else + { + /* Disable Tx NCO - set [7] = 0 */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_DIGITAL_TEST_BYTE_0, 0, 0x80, 7); + + /* Enable normal Tx Atten table mode */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_TX_TPC_CONFIG, 0x05, 0x0F, 0); + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief Writes Mykonos device registers with settings for the PA Protection block. + * + * This function writes register settings for the Mykonos PA Protection Block. + * This function does not enable the PA Protection functionality. + * Note that independent control of PA protection for both Tx channels is not possible. + * The PA Protection block allows for error flags to go high if the accumulated TX power in the data path + * exceeds a programmable threshold level based on samples taken in a programmable duration. + * + * \post After calling this function the user will need to call MYKONOS_enablePaProtection(...) + * + * Dependencies + * - device->spiSettings + * - device->spiSettings->chipSelectIndex + * + * \param device Pointer to the Mykonos device's data structure + * \param powerThreshold PA Protection Threshold sets the power level that, if detected in the TX data path, raises the PA error flags. The range is 0 to 4096. + * To calculate the required setting for the power threshold: + * powerThreshold = MAX_DAC_CODE * (10^((txPowerThresh_dBFS/10))) + * For example: If the required dBFS for the threshold is -10 dBFS, then the powerThreshold passed should be 409. + * + * \param attenStepSize Attenuation Step Size sets the size of the attenuation step when Tx Atten Control is Enabled. The range is 0 to 128 with a resolution is 0.2dB/LSB. + * \param avgDuration Averaging Duration for the TX data path power measurement. The range is 0 to 14 specified in number of cycles of the TX IQ Rate. + * \param stickyFlagEnable "1" Enables the PA Error Flags to stay high after being triggered, even if the power decreases below threshold. "0" disables this functionality. + * \param txAttenControlEnable "1" Enables autonomous attenuation changes in response to PA error flags. "0" disables this functionality. + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_SETUP_PA_PROT_INV_AVG_DURATION avgDuration parameter invalid (valid 0-15) + * \retval MYKONOS_ERR_SETUP_PA_PROT_INV_ATTEN_STEP attenStepSize function parameter invalid (valid 0-127) + */ +mykonosErr_t MYKONOS_setupPaProtection(mykonosDevice_t *device, uint16_t powerThreshold, uint8_t attenStepSize, uint8_t avgDuration, uint8_t stickyFlagEnable, uint8_t txAttenControlEnable) +{ + uint8_t paProtectConfig = 0; + uint8_t paProtectAttenCntl = 0; + + const uint8_t PROTECT_AVG_DUR_MASK = 0x1E; + const uint8_t STICKY_FLAG_EN_MASK = 0x40; + const uint8_t ATT_STEP_MASK = 0xFE; + const uint8_t PROTECT_ATT_EN_MASK = 0x01; + const uint8_t AVG_DUR_MASK = 0x0F; + const uint8_t ATT_STEP_SIZE = 0x7F; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setupPaProtection()\n"); +#endif + + /* Overwrite PA Protection Config register data with averaging duration and sticky flag. Also performing range check on stickyFlagEnable and avgDuration */ + if (avgDuration > AVG_DUR_MASK) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETUP_PA_PROT_INV_AVG_DURATION, + getMykonosErrorMessage(MYKONOS_ERR_SETUP_PA_PROT_INV_AVG_DURATION)); + return MYKONOS_ERR_SETUP_PA_PROT_INV_AVG_DURATION; + } + + if (attenStepSize > ATT_STEP_SIZE) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETUP_PA_PROT_INV_ATTEN_STEP, + getMykonosErrorMessage(MYKONOS_ERR_SETUP_PA_PROT_INV_ATTEN_STEP)); + return MYKONOS_ERR_SETUP_PA_PROT_INV_ATTEN_STEP; + } + + paProtectConfig = (PROTECT_AVG_DUR_MASK & (avgDuration << 1)); + + if (stickyFlagEnable > 0) + { + paProtectConfig |= (STICKY_FLAG_EN_MASK); + } + + paProtectAttenCntl = ATT_STEP_MASK & (attenStepSize << 1); + + if (txAttenControlEnable > 0) + { + paProtectAttenCntl |= (PROTECT_ATT_EN_MASK); + } + + /* Clear and write all PA Protection setup registers */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PA_PROTECTION_ATTEN_CONTROL, 0x00); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PA_PROTECTION_CONFIGURATION, 0x00); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PA_PROTECTION_THRESHOLD_LSB, 0x00); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PA_PROTECTION_THRESHOLD_MSB, 0x00); + + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PA_PROTECTION_ATTEN_CONTROL, paProtectAttenCntl); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PA_PROTECTION_CONFIGURATION, paProtectConfig); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PA_PROTECTION_THRESHOLD_LSB, (powerThreshold & 0xFF)); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PA_PROTECTION_THRESHOLD_MSB, ((powerThreshold >> 8) & 0x0F)); + + return MYKONOS_ERR_OK; +} + +/** + * \brief Enables the Mykonos PA Protection block according to the parameters passed in MYKONOS_setupPaProtection(...). + * + * This function enables the PA Protection block according to the parameters passed in MYKONOS_setupPaProtection(...) + * The paProtectEnable signal enables the PA Protection block, allowing usage of the PA protection functions. + * + * \pre Before calling this function the user needs to setup the PA protection by calling MYKONOS_setupPaProtection(...) + * + * Dependencies + * - device->spiSettings + * - device->spiSettings->chipSelectIndex + * + * \param device Pointer to the Mykonos device's data structure + * \param paProtectEnable "1" Enables the PA Protection block. "0" Disables the PA Protection block + * + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_enablePaProtection(mykonosDevice_t *device, uint8_t paProtectEnable) +{ + uint8_t paProtectEnableReg = 0; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_enablePaProtection()\n"); +#endif + + paProtectEnableReg = (paProtectEnable > 0) ? 1 : 0; + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_PA_PROTECTION_CONFIGURATION, paProtectEnableReg, 0x01, 0); + + return MYKONOS_ERR_OK; +} + +/** + * \brief Obtains an estimate of a TX channel's accumulated power over the sample duration provided in MYKONOS_setupPaProtection(...) + * + * This function uses the 'avgDuration' parameter provided in MYKONOS_setupPaProtection to set the number of samples to accumulate + * to obtain an estimate for a TX channel specified by the 'channel' parameter. + * A 12-bit field estimating the channel power is returned in the '*channelPower' pointer. + * To obtain the dBFS value of the reading: + * dBFS value = 10*log10(channelPower/MAX_DAC_CODE) + * where MAX_DAC_CODE = 2^12 = 4096 + * For example: If channelPower is reading 409 then the channel power in dBFS is -10dBFS. + * + * Dependencies + * - device->spiSettings + * - device->spiSettings->chipSelectIndex + * + * \param device Point to the Mykonos device's data structure + * \param channel Select the channel of interest. Only use TX1 (1) or TX2 (2) of mykonosTxChannels_t + * \param *channelPower A pointer that stores the selected channels power. Read back is provided as a 12 bit value. + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_GET_DAC_PWR_INV_POINTER Function channelPower parameter is a NULL pointer + * \retval MYKONOS_ERR_SETUP_PA_PROT_INV_TX_CHANNEL Invalid Tx Channel passed in function channel parameter (TX1 or TX2) + */ +mykonosErr_t MYKONOS_getDacPower(mykonosDevice_t *device, mykonosTxChannels_t channel, uint16_t *channelPower) +{ + uint8_t channelPowerLsb = 0; + uint8_t channelPowerMsb = 0; + + const uint8_t CHAN_POWER_MSB_MASK = 0xF; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getDacPower()\n"); +#endif + + if (channelPower == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GET_DAC_PWR_INV_POINTER, + getMykonosErrorMessage(MYKONOS_ERR_GET_DAC_PWR_INV_POINTER)); + return MYKONOS_ERR_GET_DAC_PWR_INV_POINTER; + } + + /* Set bit D5 to read the appropriate channel power */ + switch (channel) + { + case TX1: + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_PA_PROTECTION_CONFIGURATION, 0, 0x20, 5); + break; + case TX2: + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_PA_PROTECTION_CONFIGURATION, 1, 0x20, 5); + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETUP_PA_PROT_INV_TX_CHANNEL, + getMykonosErrorMessage(MYKONOS_ERR_SETUP_PA_PROT_INV_TX_CHANNEL)); + return MYKONOS_ERR_SETUP_PA_PROT_INV_TX_CHANNEL; + } + + /* SPI Write to register PA Protection power readback registers (write strobe) */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PA_PROTECTION_POWER_READBACK_LSB, 0x00); + + /* SPI Read of the PA Protection power readback registers */ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_PA_PROTECTION_POWER_READBACK_LSB, &channelPowerLsb); + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_PA_PROTECTION_POWER_READBACK_MSB, &channelPowerMsb); + + *channelPower = (channelPowerLsb | (((uint16_t)(channelPowerMsb & CHAN_POWER_MSB_MASK)) << 8)); + + return MYKONOS_ERR_OK; +} + +/** + * \brief Returns PA Protection Error Flag Status + * + * This function provides a readback of the PA protection Error Flag Status through the '*errorFlagStatus' pointer + * + * Dependencies + * - device->spiSettings + * - device->spiSettings->chipSelectIndex + * + * \param device Point to the Mykonos device's data structure + * \param errorFlagStatus Pointer to store the error flag status. + * errorFlagStatus | error + * -----------------|------------ + * 0 | indicates no PA Error Flags are high + * 1 | indicates TX1 Error Flag + * 2 | indicates TX2 Error Flag + * 3 | indicates TX1 and TX2 Error Flags are high + * + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_GET_PA_FLAG_STATUS_INV_POINTER Function errorFlagStatus parameter has NULL pointer + */ +mykonosErr_t MYKONOS_getPaProtectErrorFlagStatus(mykonosDevice_t *device, uint8_t *errorFlagStatus) +{ + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getPaProtectErrorFlagStatus()\n"); +#endif + + if (errorFlagStatus == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GET_PA_FLAG_STATUS_INV_POINTER, + getMykonosErrorMessage(MYKONOS_ERR_GET_PA_FLAG_STATUS_INV_POINTER)); + return MYKONOS_ERR_GET_PA_FLAG_STATUS_INV_POINTER; + } + + /* SPI Write to register PA Protection power readback registers (write strobe) */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PA_PROTECTION_POWER_READBACK_LSB, 0x00); + + /* SPI Read of the PA Protection power readback registers */ + CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_PA_PROTECTION_POWER_READBACK_MSB, errorFlagStatus, 0x60, 5); + + return MYKONOS_ERR_OK; +} + +/** + * \brief Manually clears the PA Protection Error Flags. + * + * This function manually clears the PA Error Flags. The user must setup the PA Protection block to enable + * sticky error flags. Sticky error flags require the user to clear the bit manually even if the accumulated power is + * below the power threshold for the PA protection block. + * + * Dependencies + * - device->spiSettings + * - device->spiSettings->chipSelectIndex + * + * \param device Pointer to the Mykonos device's data structure + * + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_clearPaErrorFlag(mykonosDevice_t *device) +{ + uint8_t paProtectConfig = 0; + + const uint8_t PA_ERROR_CLEAR_MASK = 0x80; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_clearPaErrorFlag()\n"); +#endif + + /* SPI Read of the PA Protection power readback registers */ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_PA_PROTECTION_CONFIGURATION, &paProtectConfig); + + /* SPI Write to self clear the PA Error Flags */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PA_PROTECTION_CONFIGURATION, (paProtectConfig | PA_ERROR_CLEAR_MASK)); + + return MYKONOS_ERR_OK; +} + +/** + * \brief Helper function for return of character string based on 32-bit mykonosErr_t enum value + * + * To save codespace, these error strings are ifdef'd out unless the user + * adds a define MYKONOS_VERBOSE to their workspace. This function can be + * useful for debug. Each function also returns unique error codes to + * make it easier to determine where the code broke. + * + * \param errorCode is enumerated error code value + * + * \return Returns character string based on enumerated value + */ +const char* getMykonosErrorMessage(mykonosErr_t errorCode) +{ +#ifndef MYKONOS_VERBOSE + return ""; + +#else + + switch (errorCode) + { + case MYKONOS_ERR_OK: + return ""; + case MYKONOS_ERR_INV_PARM: + return "Mykonos: Invalid parameter\n"; + case MYKONOS_ERR_FAILED: + return "Mykonos: General Failure\n"; + case MYKONOS_ERR_WAITFOREVENT_INV_PARM: + return "waitForEvent had invalid parameter.\n"; + case MYKONOS_ERR_WAITFOREVENT_TIMEDOUT: + return "waitForEvent timed out.\n"; + case MYKONOS_ERR_SETENSM_INVALID_NEWSTATE_WAIT: + return "Requested new ENSM state is invalid from the WAIT state.\n"; + case MYKONOS_ERR_SETENSM_INVALID_NEWSTATE_ALERT: + return "Requested new ENSM state is invalid from the ALERT state.\n"; + case MYKONOS_ERR_SETENSM_INVALID_NEWSTATE_TXRX: + return "Requested new ENSM state is invalid from the TXRX state.\n"; + case MYKONOS_ERR_SETENSM_INVALIDSTATE: + return "Current ENSM state is an invalid state or calibration state.\n"; + case MYKONOS_ERR_PU_RXPATH_INV_PARAM: + return "Invalid Rx channel was requested to be powered up.\n"; + case MYKONOS_ERR_PU_TXPATH_INV_PARAM: + return "Invalid Tx channel was requested to be powered up.\n"; + case MYKONOS_ERR_PU_OBSRXPATH_INV_PARAM: + return "Invalid ObsRx channel was requested to be powered up.\n"; + case MYKONOS_ERR_SETDEFOBSRXPATH_NULL_DEF_OBSRX_STRUCT: + return "Invalid default ObsRx channel was requested to be powered up.\n"; + case MYKONOS_ERR_INIT_INV_ORXCHAN: + return "Invalid ObsRx channel requested during initialize().\n"; + case MYKONOS_ERR_INIT_INV_RXSYNCB_ORXSYNCB_MODE: + return "Invalid combination for rxsyncb and orxsyncb, if shared syncb they should have the CMOS/LVDS mode\n"; + case MYKONOS_ERR_INIT_INV_TXFIR_INTERPOLATION: + return "Invalid TxFIR interpolation value.(Valid: 1,2,4)\n"; + case MYKONOS_ERR_INIT_INV_TXHB2_INTERPOLATION: + return "Invalid TXHB2 interpolation value.(Valid: 1 or 2)\n"; + case MYKONOS_ERR_INIT_INV_TXHB1_INTERPOLATION: + return "Invalid TXHB1 interpolation value.(Valid: 1 or 2)\n"; + case MYKONOS_ERR_INIT_INV_RXFIR_DECIMATION: + return "Invalid RxFIR decimation value.(Valid: 1,2,4)\n"; + case MYKONOS_ERR_INIT_INV_RXDEC5_DECIMATION: + return "Invalid Rx DEC5 decimation value.(Valid: 4 or 5)\n"; + case MYKONOS_ERR_INIT_INV_RXHB1_DECIMATION: + return "Invalid RxHB1 decimation value.(Valid: 1 or 2)\n"; + case MYKONOS_ERR_INIT_INV_SNIFFER_RHB1: + return "Invalid Sniffer HB1 decimation value (Valid 1 or 2)\n"; + case MYKONOS_ERR_INIT_INV_SNIFFER_RFIR_DEC: + return "Invalid Sniffer RFIR decimation value (Valid 1,2,4)\n"; + case MYKONOS_ERR_INIT_INV_ORX_RHB1: + return "Invalid ORx HB1 decimation value (Valid 1 or 2)\n"; + case MYKONOS_ERR_INIT_INV_ORX_RFIR_DEC: + return "Invalid ORx RFIR decimation value. (Valid 1,2,4)\n"; + case MYKONOS_ERR_INIT_INV_ADCDIV: + return "Invalid Rx ADC divider. (Valid 1 or 2)\n"; + case MYKONOS_ERR_INIT_INV_DACDIV: + return "Invalid Tx DAC divider. Use enum DACDIV_2, DACDIV_2p5 or DACDIV_4.\n"; + case MYKONOS_ERR_INIT_INV_OBSRX_ADCDIV: + return "Invalid ObsRx ADC div. (Valid 1 or 2)\n"; + case MYKONOS_ERR_CLKPLL_INV_HSDIV: + return "Invalid CLKPLL HSDIV. (Valid 4 or 5)\n"; + case MYKONOS_ERR_CLKPLL_INV_VCODIV: + return "Invalid CLKPLL VCODIV. Use enum VCODIV_1, VCODIV_1p5, VCODIV_2, VCODIV_3\n"; + case MYKONOS_ERR_CLKPLL_INV_RXTXPROFILES: + return "No Rx or Tx profile is specified.\n"; + case MYKONOS_ERR_SETCLKPLL_INV_VCOINDEX: + return "CLKPLL VCO frequency out of range.\n"; + case MYKONOS_ERR_SETCLKPLL_INV_FRACWORD: + return "CLKPLL fractional word is non zero.\n"; + case MYKONOS_ERR_SETRFPLL_INV_PLLNAME: + return "Invalid pllName requested in setRfPllFreuquency()\n"; + case MYKONOS_ERR_SETRFPLL_INV_LO_PARM: + return "RF PLL frequency out of range\n"; + case MYKONOS_ERR_GETRFPLL_INV_PLLNAME: + return "Invalid pllName requested in getRfPllFrequency()\n"; + case MYKONOS_ERR_GETRFPLL_ARMERROR: + return "ARM Command Error in MYKONOS_getRfPllFrequency()\n"; + case MYKONOS_ERR_GETRFPLL_NULLPARAM: + return "NULL pointer in function parameter for MYKONOS_setRfPllFrequency()\n"; + case MYKONOS_ERR_INV_SCALEDDEVCLK_PARAM: + return "Could not scale device clock into range 40MHz to 80Mhz.\n"; + case MYKONOS_ERR_SETRFPLL_INV_VCOINDEX: + return "RFPLL VCO frequency out of range.\n"; + case MYKONOS_ERR_SETRFPLL_INV_REFCLK: + return "Unsupported PLL reference clock or refclk out of range.\n"; + case MYKONOS_ERR_SETORXGAIN_INV_CHANNEL: + return "Invalid ObsRx channel in setObsRxManualGain().\n"; + case MYKONOS_ERR_SETORXGAIN_INV_ORX1GAIN: + return "Invalid gain requested in setObsRxManualGain() for ORX1\n"; + case MYKONOS_ERR_SETORXGAIN_INV_ORX2GAIN: + return "Invalid gain requested in setObsRxManualGain() for ORX2\n"; + case MYKONOS_ERR_SETORXGAIN_INV_SNRXGAIN: + return "Invalid gain requested in setObsRxManualGain() for Sniffer\n"; + case MYKONOS_ERR_GETORX1GAIN_INV_POINTER: + return "Cannot return ORx1 gain to gain control data structure (invalid pointer).\n"; + case MYKONOS_ERR_GETORX2GAIN_INV_POINTER: + return "Cannot return ORx2 gain to gain control data structure (invalid pointer).\n"; + case MYKONOS_ERR_GETSNIFFGAIN_INV_POINTER: + return "Cannot return Sniffer gain to gain control data structure (invalid pointer).\n"; + case MYKONOS_ERR_GETOBSRXGAIN_CH_DISABLED: + return "Cannot read ObsRx gain index. ObsRx Channel is disabled.\n"; + case MYKONOS_ERR_SETTX1ATTEN_INV_PARM: + return "Tx1 attenuation is out of range (0 - 41950 mdB).\n"; + case MYKONOS_ERR_SETTX1ATTEN_INV_STEPSIZE_PARM: + return "Invalid Tx1Atten stepsize. Use enum mykonosTxAttenStepSize_t\n"; + case MYKONOS_ERR_SETTX2ATTEN_INV_PARM: + return "Tx2 attenuation is out of range (0 - 41950 mdB).\n"; + case MYKONOS_ERR_SETTX2ATTEN_INV_STEPSIZE_PARM: + return "Invalid Tx2Atten stepsize. Use enum mykonosTxAttenStepSize_t\n"; + case MYKONOS_ERR_PROGRAMFIR_INV_NUMTAPS_PARM: + return "Invalid number of FIR taps\n"; + case MYKONOS_ERR_READFIR_INV_NUMTAPS_PARM: + return "Invalid number of FIR taps read for the selected Filter\n"; + case MYKONOS_ERR_PROGRAMFIR_INV_FIRNAME_PARM: + return "Invalid FIR filter name requested. use enum mykonosfirName_t\n"; + case MYKONOS_ERR_RXFIR_INV_GAIN_PARM: + return "Rx FIR filter has invalid gain setting\n"; + case MYKONOS_ERR_OBSRXFIR_INV_GAIN_PARM: + return "ObsRx FIR filter A (ORx) has invalid gain setting\n"; + case MYKONOS_ERR_SRXFIR_INV_GAIN_PARM: + return "ObsRx FIR filter B (Sniffer) has invalid gain setting\n"; + case MYKONOS_ERR_TXFIR_INV_GAIN_PARM: + return "Tx FIR filter has invalid gain setting\n"; + case MYKONOS_ERR_READFIR_NULL_PARM: + return "MYKONOS_readFir() has a null *firFilter parameter\n"; + case MYKONOS_ERR_READFIR_COEFS_NULL: + return "MYKONOS_readFir() has a null coef array in *firFilter structure\n"; + case MYKONOS_ERR_READFIR_INV_FIRNAME_PARM: + return "Invalid FIR filter name requested. use enum mykonosfirName_t\n"; + case MYKONOS_ERR_SETRX1GAIN_INV_GAIN_PARM: + return "Rx1 manual gain index out of range of gain table\n"; + case MYKONOS_ERR_SETRX2GAIN_INV_GAIN_PARM: + return "Rx2 manual gain index out of range of gain table\n"; + case MYKONOS_ERR_INITSER_INV_VCODIV_PARM: + return "Found invalid VCO divider value during setupSerializers()\n"; + case MYKONOS_ERR_INITSER_INV_VCODIV1_HSCLK_PARM: + return "CLKPLL VCO frequency exceeded max(8Ghz) in VCO divider /1 case ()\n"; + case MYKONOS_ERR_INITSER_INV_VCODIV1P5_HSCLK_PARM: + return "CLKPLL VCO frequency exceeded max(9.216Ghz) in VCO divider /1.5 case ()\n"; + case MYKONOS_ERR_INITDES_INV_VCODIV_PARM: + return "Found invalid VCO divider value during setupDeserializers()\n"; + case MYKONOS_ERR_SER_INV_M_PARM: + return "Invalid JESD Framer M parameter during setupSerializers()\n"; + case MYKONOS_ERR_SER_INV_L_PARM: + return "Invalid JESD Framer L parameter during setupSerializers()\n"; + case MYKONOS_ERR_SER_INV_LANERATE_PARM: + return "Invalid Lanerate frequency in setupSerializer()\n"; + case MYKONOS_ERR_SER_INV_LANEEN_PARM: + return "Invalid number of JESD204 lanes enabled.\n"; + case MYKONOS_ERR_SER_INV_AMP_PARM: + return "Invalid JESD204 serializer amplitude\n"; + case MYKONOS_ERR_SER_INV_PREEMP_PARM: + return "Invalid JESD204 serializer preemphasis setting\n"; + case MYKONOS_ERR_SER_INV_LANEPN_PARM: + return "Invald JESD204 serializer PN invert setting\n"; + case MYKONOS_ERR_SER_LANE_CONFLICT_PARM: + return "Rx framer and ObsRx framer are attempting to use the same physical lanes\n"; + case MYKONOS_ERR_SER_INV_TXSER_DIV_PARM: + return "Invalid serializer lane clock divider\n"; + case MYKONOS_ERR_SER_LANE_RATE_CONFLICT_PARM: + return "Rx lane and ObsRx lane rate must match\n"; + case MYKONOS_ERR_SER_INV_REAL_IF_DATA_PARM: + return "Framer M can only =1 if Real IF data option is enabled\n"; + case MYKONOS_ERR_HS_AND_LANE_RATE_NOT_INTEGER_MULT: + return "Serializer HSCLK and lane clock are not integer multiples\n"; + case MYKONOS_ERR_DES_HS_AND_LANE_RATE_NOT_INTEGER_MULT: + return "Deserializer HSCLK and lane clock are not integer multiples\n"; + case MYKONOS_ERR_DESER_INV_M_PARM: + return "Invalid deserializer M value. (Valid 2 or 4)\n"; + case MYKONOS_ERR_DESER_INV_L_PARM: + return "Invalid deserializer L value. (Valid 1,2,4)\n"; + case MYKONOS_ERR_DESER_INV_HSCLK_PARM: + return "Invalid HSCLK in setupDeserializer()\n"; + case MYKONOS_ERR_DESER_INV_LANERATE_PARM: + return "Invalid deserializer lane rate\n"; + case MYKONOS_ERR_DESER_INV_LANEEN_PARM: + return "Invalid number of deserializer lanes enabled\n"; + case MYKONOS_ERR_DESER_INV_EQ_PARM: + return "Invalid deserializer EQ setting"; + case MYKONOS_ERR_DESER_INV_LANEPN_PARM: + return "Invalid deserializer invert Lane PN setting\n"; + case MYKONOS_ERR_FRAMER_INV_M_PARM: + return "Invalid Rx framer M setting\n"; + case MYKONOS_ERR_FRAMER_INV_BANKID_PARM: + return "Invalid Rx framer Bank ID\n"; + case MYKONOS_ERR_FRAMER_INV_LANEID_PARM: + return "Invalid Rx framer Lane ID\n"; + case MYKONOS_ERR_FRAMER_INV_K_OFFSET_PARAM: + return "Invalid Rx framer LMFC offset\n"; + case MYKONOS_ERR_FRAMER_INV_REAL_IF_DATA_PARM: + return "Invalid Rx framer Real IF setting\n"; + case MYKONOS_ERR_OBSRX_FRAMER_INV_M_PARM: + return "Invalid ObsRx Framer M value\n"; + case MYKONOS_ERR_OBSRX_FRAMER_INV_BANKID_PARM: + return "Invalid ObsRx Framer Bank ID\n"; + case MYKONOS_ERR_OBSRX_FRAMER_INV_LANEID_PARM: + return "Invalid ObsRx framer Lane ID\n"; + case MYKONOS_ERR_OBSRX_FRAMER_INV_K_OFFSET_PARAM: + return "Invalid ObsRx framer LMFC offset\n"; + case MYKONOS_ERR_OBSRX_FRAMER_INV_REAL_IF_DATA_PARM: + return "Invalid ObsRx framer Real IF setting, M must =1\n"; + case MYKONOS_ERR_DEFRAMER_INV_M_PARM: + return "Invalid Deframer M setting\n"; + case MYKONOS_ERR_DEFRAMER_INV_BANKID_PARM: + return "Invalid Deframer Bank ID\n"; + case MYKONOS_ERR_ERR_DEFRAMER_INV_LANEID_PARM: + return "Invalid Deframer Lane ID\n"; + case MYKONOS_ERR_DEFRAMER_INV_K_OFFSET_PARAM: + return "Invalid Deframer LMFC offset"; + case MYKONOS_ERR_DEFRAMER_INV_K_PARAM: + return "Invalid Deframer K setting\n"; + case MYKONOS_ERR_DEFRAMER_INV_FK_PARAM: + return "Invalid Deframer F*K value\n"; + case MYKONOS_ERR_RX_FRAMER_INV_PRBS_POLYORDER_PARAM: + return "Invalid polyOrder parameter in enableRxFramerPrbs()\n"; + case MYKONOS_ERR_OBSRX_FRAMER_INV_PRBS_POLYORDER_PARAM: + return "Invalid polyOrder parameter in enableObsRxFramerPrbs()\n"; + case MYKONOS_ERR_DEFRAMER_INV_PRBS_ENABLE_PARAM: + return "Invalid enable parameter value in enableDeframerPrbsChecker()\n"; + case MYKONOS_ERR_DEFRAMER_INV_PRBS_POLYORDER_PARAM: + return "Invalid polyOrder parameter in enableDeframerPrbsChecker()\n"; + case MYKONOS_ERR_DEFRAMER_INV_PRBS_CNTR_SEL_PARAM: + return "Invalid lane counter select in readDeframerPrbsCounters()\n"; + case MYKONOS_ERR_INITARM_INV_DATARATE_PARM: + return 0; + case MYKONOS_ERR_INITARM_INV_VCODIV: + return "Invalid ARM VCO divider\n"; + case MYKONOS_ERR_INITARM_INV_REGCLK: + return "Invalid ARM SPI register clock rate\n"; + case MYKONOS_ERR_INITARM_INV_ARMCLK_PARAM: + return "Invalid ARM clock rate\n"; + case MYKONOS_ERR_LOADHEX_INV_CHARCOUNT: + return "LoadHex() char count = 0\n"; + case MYKONOS_ERR_LOADHEX_INVALID_FIRSTCHAR: + return "LoadHex() First char is not :\n"; + case MYKONOS_ERR_LOADHEX_INVALID_CHKSUM: + return "LoadHex() line checksum is invalid\n"; + case MYKONOS_ERR_LOADBIN_INVALID_BYTECOUNT: + return "Invalid byte count passed to function MYKONOS_loadArmFromBinary()"; + case MYKONOS_ERR_LOADARMCON_INVALID_BYTECOUNT: + return "Invalid byte count passed to function MYKONOS_loadArmConcurrent()"; + case MYKONOS_ERR_ARM_INVALID_BUILDCHKSUM: + return "Verify ARM checksum failed\n"; + case MYKONOS_ERR_READARMMEM_INV_ADDR_PARM: + return "ReadArmMem() was given an invalid memory address\n"; + case MYKONOS_ERR_WRITEARMMEM_INV_ADDR_PARM: + return "WriteArmMem() was given an invalid memory address\n"; + case MYKONOS_ERR_ARM_INV_ADDR_PARM: + return "Invalid memory address in MYKONOS_loadArmConcurrent()"; + case MYKONOS_ERR_ARMCMD_INV_OPCODE_PARM: + return "Invalid ARM opcode given to sendArmCommand()\n"; + case MYKONOS_ERR_ARMCMD_INV_NUMBYTES_PARM: + return "Invalid number of extended data in sendArmCommand()\n"; + case MYKONOS_ERR_ARMCMDSTATUS_INV_OPCODE_PARM: + return "Invalid opcode given to waitArmCmdStatus()\n"; + case MYKONOS_ERR_CHECKDEVSTRUCT_NULLDEVPOINTER: + return "Pointer to Mykonos device data structure is NULL\n"; + case MYKONOS_ERR_CHECKDEVSTRUCT_SPI: + return "Invalid spiSettings pointer in device data structure\n"; + case MYKONOS_ERR_CHECKDEVSTRUCT_RX: + return "Invalid device->rx pointer in device data structure\n"; + case MYKONOS_ERR_CHECKDEVSTRUCT_RXSUB: + return "Invalid pointer within device->rx data structure\n"; + case MYKONOS_ERR_CHECKDEVSTRUCT_RXFIR: + return "Invalid RXFIR pointer in device data structure\n"; + case MYKONOS_ERR_CHECKDEVSTRUCT_TX: + return "Invalid device->tx pointer in device data structure\n"; + case MYKONOS_ERR_CHECKDEVSTRUCT_TXSUB: + return "Invalid pointer within device->tx data structure\n"; + case MYKONOS_ERR_CHECKDEVSTRUCT_TXFIR: + return "Invalid TXFIR pointer in device data structure\n"; + case MYKONOS_ERR_CHECKDEVSTRUCT_OBSRX: + return "Invalid device->obsRx pointer in device data structure\n"; + case MYKONOS_ERR_CHECKDEVSTRUCT_OBSRXSUB: + return "Invalid pointer within device->obsRx data structure\n"; + case MYKONOS_ERR_CHECKDEVSTRUCT_SNIFFERFIR: + return "Invalid Sniffer FIR pointer in device data structure\n"; + case MYKONOS_ERR_CHECKDEVSTRUCT_ORXFIR: + return "Invalid ORX FIR pointer in device data structure\n"; + case MYKONOS_ERR_CHECKDEVSTRUCT_ORXGAINCTRL: + return "Invalid Orx gain control pointer in device data structure\n"; + case MYKONOS_ERR_CHECKDEVSTRUCT_SNIFFERGAINCTRL: + return "Invalid Sniffer gain control pointer in device data structure\n"; + case MYKONOS_ERR_CHECKDEVSTRUCT_OBSRXFRAMER: + return "Invalid obsRx framer pointer in device data structure\n"; + case MYKONOS_ERR_INITSER_INV_PROFILE: + return "Invalid RX profile within device data structure detected in MYKONOS_setupSerializers()\n"; + case MYKONOS_ERR_INITDES_INV_TXPROFILE: + return "Invalid TX profile within device data structure detected in MYKONOS_setupDeserializers()\n"; + case MYKONOS_ERR_JESD204B_ILAS_MISMATCH: + return "Mismatch detected in MYKONOS_jesd204bIlasCheck()\n"; + case MYKONOS_ERR_RXGAINTABLE_INV_CHANNEL: + return "Invalid channel specified in MYKONOS_programRxGainTable()\n"; + case MYKONOS_ERR_RXGAINTABLE_INV_GAIN_INDEX_RANGE: + return "Invalid numGainIndicesinTable greater than possible number of gain indices for channel. \n"; + case MYKONOS_ERR_WRITE_CFG_MEMORY_FAILED: + return "Failed write to ARM memory in MYKONOS_writeArmProfile()\n"; + case MYKONOS_ERR_INV_RXFRAMER_PCLKDIV_PARM: + return "Invalid PCLKDIV parameter detected in MYKONOS_setupSerializers()\n"; + case MYKONOS_ERR_RXFRAMER_INV_FK_PARAM: + return "Invalid FK parameter detected in MYKONOS_setupJesd204bFramer()\n"; + case MYKONOS_ERR_OBSRXFRAMER_INV_FK_PARAM: + return "Invalid FK paramter detected in MYKONOS_setupJesd204bObsRxFramer()\n"; + case MYKONOS_ERR_INV_OBSRXFRAMER_PCLKDIV_PARM: + return "Invalid PCLKDIV paramter detected in MYKONOS_setupSerializers()\n"; + case MYKONOS_ERR_PU_OBSRXPATH_INV_LOSOURCE_PARAM: + return "Invalid LO Source for OBSRX data path \n"; + case MYKONOS_ERR_ARM_RADIOON_FAILED: + return "ARM command to move to radioOn state failed. \n"; + case MYKONOS_ERR_ARM_RADIOOFF_FAILED: + return "ARM command to move to radioOff state failed. \n"; + case MYKONOS_ERR_INV_RX_GAIN_MODE_PARM: + return "Invalid gain control mode detected in MYKONOS_setRxGainControlMode()\n"; + case MYKONOS_ERR_INV_ORX_GAIN_MODE_PARM: + return "Invalid gain control mode detected in MYKONOS_setObsRxGainControlMode()\n"; + case MYKONOS_ERR_INV_AGC_RX_STRUCT_INIT: + return "Invalid RX AGC structure detected at &device->rx->rxAgcCtrl in MYKONOS_setupRxAgc()\n"; + case MYKONOS_ERR_INV_AGC_RX_PEAK_WAIT_TIME_PARM: + return "device->rx->rxAgcCtrl->agcPeakWaitTime out of range in MYKONOS_setupRxAgc()\n"; + case MYKONOS_ERR_INV_AGC_RX_GAIN_UPDATE_TIME_PARM: + return "device->rx->rxAgcCtrl->agcGainUpdateTime_us out of range in MYKONOS_setupRxAgc()\n"; + case MYKONOS_ERR_INV_AGC_RX_APD_HIGH_THRESH_PARM: + return "device->rx->rxAgcCtrl->apdHighThresh out of range in MYKONOS_setupRxAgc()\n"; + case MYKONOS_ERR_INV_AGC_RX_APD_LOW_THRESH_PARM: + return "device->rx->rxAgcCtrl->apdLowThresh out of range in MYKONOS_setupRxAgc()\n"; + case MYKONOS_ERR_INV_AGC_RX_BLOCK_DET_DECAY_PARM: + return "device->rx->rxAgcCtrl->apdDecay out of range in MYKONOS_setupRxAgc()\n"; + case MYKONOS_ERR_INV_AGC_RX_PEAK_STRUCT_INIT: + return "Data structure for peakAgc not initialized when used in MYKONOS_setupRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_RX_PWR_STRUCT_INIT: + return "Data structure for powerAgc not initialized when used in MYKONOS_setupRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_RX1_MAX_GAIN_INDEX: + return "device->rx->rxAgcCtrl->agcRx1MaxGainIndex out of range in MYKONOS_setupRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_RX1_MIN_GAIN_INDEX: + return "device->rx->rxAgcCtrl->agcRx1MinGainIndex out of range in MYKONOS_setupRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_RX2_MAX_GAIN_INDEX: + return "device->rx->rxAgcCtrl->agcRx2MaxGainIndex out of range in MYKONOS_setupRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_RX2_MIN_GAIN_INDEX: + return "device->rx->rxAgcCtrl->agcRx2MinGainIndex out of range in MYKONOS_setupRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_RX_SLOW_LOOP_SETTLING_DELAY: + return "device->rx->rxAgcCtrl->agcSlowLoopSettlingDelay out of range in MYKONOS_setupRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_PMD_MEAS_DURATION: + return "device->rx->rxAgcCtrl->powerAgc->pmdMeasDuration out of range in MYKONOS_setupRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_PMD_MEAS_CONFIG: + return "device->rx->rxAgcCtrl->powerAgc->pmdMeasConfig out of range in MYKONOS_setupRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_RX_LOW_THS_PREV_GAIN_INC: + return "device->rx->rxAgcCtrl->agcLowThsPreventGainIncrease out of range in MYKONOS_setupRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_RX_PEAK_THRESH_MODE: + return "device->rx->rxAgcCtrl->agcPeakThresholdMode out of range in MYKONOS_setupRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_RX_RESET_ON_RX_ENABLE: + return "device->rx->rxAgcCtrl->agcResetOnRxEnable out of range in MYKONOS_setupRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_RX_ENABLE_SYNC_PULSE_GAIN_COUNTER: + return "device->rx->rxAgcCtrl->agcEnableSyncPulseForGainCounter out of range in MYKONOS_setupRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_HIGH_THRESH: + return "device->rx->rxAgcCtrl->powerAgc->pmdLowerHighThresh out of range in MYKONOS_setupRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_LOW_THRESH: + return "device->rx->rxAgcCtrl->powerAgc->pmdUpperLowThresh out of range in MYKONOS_setupRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_LOW_THRESH: + return "device->rx->rxAgcCtrl->powerAgc->pmdLowerLowThresh out of range in MYKONOS_setupRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_HIGH_THRESH: + return "device->rx->rxAgcCtrl->powerAgc->pmdUpperHighThresh out of range in MYKONOS_setupRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_HIGH_GAIN_STEP: + return "device->rx->rxAgcCtrl->powerAgc->pmdUpperHighGainStepAttack out of range in MYKONOS_setupRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_LOW_GAIN_STEP: + return "device->rx->rxAgcCtrl->powerAgc->pmdLowerLowGainStepRecovery out of range in MYKONOS_setupRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_HIGH_GAIN_STEP: + return "device->rx->rxAgcCtrl->powerAgc->pmdLowerHighGainStepRecovery out of range in MYKONOS_setupRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_LOW_GAIN_STEP: + return "device->rx->rxAgcCtrl->powerAgc->pmdUpperLowGainStepAttack out of range in MYKONOS_setupRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_RX_PKDET_FAST_ATTACK_VALUE: + return "device->rx->rxAgcCtrl->peakAgc->apdFastAttack or hb2FastAttack out of range in MYKONOS_setupRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_RX_HB2_HIGH_THRESH_PARM: + return "device->rx->rxAgcCtrl->peakAgc->hb2HighThresh out of range in MYKONOS_setupRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_RX_HB2_LOW_THRESH_PARM: + return "device->rx->rxAgcCtrl->peakAgc->hb2LowThresh out of range in MYKONOS_setupRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_RX_HB2_VERY_LOW_THRESH_PARM: + return "device->rx->rxAgcCtrl->peakAgc->hb2VeryLowThresh out of range in MYKONOS_setupRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_RX_APD_HIGH_GAIN_STEP_PARM: + return "device->rx->rxAgcCtrl->peakAgc->apdHighGainStepAttack out of range in MYKONOS_setupRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_RX_APD_LOW_GAIN_STEP_PARM: + return "device->rx->rxAgcCtrl->peakAgc->apdLowGainStepRecovery out of range in MYKONOS_setupRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_RX_HB2_HIGH_GAIN_STEP_PARM: + return "device->rx->rxAgcCtrl->peakAgc->hb2HighGainStepAttack out of range in MYKONOS_setupRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_RX_HB2_LOW_GAIN_STEP_PARM: + return "device->rx->rxAgcCtrl->peakAgc->hb2LowGainStepRecovery out of range in MYKONOS_setupRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_RX_HB2_VERY_LOW_GAIN_STEP_PARM: + return "device->rx->rxAgcCtrl->peakAgc->hb2VeryLowGainStepRecovery out of range in MYKONOS_setupRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_RX_HB2_OVLD_ENABLE: + return "device->rx->rxAgcCtrl->peakAgc->hb2OverloadEnable out of range in MYKONOS_setupRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_RX_HB2_OVLD_THRESH_CNT: + return "device->rx->rxAgcCtrl->peakAgc->hb2OverloadThreshCnt out of range in MYKONOS_setupRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_RX_HB2_OVLD_DUR_CNT: + return "device->rx->rxAgcCtrl->peakAgc->hb2OverloadDurationCnt out of range in MYKONOS_setupRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_OBSRX_STRUCT_INIT: + return "Invalid OBSRX AGC structure detected at &device->obsRx->orxAgcCtrl in MYKONOS_setupObsRxAgc()\n"; + case MYKONOS_ERR_INV_AGC_OBSRX_PEAK_STRUCT_INIT: + return "Data structure for obsRx->orxAgcCtrl->peakAgc not initialized when used in MYKONOS_setupObsRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_OBSRX_PWR_STRUCT_INIT: + return "Data structure for obsRx->orxAgcCtrl->powerAgc not initialized when used in MYKONOS_setupObsRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_OBSRX_MAX_GAIN_INDEX: + return "device->obsRx->orxAgcCtrl->agcObsRxMaxGainIndex out of range in MYKONOS_setupObsRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_OBSRX_MIN_GAIN_INDEX: + return "device->obsRx->orxAgcCtrl->agcObsRxMinGainIndex out of range in MYKONOS_setupObsRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_OBSRX_SELECT: + return "device->obsRx->orxAgcCtrl->agcObsRxSelect out of range in MYKONOS_setupObsRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_OBSRX_GAIN_UPDATE_TIME_PARM: + return "device->obsRx->orxAgcCtrl->agcGainUpdateTime_us out of range in MYKONOS_setupObsRxAgc()\n"; + case MYKONOS_ERR_INV_AGC_OBSRX_PEAK_WAIT_TIME_PARM: + return "device->obsRx->orxAgcCtrl->agcPeakWaitTime out of range in MYKONOS_setupObsRxAgc()\n"; + case MYKONOS_ERR_INV_AGC_OBSRX_SLOW_LOOP_SETTLING_DELAY: + return "device->obsRx->orxAgcCtrl->agcSlowLoopSettlingDelay out of range in MYKONOS_setupObsRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_OBSRX_PMD_MEAS_DURATION: + return "device->obsRx->orxAgcCtrl->powerAgc->pmdMeasDuration out of range in MYKONOS_setupObsRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_OBSRX_PMD_MEAS_CONFIG: + return "device->obsRx->orxAgcCtrl->powerAgc->pmdMeasConfig out of range in MYKONOS_setupObsRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_OBSRX_LOW_THS_PREV_GAIN_INC: + return "device->obsRx->orxAgcCtrl->agcLowThsPreventGainIncrease out of range in MYKONOS_setupObsRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_OBSRX_PEAK_THRESH_MODE: + return "device->obsRx->orxAgcCtrl->agcPeakThresholdMode out of range in MYKONOS_setupObsRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_OBSRX_RESET_ON_RX_ENABLE: + return "device->obsRx->orxAgcCtrl->agcResetOnRxEnable out of range in MYKONOS_setupObsRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_OBSRX_ENABLE_SYNC_PULSE_GAIN_COUNTER: + return "device->obsRx->orxAgcCtrl->agcEnableSyncPulseForGainCounter out of range in MYKONOS_setupObsRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_HIGH_THRESH: + return "device->obsRx->orxAgcCtrl->powerAgc->pmdLowerHighThresh out of range in MYKONOS_setupObsRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_LOW_THRESH: + return "device->obsRx->orxAgcCtrl->powerAgc->pmdUpperLowThresh out of range in MYKONOS_setupObsRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_LOW_THRESH: + return "device->obsRx->orxAgcCtrl->powerAgc->pmdLowerLowThresh out of range in MYKONOS_setupObsRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_HIGH_THRESH: + return "device->obsRx->orxAgcCtrl->powerAgc->pmdUpperHighThresh out of range in MYKONOS_setupObsRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_HIGH_GAIN_STEP: + return "device->obsRx->orxAgcCtrl->powerAgc->pmdUpperHighGainStepAttack out of range in MYKONOS_setupObsRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_LOW_GAIN_STEP: + return "device->obsRx->orxAgcCtrl->powerAgc->pmdLowerLowGainStepRecovery out of range in MYKONOS_setupObsRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_LOW_GAIN_STEP: + return "device->obsRx->orxAgcCtrl->powerAgc->pmdUpperLowGainStepAttack out of range in MYKONOS_setupObsRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_OBSRX_PKDET_FAST_ATTACK_VALUE: + return "device->obsRx->orxAgcCtrl->peakAgc->apdFastAttack or hb2FastAttack out of range in MYKONOS_setupObsRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_OBSRX_APD_HIGH_THRESH_PARM: + return "device->obsRx->orxAgcCtrl->apdHighThresh out of range in MYKONOS_setupObsRxAgc()\n"; + case MYKONOS_ERR_INV_AGC_OBSRX_APD_LOW_THRESH_PARM: + return "device->obsRx->orxAgcCtrl->apdLowThresh out of range in MYKONOS_setupObsRxAgc()\n"; + case MYKONOS_ERR_INV_AGC_OBSRX_HB2_HIGH_THRESH_PARM: + return "device->obsRx->orxAgcCtrl->peakAgc->hb2HighThresh out of range in MYKONOS_setupObsRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_OBSRX_HB2_LOW_THRESH_PARM: + return "device->obsRx->orxAgcCtrl->peakAgc->hb2LowThresh out of range in MYKONOS_setupObsRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_OBSRX_HB2_VERY_LOW_THRESH_PARM: + return "device->obsRx->orxAgcCtrl->peakAgc->hb2VeryLowThresh out of range in MYKONOS_setupObsRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_OBSRX_APD_HIGH_GAIN_STEP_PARM: + return "device->obsRx->orxAgcCtrl->peakAgc->apdHighGainStepAttack out of range in MYKONOS_setupObsRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_OBSRX_APD_LOW_GAIN_STEP_PARM: + return "device->obsRx->orxAgcCtrl->peakAgc->apdLowGainStepRecovery out of range in MYKONOS_setupObsRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_OBSRX_HB2_HIGH_GAIN_STEP_PARM: + return "device->obsRx->orxAgcCtrl->peakAgc->hb2HighGainStepAttack out of range in MYKONOS_setupObsRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_OBSRX_HB2_LOW_GAIN_STEP_PARM: + return "device->obsRx->orxAgcCtrl->peakAgc->hb2LowGainStepRecovery out of range in MYKONOS_setupObsRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_OBSRX_HB2_VERY_LOW_GAIN_STEP_PARM: + return "device->obsRx->orxAgcCtrl->peakAgc->hb2VeryLowGainStepRecovery out of range in MYKONOS_setupObsRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_OBSRX_HB2_OVLD_ENABLE: + return "device->obsRx->orxAgcCtrl->peakAgc->hb2OverloadEnable out of range in MYKONOS_setupObsRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_OBSRX_HB2_OVLD_DUR_CNT: + return "device->obsRx->orxAgcCtrl->peakAgc->hb2OverloadDurationCnt out of range in MYKONOS_setupObsRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_OBSRX_HB2_OVLD_THRESH_CNT: + return "device->obsRx->orxAgcCtrl->peakAgc->hb2OverloadThresholdCnt out of range in MYKONOS_setupObsRxAgc() \n"; + case MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_HIGH_GAIN_STEP: + return "device->obsRx->orxAgcCtrl->powerAgc->pmdLowerHighGainStepRecovery out of range in MYKONOS_setupObsRxAgc() \n"; + case MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_CALPLL_LOCK: + return "CAL PLL Lock event timed out in MYKONOS_waitForEvent()\n"; + case MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_CLKPLLCP: + return "Clock PLL Charge Pump Cal event timed out in MYKONOS_waitForEvent()\n"; + case MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_CLKPLL_LOCK: + return "Clock PLL Lock event timed out in MYKONOS_waitForEvent()\n"; + case MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_RXPLLCP: + return "RX PLL Charge Pump Cal event timed out in MYKONOS_waitForEvent()\n"; + case MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_RXPLL_LOCK: + return "RX PLL Lock event timed out in MYKONOS_waitForEvent()\n"; + case MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_TXPLLCP: + return "TX PLL Charge Pump Cal event timed out in MYKONOS_waitForEvent()\n"; + case MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_TXPLL_LOCK: + return "TX PLL Lock event timed out in MYKONOS_waitForEvent()\n"; + case MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_SNIFFPLLCP: + return "Sniffer PLL Charge Pump Cal event timed out in MYKONOS_waitForEvent()\n"; + case MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_SNIFFPLL_LOCK: + return "Sniffer PLL Lock event timed out in MYKONOS_waitForEvent()\n"; + case MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_RXBBFCALDONE: + return "RX Baseband Filter Cal event timed out in MYKONOS_waitForEvent()\n"; + case MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_TXBBFCALDONE: + return "TX Baseband Filter Cal timed out in MYKONOS_waitForEvent()\n"; + case MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_RFDCCALDONE: + return "RF DC Offset Cal event timed out in MYKONOS_waitForEvent()\n"; + case MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_ADCTUNECALDONE: + return "ADC Tuner Cal event timed out in MYKONOS_waitForEvent()\n"; + case MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_RX1ADCPROFILE: + return "Rx1 ADC Profile Loading event timed out in MYKONOS_waitForEvent()\n"; + case MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_RX2ADCPROFILE: + return "Rx2 ADC Profile Loading event timed out in MYKONOS_waitForEvent()\n"; + case MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_ORXADCPROFILE: + return "ObsRx ADC Profile Loading event timed out in MYKONOS_waitForEvent()\n"; + case MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_RCALDONE: + return "Resistor Cal event timed out in MYKONOS_waitForEvent()\n"; + case MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_ARMBUSY: + return "ARM Busy event timed out in MYKONOS_waitForEvent()\n"; + case MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_INITARMDONE: + return "Initialize ARM event timed out in MYKONOS_waitForEvent()\n"; + case MYKONOS_ERR_TIMEDOUT_ARMMAILBOXBUSY: + return "ARM Mailbox Busy. Command not executed in MYKONOS_sendArmCommand()\n"; + case MYKONOS_ERR_PU_OBSRXPATH_ARMERROR: + return "ARM Command Error in MYKONOS_setObsRxPathSource()\n"; + case MYKONOS_ERR_EN_TRACKING_CALS_ARMSTATE_ERROR: + return "Device not in radioOff/IDLE state. Error in MYKONOS_enableTrackingCals()\n"; + case MYKONOS_ERR_SET_RADIOCTRL_PINS_ARMERROR: + return "ARM command Error in MYKONOS_setRadioControlPinMode()\n"; + case MYKONOS_ERR_EN_TRACKING_CALS_ARMERROR: + return "ARM Command Error in MYKONOS_enableTrackingCals()\n"; + case MYKONOS_ERR_SETRFPLL_ARMERROR: + return "ARM Command Error in MYKONOS_setRfPllFrequency()\n"; + case MYKONOS_ERR_INIT_INV_TXINPUTHB_PARM: + return "device->tx->txProfile->txInputHbInterpolation out of range in MYKONOS_initialize(): valid = 1,2 or 4\n"; + case MYKONOS_ERR_LOAD_ADCPROFILE_INV_VCODIV: + return "device->clocks->clkPllVcoDiv value not supported in MYKONOS_loadAdcProfiles\n"; + case MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_RXREQUIRED: + return "Custom RX ADC Profile required\n"; + case MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_ORXREQUIRED: + return "Custom ORX ADC Profile required\n"; + case MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_SNRXREQUIRED: + return "Custom SNRX ADC Profile required\n"; + case MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_LBREQUIRED: + return "Custom Loopback ADC profile required\n"; + case MYKONOS_ERR_LOAD_LBADCPROFILE_ARMMEM_FAILED: + return "WriteArmMemory call failed while writing the Loopback ADC profile into ARM memory\n"; + case MYKONOS_ERR_LOAD_SNRXADCPROFILE_ARMMEM_FAILED: + return "WriteArmMemory call failed while writing the Sniffer ADC profile into ARM memory\n"; + case MYKONOS_ERR_LOAD_ORXADCPROFILE_ARMMEM_FAILED: + return "WriteArmMemory call failed while writing the ObsRx ADC profile into ARM memory\n"; + case MYKONOS_ERR_LOAD_RXADCPROFILE_ARMMEM_FAILED: + return "WriteArmMemory call failed while writing the RX ADC profile into ARM memory\n"; + case MYKONOS_ERR_LOAD_ADCPROFILE_SNRX_ADCDIV_ZERO: + return "SnRx profile has invalid ADC divider of 0, causing a divide by zero\n"; + case MYKONOS_ERR_LOAD_ADCPROFILE_ORXADCDIV_ZERO: + return "ORx profile has invalid ADC divider of 0, causing a divide by zero\n"; + case MYKONOS_ERR_LOAD_ADCPROFILE_RXADCDIV_ZERO: + return "Rx profile has invalid ADC divider of 0, causing a divide by zero\n"; + case MYKONOS_ERR_LOAD_ADCPROFILE_MISSING_ORX_PROFILE: + return "If Tx Profile is valid, a matching ORx profile must be provided to set ADC divider and digital filtering for loopback calibrations\n"; + case MYKONOS_ERR_SETUP_PA_PROT_INV_AVG_DURATION: + return "Invalid setting for avgDuration in MYKONOS_setupPaProtection(...)\n"; + case MYKONOS_ERR_SETUP_PA_PROT_INV_ATTEN_STEP: + return "Invalid setting for attenStepSize in MYKONOS_setupPaProtection(...)\n"; + case MYKONOS_ERR_SETUP_PA_PROT_INV_ATTEN_ENABLE: + return "Invalid setting for txAttenControlEnable in MYKONOS_setupPaProtection(...)\n"; + case MYKONOS_ERR_SETUP_PA_PROT_INV_POWER_THRESH: + return "Invalid setting for powerThreshold in MYKONOS_setupPaProtection(...)\n"; + case MYKONOS_ERR_SETUP_PA_PROT_INV_TX_CHANNEL: + return "Invalid TX channel selected for MYKONOS_getDacPower(...)\n"; + case MYKONOS_ERR_GET_DAC_PWR_INV_POINTER: + return "Cannot return DAC Power information (invalid pointer)\n"; + case MYKONOS_ERR_GET_PA_FLAG_STATUS_INV_POINTER: + return "Cannot return PA Protection Flag Status information (invalid pointer)\n"; + case MYKONOS_ERR_GET_OBSRX_OVERLOADS_NULL_PARM: + return "MYKONOS_getObsRxPathOverloads() has null *obsRxOverloads parameter\n"; + case MYKONOS_ERR_GET_RX1_OVERLOADS_NULL_PARM: + return "MYKONOS_getRxPathOverloads() has null *rx1Overloads parameter\n"; + case MYKONOS_ERR_GET_RX2_OVERLOADS_NULL_PARM: + return "MYKONOS_getRxPathOverloads() has null *rx2Overloads parameter\n"; + case MYKONOS_ERR_GETRADIOSTATE_NULL_PARAM: + return "MYKONOS_getRadioState() has null *radioStatus parameter\n"; + case MYKONOS_ERR_ABORT_INITCALS_NULL_PARAM: + return "MYKONOS_abortInitCals() has null *calsCompleted parameter\n"; + case MYKONOS_ERR_WAIT_INITCALS_ARMERROR: + return "MYKONOS_waitInitCals() returned an ARM error\n"; + case MYKONOS_ERR_WAIT_INITCALS_NULL_PARAM: + return "MYKONOS_waitInitCals() has one or more null parameters\n"; + case MYKONOS_ERR_CHECK_PLL_LOCK_NULL_PARM: + return "MYKONOS_checkPllsLockStatus() has a null *pllLockStatus parameter\n"; + case MYKONOS_ERR_GET_TXFILTEROVRG_NULL_PARM: + return "MYKONOS_getTxFilterOverRangeStatus() has a null *txFilterStatus parameter\n"; + case MYKONOS_ERR_PROGRAM_RXGAIN_TABLE_NULL_PARM: + return "MYKONOS_programRxGainTable() has a null *gainTablePtr parameter\n"; + case MYKONOS_ERR_PROGRAMFIR_NULL_PARM: + return "MYKONOS_programFir() has a null *firFilter parameter\n"; + case MYKONOS_ERR_PROGRAMFIR_COEFS_NULL: + return "MYKONOS_programFir() has a null coef array in *firFilter structure\n"; + case MYKONOS_ERR_READ_DEFRAMERSTATUS_NULL_PARAM: + return "MYKONOS_readDeframerStatus() has a null *deframerStatus parameter\n"; + case MYKONOS_ERR_READ_DEFRAMERPRBS_NULL_PARAM: + return "MYKONOS_readDeframerPrbscounters() has a null *prbsErrorCount parameter\n"; + case MYKONOS_ERR_READ_ORXFRAMERSTATUS_NULL_PARAM: + return "MYKONOS_readOrxFramerStatus() has a null *obsFramerStatus parameter\n"; + case MYKONOS_ERR_READ_RXFRAMERSTATUS_NULL_PARAM: + return "MYKONOS_readRxFramerStatus() has a null *framerStatus parameter\n"; + case MYKONOS_ERR_ARMCMDSTATUS_NULL_PARM: + return "MYKONOS_waitArmCmdStatus() has a null *cmdStatByte parameter\n"; + case MYKONOS_ERR_READARMCMDSTATUS_NULL_PARM: + return "MYKONOS_readArmCmdStatus() has one or more null pointer parameters\n"; + case MYKONOS_ERR_READARMCMDSTATUS_INV_OPCODE_PARM: + return "MYKONOS_readArmCmdStatusByte() has an invalid opcode parameter\n"; + case MYKONOS_ERR_READARMCMDSTATUSBYTE_NULL_PARM: + return "MYKONOS_readArmCmdStatusByte() has a null *cmdStatByte parameter\n"; + case MYKONOS_ERR_ARMCMD_NULL_PARM: + return "MYKONOS_sendArmCommand() has a null *extendedData parameter\n"; + case MYKONOS_ERR_WRITEARMMEM_NULL_PARM: + return "MYKONOS_writeArmMem() has a null *data parameter\n"; + case MYKONOS_ERR_LOADBIN_NULL_PARAM: + return "MYKONOS_loadArmFromBinary() has a null *binary parameter\n"; + case MYKONOS_ERR_LOADARMCON_NULL_PARAM: + return "MYKONOS_loadArmConcurrent() has a null *binary parameter\n"; + case MYKONOS_ERR_GETTX1ATTEN_NULL_PARM: + return "MYKONOS_getTx1Attenuation() has NULL tx1Attenuation_mdB parameter\n"; + case MYKONOS_ERR_GETTX2ATTEN_NULL_PARM: + return "MYKONOS_getTx2Attenuation() has NULL tx2Attenuation_mdB parameter\n"; + case MYKONOS_ERR_ENFRAMERLINK_INV_LANESEN_PARM: + return "Invalid serializer Lanes Enable parameter in Rx framer structure\n"; + case MYKONOS_ERR_ENOBSFRAMERLINK_INV_LANESEN_PARM: + return "Invalid serializer Lanes Enable parameter in ObsRx framer structure\n"; + case MYKONOS_ERR_ENTXNCO_TXPROFILE_INVALID: + return "Can not enable Tx NCO when Tx Profile is invalid\n"; + case MYKONOS_ERR_ENTXNCO_TX1_FREQ_INVALID: + return "Invalid Tx1 NCO frequency\n"; + case MYKONOS_ERR_ENTXNCO_TX2_FREQ_INVALID: + return "Invalid Tx2 NCO frequency\n"; + case MYKONOS_ERR_JESD204B_ILAS_MISMATCH_NULLPARAM: + return "Function parameter has NULL pointer in MYKONOS_jesd204bIlasCheck()\n"; + case MYKONOS_ERR_GET_PLLFREQ_INV_REFCLKDIV: + return "CLKPLL refclk divider was read back as an invalid setting in MYKONOS_getRfPllFrequency()\n"; + case MYKONOS_ERR_GET_PLLFREQ_INV_HSDIV: + return "CLKPLL HSDIV divider was read back as an invalid setting in MYKONOS_getRfPllFrequency()\n"; + case MYKONOS_ERR_GET_PLLFREQ_INV_VCODIV: + return "CLKPLL VCODIV divider was read back as an invalid setting in MYKONOS_getRfPllFrequency()\n"; + case MYKONOS_ERR_GET_RX1_DEC_POWER_NULL_PARM: + return "MYKONOS_getRx1DecPower() has a null *rx1DecPower_mdBFS parameter\n"; + case MYKONOS_ERR_GET_RX1_DEC_POWER_NUM_SAMPLES: + return "MYKONOS_getRx1DecPower() numSamples greater than agcGainUpdateCounter\n"; + case MYKONOS_ERR_GET_RX2_DEC_POWER_NULL_PARM: + return "MYKONOS_getRx2DecPower() has a null *rx2DecPower_mdBFS parameter\n"; + case MYKONOS_ERR_GET_RX2_DEC_POWER_NUM_SAMPLES: + return "MYKONOS_getRx2DecPower() numSamples greater than agcGainUpdateCounter\n"; + case MYKONOS_ERR_GET_OBSRX_DEC_POWER_NULL_PARM: + return "MYKONOS_getObsRxDecPower() has a null *obsRxDecPower_mdBFS parameter\n"; + case MYKONOS_ERR_GET_OBSRX_DEC_POWER_NUM_SAMPLES: + return "MYKONOS_getObsRxDecPower() numSamples greater than agcGainUpdateCounter\n"; + case MYKONOS_ERR_GETARMVER_NULL_PARM: + return "MYKONOS_getArmVersion() has a NULL pointer in one of the function parameters\n"; + case MYKONOS_ERR_EN_DPDTRACKING_ARMSTATE_ERROR: + return "ARM is not in the RadioOff state before MYKONOS_enableDpdTracking(), call MYKONOS_radioOff()\n"; + case MYKONOS_ERR_RESTDPDMOD_WRONGBUFFERSIZE: + return "MYKONOS_restoreDpdModel() supplied DPD Model Data Buffer is incorrect size\n"; + case MYKONOS_ERR_RESTDPDMOD_ARMERRFLAG: + return "The ARM reported a error while in MYKONOS_restoreDpdModel().\n"; + case MYKONOS_ERR_RESTDPDMOD_INVALID_TXCHANNEL: + return "MYKONOS_restoreDpdModel() invalid txChannel specified\n"; + case MYKONOS_ERR_SAVDPDMOD_WRONGBUFFERSIZE: + return "MYKONOS_saveDpdModel() supplied DPD Model Data Buffer is incorrect size\n"; + case MYKONOS_ERR_SAVDPDMOD_ARMSTATE: + return "ARM is not in the RadioOff state before MYKONOS_saveDpdModel(), call MYKONOS_radioOff()\n"; + case MYKONOS_ERR_SAVDPDMOD_INVALID_TXCHANNEL: + return "MYKONOS_saveDpdModel() invalid txChannel specified\n"; + case MYKONOS_ERR_EN_CLGCTRACKING_ARMSTATE_ERROR: + return "ARM is not in the RadioOff state before MYKONOS_enableClgcTracking(), call MYKONOS_radioOff()\n"; + case MYKONOS_ERR_CFGDPD_TXORX_PROFILE_INV: + return "Tx or ORx profile is not valid, both are necessary for DPD features in MYKONOS_configDpd()\n"; + case MYKONOS_ERR_CFGDPD_NULL_DPDCFGSTRUCT: + return "device->tx->dpdConfig structure has NULL pointer in MYKONOS_configDpd()\n"; + case MYKONOS_ERR_WRITEARMCFG_ARMERRFLAG: + return "The ARM reported a error while writing to an ARM config structure in MYKONOS_writeArmCfgStruct()\n"; + case MYKONOS_ERR_CFGDPD_INV_DPDDAMPING: + return "ERROR: device->tx->dpdConfig->damping parameter is out of range (0-15)\n"; + case MYKONOS_ERR_CFGDPD_INV_DPDSAMPLES: + return "ERROR: device->tx->dpdConfig->samples parameter is out of range (64 - 32768)\n"; + case MYKONOS_ERR_CFGDPD_INV_NUMWEIGHTS: + return "ERROR: device->tx->dpdConfig->numWeights parameter is out of range (0-3)\n"; + case MYKONOS_ERR_CFGDPD_INV_DPDOUTLIERTHRESH: + return "ERROR: device->tx->dpdConfig->outlierThreshold parameter is out of range\n"; + case MYKONOS_ERR_CFGDPD_INV_DPDPRIORWEIGHT: + return "ERROR: device->tx->dpdConfig->modelPriorWeight parameter is out of range (Valid 0-32)\n"; + case MYKONOS_ERR_CFGCLGC_INV_DESIREDGAIN: + return "ERROR: device->tx->clgcConfig->tx1DesiredGain or tx2DesiredGain parameter is out of range\n"; + case MYKONOS_ERR_CFGCLGC_INV_TXATTENLIMIT: + return "ERROR: device->tx->clgcConfig->tx1AttenLimit or tx2AttenLimit parameter is out of range\n"; + case MYKONOS_ERR_CFGCLGC_INV_CLGC_CTRLRATIO: + return "ERROR: device->tx->clgcConfig->tx1ControlRatio or tx2ControlRatio parameter is out of range\n"; + case MYKONOS_ERR_CFGDPD_INV_DPD_ADDDELAY: + return "ERROR: device->tx->dpdConfig->additionalDelayOffset parameter is out of range\n"; + case MYKONOS_ERR_CFGDPD_INV_PNSEQLEVEL: + return "ERROR: device->tx->dpdConfig->pathDelayPnSeqLevel parameter is out of range\n"; + case MYKONOS_ERR_CFGDPD_INV_MODELVERSION: + return "ERROR: device->tx->dpdConfig->modelVersion parameter is out of range\n"; + case MYKONOS_ERR_READARMCFG_ARMERRFLAG: + return "ERROR: MYKONOS_readArmConfig failed due to an ARM error\n"; + case MYKONOS_ERR_GETPENDTRKCALS_NULL_PARAM: + return "MYKONOS_getPendingTrackingCals() has NULL function parameter\n"; + case MYKONOS_ERR_ARMCMDSTATUS_ARMERROR: + return "MYKONOS_waitArmCmdStatus() exited due to ARM error for the desired ARM opcode\n"; + case MYKONOS_ERR_WAITARMCMDSTATUS_TIMEOUT: + return "MYKONOS_waitArmCmdStatus() timed out waiting for the ARM to complete the requested command\n"; + case MYKONOS_ERR_PU_GETOBSRXPATH_ARMERROR: + return "ARM returned an error while trying to get the ObsRx Path source in MYKONOS_getObsRxPathSource()\n"; + case MYKONOS_ERR_GETDPDCFG_NULL_DPDCFGSTRUCT: + return "MYKONOS_getDpdConfig() could not complete due to a NULL pointer to device->tx->dpdConfig structure\n"; + case MYKONOS_ERR_GETDPDCFG_TXORX_PROFILE_INV: + return "The Tx and ORx profiles must be valid for DPD related functions\n"; + case MYKONOS_ERR_GETDPDSTATUS_ARMERRFLAG: + return "MYKONOS_getDpdStatus() reported an ARM error with the ARM Get command\n"; + case MYKONOS_ERR_GETDPDSTATUS_NULLPARAM: + return "MYKONOS_getDpdStatus() has NULL pointer in the function parameter\n"; + case MYKONOS_ERR_SETDEFOBSRXPATH_NULL_OBSRX_STRUCT: + return "Observation profile not valid, device->obsRx structure is NULL in MYKONOS_setDefaultObsRxPath()\n"; + case MYKONOS_ERR_GETCLGCSTATUS_NULLPARAM: + return "MYKONOS_getClgcStatus() has NULL clgcStatus parameter\n"; + case MYKONOS_ERR_GETCLGCSTATUS_ARMERRFLAG: + return "ARM reported an error with the ARM GET command during MYKONOS_getClgcStatus()\n"; + case MYKONOS_ERR_READ_DEFFIFODEPTH_NULL_PARAM: + return "MYKONOS_getDeframerFifoDepth() function parameter fifoDepth is a NULL pointer\n"; + case MYKONOS_ERR_READ_DEFFIFODEPTH_LMFCCOUNT_NULL_PARAM: + return "MYKONOS_getDeframerFifoDepth() function parameter readEnLmfcCount is a NULL pointer\n"; + case MYKONOS_ERR_GETDPDSTATUS_INV_CH: + return "MYKONOS_getDpdStatus() txChannel parameter is not valid (TX1 and TX2 are the only valid options)\n"; + case MYKONOS_ERR_GETCLGCSTATUS_INV_CH: + return "MYKONOS_getClgcStatus() txChannel parameter is not valid (TX1 and TX2 are the only valid options)\n"; + case MYKONOS_ERR_INIT_INV_TXINPUTHB_INV_RATE: + return "Invalid Tx profile: When using Tx Input halfband, IQ rate must not exceed 160MSPS\n"; + case MYKONOS_ERR_INIT_INV_TXINPUTHB0_INV_RATE: + return "Invalid Tx profile: When using Tx Input halfband 0, IQ rate must not exceed 80MSPS\n"; + case MYKONOS_ERR_RXFIR_TAPSEXCEEDED: + return "Rx PFIR can not be clocked fast enough to handle the number of FIR coefficents provided\n"; + case MYKONOS_ERR_ORXFIR_TAPSEXCEEDED: + return "ORx PFIR can not be clocked fast enough to handle the number of FIR coefficents provided\n"; + case MYKONOS_ERR_SNRXFIR_TAPSEXCEEDED: + return "Sniffer Rx PFIR can not be clocked fast enough to handle the number of FIR coefficents provided\n"; + case MYKONOS_ERR_TXFIR_INV_NUMTAPS_PARM: + return "Invalid number of Tx FIR coefficients\n"; + case MYKONOS_ERR_TXFIR_INV_NUMROWS: + return "Invalid number of PFIR coefficient rows\n"; + case MYKONOS_ERR_TXFIR_TAPSEXCEEDED: + return "Too many Tx PFIR taps for the IQ sample rate. FIR processing clock can not run fast enough to handle the number of taps\n"; + case MYKONOS_ERR_GETINITCALSTATUS_NULL_PARAM: + return "MYKONOS_getInitCalStatus() has a null pointer in parameter list\n"; + case MYKONOS_ERR_GETINITCALSTATUS_ARMERROR: + return "MYKONOS_getInitCalStatus() returned an ARM error while getting the init cal status information"; + case MYKONOS_ERR_CFGCLGC_TXORX_PROFILE_INV: + return "Tx and ObsRx profiles must be valid to use the CLGC feature in MYKONOS_configClgc()\n"; + case MYKONOS_ERR_CFGCLGC_NULL_CLGCCFGSTRUCT: + return "CLGC config structure is NULL in device->tx->clgcConfig in MYKONOS_configClgc()\n"; + case MYKONOS_ERR_GETCLGCCFG_TXORX_PROFILE_INV: + return "Could not read back CLGC status because Tx and ORx profiles are not valid\n"; + case MYKONOS_ERR_GETCLGCCFG_NULL_CFGSTRUCT: + return "Could not read back CLGC status because return structure device->tx->clgcConfig pointer is NULL\n"; + case MYKONOS_ERR_CALCDIGCLK_NULLDEV_PARAM: + return "device structure pointer is NULL in MYKONOS_calculateDigitalClocks()\n"; + case MYKONOS_ERR_CALCDIGCLK_NULL_CLKSTRUCT: + return "device->clocks structure pointer is NULL in MYKONOS_calculateDigitalClocks()\n"; + case MYKONOS_ERR_NULL_DEVICE_PARAM: + return "The device pointer in the calling function's parameter list is a NULL pointer\n"; + case MYKONOS_ERR_CALCDEVCLK_NULLPARAM: + return "MYKONOS_calculateScaledDeviceClk_kHz() has a NULL pointer in one of the function parameters\n"; + case MYKONOS_ERR_CFGCLGC_INV_CLGC_ADDDELAY: + return "CLGC Additional Delay parameter is out of range in MYKONOS_configClgc\n"; + case MYKONOS_ERR_CFGCLGC_INV_PNSEQLEVEL: + return "CLGC PN Sequence level parameter is out of range in MYKONOS_configClgc\n"; + case MYKONOS_ERR_CFGVSWR_TXORX_PROFILE_INV: + return "The Tx and ORx profiles must be valid to use the VSWR feature in MYKONOS_configVswr()\n"; + case MYKONOS_ERR_CFGVSWR_ARMSTATE_ERROR: + return "ARM must be in radioOff state to configure the VSWR config parameters in MYKONOS_configVswr()\n"; + case MYKONOS_ERR_CFGVSWR_INV_3P3GPIOPIN: + return "VSWR 3.3v GPIO pin selection is out of range (0-11) in MYKONOS_configVswr()\n"; + case MYKONOS_ERR_CFGVSWR_INV_PNSEQLEVEL: + return "VSWR init PN sequence level is out of range in MYKONOS_configVswr()\n"; + case MYKONOS_ERR_CFGVSWR_INV_VSWR_ADDDELAY: + return "VSWR additionalDelay member is out of range in MYKONOS_configVswr()\n"; + case MYKONOS_ERR_CFGVSWR_NULL_VSWRCFGSTRUCT: + return "device->tx->vswrConfig pointer is null in MYKONOS_confgiVswr()\n"; + case MYKONOS_ERR_GETVSWRCFG_NULL_CFGSTRUCT: + return "device->tx->vswrConfig pointer is null in MYKONOS_getVswrConfig()\n"; + case MYKONOS_ERR_GETVSWRCFG_TXORX_PROFILE_INV: + return "Tx and ORx profiles must be valid in MYKONOS_getVswrConfig()\n"; + case MYKONOS_ERR_GETVSWRSTATUS_ARMERRFLAG: + return "ARM returned an error while attempting to read the VSWR status structure\n"; + case MYKONOS_ERR_GETVSWRSTATUS_INV_CH: + return "Invalid Tx channel parameter passed to MYKONOS_getVswrStatus()\n"; + case MYKONOS_ERR_GETVSWRSTATUS_NULLPARAM: + return "vswrStatus function parameter is null in MYKONOS_getVswrStatus\n"; + case MYKONOS_ERR_SET_RX_MAX_GAIN_INDEX: + return "Max gain index bigger than max gain index loaded table in MYKONOS_setRxAgcMinMaxGainIndex().\n"; + case MYKONOS_ERR_SET_RX_MIN_GAIN_INDEX: + return "Min gain index lower than min gain index loaded table in MYKONOS_setRxAgcMinMaxGainIndex().\n"; + case MYKONOS_ERR_AGC_MIN_MAX_RX_CHANNEL: + return "Wrong RX channel selected in MYKONOS_setRxAgcMinMaxGainIndex().\n"; + case MYKONOS_ERR_SET_ORX_MAX_GAIN_INDEX_CHANNEL: + return "Wrong read back channel in MYKONOS_setObsRxAgcMinMaxGainIndex().\n"; + case MYKONOS_ERR_SET_ORX_MAX_GAIN_INDEX: + return "Max gain index bigger than max gain index loaded table in MYKONOS_setObsRxAgcMinMaxGainIndex().\n"; + case MYKONOS_ERR_SET_ORX_MIN_GAIN_INDEX: + return "Min gain index lower than min gain index loaded table in MYKONOS_setObsRxAgcMinMaxGainIndex().\n"; + case MYKONOS_ERR_AGC_MIN_MAX_ORX_CHANNEL: + return "Wrong observation channel selected in MYKONOS_setObsRxAgcMinMaxGainIndex().\n"; + case MYKONOS_ERR_RX1_TEMP_GAIN_COMP_RANGE: + return "The temp gain compensation is outside range (-3000mdB to 3000mdB) in MYKONOS_setRx1TempGainComp().\n"; + case MYKONOS_ERR_RX1_TEMP_GAIN_COMP_STEP: + return "Not valid temp gain compensation, step size is 250mdB in MYKONOS_setRx1TempGainComp().\n"; + case MYKONOS_ERR_RX2_TEMP_GAIN_COMP_RANGE: + return "The temp gain compensation is outside range (-3000mdB to 3000mdB) in MYKONOS_setRx2TempGainComp().\n"; + case MYKONOS_ERR_RX2_TEMP_GAIN_COMP_STEP: + return "Not valid temp gain compensation, step size is 250mdB in MYKONOS_setRx2TempGainComp().\n"; + case MYKONOS_ERR_OBS_RX_TEMP_GAIN_COMP_RANGE: + return "The temp gain compensation is outside range (-3000mdB to 3000mdB) in MYKONOS_setObsRxTempGainComp().\n"; + case MYKONOS_ERR_OBS_RX_TEMP_GAIN_COMP_STEP: + return "Not valid temp gain compensation, step size is 250mdB in MYKONOS_setObsRxTempGainComp().\n"; + case MYKONOS_ERR_RX1_TEMP_GAIN_COMP_NULL: + return "rx1TempCompGain_mdB pointer is null MYKONOS_getRx1TempGainComp().\n"; + case MYKONOS_ERR_RX2_TEMP_GAIN_COMP_NULL: + return "rx2TempCompGain_mdB pointer is null MYKONOS_getRx2TempGainComp().\n"; + case MYKONOS_ERR_OBS_RX_TEMP_GAIN_COMP_NULL: + return "obsRxTempCompGain_mdB pointer is null MYKONOS_getObsRxTempGainComp().\n"; + case MYKONOS_ERR_GETORXQECSTATUS_NULLPARAM: + return "Function parameter mykonosOrxQecStatus_t is a NULL pointer in MYKONOS_getOrxQecStatus().\n"; + case MYKONOS_ERR_GETORXQECSTATUS_INV_CH: + return "Channel selection not valid in MYKONOS_getOrxQecStatus().\n"; + case MYKONOS_ERR_GETORXQECSTATUS_ARMERRFLAG: + return "ARM command error in MYKONOS_getOrxQecStatus().\n"; + case MYKONOS_ERR_GETRXQECSTATUS_NULLPARAM: + return "Function parameter mykonosRxQecStatus_t is a NULL pointer in MYKONOS_getRxQecStatus().\n"; + case MYKONOS_ERR_GETRXQECSTATUS_INV_CH: + return "Channel selection not valid in MYKONOS_getRxQecStatus().\n"; + case MYKONOS_ERR_GETRXQECSTATUS_ARMERRFLAG: + return "ARM command error in MYKONOS_getRxQecStatus().\n"; + case MYKONOS_ERR_GETTXQECSTATUS_NULLPARAM: + return "Function parameter mykonosTxQecStatus_t is a NULL pointer in MYKONOS_getRxQecStatus().\n"; + case MYKONOS_ERR_GETTXQECSTATUS_INV_CH: + return "Channel selection not valid in MYKONOS_getTxQecStatus().\n"; + case MYKONOS_ERR_GETTXQECSTATUS_ARMERRFLAG: + return "ARM command error in MYKONOS_getTxQecStatus().\n"; + case MYKONOS_ERR_GETTXLOLSTATUS_NULLPARAM: + return "Function parameter mykonosTxLolStatus_t is a NULL pointer in MYKONOS_getTLolStatus().\n"; + case MYKONOS_ERR_GETTXLOLSTATUS_INV_CH: + return "Channel selection not valid in MYKONOS_getTLolStatus().\n"; + case MYKONOS_ERR_GETTXLOLSTATUS_ARMERRFLAG: + return "ARM command error in MYKONOS_getTLolStatus().\n"; + case MYKONOS_ERR_RESCHEDULE_TRACK_CAL_INV: + return "Not valid calibration passed to MYKONOS_rescheduleTrackingCal().\n"; + case MYKONOS_ERR_RESCHEDULE_TRACK_ARMERRFLAG: + return "ARM error in MYKONOS_rescheduleTrackingCal().\n"; + case MYKONOS_ERR_ARMSTATE_EXCEPTION: + return "ARM system problem has been detected.\n"; + case MYKONOS_ERR_ARMSTATE_CAL_ERROR: + return "ARM has detected an error in the tracking calibrations.\n"; + case MYKONOS_ERR_ARMSTATE_PROFILE_ERROR: + return "ARM has detected an illegal profile.\n"; + case MYKONOS_ERR_WAITARMCSTATE_TIMEOUT: + return "Timeout occurred in MYKONOS_checkArmState().\n"; + case MYKONOS_ERR_GET_API_VERSION_NULL_PARAM: + return "Null parameter passed to the function MYKONOS_getApiVersion().\n"; + case MYKONOS_ERR_GETPRODUCTID_NULL_PARAM: + return "Null parameter passed to the function MYKONOS_getProductId().\n"; + case MYKONOS_ERR_TXPROFILE_IQRATE: + return "Tx Profile IQ rate out of range.\n"; + case MYKONOS_ERR_TXPROFILE_RFBW: + return "Tx Profile RF bandwidth out of range.\n"; + case MYKONOS_ERR_TXPROFILE_FILTER_INTERPOLATION: + return "Tx Filter interpolation not valid.\n"; + case MYKONOS_ERR_TXPROFILE_FIR_COEFS: + return "Tx FIR filter not valid.\n"; + case MYKONOS_ERR_RXPROFILE_RXCHANNEL: + return " Rx channel is not valid.\n"; + case MYKONOS_ERR_RXPROFILE_IQRATE: + return "Receiver profile out of range IQ rate.\n"; + case MYKONOS_ERR_RXPROFILE_RFBW: + return "Receiver profile out of range RF bandwidth.\n"; + case MYKONOS_ERR_RXPROFILE_FILTER_DECIMATION: + return "Receiver profile not valid filter decimation setting.\n"; + case MYKONOS_ERR_RXPROFILE_FIR_COEFS: + return "Receiver profile FIR filter not valid.\n"; + case MYKONOS_ERR_RXPROFILE_ADCDIV: + return "Receiver profile not valid ADC divider.\n"; + case MYKONOS_ERR_PROFILES_HSDIGCLK: + return "Profile combinations loaded are not valid.\n"; + case MYKONOS_ERR_RESET_TXLOL_INV_PARAM: + return "Selected channel is not valid.\n"; + case MYKONOS_ERR_RESET_TXLOL_ARMERROR: + return "ARM command error in MYKONOS_resetExtTxLolChannel().\n"; + case MYKONOS_ERR_SETSTATEALL_TRACK_CAL_INV: + return "Not valid calibration mask passed for trackCals.\n"; + case MYKONOS_ERR_SETSTATEALL_TRACK_ARMERRFLAG: + return "ARM error flag set.\n"; + case MYKONOS_ERR_GETSTATEALL_TRACK_ARMERRFLAG: + return "ARM error flag set.\n"; + case MYKONOS_ERR_GETSTATEALL_TRACK_ARMERROR: + return "ARM command error.\n"; + case MYKONOS_ERR_GETSTATEALL_TRACK_NULL_PARAM: + return "Null parameter passed for trackCals.\n"; + case MYKONOS_ERR_SETSTATE_TRACK_CAL_INV: + return "Not valid calibration passed.\n"; + case MYKONOS_ERR_SETSTATE_TRACK_ARMERRFLAG: + return "ARM command error.\n"; + case MYKONOS_ERR_GETSTATE_TRACK_NULL_PARAM: + return "Null parameter passed to trackCalState.\n"; + case MYKONOS_ERR_GETSTATE_TRACK_ARMERRFLAG: + return "ARM command error flag set.\n"; + case MYKONOS_ERR_GETSTATE_TRACK_ARMERROR: + return "ARM command error.\n"; + case MYKONOS_ERR_SETCLGCGAIN_INV_TXCHANNEL: + return "Tx channel is not valid (Valid ENUM values: TX1 or TX2 only).\n"; + case MYKONOS_ERR_SETCLGCGAIN_TRACK_ARMERRFLAG: + return "ARM command flag error set.\n"; + case MYKONOS_ERR_SETCLGCGAIN_INV_DESIREDGAIN: + return "CLGC gain parameter is out of range, valid range is from -10000 to 10000.\n"; + case MYKONOS_ERR_SETDPDACT_INV_TXCHANNEL: + return "Tx channel is not valid (Valid ENUM values: TX1, TX2 or TX1_TX2).\n"; + case MYKONOS_ERR_SETDPDACT_INV_STATE: + return "Invalid Actuator state, valid states are 0-disable and 1-enable.\n"; + case MYKONOS_ERR_SETDPDACT_ARMERRFLAG: + return "ARM command flag error set.\n"; + case MYKONOS_ERR_SETRFPLL_LF_PLLNAME: + return "Invalid pllName requested in MYKONOS_setRfPllLoopFilter()\n"; + case MYKONOS_ERR_SETRFPLL_LF_INV_STABILITY: + return "Invalid stability value requested in MYKONOS_setRfPllLoopFilter()\n"; + case MYKONOS_ERR_SETRFPLL_LF_ARMERROR: + return "ARM Command Error in MYKONOS_setRfPllLoopFilter()\n"; + case MYKONOS_ERR_SETRFPLL_LF_INV_TXRX_LOOPBANDWIDTH: + return "Invalid Tx/Rx value bandwith requested in MYKONOS_setRfPllLoopFilter()\n"; + case MYKONOS_ERR_SETRFPLL_LF_INV_SNF_LOOPBANDWIDTH: + return "Invalid Sniffer value bandwith in MYKONOS_setRfPllLoopFilter()\n"; + case MYKONOS_ERR_GETRFPLL_LF_INV_PLLNAME: + return "Invalid pllName requested in MYKONOS_getRfPllLoopFilter()\n"; + case MYKONOS_ERR_GETRFPLL_LF_ARMERROR: + return "ARM Command Error in MYKONOS_getRfPllLoopFilter()\n"; + case MYKONOS_ERR_GETRFPLL_LF_NULLPARAM: + return "NULL pointer in function parameter for MYKONOS_getRfPllLoopFilter()\n"; + case MYKONOS_ERR_SET_RF_DC_OFFSET_INV_MEASURECNT: + return "Invalid value passed as parameter for measureCount to function MYKONOS_setRfDcOffsetCnt().\n"; + case MYKONOS_ERR_SET_RF_DC_OFFSET_MEASURECNT_MIN_LIMIT: + return "The measureCount value passed to function MYKONOS_setRfDcOffsetCnt() is less than the minimum limit allowed.\n"; + case MYKONOS_ERR_DC_OFFSET_INV_CHAN: + return "Invalid channel passed as parameter, for valid channel refer mykonosDcOffsetChannels_t enum.\n"; + case MYKONOS_ERR_GET_RF_DC_OFFSET_NULL_MEASURECNT: + return "Null parameter passed for measureCount MYKONOS_getRfDcOffsetCnt().\n"; + case MYKONOS_ERR_SET_DIG_DC_OFFSET_INV_MSHIFT: + return "Invalid MShift value passed as parameter to function MYKONOS_setDigDcOffsetMShift().\n"; + case MYKONOS_ERR_GET_DIG_DC_OFFSET_NULL_MSHIFT: + return "MShift passed to the function MYKONOS_getDigDcOffsetMShift() is NULL.\n"; + case MYKONOS_ERR_DIG_DC_OFFSET_INV_ENABLE_MASK: + return "Invalid enable mask passed to the function MYKONOS_setDigDcOffsetEn().\n"; + case MYKONOS_ERR_DIG_DC_OFFSET_NULL_ENABLE_MASK: + return "Enable mask passed to the function MYKONOS_getDigDcOffsetEn() is NULL.\n"; + case MYKONOS_ERR_RESETDPD_WRONG_PARAM: + return "reset parameter passed to function MYKONOS_resetDpd() is not valid, possible values are: MYK_DPD_RESET_FULL, MYK_DPD_RESET_PRIOR or MYK_DPD_RESET_CORRELATOR \n"; + case MYKONOS_ERR_RESETDPD_ARMERRFLAG: + return "ARM command flag error set in function MYKONOS_resetDpd().\n"; + case MYKONOS_ERR_CFGCLGC_INV_THRESHOLD: + return "tx1RelThreshold or tx2RelThreshold parameter is out of range in function MYKONOS_configClgc().\n"; + case MYKONOS_ERR_RESETDPD_INV_TXCHANNEL: + return "Tx channel is not valid (Valid ENUM values: TX1, TX2 or TX1_TX2 in function MYKONOS_resetDpd().\n"; + case MYKONOS_ERR_SET_PATH_DELAY_NULL_PARAM: + return "pathDelay structure is null in function MYKONOS_setPathDelay().\n"; + case MYKONOS_ERR_SET_PATH_DELAY_PARAM_OUT_OF_RANGE: + return "path delay not valid range in MYKONOS_setPathDelay(), valid ranges are from 0 to 4095 at 1/16 sample resolution of ORx sample rate.\n"; + case MYKONOS_ERR_GET_PATH_DELAY_NULL_PARAM: + return "pathDelay structure is null in function MYKONOS_getPathDelay().\n"; + case MYKONOS_ERR_GET_PATH_DELAY_INVALID_SELECTION: + return "invalid selection for getting the path delay, valid selections are given by mykonosPathDelaySel_t.\n"; + case MYKONOS_ERR_GET_PATH_DELAY_ARMERRFLAG: + return "Arm error while reading path delay for the selected calibration status.\n"; + case MYKONOS_ERR_GETDPD_ERROR_CNT_NULLPARAM: + return "dpdErrCnt is null in function MYKONOS_getDpdErrorCounters().\n"; + case MYKONOS_ERR_GETDPD_ERROR_CNT_INV_CH: + return "invalid selection for getting the error counters tx channel in MYKONOS_getDpdErrorCounters().\n"; + case MYKONOS_ERR_GETDPD_ERROR_CNT_ARMERRFLAG: + return "Arm error while reading the error counters for the DPD status MYKONOS_getDpdErrorCounters().\n"; + case MYKONOS_ERR_SETDPDACT_NULL_ACTSTRUCT: + return "Passed structure is null in MYKONOS_setDpdBypassConfig().\n"; + case MYKONOS_ERR_SETDPDACT_INV_ACTMODE: + return "Invalid mode passed detected in MYKONOS_setDpdBypassConfig(), actConfig->bypassActuatorMode for valid modes mykonosDpdResetMode_t.\n"; + case MYKONOS_ERR_SETDPDACT_INV_LEVEL: + return "Passed actConfig->bypassActuatorLevel outside the range in MYKONOS_setDpdBypassConfig().\n"; + case MYKONOS_ERR_GETDPDACT_NULL_ACTSTRUCT: + return "Passed structure is null in MYKONOS_getDpdBypassConfig().\n"; + case MYKONOS_ERR_SETDPDACTCHECK_NULL_ACTSTRUCT: + return "Passed structure is null in MYKONOS_setDpdActuatorCheck().\n"; + case MYKONOS_ERR_SETDPDACTCHECK_INV_ACTMODE: + return "Invalid mode detected in MYKONOS_setDpdActuatorCheck(), actCheck->actuatorGainCheckMode for valid modes mykonosDpdResetMode_t.\n"; + case MYKONOS_ERR_SETDPDACTCHECK_INV_LEVEL: + return "Passed actCheck->actuatorGainCheckLevel outside the range in MYKONOS_setDpdActuatorCheck().\n"; + case MYKONOS_ERR_GETDPDACTCHECK_NULL_ACTSTRUCT: + return "Passed structure is null in MYKONOS_getDpdActuatorCheck().\n"; + case MYKONOS_ERR_CLGCATTENTUNCFG_NULL_ATTRANGECFGSTRUCT: + return "Passed structure is null in MYKONOS_setClgcAttenTuningConfig().\n"; + case MYKONOS_ERR_CLGCATTENTUNCFG_INVALID_MODE: + return "Invalid mode detected for attRangeCfg member in MYKONOS_getClgcAttenTuningConfig(), for valid modes ::mykonosClgcAttenTuningMode_t.\n"; + case MYKONOS_ERR_CLGCATTENTUNCFG_INVALID_PRESET: + return "Invalid AttenTuningPreset detected for attRangeCfg member in MYKONOS_getClgcAttenTuningConfig(), valid range is from 0 to 839 (0 to 41.95dB).\n"; + case MYKONOS_ERR_CLGCATTENTUNCFG_INVALID_RANGE: + return "Invalid AttenTuningRange detected for attRangeCfg member in MYKONOS_getClgcAttenTuningConfig(), valid range is from 0 to 420 (0 to 21dB).\n"; + case MYKONOS_ERR_CLGCATTENTUNCFG_INVALID_TX1_SETTINGS: + return "Invalid Tx1 AttenTuningRange and AttenTuningPreset combination in MYKONOS_getClgcAttenTuningConfig().\n"; + case MYKONOS_ERR_CLGCATTENTUNCFG_INVALID_TX2_SETTINGS: + return "Invalid Tx2 AttenTuningRange and AttenTuningPreset combination in MYKONOS_getClgcAttenTuningConfig().\n"; + case MYKONOS_ERR_CLGCATTENTUNCFGGET_NULL_ATTRANGECFGSTRUCT: + return "Passed structure is null in MYKONOS_getClgcAttenTuningConfig().\n"; + + default: + return "Unknown error was encountered.\n"; + } + +#endif +} + +/** + * \brief Calculates the scaled device clock frequency at the input of the + * CLKPLL or RFPLL + * + * Use this helper function any time the scaled device clock frequency is needed. + * + * Dependencies + * - device->clocks->deviceClock_kHz + * - device->spiSettings->chipSelectIndex + * + * \param device is structure pointer to the Mykonos data structure containing settings + * \param scaledRefClk_kHz Output: The returned scaled reference clock for the device's PLLs + * \param deviceClkDiv Output: The device clock divider setting that gets set in the devices SPI register. + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_NULL_DEVICE_PARAM Function parameter device pointer is NULL + * \retval MYKONOS_ERR_INV_SCALEDDEVCLK_PARAM The scaled PLL refclk frequency is out of range (40MHz to 80MHz) + * \retval MYKONOS_ERR_CALCDEVCLK_NULLPARAM Function parameter scaledRefClk_kHz or deviceClkDiv has a NULL pointer + */ +static mykonosErr_t MYKONOS_calculateScaledDeviceClk_kHz(mykonosDevice_t *device, uint32_t *scaledRefClk_kHz, uint8_t *deviceClkDiv) +{ + uint32_t deviceClock_kHz = 0; + + if ((device == NULL) || (device->clocks == NULL)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, 0, MYKONOS_ERR_NULL_DEVICE_PARAM, getMykonosErrorMessage(MYKONOS_ERR_NULL_DEVICE_PARAM)); + return MYKONOS_ERR_NULL_DEVICE_PARAM; + } + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_calculateScaledDeviceClk_kHz()\n"); +#endif + + deviceClock_kHz = device->clocks->deviceClock_kHz; + + if ((scaledRefClk_kHz == NULL) || (deviceClkDiv == NULL)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CALCDEVCLK_NULLPARAM, + getMykonosErrorMessage(MYKONOS_ERR_CALCDEVCLK_NULLPARAM)); + return MYKONOS_ERR_CALCDEVCLK_NULLPARAM; + } + + /* scaled Ref Clock at input to CLKPLL must be in range 40-80MHz. */ + if (deviceClock_kHz > 20000 && deviceClock_kHz <= 40000) + { + *scaledRefClk_kHz = deviceClock_kHz << 1; + *deviceClkDiv = 3; + } /* x2 */ + else if (deviceClock_kHz > 40000 && deviceClock_kHz <= 80000) + { + *scaledRefClk_kHz = deviceClock_kHz; + *deviceClkDiv = 0; + } /* x1 */ + else if (deviceClock_kHz > 80000 && deviceClock_kHz <= 160000) + { + *scaledRefClk_kHz = deviceClock_kHz >> 1; + *deviceClkDiv = 1; + } /* div2 */ + else if (deviceClock_kHz > 160000 && deviceClock_kHz <= 320000) + { + *scaledRefClk_kHz = deviceClock_kHz >> 2; + *deviceClkDiv = 2; + } /* div4 */ + else + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_SCALEDDEVCLK_PARAM, + getMykonosErrorMessage(MYKONOS_ERR_INV_SCALEDDEVCLK_PARAM)); + return MYKONOS_ERR_INV_SCALEDDEVCLK_PARAM; + } + return MYKONOS_ERR_OK; +} + +/** + * \brief Resets the JESD204B Deframer + * + * Dependencies + * - device->spiSettings + * + * \param device is a pointer to the device settings structure + * + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_resetDeframer(mykonosDevice_t *device) +{ + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_resetDeframer()\n"); +#endif + + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_RESET, 0x03); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_RESET, 0x00); + + return MYKONOS_ERR_OK; +} + +/** + * \brief Sets up the JESD204B Serializers + * + * This function uses the Rx framer and ObsRx framer structures to setup the 4 + * serializer lanes that are shared between the two framers. If the Rx profile is valid + * the serializer amplitude and preEmphasis are used from the Rx framer. If only the ObsRx + * profile is valid, the obsRx framer settings are used. + * + * Dependencies + * - device->spiSettings + * - device->spiSettings->chipSelectIndex + * - device->rx->framer->M + * - device->rx->framer->serializerAmplitude + * - device->rx->framer->preEmphasis + * - device->rx->framer->serializerLanesEnabled + * - device->rx->framer->invertLanePolarity + * - device->obsRx->framer->serializerLanesEnabled + * - device->obsRx->framer->invertLanePolarity + * - device->obsRx->framer->M + * - device->obsRx->framer->serializerLanesEnabled + * - device->obsRx->framer->serializerAmplitude + * - device->obsRx->framer->preEmphasis + * + * \param device Pointer to the device settings structure + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_INITSER_INV_VCODIV_PARM Mykonos CLKPLL has invalid VCO divider, verify CLKPLL config + * \retval MYKONOS_ERR_SER_LANE_CONFLICT_PARM When both Rx and ObsRx framers are enabled, framers can not share the same physical lane. + * \retval MYKONOS_ERR_SER_INV_REAL_IF_DATA_PARM Rx Framer M can only = 1 when Real IF mode is enabled + * \retval MYKONOS_ERR_SER_INV_M_PARM Invalid Rx Framer M (valid 1,2,4) + * \retval MYKONOS_ERR_SER_INV_LANEEN_PARM Invalid Rx framer serializerLanesEnabled (valid 0-15) + * \retval MYKONOS_ERR_SER_INV_AMP_PARM Invalid Rx serializer amplitude (valid 0-31) + * \retval MYKONOS_ERR_SER_INV_PREEMP_PARM Invalid Rx serializer pre-emphesis (valid 0-7) + * \retval MYKONOS_ERR_SER_INV_LANEPN_PARM Invalid Rx serializer PN invert setting (valid 0-15) + * \retval MYKONOS_ERR_SER_INV_L_PARM Invalid Rx serializer lanes enabled (must use 1, 2 or 4 lanes) + * \retval MYKONOS_ERR_SER_INV_LANERATE_PARM Invalid Rx serializer lane rate (valid 614.4Mbps - 6144Mbps) + * + * \retval MYKONOS_ERR_SER_INV_REAL_IF_DATA_PARM + * \retval MYKONOS_ERR_SER_INV_LANEEN_PARM + * \retval MYKONOS_ERR_SER_INV_AMP_PARM + * \retval MYKONOS_ERR_SER_INV_PREEMP_PARM + * \retval MYKONOS_ERR_SER_INV_LANEPN_PARM + * \retval MYKONOS_ERR_SER_INV_L_PARM + * \retval MYKONOS_ERR_SER_INV_LANERATE_PARM + * + * \retval MYKONOS_ERR_SER_LANE_RATE_CONFLICT_PARM Necessary lane rates for Rx and ObsRx framer can not be obtained with possible divider settings + * \retval MYKONOS_ERR_HS_AND_LANE_RATE_NOT_INTEGER_MULT HSCLK is not an integer multiple of the lane clock rate + * \retval MYKONOS_ERR_SER_INV_TXSER_DIV_PARM No valid Tx serializer divider to obtain desired lane rates + * \retval MYKONOS_ERR_INITSER_INV_PROFILE Rx/ObsRx and sniffer profiles are not valid - can not config serializers + * \retval MYKONOS_ERR_INV_RXFRAMER_PCLKDIV_PARM Invalid Rx framer PCLK divider + * \retval MYKONOS_ERR_INV_OBSRXFRAMER_PCLKDIV_PARM Invalid ORx/Sniffer framer PCLK divider + * + */ +mykonosErr_t MYKONOS_setupSerializers(mykonosDevice_t *device) +{ + uint8_t serializerHalfRateReg = 0; + uint8_t txser_div = 0; + uint8_t txser_div_reg = 0; + uint32_t clkPllVcoFrequency_kHz = 0; + uint32_t hsclkRate_kHz = 0; + uint32_t rxLaneRate_kHz = 0; + uint32_t obsRxLaneRate_kHz = 0; + uint32_t fasterLaneRate_kHz = 0; + uint32_t slowerLaneRate_kHz = 0; + uint8_t modHsLaneRate = 0; + uint8_t rxL = 0; + uint8_t obsRxL = 0; + uint8_t i = 0; + uint8_t amplitudeEmphasis = 0; + uint8_t lanePowerDown = 0x00; + mykonosVcoDiv_t vcoDiv = VCODIV_1; + uint8_t rxLanePn = 0; + uint8_t obsRxLanePn = 0; + + uint32_t hsDigClkdiv4_5_kHz = 0; + uint32_t rxPclkDiv = 0; + uint32_t obsRxPclkDiv = 0; + uint32_t tempPclkDiv = 0; + uint32_t rxFramerPclk_kHz = 0; + uint32_t obsRxFramerPclk_kHz = 0; + uint8_t rxSyncbSelect = 0; + uint8_t obsRxSyncbSelect = 0; + + static const uint32_t MAX_HSCLK_KHZ_IF_VCODIV1P5 = 6144000; /* max VCO /1.5 output is 6144Mhz. This limits VCO to 9216MHz */ + static const uint32_t MAX_HSCLK_KHZ_IF_VCODIV1 = 8000000; /* max VCO div1 output is 8000Mhz. This limits VCO to 8000MHz */ + static const uint32_t MIN_SERIALIZER_RATE_KHZ = 614400; /* max serializer lane rate = 0.6144 Gbps */ + static const uint32_t MAX_SERIALIZER_RATE_KHZ = 6144000; /* max serializer lane rate = 6.144 Gbps */ +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setupSerializers()\n"); +#endif + + vcoDiv = device->clocks->clkPllVcoDiv; + clkPllVcoFrequency_kHz = device->clocks->clkPllVcoFreq_kHz; + + switch (vcoDiv) + { + case VCODIV_1: + hsclkRate_kHz = clkPllVcoFrequency_kHz; + + /* max VCO /1 output is 8000Mhz. This limits VCO to 8000MHz */ + if (hsclkRate_kHz > MAX_HSCLK_KHZ_IF_VCODIV1) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INITSER_INV_VCODIV1_HSCLK_PARM, + getMykonosErrorMessage(MYKONOS_ERR_INITSER_INV_VCODIV1_HSCLK_PARM)); + return MYKONOS_ERR_INITSER_INV_VCODIV1_HSCLK_PARM; + } + + break; + + case VCODIV_1p5: + hsclkRate_kHz = (clkPllVcoFrequency_kHz / 15) * 10; + + /* max VCO /1.5 output is 6144Mhz. This limits VCO to 9216MHz */ + if (hsclkRate_kHz > MAX_HSCLK_KHZ_IF_VCODIV1P5) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INITSER_INV_VCODIV1P5_HSCLK_PARM, + getMykonosErrorMessage(MYKONOS_ERR_INITSER_INV_VCODIV1P5_HSCLK_PARM)); + return MYKONOS_ERR_INITSER_INV_VCODIV1P5_HSCLK_PARM; + } + + break; + + case VCODIV_2: + hsclkRate_kHz = clkPllVcoFrequency_kHz >> 1; + break; + + case VCODIV_3: + hsclkRate_kHz = (clkPllVcoFrequency_kHz / 30) * 10; + break; + + default: + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INITSER_INV_VCODIV_PARM, + getMykonosErrorMessage(MYKONOS_ERR_INITSER_INV_VCODIV_PARM)); + return MYKONOS_ERR_INITSER_INV_VCODIV_PARM; + } + } + + if ((device->profilesValid & RX_PROFILE_VALID) && (device->profilesValid & (ORX_PROFILE_VALID | SNIFF_PROFILE_VALID))) + { + if (device->rx->framer->serializerLanesEnabled & device->obsRx->framer->serializerLanesEnabled) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SER_LANE_CONFLICT_PARM, + getMykonosErrorMessage(MYKONOS_ERR_SER_LANE_CONFLICT_PARM)); + return MYKONOS_ERR_SER_LANE_CONFLICT_PARM; + } + } + + lanePowerDown = 0x9F; + if (device->profilesValid & RX_PROFILE_VALID) + { + if (device->rx->framer->M == 1 && !(device->rx->realIfData)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SER_INV_REAL_IF_DATA_PARM, + getMykonosErrorMessage(MYKONOS_ERR_SER_INV_REAL_IF_DATA_PARM)); + return MYKONOS_ERR_SER_INV_REAL_IF_DATA_PARM; + } + + if (device->rx->framer->M != 1 && device->rx->framer->M != 2 && device->rx->framer->M != 4) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SER_INV_M_PARM, getMykonosErrorMessage(MYKONOS_ERR_SER_INV_M_PARM)); + return MYKONOS_ERR_SER_INV_M_PARM; + } + + for (i = 0; i < 4; i++) + { + rxL += ((device->rx->framer->serializerLanesEnabled >> i) & 0x01); + } + + if (device->rx->framer->serializerLanesEnabled > 15) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SER_INV_LANEEN_PARM, + getMykonosErrorMessage(MYKONOS_ERR_SER_INV_LANEEN_PARM)); + return MYKONOS_ERR_SER_INV_LANEEN_PARM; + } + + if (device->rx->framer->serializerAmplitude > 31) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SER_INV_AMP_PARM, getMykonosErrorMessage(MYKONOS_ERR_SER_INV_AMP_PARM)); + return MYKONOS_ERR_SER_INV_AMP_PARM; + } + + if (device->rx->framer->preEmphasis > 7) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SER_INV_PREEMP_PARM, + getMykonosErrorMessage(MYKONOS_ERR_SER_INV_PREEMP_PARM)); + return MYKONOS_ERR_SER_INV_PREEMP_PARM; + } + + if (device->rx->framer->invertLanePolarity > 15) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SER_INV_LANEPN_PARM, + getMykonosErrorMessage(MYKONOS_ERR_SER_INV_LANEPN_PARM)); + return MYKONOS_ERR_SER_INV_LANEPN_PARM; + } + if ((rxL != 1) && (rxL != 2) && (rxL != 4)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SER_INV_L_PARM, getMykonosErrorMessage(MYKONOS_ERR_SER_INV_L_PARM)); + return MYKONOS_ERR_SER_INV_L_PARM; + } + + rxLaneRate_kHz = device->rx->rxProfile->iqRate_kHz * 20 * device->rx->framer->M / rxL; + lanePowerDown &= (~(device->rx->framer->serializerLanesEnabled)); + + if ((rxLaneRate_kHz < MIN_SERIALIZER_RATE_KHZ) || (rxLaneRate_kHz > MAX_SERIALIZER_RATE_KHZ)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SER_INV_LANERATE_PARM, + getMykonosErrorMessage(MYKONOS_ERR_SER_INV_LANERATE_PARM)); + return MYKONOS_ERR_SER_INV_LANERATE_PARM; + } + } + + if ((device->obsRx->framer != NULL) && (device->profilesValid & (ORX_PROFILE_VALID | SNIFF_PROFILE_VALID))) + { + if ((device->obsRx->framer->M == 1) && !(device->obsRx->realIfData)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SER_INV_REAL_IF_DATA_PARM, + getMykonosErrorMessage(MYKONOS_ERR_SER_INV_REAL_IF_DATA_PARM)); + return MYKONOS_ERR_SER_INV_REAL_IF_DATA_PARM; + } + + for (i = 0; i < 4; i++) + { + obsRxL += ((device->obsRx->framer->serializerLanesEnabled >> i) & 0x01); + } + + if (device->obsRx->framer->serializerLanesEnabled > 15) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SER_INV_LANEEN_PARM, + getMykonosErrorMessage(MYKONOS_ERR_SER_INV_LANEEN_PARM)); + return MYKONOS_ERR_SER_INV_LANEEN_PARM; + } + + if (device->obsRx->framer->serializerAmplitude > 31) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SER_INV_AMP_PARM, getMykonosErrorMessage(MYKONOS_ERR_SER_INV_AMP_PARM)); + return MYKONOS_ERR_SER_INV_AMP_PARM; + } + + if (device->obsRx->framer->preEmphasis > 7) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SER_INV_PREEMP_PARM, + getMykonosErrorMessage(MYKONOS_ERR_SER_INV_PREEMP_PARM)); + return MYKONOS_ERR_SER_INV_PREEMP_PARM; + } + + if (device->obsRx->framer->invertLanePolarity > 15) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SER_INV_LANEPN_PARM, + getMykonosErrorMessage(MYKONOS_ERR_SER_INV_LANEPN_PARM)); + return MYKONOS_ERR_SER_INV_LANEPN_PARM; + } + + if ((obsRxL != 0) && (obsRxL != 1) && (obsRxL != 2) && (obsRxL != 4)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SER_INV_L_PARM, getMykonosErrorMessage(MYKONOS_ERR_SER_INV_L_PARM)); + return MYKONOS_ERR_SER_INV_L_PARM; + } + + /* check for valid pointer */ + if (obsRxL == 0) + { + /* Allow ORx receiver to work but disable Obs Rx framer link - valid on a DPD-enabled transceiver */ + obsRxLaneRate_kHz = 0; + } + else if (device->profilesValid & ORX_PROFILE_VALID) + { + obsRxLaneRate_kHz = device->obsRx->orxProfile->iqRate_kHz * 20 * device->obsRx->framer->M / obsRxL; + } + else if (device->profilesValid & SNIFF_PROFILE_VALID) + { + obsRxLaneRate_kHz = device->obsRx->snifferProfile->iqRate_kHz * 20 * device->obsRx->framer->M / obsRxL; + } + + lanePowerDown &= (~(device->obsRx->framer->serializerLanesEnabled)); + + if ((obsRxLaneRate_kHz != 0) && ((obsRxLaneRate_kHz < MIN_SERIALIZER_RATE_KHZ) || (obsRxLaneRate_kHz > MAX_SERIALIZER_RATE_KHZ))) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SER_INV_LANERATE_PARM, + getMykonosErrorMessage(MYKONOS_ERR_SER_INV_LANERATE_PARM)); + return MYKONOS_ERR_SER_INV_LANERATE_PARM; + } + } + + /* checking for RX and OBSRX effective lane rates match */ + /* Need to account for oversampling, verify that the 2 lane rate are integer related */ + + if ((rxLaneRate_kHz > 0) && (obsRxLaneRate_kHz > 0)) + { + fasterLaneRate_kHz = (rxLaneRate_kHz >= obsRxLaneRate_kHz) ? (rxLaneRate_kHz) : (obsRxLaneRate_kHz); + slowerLaneRate_kHz = (rxLaneRate_kHz >= obsRxLaneRate_kHz) ? (obsRxLaneRate_kHz) : (rxLaneRate_kHz); + + /* Verify that lane rates are integer multiples of each other */ + if ((fasterLaneRate_kHz % slowerLaneRate_kHz) != 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SER_LANE_RATE_CONFLICT_PARM, + getMykonosErrorMessage(MYKONOS_ERR_SER_LANE_RATE_CONFLICT_PARM)); + return MYKONOS_ERR_SER_LANE_RATE_CONFLICT_PARM; + } + } + else + { + fasterLaneRate_kHz = (rxLaneRate_kHz >= obsRxLaneRate_kHz) ? (rxLaneRate_kHz) : (obsRxLaneRate_kHz); + } + + /* performing integer multiple check on HS clock and lane rate clock */ + if (fasterLaneRate_kHz == 0) + { + /* All serializer lanes are disabled */ + txser_div = 1; + txser_div_reg = 0; + serializerHalfRateReg = 0; + } + else + { + if ((fasterLaneRate_kHz > hsclkRate_kHz) || + (fasterLaneRate_kHz > MAX_SERIALIZER_RATE_KHZ)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SER_INV_LANERATE_PARM, + getMykonosErrorMessage(MYKONOS_ERR_SER_INV_LANERATE_PARM)); + return MYKONOS_ERR_SER_INV_LANERATE_PARM; + } + + modHsLaneRate = (uint8_t)(hsclkRate_kHz % fasterLaneRate_kHz); + if (modHsLaneRate != 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_HS_AND_LANE_RATE_NOT_INTEGER_MULT, + getMykonosErrorMessage(MYKONOS_ERR_HS_AND_LANE_RATE_NOT_INTEGER_MULT)); + return MYKONOS_ERR_HS_AND_LANE_RATE_NOT_INTEGER_MULT; + } + + txser_div = (uint8_t)(hsclkRate_kHz / fasterLaneRate_kHz); /* Total serializer Divider (1,2,4,8) */ + switch (txser_div) + { + case 1: + txser_div_reg = 0; /* Divide hsclk by 1 */ + serializerHalfRateReg = 0; /* 0 = divide serializer clock by 1 */ + break; + case 2: + txser_div_reg = 1; /* Divide hsclk by 2 */ + serializerHalfRateReg = 0; /* 0 = divide serializer clock by 1 */ + break; + case 4: + txser_div_reg = 2; /* Divide hsclk by 4 */ + serializerHalfRateReg = 0; /* 0 = divide serializer clock by 1 */ + break; + case 8: + txser_div_reg = 2; /* Divide hsclk by 4 */ + serializerHalfRateReg = 1; /* 1 = divide serializer clock by 2 */ + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SER_INV_TXSER_DIV_PARM, + getMykonosErrorMessage(MYKONOS_ERR_SER_INV_TXSER_DIV_PARM)); + return MYKONOS_ERR_SER_INV_TXSER_DIV_PARM; + } + } + + if (device->profilesValid & RX_PROFILE_VALID) + { + amplitudeEmphasis = ((device->rx->framer->serializerAmplitude & 0x1f) << 3) | (device->rx->framer->preEmphasis & 0x07); + } + else if (device->profilesValid & (ORX_PROFILE_VALID | SNIFF_PROFILE_VALID)) + { + amplitudeEmphasis = ((device->obsRx->framer->serializerAmplitude & 0x1f) << 3) | (device->obsRx->framer->preEmphasis & 0x07); + } + else + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INITSER_INV_PROFILE, getMykonosErrorMessage(MYKONOS_ERR_INITSER_INV_PROFILE)); + return MYKONOS_ERR_INITSER_INV_PROFILE; + } + + if (device->profilesValid & RX_PROFILE_VALID) + { + rxSyncbSelect = (device->rx->framer->obsRxSyncbSelect > 0) ? 1 : 0; + rxLanePn = (uint8_t)(rxSyncbSelect << 7) | (device->rx->framer->invertLanePolarity & 0xF); + } + + if (device->profilesValid & (ORX_PROFILE_VALID | SNIFF_PROFILE_VALID)) + { + obsRxSyncbSelect = (device->obsRx->framer->obsRxSyncbSelect > 0) ? 1 : 0; + obsRxLanePn = (uint8_t)(obsRxSyncbSelect << 7) | (device->obsRx->framer->invertLanePolarity & 0xF); + } + + /* Serializer lane clock frequency */ + /* serLaneClock_kHz = fasterLaneRate_kHz / txser_div / 20; */ + if (device->profilesValid & RX_PROFILE_VALID) + { + /* calculate manual PCLK frequency for Rx framer = Rx IQrate * F, where F = (2*M/L) or PCLK = lanerate /10 */ + if (device->rx->framer->overSample) + { + rxFramerPclk_kHz = fasterLaneRate_kHz / 10; + } + else + { + rxFramerPclk_kHz = rxLaneRate_kHz / 10; + } + + hsDigClkdiv4_5_kHz = hsclkRate_kHz / device->clocks->clkPllHsDiv / device->rx->rxProfile->rxDec5Decimation; + + /* PCLKDiv: 0=4x, 1=2x, 2=1x, 3=/2, 4=/4, 5=/8, 6=/16 */ + if (hsDigClkdiv4_5_kHz == rxFramerPclk_kHz) + { + rxPclkDiv = 2; + } + else if (hsDigClkdiv4_5_kHz > rxFramerPclk_kHz) + { + if (rxFramerPclk_kHz == 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_RXFRAMER_PCLKDIV_PARM, + getMykonosErrorMessage(MYKONOS_ERR_INV_RXFRAMER_PCLKDIV_PARM)); + return MYKONOS_ERR_INV_RXFRAMER_PCLKDIV_PARM; + } + + tempPclkDiv = hsDigClkdiv4_5_kHz / rxFramerPclk_kHz; + switch (tempPclkDiv) + { + case 2: + rxPclkDiv = 3; + break; + case 4: + rxPclkDiv = 4; + break; + case 8: + rxPclkDiv = 5; + break; + case 16: + rxPclkDiv = 6; + break; + default: + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_RXFRAMER_PCLKDIV_PARM, + getMykonosErrorMessage(MYKONOS_ERR_INV_RXFRAMER_PCLKDIV_PARM)); + return MYKONOS_ERR_INV_RXFRAMER_PCLKDIV_PARM; + } + } + } + else if (hsDigClkdiv4_5_kHz < rxFramerPclk_kHz) + { + tempPclkDiv = rxFramerPclk_kHz / hsDigClkdiv4_5_kHz; + switch (tempPclkDiv) + { + case 2: + rxPclkDiv = 1; + break; + case 4: + rxPclkDiv = 0; + break; + default: + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_RXFRAMER_PCLKDIV_PARM, + getMykonosErrorMessage(MYKONOS_ERR_INV_RXFRAMER_PCLKDIV_PARM)); + return MYKONOS_ERR_INV_RXFRAMER_PCLKDIV_PARM; + } + } + } + } + + if (obsRxL == 0) + { + /* Make sure PCLK is set as low as possible because it interacts with Rx Framer logic, */ + /* even though ObsRx Framer disabled */ + obsRxPclkDiv = 6; + } + else if (device->profilesValid & (ORX_PROFILE_VALID | SNIFF_PROFILE_VALID)) + { + /* calculate manual PCLK frequency for obsRx framer = obsRx IQrate * F, where F = (2*M/L) */ + if (device->profilesValid & ORX_PROFILE_VALID) + { + if (device->obsRx->framer->overSample) + { + obsRxFramerPclk_kHz = fasterLaneRate_kHz / 10; + } + else + { + obsRxFramerPclk_kHz = obsRxLaneRate_kHz / 10; + } + + hsDigClkdiv4_5_kHz = hsclkRate_kHz / device->clocks->clkPllHsDiv / device->obsRx->orxProfile->rxDec5Decimation; + } + else if (device->profilesValid & SNIFF_PROFILE_VALID) + { + if (device->obsRx->framer->overSample) + { + obsRxFramerPclk_kHz = fasterLaneRate_kHz / 10; + } + else + { + obsRxFramerPclk_kHz = obsRxLaneRate_kHz / 10; + } + + hsDigClkdiv4_5_kHz = hsclkRate_kHz / device->clocks->clkPllHsDiv / device->obsRx->snifferProfile->rxDec5Decimation; + } + + /* PCLKDiv: 0=4x, 1=2x, 2=1x, 3=/2, 4=/4, 5=/8, 6=/16 */ + if (hsDigClkdiv4_5_kHz == obsRxFramerPclk_kHz) + { + obsRxPclkDiv = 2; + } + else if ((hsDigClkdiv4_5_kHz > obsRxFramerPclk_kHz) && (obsRxFramerPclk_kHz != 0)) + { + tempPclkDiv = hsDigClkdiv4_5_kHz / obsRxFramerPclk_kHz; + switch (tempPclkDiv) + { + case 2: + obsRxPclkDiv = 3; + break; + case 4: + obsRxPclkDiv = 4; + break; + case 8: + obsRxPclkDiv = 5; + break; + case 16: + obsRxPclkDiv = 6; + break; + default: + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_OBSRXFRAMER_PCLKDIV_PARM, + getMykonosErrorMessage(MYKONOS_ERR_INV_OBSRXFRAMER_PCLKDIV_PARM)); + return MYKONOS_ERR_INV_OBSRXFRAMER_PCLKDIV_PARM; + } + } + } + else if (hsDigClkdiv4_5_kHz < obsRxFramerPclk_kHz) + { + if (hsDigClkdiv4_5_kHz == 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_OBSRXFRAMER_PCLKDIV_PARM, + getMykonosErrorMessage(MYKONOS_ERR_INV_OBSRXFRAMER_PCLKDIV_PARM)); + return MYKONOS_ERR_INV_OBSRXFRAMER_PCLKDIV_PARM; + } + + tempPclkDiv = obsRxFramerPclk_kHz / hsDigClkdiv4_5_kHz; + switch (tempPclkDiv) + { + case 2: + obsRxPclkDiv = 1; + break; + case 4: + obsRxPclkDiv = 0; + break; + default: + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_OBSRXFRAMER_PCLKDIV_PARM, + getMykonosErrorMessage(MYKONOS_ERR_INV_OBSRXFRAMER_PCLKDIV_PARM)); + return MYKONOS_ERR_INV_OBSRXFRAMER_PCLKDIV_PARM; + } + } + } + } + + /* set lane rate divide setting */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_CLOCK_CONTROL_3, txser_div_reg, 0x03, 0); + + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_SERIALIZER_CTL_2, amplitudeEmphasis); + + /* Serializer: Release Reset */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_SERIALIZER_SPECIAL, 0x03); + + /* Serializer: txser clk enable */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_SERIALIZER_HS_DIV_TXSER_CLK_EN, 0x01); + + /* Serializer: Enable 2 to 1 serializer */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_SERIALIZER_CTL_3, 0x20 | serializerHalfRateReg); + + /* power up desired serializer lanes */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_SERIALIZER_CTL_1, lanePowerDown); + + /* apply desired lane PN inversions to the TX and OBSRX framers */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_LANE_DATA_CTL, rxLanePn); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_LANE_DATA_CTL, obsRxLanePn); + + /* set Rx framer manual PCLK frequency based on lane rate of the serializers */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_FRAMER_CLK_EN, (uint8_t)rxPclkDiv, 0x70, 4); + + /* enable bit repeat mode in Rx framer - since manual PCLK, oversample will still work */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_FRAMER_CLK_EN, 0, 0x80, 7); + + /* enable manual PCLK mode in Rx framer */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_FRAMER_CLK_EN, 1, 0x04, 2); + + /* set obsRx framer manual PCLK frequency based on lane rate of the serializers */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_CLK_EN, (uint8_t)obsRxPclkDiv, 0x70, 4); + + /* enable bit repeat mode in ObsRx framer - since manual PCLK, oversample will still work */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_CLK_EN, 0, 0x80, 7); + + /* enable manual PCLK mode in ObsRx framer */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_CLK_EN, 1, 0x04, 2); + + return MYKONOS_ERR_OK; +} + +/** + * \brief Sets up the JESD204B Deserializers + * + * This function enables the necessary deserializer lanes, sets the deserializer clocks + * PN inversion settings, and EQ settings based on the info found in the device data structure. + * + * Dependencies + * - device->spiSettings + * - device->spiSettings->chipSelectIndex + * - device->tx->txProfile->clkPllVcoDiv + * - device->tx->txProfile->vcoFreq_kHz + * - device->tx->txProfile->txIqRate_kHz + * - device->tx->deframer->M + * - device->tx->deframer->deserializerLanesEnabled + * - device->tx->deframer->invertLanePolarity + * - device->tx->deframer->EQSetting + * + * \param device Pointer to the device settings structure + + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_INITDES_INV_TXPROFILE Tx Profile is not valid in data structure - can not setup deserializer + * \retval MYKONOS_ERR_INITDES_INV_VCODIV_PARM Mykonos CLKPLL VCO divider is invalid + * \retval MYKONOS_ERR_DESER_INV_M_PARM Invalid M (valid 2 or 4) + * \retval MYKONOS_ERR_DESER_INV_L_PARM Invalid L (valid 1,2,4) + * \retval MYKONOS_ERR_DESER_INV_HSCLK_PARM Invalid HSCLK, must be 6.144G or less after CLKPLL VCO divider - verify CLKPLL config + * \retval MYKONOS_ERR_DESER_INV_LANERATE_PARM Invalid lanerate, must be between 614.4 Mbps to 6144 Mbps + * \retval MYKONOS_ERR_DESER_INV_LANEEN_PARM Invalid deserializerLanesEnabled (valid 0-15 in 1,2,4 lane combinations) + * \retval MYKONOS_ERR_DESER_INV_EQ_PARM Invalid EQ parameter (valid 0-4) + * \retval MYKONOS_ERR_DESER_INV_LANEPN_PARM Invalid PN invert setting, (valid 0-15, invert bit per lane) + * \retval MYKONOS_ERR_DES_HS_AND_LANE_RATE_NOT_INTEGER_MULT Invalid clock settings, HSCLK is not an integer multiple of lane rate + * + */ +mykonosErr_t MYKONOS_setupDeserializers(mykonosDevice_t *device) +{ + uint8_t lanePowerDown = 0xF; + uint8_t des_div = 0; + uint8_t des_div_bitfield = 0; + uint8_t rxcdr_div = 0; + uint8_t rxcdr_div_bitfield = 0; + uint32_t hsclkRate_kHz = 0; + uint8_t i = 0; + uint8_t L = 0; + uint32_t laneRate_kHz = 0; + uint8_t invertLanePolarity = 0; + uint8_t modHsLaneRate = 0; + + const uint32_t MAX_HSCLKRATE_KHZ = 12288000; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setupDeserializers()\n"); +#endif + + if ((device->profilesValid & TX_PROFILE_VALID) == 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INITDES_INV_TXPROFILE, + getMykonosErrorMessage(MYKONOS_ERR_INITDES_INV_TXPROFILE)); + return MYKONOS_ERR_INITDES_INV_TXPROFILE; + } + + if (device->tx->deframer->M != 2 && device->tx->deframer->M != 4) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DESER_INV_M_PARM, getMykonosErrorMessage(MYKONOS_ERR_DESER_INV_M_PARM)); + return MYKONOS_ERR_DESER_INV_M_PARM; + } + + for (i = 0; i < 4; i++) + { + L += ((device->tx->deframer->deserializerLanesEnabled >> i) & 0x01); + } + + if ((L == 0) || (L == 3) || (L > 4)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DESER_INV_L_PARM, getMykonosErrorMessage(MYKONOS_ERR_DESER_INV_L_PARM)); + return MYKONOS_ERR_DESER_INV_L_PARM; + } + + //laneRate_kHz calculation and checks + laneRate_kHz = device->tx->txProfile->iqRate_kHz * 20 * device->tx->deframer->M / L; + + if ((laneRate_kHz < 614400) || (laneRate_kHz > 6144000)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DESER_INV_LANERATE_PARM, + getMykonosErrorMessage(MYKONOS_ERR_DESER_INV_LANERATE_PARM)); + return MYKONOS_ERR_DESER_INV_LANERATE_PARM; + } + + if (device->tx->deframer->deserializerLanesEnabled > 15) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DESER_INV_LANEEN_PARM, + getMykonosErrorMessage(MYKONOS_ERR_DESER_INV_LANEEN_PARM)); + return MYKONOS_ERR_DESER_INV_LANEEN_PARM; + } + + if ((device->tx->deframer->deserializerLanesEnabled == 0x7) || (device->tx->deframer->deserializerLanesEnabled == 0xB) + || (device->tx->deframer->deserializerLanesEnabled == 0xD) || (device->tx->deframer->deserializerLanesEnabled == 0xE)) + { + /* 3 lanes not valid, only 1,2, or 4 lanes */ + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DESER_INV_LANEEN_PARM, + getMykonosErrorMessage(MYKONOS_ERR_DESER_INV_LANEEN_PARM)); + return MYKONOS_ERR_DESER_INV_LANEEN_PARM; + } + + if (device->tx->deframer->EQSetting > 4) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DESER_INV_EQ_PARM, getMykonosErrorMessage(MYKONOS_ERR_DESER_INV_EQ_PARM)); + return MYKONOS_ERR_DESER_INV_EQ_PARM; + } + + if (device->tx->deframer->invertLanePolarity > 15) + { + /* only lower 4 bits of parameter are valid */ + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DESER_INV_LANEPN_PARM, + getMykonosErrorMessage(MYKONOS_ERR_DESER_INV_LANEPN_PARM)); + return MYKONOS_ERR_DESER_INV_LANEPN_PARM; + } + + //hsclkRate_kHz calculations + switch (device->clocks->clkPllVcoDiv) + { + case VCODIV_1: + hsclkRate_kHz = device->clocks->clkPllVcoFreq_kHz; + break; + case VCODIV_1p5: + hsclkRate_kHz = (device->clocks->clkPllVcoFreq_kHz / 15) * 10; + break; + case VCODIV_2: + hsclkRate_kHz = device->clocks->clkPllVcoFreq_kHz >> 1; + break; + case VCODIV_3: + hsclkRate_kHz = (device->clocks->clkPllVcoFreq_kHz / 30) * 10; + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INITDES_INV_VCODIV_PARM, + getMykonosErrorMessage(MYKONOS_ERR_INITDES_INV_VCODIV_PARM)); + return MYKONOS_ERR_INITDES_INV_VCODIV_PARM; + } + + /* The deserializer clock needs to be in the range 3.8GHz to 6.144 GHz in reg x107. The rest of the division is in xDD */ + if (hsclkRate_kHz <= 6144000) + { + rxcdr_div = 1; + } + else if ((hsclkRate_kHz > 6144000) && (hsclkRate_kHz <= MAX_HSCLKRATE_KHZ)) + { + rxcdr_div = 2; + } + else if ((hsclkRate_kHz > MAX_HSCLKRATE_KHZ) && (hsclkRate_kHz < 24576000)) + { + rxcdr_div = 4; + } + else + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DESER_INV_HSCLK_PARM, + getMykonosErrorMessage(MYKONOS_ERR_DESER_INV_HSCLK_PARM)); + return MYKONOS_ERR_DESER_INV_HSCLK_PARM; + } + + switch (rxcdr_div) + { + case 1: + rxcdr_div_bitfield = 0; + break; + case 2: + rxcdr_div_bitfield = 1; + break; + + default: + /* Default case is when rxcdr_div == 4 */ + rxcdr_div_bitfield = 2; + break; + } + + /* performing integer multiple check on HS clock and lane rate clock */ + modHsLaneRate = (uint8_t)(hsclkRate_kHz % laneRate_kHz); + if (modHsLaneRate) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DES_HS_AND_LANE_RATE_NOT_INTEGER_MULT, + getMykonosErrorMessage(MYKONOS_ERR_DES_HS_AND_LANE_RATE_NOT_INTEGER_MULT)); + return MYKONOS_ERR_DES_HS_AND_LANE_RATE_NOT_INTEGER_MULT; + } + + des_div = (uint8_t)(hsclkRate_kHz / laneRate_kHz / rxcdr_div); + + switch (des_div) + { + case 1: + des_div_bitfield = 0; + break; + case 2: + des_div_bitfield = 1; + break; + case 4: + des_div_bitfield = 2; + break; + case 8: + des_div_bitfield = 3; + break; + default: + des_div_bitfield = 0; + break; + } + + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_CLOCK_CONTROL_3, rxcdr_div_bitfield, 0x0C, 0x02); + + invertLanePolarity = (device->tx->deframer->invertLanePolarity & 0xF); + + lanePowerDown = (~(device->tx->deframer->deserializerLanesEnabled)) & 0xF; + + /* Deserializer: PLL clock enable */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DESERIALIZER_HS_DIV_RXCDR_CLK_EN, 0x01); + + /* Deserializer: Set Pdet control */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DESERIALIZER_PDET_CTL, 0x09); + + /* Deserializer: Set Power down control */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DESERIALIZER_CTL_0, (0x80U | lanePowerDown | (uint8_t)(des_div_bitfield << 4))); + + /* Deserializer: Set Sine Shape */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DESERIALIZER_SIN_SHAPE_0, 0x00); + + /* Deserializer: Set ss gain and vga */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DESERIALIZER_SIN_SHAPE_1, 0x00); + + /* Deserializer: Enable EQ, AC coupled JESD204B lanes */ + /* TODO: add ability to set this for AC coupling or DC coupling */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DESERIALIZER_EQ_CTL_1, 0x07); + + /* Deserializer: Clear Data present at negedge, disable peak adjust */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DESERIALIZER_MISC_CTL, 0x04); + + /* Deserializer: Set Equalizer for lanes 1 and 0 */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DESERIALIZER_EQ_CTL_1_TO_0, ((uint8_t)(device->tx->deframer->EQSetting << 3) | device->tx->deframer->EQSetting)); + + /* Deserializer: Set Equalizer for lanes 2 and 3 */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DESERIALIZER_EQ_CTL_3_TO_2, ((uint8_t)(device->tx->deframer->EQSetting << 3) | device->tx->deframer->EQSetting)); + + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_LANE_DATA_CTL, invertLanePolarity); + + /* Reset Deserializers - toggle resetb bit in [0] */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DESERIALIZER_SPECIAL, 0x00); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DESERIALIZER_SPECIAL, 0x01); + + /* Start ALC cal */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DESERIALIZER_CDR_CAL_CTL, 0x02); + + /* Deframer: Enable clocks and lane clocks */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_CLK_EN, 0x03); + + return MYKONOS_ERR_OK; +} + +/** + * \brief Sets up the JESD204B Framer + * + * Dependencies + * - device->spiSettings + * - device->spiSettings->chipSelectIndex + * - device->rx->framer->M + * - device->rx->realIfData + * - device->rx->framer->bankId + * - device->rx->framer->lane0Id + * - device->rx->framer->serializerLanesEnabled + * - device->rx->framer->obsRxSyncbSelect + * - device->rx->framer->K + * - device->rx->framer->externalSysref + * - device->rx->rxChannels + * - device->rx->framer->newSysrefOnRelink + * - device->rx->framer->enableAutoChanXbar + * - device->rx->framer->lmfcOffset + * - device->rx->framer->scramble + * + * \param device Pointer to the device settings structure + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_FRAMER_INV_REAL_IF_DATA_PARM Invalid framer M, M can only = 1 in real IF mode + * \retval MYKONOS_ERR_FRAMER_INV_M_PARM Invalid framer M (valid 1,2,4) + * \retval MYKONOS_ERR_FRAMER_INV_BANKID_PARM Invalid BankId (valid 0-15) + * \retval MYKONOS_ERR_FRAMER_INV_LANEID_PARM Invalid Lane0Id (valid 0-31) + * \retval MYKONOS_ERR_RXFRAMER_INV_FK_PARAM + * \retval MYKONOS_ERR_FRAMER_INV_K_OFFSET_PARAM + */ +mykonosErr_t MYKONOS_setupJesd204bFramer(mykonosDevice_t *device) +{ + uint8_t i = 0; + uint8_t fifoLaneEnable = 0; + uint8_t L = 0; + uint8_t ML = 0; + uint8_t framerConfigF = 0; + + uint8_t subaddr[29] = {0}; /* holds address to framer sub register map */ + uint8_t subdata[29] = {0}; /* holds data for framer sub register map */ + + /* Setup submap registers */ + uint8_t SUBCLASSV = 1; /* JESD subclass 1 */ + uint8_t JESDV = 1; /* Version: JESD204B */ + uint8_t DID = 0; + uint8_t BID = 0; + uint8_t LID0 = 0; + uint8_t LID1 = 1; + uint8_t LID2 = 2; + uint8_t LID3 = 3; + uint8_t CS = 0; + uint8_t N = 0x0F; + uint8_t Np = 0x0F; + uint8_t S = 0; + uint8_t CF = 0; + uint8_t K = 31; + uint8_t HD = 0; + uint8_t FramerL = 1; + uint8_t FramerM = 2; + uint8_t FramerF = 1; + uint8_t framerADC_XBar = 0xE4; + uint16_t FK = 0; + + uint8_t regE0 = 0; + uint8_t regE2 = 0; + uint8_t framerLaneXbar = 0xE4; + uint16_t CheckSum = 0; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setupJesd204bFramer()\n"); +#endif + + if (device->rx->framer->M == 1 && !(device->rx->realIfData)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FRAMER_INV_REAL_IF_DATA_PARM, + getMykonosErrorMessage(MYKONOS_ERR_FRAMER_INV_REAL_IF_DATA_PARM)); + return MYKONOS_ERR_FRAMER_INV_REAL_IF_DATA_PARM; + } + + if (device->rx->framer->M != 1 && device->rx->framer->M != 2 && device->rx->framer->M != 4) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FRAMER_INV_M_PARM, getMykonosErrorMessage(MYKONOS_ERR_FRAMER_INV_M_PARM)); + return MYKONOS_ERR_FRAMER_INV_M_PARM; + } + + if (device->rx->framer->bankId > 15) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FRAMER_INV_BANKID_PARM, + getMykonosErrorMessage(MYKONOS_ERR_FRAMER_INV_BANKID_PARM)); + return MYKONOS_ERR_FRAMER_INV_BANKID_PARM; + } + + /* no need to check deviceId, its range is full uint8_t range */ + if (device->rx->framer->lane0Id > 31) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FRAMER_INV_LANEID_PARM, + getMykonosErrorMessage(MYKONOS_ERR_FRAMER_INV_LANEID_PARM)); + return MYKONOS_ERR_FRAMER_INV_LANEID_PARM; + } + + //count number of lanes + L = 0; + ML = 0; + + for (i = 0; i < 4; i++) + { + L += ((device->rx->framer->serializerLanesEnabled >> i) & 0x01); + } + ML = (uint8_t)(device->rx->framer->M * 10) + L; + + FK = (uint16_t)(device->rx->framer->K * 2 * device->rx->framer->M / L); + + if (FK < 20 || FK > 256 || FK % 4 != 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RXFRAMER_INV_FK_PARAM, + getMykonosErrorMessage(MYKONOS_ERR_RXFRAMER_INV_FK_PARAM)); + return MYKONOS_ERR_RXFRAMER_INV_FK_PARAM; + } + + if (device->rx->framer->externalSysref == 0) + { + /* Framer: Generate SYSREF internally */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_TEST_CNTR_CTL, 0x20); + } + + framerADC_XBar = 0xB1; + if (ML == 24) + { + if (device->rx->rxChannels == RX1) + { + /* adc 0 and 2 used */ + framerADC_XBar = ((framerADC_XBar & 0x0C) << 2) | (framerADC_XBar & 0x03); + } + else if (device->rx->rxChannels == RX2) + { + /* swap ADC xbar for Rx1 and Rx2 */ + framerADC_XBar = ((framerADC_XBar & 0xF) << 4) | ((framerADC_XBar & 0xF0) >> 4); + /* adc 0 and 2 used */ + framerADC_XBar = ((framerADC_XBar & 0x0C) << 2) | (framerADC_XBar & 0x03); + } + + /* Framer: Set ADC Crossbar */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_ADC_XBAR_SEL, framerADC_XBar); + } + else + { + /* Framer: Set ADC Crossbar */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_ADC_XBAR_SEL, framerADC_XBar); + } + + if (device->rx->framer->enableManualLaneXbar == 1) + { + framerLaneXbar = device->rx->framer->serializerLaneCrossbar; + } + else + { + if (ML == 42) + { + /* uses framer outputs 0 and 2 instead of 0 and 1...fix framer lane XBar */ + /* only 2 lane cases here */ + switch ((device->rx->framer->serializerLanesEnabled & 0x0F)) + { + case 3: + framerLaneXbar = 0x08; + break; + case 5: + framerLaneXbar = 0x20; + break; + case 6: + framerLaneXbar = 0x20; + break; + case 9: + framerLaneXbar = 0x80; + break; + case 10: + framerLaneXbar = 0x80; + break; + case 12: + framerLaneXbar = 0x80; + break; + default: + /* default to valid setting for Lane 0 */ + framerLaneXbar = 0x08; + break; + } + } + else + { + switch ((device->rx->framer->serializerLanesEnabled & 0x0F)) + { + /* all 4 lanes get framer 0 output */ + case 1: + framerLaneXbar = 0x00; + break; + case 2: + framerLaneXbar = 0x00; + break; + case 3: + framerLaneXbar = 0x04; + break; + case 4: + framerLaneXbar = 0x00; + break; + case 5: + framerLaneXbar = 0x10; + break; + case 6: + framerLaneXbar = 0x10; + break; + case 8: + framerLaneXbar = 0x00; + break; + case 9: + framerLaneXbar = 0x40; + break; + case 10: + framerLaneXbar = 0x40; + break; + case 12: + framerLaneXbar = 0x40; + break; + case 15: + framerLaneXbar = 0xE4; + break; + default: + /* default to valid setting for all Lanes */ + framerLaneXbar = 0xE4; + break; + } + } + } + + /* Framer: Set Lane Crossbar */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_LANE_XBAR_SEL, framerLaneXbar); + + if (ML == 24) + { + /* Framer: Clear ADC Xbar channel auto switch */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_CONFIG_LOOPBACK_XBAR_REV, 0x00); + } + else + { + /* Framer: Set ADC Xbar channel auto switch */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_CONFIG_LOOPBACK_XBAR_REV, 0x04); + } + + /* enabling the SYSREF for relink if newSysrefOnRelink is set */ + if (device->rx->framer->newSysrefOnRelink) + { + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_FRAMER_SYSREF_FIFO_EN, 0x01, 0x40, 6); + } + + /* enabling auto channel if the enableAutoChanXbar structure member is set */ + if (device->rx->framer->enableAutoChanXbar) + { + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_FRAMER_CONFIG_LOOPBACK_XBAR_REV, 0x01, 0x04, 2); + } + + /* determining F octets per frame based on 2*M/L */ + framerConfigF = (uint8_t)(2 * (device->rx->framer->M / L)); + + /* Framer: Soft Reset */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_RESET, 0x03); + + /* Framer: Clear Soft Reset */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_RESET, 0x00); + + /* Framer: Set F (Octets in Frame) */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_CONFIG_F, framerConfigF); + + /* Framer: Enable framer clock and lane clocks */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_FRAMER_CLK_EN, 0x03, 0x03, 0); + + /* Set Framer lane FIFO enable for each lane enabled */ + fifoLaneEnable = (((device->rx->framer->serializerLanesEnabled & 0x0F) << 4) | 0x01); + + /* Framer: Enable Lane FIFOs */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_LANE_CTL, fifoLaneEnable); + + /* Setup submap registers */ + SUBCLASSV = 1; /* JESD subclass 1 */ + JESDV = 1; /* Version: JESD204B */ + DID = device->rx->framer->deviceId; + BID = device->rx->framer->bankId; + LID0 = device->rx->framer->lane0Id; + LID1 = device->rx->framer->lane0Id + 1; + LID2 = device->rx->framer->lane0Id + 2; + LID3 = device->rx->framer->lane0Id + 3; + + CS = 0; + N = 0x0F; + Np = 0x0F; + S = 0; + CF = 0; + HD = 0; + K = device->rx->framer->K - 1; + FramerL = L - 1; + FramerM = device->rx->framer->M - 1; + FramerF = (uint8_t)(2 * device->rx->framer->M / L) - 1; + + if (ML == 11) + { + regE0 = 0x01; + regE2 = 0x01; + } + else if (ML == 12) + { + regE0 = 0x01; + regE2 = 0x03; + HD = 0x01; + } + else if (ML == 21) + { + regE0 = 0x03; + regE2 = 0x01; + } + else if (ML == 22) + { + regE0 = 0x03; + regE2 = 0x03; + } + else if (ML == 24) + { + regE0 = 0x05; + regE2 = 0x0F; + HD = 0x01; + } + else if (ML == 41) + { + regE0 = 0x0F; + regE2 = 0x01; + } + else if (ML == 42) + { + regE0 = 0x0F; + regE2 = 0x05; + } + else if (ML == 44) + { + regE0 = 0x0F; + regE2 = 0x0F; + } + else + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FRAMER_INV_M_PARM, getMykonosErrorMessage(MYKONOS_ERR_FRAMER_INV_M_PARM)); + return MYKONOS_ERR_FRAMER_INV_M_PARM; + } + + /* setting K offset for framer */ + if (device->rx->framer->lmfcOffset < device->rx->framer->K) + { + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_LMFC_K_OFFSET, device->rx->framer->lmfcOffset); + } + else + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FRAMER_INV_K_OFFSET_PARAM, + getMykonosErrorMessage(MYKONOS_ERR_FRAMER_INV_K_OFFSET_PARAM)); + return MYKONOS_ERR_FRAMER_INV_K_OFFSET_PARAM; + } + + subaddr[0] = 0x00; + subdata[0] = (DID & 0xFF); /* Device ID */ + subaddr[1] = 0x01; + subdata[1] = (BID & 0x0F); /* Bank ID */ + subaddr[2] = 0x02; + subdata[2] = (LID0 & 0x1F); /* Lane 0 ID */ + subaddr[3] = 0x03; + subdata[3] = (uint8_t)(device->rx->framer->scramble << 7) | (FramerL & 0x1F); /* [7] Scramble, #Lanes[4:0]-1 */ + subaddr[4] = 0x04; + subdata[4] = (FramerF & 0xFF); /* F[7:0]-1 */ + subaddr[5] = 0x05; + subdata[5] = (K & 0x1F); /* K[4:0]-1 */ + subaddr[6] = 0x06; + subdata[6] = (FramerM & 0xFF); /* M[7:0]-1 */ + subaddr[7] = 0x07; + subdata[7] = ((CS & 0x3) << 6) | (N & 0x1F); /* [7:6] = CS[1:0], N[4:0]-1 */ + subaddr[8] = 0x08; + subdata[8] = ((SUBCLASSV & 7) << 5) | (Np & 0x1F); /* NP[4:0] -1 */ + subaddr[9] = 0x09; + subdata[9] = ((JESDV & 7) << 5) | (S & 0x1F); /* S[4:0]-1 */ + subaddr[10] = 0x0A; + subdata[10] = ((HD & 1) << 7) | (CF & 0x1F); /* [7] = HD, CF[4:0] */ + subaddr[11] = 0x0B; + subdata[11] = 0x00; /* reserved */ + subaddr[12] = 0x0C; + subdata[12] = 0x00; /* reserved */ + + CheckSum = (DID & 0xFF) + (BID & 0xF) + (LID0 & 0x1F) + (device->rx->framer->scramble) + (FramerL & 0x1F) + (FramerF & 0xFF) + (K & 0x1F) + (FramerM & 0xFF) + + (CS & 0x3) + (N & 0x1F) + (Np & 0x1F) + (S & 0x1F) + (HD & 1) + (CF & 0x1F) + (SUBCLASSV & 7) + (JESDV & 7); + + /* Checksum Lane 0 */ + subaddr[13] = 0x0D; + subdata[13] = CheckSum & 0xFF; + + /* in JESD204B ML=42 case, framer ip lanes 0 and 2 are used, write lane 1 id and checksum to ip lane 2 regs */ + if (ML == 42) + { + /* Lane 1 ID */ + subaddr[14] = 0x1A; + subdata[14] = LID1; + + CheckSum = (DID & 0xFF) + (BID & 0xF) + (LID1 & 0x1F) + (device->rx->framer->scramble) + (FramerL & 0x1F) + (FramerF & 0xFF) + (K & 0x1F) + (FramerM & 0xFF) + + (CS & 0x3) + (N & 0x1F) + (Np & 0x1F) + (S & 0x1F) + (HD & 1) + (CF & 0x1F) + (SUBCLASSV & 7) + (JESDV & 7); + + /* Checksum Lane 1 */ + subaddr[15] = 0x1D; + subdata[15] = CheckSum & 0xFF; + } + else + { + /* Lane 1 ID */ + subaddr[14] = 0x12; + subdata[14] = LID1; + + CheckSum = (DID & 0xFF) + (BID & 0xF) + (LID1 & 0x1F) + (device->rx->framer->scramble) + (FramerL & 0x1F) + (FramerF & 0xFF) + (K & 0x1F) + (FramerM & 0xFF) + + (CS & 0x3) + (N & 0x1F) + (Np & 0x1F) + (S & 0x1F) + (HD & 1) + (CF & 0x1F) + (SUBCLASSV & 7) + (JESDV & 7); + + /* Checksum Lane 1 */ + subaddr[15] = 0x15; + subdata[15] = CheckSum & 0xFF; + + /* Lane 2 ID */ + subaddr[16] = 0x1A; + subdata[16] = LID2; + + CheckSum = (DID & 0xFF) + (BID & 0xF) + (LID2 & 0x1F) + (device->rx->framer->scramble) + (FramerL & 0x1F) + (FramerF & 0xFF) + (K & 0x1F) + (FramerM & 0xFF) + + (CS & 0x3) + (N & 0x1F) + (Np & 0x1F) + (S & 0x1F) + (HD & 1) + (CF & 0x1F) + (SUBCLASSV & 7) + (JESDV & 7); + + /* Checksum Lane 2 */ + subaddr[17] = 0x1D; + subdata[17] = CheckSum & 0xFF; + + /* Lane 3 ID */ + subaddr[18] = 0x22; + subdata[18] = LID3; + + CheckSum = (DID & 0xFF) + (BID & 0xF) + (LID3 & 0x1F) + (device->rx->framer->scramble) + (FramerL & 0x1F) + (FramerF & 0xFF) + (K & 0x1F) + (FramerM & 0xFF) + + (CS & 0x3) + (N & 0x1F) + (Np & 0x1F) + (S & 0x1F) + (HD & 1) + (CF & 0x1F) + (SUBCLASSV & 7) + (JESDV & 7); + + subaddr[19] = 0x25; + subdata[19] = CheckSum & 0xFF; + } + + subaddr[20] = 0xE0; + subdata[20] = regE0; /* Enable converter n logic */ + subaddr[21] = 0xE2; + subdata[21] = regE2; /* Enable Lane n logic */ + subaddr[22] = 0xE4; + subdata[22] = 0x00; + subaddr[23] = 0xE6; + subdata[23] = 0x00; + subaddr[24] = 0xF0; + subdata[24] = 0x00; /* #multiframes in ILAS */ + subaddr[25] = 0xF2; + subdata[25] = 0x00; + subaddr[26] = 0xF3; + subdata[26] = 0x00; + subaddr[27] = 0xF4; + subdata[27] = 0x00; + subaddr[28] = 0xC0; + subdata[28] = 0x03; /* Framer enable, both sides perform lane sync */ + + for (i = 0; i <= 28; i++) + { + /* Set framer sub register map address */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_ADDR, subaddr[i]); + + /* Set framer sub register map data word */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_DATA, subdata[i]); + + /* Write enable */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_WRITE_EN, 0x01); + } + + if (device->rx->framer->externalSysref > 0) + { + /* Framer: Enable lane FIFO sync (Enable CGS) */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_SYSREF_FIFO_EN, 0x30); + } + else + { + /* Framer: Enable lane FIFO sync (Enable CGS) */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_SYSREF_FIFO_EN, 0x10); + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief Sets up the JESD204B OBSRX Framer + * + * Dependencies + * - device->rxChannels + * - device->spiSettings->chipSelectIndex + * - device->obsRx->framer->bankId + * - device->obsRx->framer->M + * - device->obsRx->framer->serializerLanesEnabled + * - device->obsRx->framer->externalSysref + * - device->spiSettings + * - device->obsRx->framer->deviceId + * - device->obsRx->framer->lane0Id + * - device->obsRx->framer->K + * - device->obsRx->framer->lmfcOffset + * - device->obsRx->framer->scramble + * - device->obsRx->framer->obsRxSyncbSelect + * + * \param device Pointer to the device settings structure + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_OBSRX_FRAMER_INV_REAL_IF_DATA_PARM M parameter can only be 1 when real IF data mode is enabled + * \retval MYKONOS_ERR_OBSRX_FRAMER_INV_M_PARM ObsRx Framer M parameter can only be 1 or 2 + * \retval MYKONOS_ERR_OBSRX_FRAMER_INV_BANKID_PARM Invalid BankId (0-15) + * \retval MYKONOS_ERR_OBSRX_FRAMER_INV_LANEID_PARM Invalid lane0Id (0-31) + * \retval MYKONOS_ERR_OBSRXFRAMER_INV_FK_PARAM Invalid F*K value (F * K must be > 20 and divisible by 4) + * \retval MYKONOS_ERR_OBSRX_FRAMER_INV_K_OFFSET_PARAM Invalid K offset, must be less than K + */ +mykonosErr_t MYKONOS_setupJesd204bObsRxFramer(mykonosDevice_t *device) +{ + uint8_t i = 0; + uint8_t laneFifoEnable = 0; + uint8_t L = 1; + uint8_t ML = 2; + uint8_t framerConfigF = 0; + + uint8_t subaddr[29] = {0}; /* holds address to framer sub register map */ + uint8_t subdata[29] = {0}; /* holds data for framer sub register map */ + + /* Setup submap registers */ + uint8_t SUBCLASSV = 1; /* JESD subclass 1 */ + uint8_t JESDV = 1; /* Version: JESD204B */ + uint8_t DID = 0; + uint8_t BID = 0; + uint8_t LID0 = 0; + uint8_t LID1 = 1; + uint8_t LID2 = 2; + uint8_t LID3 = 3; + uint8_t CS = 0; + uint8_t N = 0x0F; + uint8_t Np = 0x0F; + uint8_t S = 0; + uint8_t CF = 0; + uint8_t K = 31; + uint8_t HD = 0; + uint8_t FramerL = 1; + uint8_t FramerM = 2; + uint8_t FramerF = 1; + uint8_t framerADC_XBar = 0xE4; + uint8_t regE0 = 0; + uint8_t regE2 = 0; + uint8_t framerLaneXbar = 0xE4; + uint16_t CheckSum = 0; + uint16_t FK = 0; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setupJesd204bObsRxFramer()\n"); +#endif + + if (device->obsRx->framer->M == 1 && !(device->obsRx->realIfData)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OBSRX_FRAMER_INV_REAL_IF_DATA_PARM, + getMykonosErrorMessage(MYKONOS_ERR_OBSRX_FRAMER_INV_REAL_IF_DATA_PARM)); + return MYKONOS_ERR_OBSRX_FRAMER_INV_REAL_IF_DATA_PARM; + } + + if (device->obsRx->framer->M != 1 && device->obsRx->framer->M != 2) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OBSRX_FRAMER_INV_M_PARM, + getMykonosErrorMessage(MYKONOS_ERR_OBSRX_FRAMER_INV_M_PARM)); + return MYKONOS_ERR_OBSRX_FRAMER_INV_M_PARM; + } + + if (device->obsRx->framer->bankId > 15) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OBSRX_FRAMER_INV_BANKID_PARM, + getMykonosErrorMessage(MYKONOS_ERR_OBSRX_FRAMER_INV_BANKID_PARM)); + return MYKONOS_ERR_OBSRX_FRAMER_INV_BANKID_PARM; + } + + /* no need to check deviceId, its range is full uint8_t range */ + if (device->obsRx->framer->lane0Id > 31) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OBSRX_FRAMER_INV_LANEID_PARM, + getMykonosErrorMessage(MYKONOS_ERR_OBSRX_FRAMER_INV_LANEID_PARM)); + return MYKONOS_ERR_OBSRX_FRAMER_INV_LANEID_PARM; + } + + //count number of lanes + L = 0; + ML = 0; + + for (i = 0; i < 4; i++) + { + L += ((device->obsRx->framer->serializerLanesEnabled >> i) & 0x01); + } + + ML = (uint8_t)(device->obsRx->framer->M * 10 + L); + + if (L == 0) + { + /* Disable framer and return successfully */ + /* Disable framer clock and lane clocks */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_CLK_EN, 0, 0x03, 0); + + /* Disable lane FIFO enables */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_LANE_CTL, 0, 0xF0, 4); + return MYKONOS_ERR_OK; + } + + FK = (uint16_t)(device->obsRx->framer->K * 2 * device->obsRx->framer->M / L); + if (FK < 20 || FK > 256 || FK % 4 != 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OBSRXFRAMER_INV_FK_PARAM, + getMykonosErrorMessage(MYKONOS_ERR_OBSRXFRAMER_INV_FK_PARAM)); + return MYKONOS_ERR_OBSRXFRAMER_INV_FK_PARAM; + } + + if (device->obsRx->framer->externalSysref == 0) + { + /* Framer: Generate SYSREF internally */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_TEST_CNTR_CTL, 0x20); + } + + /* Framer: Set ADC Crossbar */ + framerADC_XBar = 0xB1; + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_ADC_XBAR_SEL, framerADC_XBar); + + if (device->obsRx->framer->enableManualLaneXbar == 1) + { + framerLaneXbar = device->obsRx->framer->serializerLaneCrossbar; + } + else + { + if (ML == 42) + { + /* uses framer outputs 0 and 2 instead of 0 and 1...fix framer lane XBar */ + /* only 2 lane cases here */ + switch ((device->obsRx->framer->serializerLanesEnabled & 0x0F)) + { + case 3: + framerLaneXbar = 0x08; + break; + case 5: + framerLaneXbar = 0x20; + break; + case 6: + framerLaneXbar = 0x20; + break; + case 9: + framerLaneXbar = 0x80; + break; + case 10: + framerLaneXbar = 0x80; + break; + case 12: + framerLaneXbar = 0x80; + break; + default: + /* default to valid setting for Lane 0 */ + framerLaneXbar = 0x08; + break; + } + } + else + { + switch ((device->obsRx->framer->serializerLanesEnabled & 0x0F)) + { + /* all 4 lanes get framer 0 output */ + case 1: + framerLaneXbar = 0x00; + break; + case 2: + framerLaneXbar = 0x00; + break; + case 3: + framerLaneXbar = 0x04; + break; + case 4: + framerLaneXbar = 0x00; + break; + case 5: + framerLaneXbar = 0x10; + break; + case 6: + framerLaneXbar = 0x10; + break; + case 8: + framerLaneXbar = 0x00; + break; + case 9: + framerLaneXbar = 0x40; + break; + case 10: + framerLaneXbar = 0x40; + break; + case 12: + framerLaneXbar = 0x40; + break; + case 15: + framerLaneXbar = 0xE4; + break; + default: + /* default to valid setting for all Lanes */ + framerLaneXbar = 0xE4; + break; + } + } + } + + /* Framer: set Lane Crossbar */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_LANE_XBAR_SEL, framerLaneXbar); + + /* Framer: determine the framerConfigF value (2*M/L) */ + framerConfigF = (uint8_t)(2 * (device->obsRx->framer->M/L)); + + /* Framer: Soft Reset */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_RESET, 0x03); + + /* Framer: Clear Soft Reset */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_RESET, 0x00); + + /* Framer: Set F (Octets in Frame) */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_CONFIG_F, framerConfigF); + + /* Framer: Enable framer clock and lane clocks */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_CLK_EN, 0x03, 0x03, 0); + + /* Set Framer lane FIFO enable for each lane enabled */ + laneFifoEnable = (uint8_t)(((device->obsRx->framer->serializerLanesEnabled & 0x0F) << 4) | 0x01); + + /* Framer: Enable Lane FIFOs */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_LANE_CTL, laneFifoEnable); + + /* enabling the SYSREF for relink if newSysrefOnRelink is set */ + if (device->obsRx->framer->newSysrefOnRelink) + { + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_SYSREF_FIFO_EN, 0x01, 0x40, 6); + } + + /* enabling auto channel if the enableAutoChanXbar structure member is set */ + if (device->obsRx->framer->enableAutoChanXbar) + { + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_CONFIG_LOOPBACK_XBAR_REV, 0x01, 0x04, 2); + } + + /* Setup submap registers */ + SUBCLASSV = 1; /* JESD subclass 1 */ + JESDV = 1; /* Version: JESD204B */ + DID = device->obsRx->framer->deviceId; + BID = device->obsRx->framer->bankId; + LID0 = device->obsRx->framer->lane0Id; + LID1 = device->obsRx->framer->lane0Id + 1; + LID2 = device->obsRx->framer->lane0Id + 2; + LID3 = device->obsRx->framer->lane0Id + 3; + + CS = 0; + N = 0x0F; + Np = 0x0F; + S = 0; + CF = 0; + K = device->obsRx->framer->K - 1; + HD = 0; + FramerL = L - 1; + FramerM = device->obsRx->framer->M - 1; + FramerF = (uint8_t)((2*device->obsRx->framer->M/L) - 1); + + if (ML == 11) + { + regE0 = 0x1; + regE2 = 0x1; + } + else if (ML == 12) + { + regE0 = 0x1; + regE2 = 0x3; + HD = 1; + } + else if (ML == 21) + { + regE0 = 0x3; + regE2 = 0x1; + } + else if (ML == 22) + { + regE0 = 0x3; + regE2 = 0x3; + } + else + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OBSRX_FRAMER_INV_M_PARM, + getMykonosErrorMessage(MYKONOS_ERR_OBSRX_FRAMER_INV_M_PARM)); + return MYKONOS_ERR_OBSRX_FRAMER_INV_M_PARM; + } + + /* setting K offset for framer */ + if (device->obsRx->framer->lmfcOffset < device->rx->framer->K) + { + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_LMFC_K_OFFSET, device->obsRx->framer->lmfcOffset); + } + else + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OBSRX_FRAMER_INV_K_OFFSET_PARAM, + getMykonosErrorMessage(MYKONOS_ERR_OBSRX_FRAMER_INV_K_OFFSET_PARAM)); + return MYKONOS_ERR_OBSRX_FRAMER_INV_K_OFFSET_PARAM; + } + + subaddr[0] = 0x00; + subdata[0] = (DID & 0xFF); /* Device ID */ + subaddr[1] = 0x01; + subdata[1] = (BID & 0x0F); /* Bank ID */ + subaddr[2] = 0x02; + subdata[2] = (LID0 & 0x1F); /* Lane 0 ID */ + subaddr[3] = 0x03; + subdata[3] = (uint8_t)(device->obsRx->framer->scramble << 7) | (FramerL & 0x1F); /* [7] Scramble, #Lanes[4:0]-1 */ + subaddr[4] = 0x04; + subdata[4] = (FramerF & 0xFF); /* F[7:0]-1 */ + subaddr[5] = 0x05; + subdata[5] = (K & 0x1F); /* K[4:0]-1 */ + subaddr[6] = 0x06; + subdata[6] = (FramerM & 0xFF); /* M[7:0]-1 */ + subaddr[7] = 0x07; + subdata[7] = ((CS & 0x3) << 6) | (N & 0x1F); /* [7:6] = CS[1:0], N[4:0]-1 */ + subaddr[8] = 0x08; + subdata[8] = ((SUBCLASSV & 7) << 5) | (Np & 0x1F); /* NP[4:0] -1 */ + subaddr[9] = 0x09; + subdata[9] = ((JESDV & 7) << 5) | (S & 0x1F); /* S[4:0]-1 */ + subaddr[10] = 0x0a; + subdata[10] = ((HD & 1) << 7) | (CF & 0x1F); /* [7] = HD, CF[4:0] */ + subaddr[11] = 0x0b; + subdata[11] = 0x00; /* reserved */ + subaddr[12] = 0x0c; + subdata[12] = 0x00; /* reserved */ + + CheckSum = (DID & 0xFF) + (BID & 0xF) + (LID0 & 0x1F) + (device->obsRx->framer->scramble) + (FramerL & 0x1F) + (FramerF & 0xFF) + (K & 0x1F) + (FramerM & 0xFF) + + (CS & 0x3) + (N & 0x1F) + (Np & 0x1F) + (S & 0x1F) + (HD & 1) + (CF & 0x1F) + (SUBCLASSV & 7) + (JESDV & 7); + + /* Checksum Lane 0 */ + subaddr[13] = 0x0d; + subdata[13] = CheckSum & 0xFF; + + /* Lane 1 ID */ + subaddr[14] = 0x12; + subdata[14] = LID1; + + CheckSum = (DID & 0xFF) + (BID & 0xF) + (LID1 & 0x1F) + (device->obsRx->framer->scramble) + (FramerL & 0x1F) + (FramerF & 0xFF) + (K & 0x1F) + (FramerM & 0xFF) + + (CS & 0x3) + (N & 0x1F) + (Np & 0x1F) + (S & 0x1F) + (HD & 1) + (CF & 0x1F) + (SUBCLASSV & 7) + (JESDV & 7); + + /* Checksum Lane 1 */ + subaddr[15] = 0x15; + subdata[15] = CheckSum & 0xFF; + + /* Lane 2 ID */ + subaddr[16] = 0x1a; + subdata[16] = LID2; + + CheckSum = (DID & 0xFF) + (BID & 0xF) + (LID2 & 0x1F) + (device->obsRx->framer->scramble) + (FramerL & 0x1F) + (FramerF & 0xFF) + (K & 0x1F) + (FramerM & 0xFF) + + (CS & 0x3) + (N & 0x1F) + (Np & 0x1F) + (S & 0x1F) + (HD & 1) + (CF & 0x1F) + (SUBCLASSV & 7) + (JESDV & 7); + + /* Checksum Lane 2 */ + subaddr[17] = 0x1d; + subdata[17] = CheckSum & 0xFF; + + /* Lane 3 ID */ + subaddr[18] = 0x22; + subdata[18] = LID3; + + CheckSum = (DID & 0xFF) + (BID & 0xF) + (LID3 & 0x1F) + (device->obsRx->framer->scramble) + (FramerL & 0x1F) + (FramerF & 0xFF) + (K & 0x1F) + (FramerM & 0xFF) + + (CS & 0x3) + (N & 0x1F) + (Np & 0x1F) + (S & 0x1F) + (HD & 1) + (CF & 0x1F) + (SUBCLASSV & 7) + (JESDV & 7); + + subaddr[19] = 0x25; + subdata[19] = CheckSum & 0xFF; + + subaddr[20] = 0xe0; + subdata[20] = regE0; /* Enable converter n logic */ + subaddr[21] = 0xe2; + subdata[21] = regE2; /* Enable Lane n logic */ + subaddr[22] = 0xe4; + subdata[22] = 0x00; + subaddr[23] = 0xe6; + subdata[23] = 0x00; + subaddr[24] = 0xf0; + subdata[24] = 0x00; /* #multiframes in ILAS */ + subaddr[25] = 0xf2; + subdata[25] = 0x00; + subaddr[26] = 0xf3; + subdata[26] = 0x00; + subaddr[27] = 0xf4; + subdata[27] = 0x00; + subaddr[28] = 0xc0; + subdata[28] = 0x03; /* Framer enable, both sides perform lane sync */ + + for (i = 0; i <= 28; i++) + { + /* Set framer sub register map address */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_ADDR, subaddr[i]); + + /* Set framer sub register map data word */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_DATA, subdata[i]); + + /* Write enable */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_WRITE_EN, 0x01); + } + + if (device->obsRx->framer->externalSysref > 0) + { + /* Framer: Enable lane FIFO sync (Enable CGS) */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_SYSREF_FIFO_EN, 0x30); + } + else + { + /* Framer: Enable lane FIFO sync (Enable CGS) */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_SYSREF_FIFO_EN, 0x10); + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief Enables/Disables the JESD204B Rx Framer + * + * This function is normally not necessary. In the event that the link needs to be reset, this + * function allows the Rx framer to be disabled and re-enabled. + * + * Dependencies + * - device->spiSettings + * - device->rx->framer->serializerLanesEnabled + * + * \param device is a pointer to the device settings structure + * \param enable 0 = Disable the selected framer, 1 = enable the selected framer link + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_ENFRAMERLINK_INV_LANESEN_PARM Invalid serializerLanesEnabled parameter in device data structure + */ +mykonosErr_t MYKONOS_enableRxFramerLink(mykonosDevice_t *device, uint8_t enable) +{ + uint8_t enableLink = 0; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_enableFramerLink()\n"); +#endif + + enableLink = (enable > 0) ? 1 : 0; + + if (enableLink) + { + /* Power Up serializer lanes */ + if (device->rx->framer->serializerLanesEnabled > 15) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_ENFRAMERLINK_INV_LANESEN_PARM, + getMykonosErrorMessage(MYKONOS_ERR_ENFRAMERLINK_INV_LANESEN_PARM)); + return MYKONOS_ERR_ENFRAMERLINK_INV_LANESEN_PARM; + } + + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_SERIALIZER_CTL_1, ((~device->rx->framer->serializerLanesEnabled) & 0x0F), + device->rx->framer->serializerLanesEnabled, 0); + + /* Enable Clocks to Framer */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_FRAMER_CLK_EN, 3, 0x03, 0); + + /* Release reset to framer and lane FIFOs */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_RESET, 0x00); + } + else + { + /* Disable Link */ + /* Hold Rx framer in reset */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_RESET, 0x03); + + /* Disable Clocks to Framer */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_FRAMER_CLK_EN, 0, 0x03, 0); + + /* Power down serializer lanes */ + if (device->rx->framer->serializerLanesEnabled > 15) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_ENFRAMERLINK_INV_LANESEN_PARM, + getMykonosErrorMessage(MYKONOS_ERR_ENFRAMERLINK_INV_LANESEN_PARM)); + return MYKONOS_ERR_ENFRAMERLINK_INV_LANESEN_PARM; + } + + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_SERIALIZER_CTL_1, device->rx->framer->serializerLanesEnabled, device->rx->framer->serializerLanesEnabled, 0); + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief Enables/Disables the JESD204B ObsRx Framer + * + * This function is normally not necessary. In the event that the link needs to be reset, this + * function allows the ObsRx framer to be disabled and re-enabled. + * + * Dependencies + * - device->spiSettings + * - device->obsRx->framer->serializerLanesEnabled + * + * \param device is a pointer to the device settings structure + * \param enable 0 = Disable the selected framer, 1 = enable the selected framer link + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_ENFRAMERLINK_INV_LANESEN_PARM Invalid serializerLanesEnabled parameter in device data structure (Valid 0-15) + */ +mykonosErr_t MYKONOS_enableObsRxFramerLink(mykonosDevice_t *device, uint8_t enable) +{ + uint8_t enableLink = 0; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_enableObsRxFramerLink()\n"); +#endif + + enableLink = (enable > 0) ? 1 : 0; + + if (enableLink) + { + /* Power Up serializer lanes */ + if (device->rx->framer->serializerLanesEnabled > 15) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_ENOBSFRAMERLINK_INV_LANESEN_PARM, + getMykonosErrorMessage(MYKONOS_ERR_ENOBSFRAMERLINK_INV_LANESEN_PARM)); + return MYKONOS_ERR_ENOBSFRAMERLINK_INV_LANESEN_PARM; + } + + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_SERIALIZER_CTL_1, ((~device->obsRx->framer->serializerLanesEnabled) & 0x0F), + device->obsRx->framer->serializerLanesEnabled, 0); + + /* Enable Clocks to Framer */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_CLK_EN, 3, 0x03, 0); + + /* Release reset to framer and lane FIFOs */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_RESET, 0x00); + } + else + { + /* Disable Link */ + /* Hold Rx framer in reset */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_RESET, 0x03); + + /* Disable Clocks to Framer */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_CLK_EN, 0, 0x03, 0); + + /* Power down serializer lanes */ + if (device->obsRx->framer->serializerLanesEnabled > 15) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_ENOBSFRAMERLINK_INV_LANESEN_PARM, + getMykonosErrorMessage(MYKONOS_ERR_ENOBSFRAMERLINK_INV_LANESEN_PARM)); + return MYKONOS_ERR_ENOBSFRAMERLINK_INV_LANESEN_PARM; + } + + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_SERIALIZER_CTL_1, device->obsRx->framer->serializerLanesEnabled, + device->obsRx->framer->serializerLanesEnabled, 0); + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief Sets up the JESD204B Deframer + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - device->tx->deframer->M + * - device->tx->deframer->bankId + * - device->tx->deframer->lane0Id + * - device->tx->deframer->K + * - device->tx->deframer->deserializerLanesEnabled + * - device->tx->deframer->externalSysref + * - device->tx->deframer->newSysrefOnRelink + * - device->tx->deframer->enableAutoChanXbar + * - device->tx->deframer->lmfcOffset + * - device->tx->deframer->scramble + * + * \param device Pointer to device settings structure + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_DEFRAMER_INV_M_PARM Invalid M parameter in deframer structure + * \retval MYKONOS_ERR_DEFRAMER_INV_BANKID_PARM Invalid BankId parameter in deframer structure (Valid 0-15) + * \retval MYKONOS_ERR_ERR_DEFRAMER_INV_LANEID_PARM Invalid Lane0Id parameter in deframer structure (Valid 0-31) + * \retval MYKONOS_ERR_DEFRAMER_INV_K_PARAM Invalid K parameter in deframer structure (valid 1-32 with other constraints) + * \retval MYKONOS_ERR_DEFRAMER_INV_FK_PARAM Invalid F*K parameter (Valid F*K > 20, F*K must be divisible by 4), K must be <= 32 + * \retval MYKONOS_ERR_DEFRAMER_INV_K_OFFSET_PARAM Invalid K offset parameter in deframer structure (must be less than K) + */ +mykonosErr_t MYKONOS_setupJesd204bDeframer(mykonosDevice_t *device) +{ + uint8_t i = 0; + uint8_t temp = 0; + uint8_t reg080 = 0; + uint8_t laneXbar = 0; + uint8_t L = 0; + uint8_t ML = 0; + + /* Setup submap registers */ + uint8_t SUBCLASSV = 1; + uint8_t JESDV = 1; + uint8_t DID = 0; + uint8_t BID = 0; + uint8_t LID0 = 0; + uint8_t CS = 2; /* 2 control bits */ + uint8_t N = 0x0D; /* 14 bits */ + uint8_t Np = 0x0F; /* 16 bits */ + uint8_t S = 0; + uint8_t CF = 0; + uint8_t K = 0x1F; + uint16_t FK = 0; + uint8_t HD = 0; /* only one case has HD == 1 */ + uint8_t CTRLREG0 = 0; + uint8_t DeframerL = 1; + uint8_t DeframerM = 2; + uint8_t DeframerF = 0; + uint8_t CTRLREG1 = 0; + uint8_t CTRLREG2 = 0; + uint8_t DeframerLaneEnable = 0x00; + uint16_t CheckSum = 0; + uint8_t subaddr[25] = {0}; + uint8_t subdata[25] = {0}; + + uint8_t deframerInput = 0; + uint8_t lane = 0; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setupJesd204bDeframer()\n"); +#endif + + if (device->tx->deframer->M != 0 && device->tx->deframer->M != 2 && device->tx->deframer->M != 4) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DEFRAMER_INV_M_PARM, getMykonosErrorMessage(MYKONOS_ERR_DEFRAMER_INV_M_PARM)); + return MYKONOS_ERR_DEFRAMER_INV_M_PARM; + } + + if (device->tx->deframer->bankId > 15) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DEFRAMER_INV_BANKID_PARM, + getMykonosErrorMessage(MYKONOS_ERR_DEFRAMER_INV_BANKID_PARM)); + return MYKONOS_ERR_DEFRAMER_INV_BANKID_PARM; + } + + if (device->tx->deframer->lane0Id > 31) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_ERR_DEFRAMER_INV_LANEID_PARM, + getMykonosErrorMessage(MYKONOS_ERR_ERR_DEFRAMER_INV_LANEID_PARM)); + return MYKONOS_ERR_ERR_DEFRAMER_INV_LANEID_PARM; + } + + //count number of lanes + L = 0; + ML = 0; + + for (i = 0; i < 4; i++) + { + L += ((device->tx->deframer->deserializerLanesEnabled >> i) & 0x01); + } + + ML = (uint8_t)(device->tx->deframer->M * 10 + L); + + if (device->tx->deframer->K > 32) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DEFRAMER_INV_K_PARAM, + getMykonosErrorMessage(MYKONOS_ERR_DEFRAMER_INV_K_PARAM)); + return MYKONOS_ERR_DEFRAMER_INV_K_PARAM; + } + + FK = (uint16_t)(device->tx->deframer->K * 2 * device->tx->deframer->M / L); + + if (FK < 20 || FK > 256 || FK % 4 != 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DEFRAMER_INV_FK_PARAM, + getMykonosErrorMessage(MYKONOS_ERR_DEFRAMER_INV_FK_PARAM)); + return MYKONOS_ERR_DEFRAMER_INV_FK_PARAM; + } + + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_DEFRAMER_SYNC_REQ_RETIME, (device->tx->deframer->K - 1), 0x1F, 0x00); + + if (!device->tx->deframer->externalSysref) + { + /* Deframer: Generate SYSREF internally */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_TEST, 0x02); + } + + /* enabling the SYSREF for relink if newSysrefOnRelink is set */ + if (device->tx->deframer->newSysrefOnRelink) + { + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_DEFRAMER_SYSREF_FIFO_EN, 0x01, 0x40, 6); + } + + /* enabling auto channel if the enableAutoChanXbar structure member is set */ + if (device->tx->deframer->enableAutoChanXbar) + { + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_DEFRAMER_DET_FIFO_WR_STRT_DAC_XBAR_REV, 0x01, 0x04, 2); + } + + /* Fix bad default bit to allow deterministic latency on deframer (Clear bit 4)*/ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_DEFRAMER_DET_FIFO_WR_STRT_DAC_XBAR_REV, 0x00, 0x10, 4); + + /* Deframer: Set DAC Crossbar */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_DAC_XBAR_SEL, 0xB1); + + if (device->tx->deframer->enableManualLaneXbar == 1) + { + laneXbar = device->tx->deframer->deserializerLaneCrossbar; + } + else + { + /* Lane crossbar - Allow user to reorder lanes in deframer->deserializerLaneCrossbar, but this code still */ + /* maps used lanes to deframer inputs */ + deframerInput = 0; + for (lane = 0; lane < 4; lane++) + { + if ((device->tx->deframer->deserializerLanesEnabled >> lane) & 1) + { + laneXbar |= (uint8_t)(((device->tx->deframer->deserializerLaneCrossbar >> (lane << 1)) & 3) << (deframerInput << 1)); + deframerInput += 1; + } + } + + if (ML == 42) + { + /* M4L2 uses internal deframer ports 0 and 2 */ + /* swap bits 3:2 and 5:4, keep 1:0 and 7:6 in place */ + laneXbar = (laneXbar & 0xC3U) | ((laneXbar & 0x30) >> 2) | ((laneXbar & 0x0C) << 2); + } + } + + /* Deframer: Set Lane Crossbar */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_LANE_XBAR_SEL, laneXbar); + + //Find value for Framer F depending on M and L + switch (ML) + { + case 21: + reg080 = 0x04; + break; + case 22: + reg080 = 0x22; + break; + case 24: + reg080 = 0x41; + break; + case 41: + reg080 = 0x18; + break; + case 42: + reg080 = 0x34; + break; + case 44: + reg080 = 0x52; + break; + default: + reg080 = 0x04; + break; + } + + /* Deframer: Set F (Octets in Frame) */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_CONFIG_F, reg080); + + /* Deframer: Enable clocks and lane clocks */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_CLK_EN, 0x03); + + /* Set deframer lane FIFO enable for each lane enabled */ + temp = (device->tx->deframer->deserializerLanesEnabled & 0x0F); + + /* Deframer: Enable Lane FIFOs */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_LANE_FIFO_CTL, temp); + + /* Setup submap registers */ + SUBCLASSV = 1; /* JESD subclass 1 */ + JESDV = 1; /* Version: JESD204B */ + DID = device->tx->deframer->deviceId; + BID = device->tx->deframer->bankId; + LID0 = device->tx->deframer->lane0Id; + CS = 2; /* 2 control bits */ + N = 0x0D; /* 14 bits */ + Np = 0x0F; + S = 0; + CF = 0; + K = device->tx->deframer->K - 1; + HD = 0; /* only one case has HD = 1 */ + CTRLREG0 = 1; + DeframerL = L - 1; + DeframerM = device->tx->deframer->M - 1; + DeframerF = (uint8_t)((2*device->tx->deframer->M/L) - 1); + CheckSum = 0; + + if (ML == 21) + { + CTRLREG1 = 4; + CTRLREG2 = 0x14; + DeframerLaneEnable = 1; + } + else if (ML == 22) + { + CTRLREG1 = 2; + CTRLREG2 = 4; + DeframerLaneEnable = 3; + } + else if (ML == 24) + { + HD = 1; + CTRLREG1 = 1; + CTRLREG2 = 0; + DeframerLaneEnable = 0x0F; + } + else if (ML == 41) + { + CTRLREG1 = 8; + CTRLREG2 = 0; + DeframerLaneEnable = 1; + } + else if (ML == 42) + { + CTRLREG1 = 4; + CTRLREG2 = 0; + DeframerLaneEnable = 5; + } + else if (ML == 44) + { + CTRLREG1 = 2; + CTRLREG2 = 0; + DeframerLaneEnable = 0x0F; + } + else + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DEFRAMER_INV_M_PARM, getMykonosErrorMessage(MYKONOS_ERR_DEFRAMER_INV_M_PARM)); + return MYKONOS_ERR_DEFRAMER_INV_M_PARM; + } + + /* LMFC offset limit check */ + if (device->tx->deframer->lmfcOffset < device->tx->deframer->K) + { + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_LMFC_K_OFFSET, device->tx->deframer->lmfcOffset); + } + else + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DEFRAMER_INV_K_OFFSET_PARAM, + getMykonosErrorMessage(MYKONOS_ERR_DEFRAMER_INV_K_OFFSET_PARAM)); + return MYKONOS_ERR_DEFRAMER_INV_K_OFFSET_PARAM; + } + + subaddr[0] = 0x50; + subdata[0] = DID & 0xFFU; /* Device ID */ + subaddr[1] = 0x51; + subdata[1] = BID & 0x0F; /* Bank ID */ + subaddr[2] = 0x52; + subdata[2] = LID0 & 0x1F; /* Lane 0 ID */ + subaddr[3] = 0x53; + subdata[3] = (uint8_t)(device->tx->deframer->scramble << 7) | (DeframerL & 0x1F); /* [7] = Scramble Enable, #Lanes[4:0] */ + subaddr[4] = 0x54; + subdata[4] = DeframerF & 0xFFU; /* F[7:0] */ + subaddr[5] = 0x55; + subdata[5] = K & 0x1F; /* K[4:0] */ + subaddr[6] = 0x56; + subdata[6] = DeframerM & 0xFFU; /* M[7:0] */ + subaddr[7] = 0x57; + subdata[7] = ((CS & 0x3) << 6) | (N & 0x1F); /* [7:6] = CS[1:0], N[4:0] */ + subaddr[8] = 0x58; + subdata[8] = ((SUBCLASSV & 7) << 5) | (Np & 0x1F); /* Np[4:0] */ + subaddr[9] = 0x59; + subdata[9] = ((JESDV & 7) << 5) | (S & 0x1F); /* S[4:0] */ + subaddr[10] = 0x5A; + subdata[10] = ((HD & 1) << 7) | (CF & 0x1F); /* [7]=HD, CF[4:0] */ + subaddr[11] = 0x5B; + subdata[11] = 0x00; /* reserved */ + subaddr[12] = 0x5C; + subdata[12] = 0x00; /* reserved */ + CheckSum = (DID & 0xFF) + (BID & 0xF) + (LID0 & 0x1F) + (device->tx->deframer->scramble) + (DeframerL & 0x1F) + (DeframerF & 0xFF) + (K & 0x1F) + (DeframerM & 0xFF) + + (CS & 0x3) + (N & 0x1F) + (Np & 0x1F) + (S & 0x1F) + (HD & 1) + (CF & 0x1F) + (SUBCLASSV & 7) + (JESDV & 7); + subaddr[13] = 0x5D; + subdata[13] = CheckSum & 0xFFU; /* Checksum Lane 0 */ + subaddr[14] = 0x6D; + subdata[14] = 0xA0U; /* Bad Disparity setup */ + subaddr[15] = 0x6E; + subdata[15] = 0xA0U; /* Not in Table setup */ + subaddr[16] = 0x6F; + subdata[16] = 0xA0U; /* UnExpected K character setup */ + subaddr[17] = 0x75; + subdata[17] = CTRLREG0; /* CTRLREG 0 */ + subaddr[18] = 0x76; + subdata[18] = CTRLREG1; /* CTRLREG 1 (Bytes per frame) */ + subaddr[19] = 0x77; + subdata[19] = CTRLREG2; /* CTRLREG 2 */ + subaddr[20] = 0x78; + subdata[20] = 0x01; /* # 4*K multiframes during ILAS */ + subaddr[21] = 0x7A; + subdata[21] = 0xE0U; /* Setup JESD interrupt sources */ + subaddr[22] = 0x7B; + subdata[22] = 0x08U; /* Sync assertion setup */ + subaddr[23] = 0x7C; + subdata[23] = 0xFFU; /* Error count threshold */ + subaddr[24] = 0x7D; + subdata[24] = DeframerLaneEnable & 0xFFU; /* Lane enable */ + + for (i = 0; i <= 24; i++) + { + /* Set deframer sub-register map address */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_ADDR, subaddr[i]); + + /* Set deframer sub-register map data word */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_DATA, subdata[i]); + + /* Set write enable to latch data into deframer sub register map */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_WR_EN, 0x01); + } + + /* Deframer: Enable lane FIFO sync */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_DEFRAMER_SYSREF_FIFO_EN, 0x01, 0x10, 4); + + return MYKONOS_ERR_OK; +} + +/** + * \brief Sets up the chip for multichip sync, and cleans up after MCS. + * + * When working with multiple transceivers or even only one transceiver that requires deterministic + * latency between the Tx and observation and or main Rx JESD204B data path, Multichip sync is + * necessary. This function should be run after all transceivers are initialized. + * + * After the SYSREF pulses have been sent, call the MYKONOS_enableMultichipSync() function again with the + * enableMcs parameter set to 0. When enableMcs = 0, the MCS status will be returned in the mcsStatus + * parameter. + * + * Typical sequence: + * 1) Initialize all Mykonos devices in system using MYKONOS_initialize() + * 2) Run MYKONOS_enableMultichipSync with enableMcs = 1 + * 3) Send at least 3 SYSREF pulses + * 4) Run MYKONOS_enableMultichipSync with enableMcs = 0 + * 5) Load ARM, run ARM cals and continue to active Transmit/Receive + * + * mcsStatus | bit Description + * -----------|-------------------------------------------------------- + * [0] | MCS JESD SYSREF Status (1 = sync occurred) + * [1] | MCS Digital Clocks Sync Status (1 = sync occurred) + * [2] | MCS CLKPLL SDM Sync Status (1 = sync occurred) + * [3] | MCS Device Clock divider Sync Status (1 = sync occurred) + * + * Dependencies + * - device->spiSettings + * + * \param device is a pointer to the device settings structure + * \param enableMcs =1 will enable the MCS state machine, =0 will allow reading back MCS status + * \param mcsStatus optional parameter, if pointer is not null the function Which will be populated with the mcsStatus word described in the table above. + * + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_enableMultichipSync(mykonosDevice_t *device, uint8_t enableMcs, uint8_t *mcsStatus) +{ + uint8_t clkPllSdmBypass = 0; + uint8_t mcsEnable = 0x9B; /* [7] Keeps RF LO divider enabled, Enable MCS[4] and reset Device Clock divider[3], Digital clocks[1], and JESD204 SYSREF[0] */ + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_enableMultichipSync()\n"); +#endif + + if (enableMcs) + { + /* If CLKPLL SDM not bypassed, reset CLKPLL SDM as well. */ + CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_DIVIDER_INT_BYTE1, &clkPllSdmBypass, 0x40, 6); + + if (clkPllSdmBypass == 0) + { + mcsEnable |= 0x04; /* enable MCS for CLKPLL SDM */ + } + + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_MCS_CONTROL, mcsEnable); + } + + /* if mcsStatus is a valid pointer, return the MCS status */ + if (mcsStatus != NULL) + { + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_MCS_STATUS, mcsStatus); + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief Enables or disables SYSREF to the transceiver's RX framer + * + * Dependencies + * - device->spiSettings + * + * \param device is a pointer to the device settings structure + * \param enable = '1' enables SYSREF to RX framer, '0' disables SYSREF to framer + * + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_enableSysrefToRxFramer(mykonosDevice_t *device, uint8_t enable) +{ + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_enableSysrefToRxFramer()\n"); +#endif + + if (enable) + { + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_FRAMER_SYSREF_FIFO_EN, 0x01, 0x01, 0); + } + else + { + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_FRAMER_SYSREF_FIFO_EN, 0x00, 0x01, 0); + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief Enables or disables SYSREF to the transceiver's Observation RX framer + * + * Dependencies + * - device->spiSettings + * + * \param device is a pointer to the device settings structure + * \param enable = '1' enables SYSREF to OBSRX framer, '0' disables SYSREF to framer + * + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_enableSysrefToObsRxFramer(mykonosDevice_t *device, uint8_t enable) +{ + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_enableSysrefToObsRxFramer()\n"); +#endif + + if (enable) + { + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_SYSREF_FIFO_EN, 0x01, 0x01, 0); + } + else + { + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_SYSREF_FIFO_EN, 0x00, 0x01, 0); + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief Enables or disables SYSREF to the transceiver's deframer + * + * Dependencies + * - device->spiSettings + * + * \param device is a pointer to the device settings structure + * \param enable = '1' enables SYSREF to deframer, '0' disables SYSREF to deframer + * + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_enableSysrefToDeframer(mykonosDevice_t *device, uint8_t enable) +{ + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_enableSysrefToDeframer()\n"); +#endif + + if (enable) + { + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_DEFRAMER_SYSREF_FIFO_EN, 0x01, 0x01, 0); + } + else + { + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_DEFRAMER_SYSREF_FIFO_EN, 0x00, 0x01, 0); + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief Reads the transceiver's RX framer status + * + * Dependencies + * - device->spiSettings + * + * framerStatus | Description + * -------------|----------------------------------------------------------------------------- + * [7] | SYSREF phase error ? a new SYSREF had different timing than the first that set the LMFC timing. + * [6] | Framer lane FIFO read/write pointer delta has changed. Can help debug issues with deterministic latency. + * [5] | Framer has received the SYSREF and has retimed its LMFC + * [4:2] | Framer ILAS state: 0=CGS, 1= 1st Multframe, 2= 2nd Multiframe, 3= 3rd Multiframe, 4= 4th multiframe, 5= Last multiframe, 6=invalid, 7= ILAS complete + * [1:0] | Framer Tx state: 0=CGS, 1= ILAS, 2 = ADC Data + * + * \param device is a pointer to the device settings structure + * \param framerStatus is the RX framer status byte read + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_READ_RXFRAMERSTATUS_NULL_PARAM Function parameter framerStatus has NULL pointer + */ +mykonosErr_t MYKONOS_readRxFramerStatus(mykonosDevice_t *device, uint8_t *framerStatus) +{ + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_readRxFramerStatus()\n"); +#endif + + if (framerStatus == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_READ_RXFRAMERSTATUS_NULL_PARAM, + getMykonosErrorMessage(MYKONOS_ERR_READ_RXFRAMERSTATUS_NULL_PARAM)); + return MYKONOS_ERR_READ_RXFRAMERSTATUS_NULL_PARAM; + } + + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_STATUS_STRB, 0x01); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_STATUS_STRB, 0x00); + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_FRAMER_STATUS, framerStatus); + + return MYKONOS_ERR_OK; +} + +/** + * \brief Reads the transceiver's Observation RX framer status + * + * Dependencies + * * - device->spiSettings + * + * obsFramerStatus | Description + * ----------------|----------------------------------------------------------------------------- + * [7] | SYSREF phase error ? a new SYSREF had different timing than the first that set the LMFC timing. + * [6] | Framer lane FIFO read/write pointer delta has changed. Can help debug issues with deterministic latency. + * [5] | Framer has received the SYSREF and has retimed its LMFC + * [4:2] | Framer ILAS state: 0=CGS, 1= 1st Multframe, 2= 2nd Multiframe, 3= 3rd Multiframe, 4= 4th multiframe, 5= Last multiframe, 6=invalid, 7= ILAS complete + * [1:0] | Framer Tx state: 0=CGS, 1= ILAS, 2 = ADC Data + * + * \param device is a pointer to the device settings structure + * \param obsFramerStatus is the OBSRX framer status byte read + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_READ_ORXFRAMERSTATUS_NULL_PARAM Function parameter obsFramerStatus has NULL pointer + */ +mykonosErr_t MYKONOS_readOrxFramerStatus(mykonosDevice_t *device, uint8_t *obsFramerStatus) +{ + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_readOrxFramerStatus()\n"); +#endif + + if (obsFramerStatus == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_READ_ORXFRAMERSTATUS_NULL_PARAM, + getMykonosErrorMessage(MYKONOS_ERR_READ_ORXFRAMERSTATUS_NULL_PARAM)); + return MYKONOS_ERR_READ_ORXFRAMERSTATUS_NULL_PARAM; + } + + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_STATUS_STRB, 0x01); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_STATUS_STRB, 0x00); + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_STATUS, obsFramerStatus); + + return MYKONOS_ERR_OK; +} + +/** + * \brief Reads the transceiver's deframer status + * + * Dependencies + * - device->spiSettings + * + * deframerStatus | Bit Name | Description + * ----------------|--------------------------|--------------------------------------------- + * [7] | Unused | Unused + * [6] | Deframer IRQ | This bit indicates that the IRQ interrupt was asserted. + * [5] | Deframer SYSREF Received | When this bit is set, it indicates that the SYSREF pulse was received by the deframer IP + * [4] | Deframer Receiver Error | This bit is set when PRBS has received an error. + * [3] | Valid Checksum | This bit is set when the received ILAS checksum is valid. + * [2] | EOF Event | This bit captures the internal status of the framer End of Frame event. Value =1 if framing error during ILAS + * [1] | EOMF Event | This bit captures the internal status of the framer End of Multi-Frame event. Value =1 if framing error during ILAS + * [0] | FS Lost | This bit captures the internal status of the framer Frame Symbol event. Value =1 if framing error during ILAS or user data (invalid replacement characters) + * + * + * \param device is a pointer to the device settings structure + * \param deframerStatus is the deframer status byte read + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_READ_DEFRAMERSTATUS_NULL_PARAM Function parameter deframerStatus has NULL pointer + */ +mykonosErr_t MYKONOS_readDeframerStatus(mykonosDevice_t *device, uint8_t *deframerStatus) +{ + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_readDeframerStatus()\n"); +#endif + + if (deframerStatus == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_READ_DEFRAMERSTATUS_NULL_PARAM, + getMykonosErrorMessage(MYKONOS_ERR_READ_DEFRAMERSTATUS_NULL_PARAM)); + return MYKONOS_ERR_READ_DEFRAMERSTATUS_NULL_PARAM; + } + + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_STAT_STRB, 0x01); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_STAT_STRB, 0x00); + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_STAT, deframerStatus); + + return MYKONOS_ERR_OK; +} + +/** + * \brief Reads the Mykonos JESD204b Deframer determinstic FIFO depth + * + * To verify that the deterministic latency FIFO is not close to a underflow or + * overflow condition, it is recommended to check the FIFO depth. If the FIFO + * is close to an overflow or underflow condition, it is possible that from + * power up to powerup, deterministic latency may not be met. If a underflow + * or overflow occurred, the data would still be correct, but would possibly + * slip by 1 multiframe (losing deterministic latency). To correct for an + * overflow/underflow, the BBIC would need to add delay from SYSREF until + * the first symbol in a multiframe + * + * Dependencies + * - device->spiSettings + * + * \param device is a pointer to the device settings structure + * \param fifoDepth Return value that describes the depth of the Mykonos + * deterministic latency deframer FIFO. + * \param readEnLmfcCount Returns the LMFC count value when the deterministic FIFO read enable was asserted. + * Counts at the Mykonos internal deframer PCLK frequency. + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_READ_DEFFIFODEPTH_NULL_PARAM Error: function parameter fifoDepth is a NULL pointer + * \retval MYKONOS_ERR_READ_DEFFIFODEPTH_LMFCCOUNT_NULL_PARAM Error: function parameter readEnLmfcCount is a NULL pointer + * + */ +mykonosErr_t MYKONOS_getDeframerFifoDepth(mykonosDevice_t *device, uint8_t *fifoDepth, uint8_t *readEnLmfcCount) +{ + uint8_t fifoReadPtr = 0; + uint8_t fifoWritePtr = 0; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getDeframerFifoDepth()\n"); +#endif + + if (fifoDepth == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_READ_DEFFIFODEPTH_NULL_PARAM, + getMykonosErrorMessage(MYKONOS_ERR_READ_DEFFIFODEPTH_NULL_PARAM)); + return MYKONOS_ERR_READ_DEFFIFODEPTH_NULL_PARAM; + } + + if (readEnLmfcCount == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_READ_DEFFIFODEPTH_LMFCCOUNT_NULL_PARAM, + getMykonosErrorMessage(MYKONOS_ERR_READ_DEFFIFODEPTH_LMFCCOUNT_NULL_PARAM)); + return MYKONOS_ERR_READ_DEFFIFODEPTH_LMFCCOUNT_NULL_PARAM; + } + + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_STAT_STRB, 0x01); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_STAT_STRB, 0x00); + + /* read/write pointers are 7 bits, (0 - 127) */ + CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_DEFRAMER_DET_FIFO_RD_ADDR, &fifoReadPtr, 0x7F, 0); + CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_DEFRAMER_DET_FIFO_WR_ADDR, &fifoWritePtr, 0x7F, 0); + + /* Adding 128 and modulus 128 handle the wrap cases where the read pointer + * is less than write pointer + */ + *fifoDepth = (((fifoWritePtr + 128) - fifoReadPtr) % 128); + + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_DET_FIFO_PHASE, readEnLmfcCount); + + return MYKONOS_ERR_OK; +} + +/** + * \brief Selects the PRBS type and enables or disables RX Framer PRBS20 generation + * + * Dependencies + * - device->spiSettings + * + * \param device is a pointer to the device settings structure + * \param polyOrder selects the PRBS type based on a two-bit value range from 0-3 + * \param enable '1' = enables PRBS RX framer PRBS generator, '0' = disables PRBS generator + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_RX_FRAMER_INV_PRBS_POLYORDER_PARAM Invalid polyOrder parameter, use ENUM + * + */ +mykonosErr_t MYKONOS_enableRxFramerPrbs(mykonosDevice_t *device, mykonosPrbsOrder_t polyOrder, uint8_t enable) +{ + uint8_t wrmask = 0; + uint8_t enableBit = 0; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_enableRxFramerPrbs()\n"); +#endif + + enableBit = (enable > 0) ? 1 : 0; + + if ((polyOrder == MYK_PRBS7) || (polyOrder == MYK_PRBS15) || (polyOrder == MYK_PRBS31)) + { + wrmask = ((uint8_t)polyOrder << 1) | enableBit; + } + else + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RX_FRAMER_INV_PRBS_POLYORDER_PARAM, + getMykonosErrorMessage(MYKONOS_ERR_RX_FRAMER_INV_PRBS_POLYORDER_PARAM)); + return MYKONOS_ERR_RX_FRAMER_INV_PRBS_POLYORDER_PARAM; + } + + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_PRBS20_CTL, wrmask); + + return MYKONOS_ERR_OK; +} + +/** + * \brief Selects the PRBS type and enables or disables OBSRX Framer PRBS20 generation + * + * Dependencies + * - device->spiSettings + * + * \param device is a pointer to the device settings structure + * \param polyOrder selects the PRBS type based on a two-bit value range from 0-3 + * \param enable '1' = enables PRBS OBSRX framer PRBS generator, '0' = disables PRBS generator + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_OBSRX_FRAMER_INV_PRBS_POLYORDER_PARAM polyOrder parameter is not a valid value - use ENUM + */ +mykonosErr_t MYKONOS_enableObsRxFramerPrbs(mykonosDevice_t *device, mykonosPrbsOrder_t polyOrder, uint8_t enable) +{ + uint8_t wrmask = 0; + uint8_t enableBit = 0; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_enableObsRxFramerPrbs()\n"); +#endif + + enableBit = (enable > 0) ? 1 : 0; + + if ((polyOrder == MYK_PRBS7) || (polyOrder == MYK_PRBS15) || (polyOrder == MYK_PRBS31)) + { + wrmask = ((uint8_t)polyOrder << 1) | enableBit; + } + else + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OBSRX_FRAMER_INV_PRBS_POLYORDER_PARAM, + getMykonosErrorMessage(MYKONOS_ERR_OBSRX_FRAMER_INV_PRBS_POLYORDER_PARAM)); + return MYKONOS_ERR_OBSRX_FRAMER_INV_PRBS_POLYORDER_PARAM; + } + + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_PRBS20_CTL, wrmask); + + return MYKONOS_ERR_OK; +} + +/** + * \brief Injects a PRBS error into the RX data path + * + * Dependencies + * - device->spiSettings + * + * \param device is a pointer to the device settings structure + * + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_rxInjectPrbsError(mykonosDevice_t *device) +{ + uint8_t prbsControl = 0x00; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_rxInjectPrbsError()\n"); +#endif + + /* reading current PRBS20 control register contents */ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_FRAMER_PRBS20_CTL, &prbsControl); + + /* setting bit 4 in framer PRBS20 control register and then clearing it for error injection */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_PRBS20_CTL, prbsControl |= 0x10); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_PRBS20_CTL, prbsControl &= ~0x10); + + return MYKONOS_ERR_OK; +} + +/** + * \brief Initiates a PRBS error injection into the Observation RX data path + * + * Dependencies + * - device->spiSettings + * + * \param device is a pointer to the device settings structure + * + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_obsRxInjectPrbsError(mykonosDevice_t *device) +{ + uint8_t prbsControl = 0x00; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_obsRxInjectPrbsError()\n"); +#endif + + /* reading current PRBS20 control register contents */ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_PRBS20_CTL, &prbsControl); + + /* setting bit 4 in framer PRBS20 control register and then clearing it for error injection */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_PRBS20_CTL, prbsControl |= 0x10); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_PRBS20_CTL, prbsControl &= ~0x10); + + return MYKONOS_ERR_OK; +} + +/** + * \brief Configures and enables or disables the transceiver's deframer PRBS checker + * + * Dependencies + * - device->spiSettings + * + * \param device is a pointer to the device settings structure + * \param lanes selects the lane for PRBS checking based on a 4-bit mask, where each weighted bit + * corresponds with a different lane selection as such: '1' = lane 0, '2' = lane 1, '4' = lane 2, '8' = lane 3 + * \param polyOrder selects the PRBS type based on enum values (MYK_PRBS7, MYK_PRBS15, MYK_PRBS31) + * \param enable '1' = enables checking, '0' = disables checking + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_DEFRAMER_INV_PRBS_POLYORDER_PARAM Invalid polyOrder parameter - use ENUM + * \retval MYKONOS_ERR_DEFRAMER_INV_PRBS_ENABLE_PARAM Invalid enable (valid 0-1) or lanes (valid 0-15) parameter + */ +mykonosErr_t MYKONOS_enableDeframerPrbsChecker(mykonosDevice_t *device, uint8_t lanes, mykonosPrbsOrder_t polyOrder, uint8_t enable) +{ + uint8_t wrmask = 0x00; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_enableDeframerPrbsChecker()\n"); +#endif + + if ((enable <= 0x01) && (lanes <= 0x0F)) + { + if ((polyOrder == MYK_PRBS7) || (polyOrder == MYK_PRBS15) || (polyOrder == MYK_PRBS31)) + { + wrmask = ((lanes << 4) | ((uint8_t)polyOrder << 1) | enable); + } + else + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DEFRAMER_INV_PRBS_POLYORDER_PARAM, + getMykonosErrorMessage(MYKONOS_ERR_DEFRAMER_INV_PRBS_POLYORDER_PARAM)); + return MYKONOS_ERR_DEFRAMER_INV_PRBS_POLYORDER_PARAM; + } + } + else + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DEFRAMER_INV_PRBS_ENABLE_PARAM, + getMykonosErrorMessage(MYKONOS_ERR_DEFRAMER_INV_PRBS_ENABLE_PARAM)); + return MYKONOS_ERR_DEFRAMER_INV_PRBS_ENABLE_PARAM; + } + + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_PRBS20_CTL, wrmask); + + return MYKONOS_ERR_OK; +} + +/** + * \brief Reads the deframer PRBS counters + * + * Dependencies + * - device->spiSettings + * + * \param device is a pointer to the device settings structure + * \param counterSelect selects the PRBS error counter to be read based on values between 0-3 + * If counterSelect exceeds this value an error is thrown. + * + * \param prbsErrorCount is return value after reading the PRBS error count + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_READ_DEFRAMERPRBS_NULL_PARAM Function parameter prbsErrorCount has NULL pointer + * \retval MYKONOS_ERR_DEFRAMER_INV_PRBS_CNTR_SEL_PARAM if counterSelect is out of bounds + */ +mykonosErr_t MYKONOS_readDeframerPrbsCounters(mykonosDevice_t *device, uint8_t counterSelect, uint32_t *prbsErrorCount) +{ + uint8_t wrmask = 0x00; + uint8_t errorCnt[3] = {0}; + const uint8_t COUNTER_SATURATE = 0x40; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_readDeframerPrbsCounters()\n"); +#endif + + if (prbsErrorCount == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_READ_DEFRAMERPRBS_NULL_PARAM, + getMykonosErrorMessage(MYKONOS_ERR_READ_DEFRAMERPRBS_NULL_PARAM)); + return MYKONOS_ERR_READ_DEFRAMERPRBS_NULL_PARAM; + } + + if (counterSelect & ~0x03) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DEFRAMER_INV_PRBS_CNTR_SEL_PARAM, + getMykonosErrorMessage(MYKONOS_ERR_DEFRAMER_INV_PRBS_CNTR_SEL_PARAM)); + return MYKONOS_ERR_DEFRAMER_INV_PRBS_CNTR_SEL_PARAM; + } + else + { + wrmask = (uint8_t)(COUNTER_SATURATE | (counterSelect << 4)); + *prbsErrorCount = 0x00000000; + } + + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_PRBS20_STRB_CHKSUM_TYPE, wrmask); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_PRBS20_STRB_CHKSUM_TYPE, wrmask |= 0x01); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_PRBS20_STRB_CHKSUM_TYPE, wrmask &= ~0x01); + + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_PRBS20_ERR_CNTR_7_TO_0, &errorCnt[0]); + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_PRBS20_ERR_CNTR_15_TO_8, &errorCnt[1]); + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_PRBS20_ERR_CNTR_23_TO_16, &errorCnt[2]); + + *prbsErrorCount = (uint32_t)(errorCnt[2] << 16) | (uint32_t)(errorCnt[1] << 8) | (uint32_t)(errorCnt[0]); + + return MYKONOS_ERR_OK; +} + +/** + * \brief Clears the deframer/deserializer PRBS counters + * + * Dependencies + * - device->spiSettings + * + * \param device is a pointer to the device settings structure + * + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_clearDeframerPrbsCounters(mykonosDevice_t *device) +{ + uint8_t spiReg = 0; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_clearDeframerPrbsCounters()\n"); +#endif + + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_PRBS20_CTL, &spiReg); + spiReg &= ~0x08; //make sure PRBS clear bit is 0 + + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_PRBS20_CTL, (spiReg | 0xF8)); //clear counters for all lanes + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_PRBS20_CTL, spiReg); //set reg back to previous value + + return MYKONOS_ERR_OK; +} + +/** + * \brief Reads the lane 0 JESD204B deframer configuration and compares it against the ILAS received values + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is a pointer to the device settings structure + * \param mismatch [15-0] is a bit-encoded word which for mismatch[15] = '0' = no mismatch, '1' = mismatch for one or more parameters + * mismatch bits [14-0] are aligned with the mykonosJesd204bLane0Config_t structure members starting at '0' = DID. The aligned bit is set to + * '1' if the configuration parameter does not agree with its corresponding received ILAS value, otherwise '0' if they agree. + * + * The bit assignments for the 16-bit word are: + * mismatch | bit description + * -----------|-------------------------------------------------------- + * [0] | JESD204B DID: device ID + * [1] | JESD204B BID: bank ID + * [2] | JESD204B LID0: lane ID + * [3] | JESD204B L: lanes per data converter + * [4] | JESD204B SCR: scramble setting + * [5] | JESD204B F: octets per frame + * [6] | JESD204B K: frames per multiframe + * [7] | JESD204B M: number of data converters + * [8] | JESD204B N: data converter sample resolution + * [9] | JESD204B CS: number of control bits transferred per sample per frame + * [10] | JESD204B NP: JESD204B word size based on the highest data converter resolution + * [11] | JESD204B S: number of samples per converter per frame + * [12] | JESD204B CF: '0' = control bits appended to each sample, '1' = control bits appended to end of frame + * [13] | JESD204B HD: high density bit, where '0' = samples are contained with single lane, '1' = samples are divided over more than one lane + * [14] | JESD204B FCHK0: configuration checksum OK bit. where '1' = fail, '0' = pass + * [15] | MISMATCH DETECTED BIT: bits 0-14 are ored together to set this bit + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_JESD204B_ILAS_MISMATCH_NULLPARAM Function parameter mismatch has NULL pointer + */ +mykonosErr_t MYKONOS_jesd204bIlasCheck(mykonosDevice_t *device, uint16_t *mismatch) +{ + uint8_t i = 0; + uint8_t ilasdata[15] = {0}; + uint8_t cfgdata[15] = {0}; + mykonosJesd204bLane0Config_t lane0ILAS; + mykonosJesd204bLane0Config_t lane0Cfg; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_jesd204bIlasCheck()\n"); +#endif + + if (mismatch == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_JESD204B_ILAS_MISMATCH_NULLPARAM, + getMykonosErrorMessage(MYKONOS_ERR_JESD204B_ILAS_MISMATCH_NULLPARAM)); + return MYKONOS_ERR_JESD204B_ILAS_MISMATCH_NULLPARAM; + } + + *mismatch = 0; + + /* setting deframer read received ILAS data */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_WR_EN, 0x00); + + /* reading deframer received ILAS register contents into array */ + for (i = 0; i < 15; i++) + { + /* setting the deframer sub-address for received ilas data */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_ADDR, MYKONOS_SUBADDR_DEFRAMER_LANE0_ILAS_RECVD + i); + + /* reading the received ILAS data into byte array */ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_DATA, &ilasdata[i]); + } + + /* reading deframer config register contents into array */ + for (i = 0; i < 15; i++) + { + /* setting the deframer sub-address for received ilas data */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_ADDR, MYKONOS_SUBADDR_DEFRAMER_LANE0_ILAS_CFG + i); + + /* reading the received ILAS data into byte array */ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_DATA, &cfgdata[i]); + } + + /* loading the structures with the read values for easier reading when doing compares */ + lane0ILAS.DID = ilasdata[0]; + lane0ILAS.BID = ilasdata[1] & 0x0F; + lane0ILAS.LID0 = ilasdata[2] & 0x1F; + lane0ILAS.L = ilasdata[3] & 0x1F; + lane0ILAS.SCR = ilasdata[3] >> 7; + lane0ILAS.F = ilasdata[4]; + lane0ILAS.K = ilasdata[5] & 0x1F; + lane0ILAS.M = ilasdata[6]; + lane0ILAS.N = ilasdata[7] & 0x1F; + lane0ILAS.CS = ilasdata[7] >> 6; + lane0ILAS.NP = ilasdata[8] & 0x1F; + lane0ILAS.S = ilasdata[9] & 0x1F; + lane0ILAS.CF = ilasdata[10] & 0x1F; + lane0ILAS.HD = ilasdata[10] >> 7; + lane0ILAS.FCHK0 = ilasdata[13]; + + lane0Cfg.DID = cfgdata[0]; + lane0Cfg.BID = cfgdata[1] & 0x0F; + lane0Cfg.LID0 = cfgdata[2] & 0x0F; + lane0Cfg.L = cfgdata[3] & 0x1F; + lane0Cfg.SCR = cfgdata[3] >> 7; + lane0Cfg.F = cfgdata[4]; + lane0Cfg.K = cfgdata[5] & 0x1F; + lane0Cfg.M = cfgdata[6]; + lane0Cfg.N = cfgdata[7] & 0x1F; + lane0Cfg.CS = cfgdata[7] >> 6; + lane0Cfg.NP = cfgdata[8] & 0x1F; + lane0Cfg.S = cfgdata[9] & 0x1F; + lane0Cfg.CF = cfgdata[10] & 0x1F; + lane0Cfg.HD = cfgdata[10] >> 7; + lane0Cfg.FCHK0 = cfgdata[13]; + + /* performing ILAS mismatch check */ + if (lane0ILAS.DID != lane0Cfg.DID) + { + *mismatch |= 0x0001; + } + + if (lane0ILAS.BID != lane0Cfg.BID) + { + *mismatch |= 0x0002; + } + + if (lane0ILAS.LID0 != lane0Cfg.LID0) + { + *mismatch |= 0x0004; + } + + if (lane0ILAS.L != lane0Cfg.L) + { + *mismatch |= 0x0008; + } + + if (lane0ILAS.SCR != lane0Cfg.SCR) + { + *mismatch |= 0x0010; + } + + if (lane0ILAS.F != lane0Cfg.F) + { + *mismatch |= 0x0020; + } + + if (lane0ILAS.K != lane0Cfg.K) + { + *mismatch |= 0x0040; + } + + if (lane0ILAS.M != lane0Cfg.M) + { + *mismatch |= 0x0080; + } + + if (lane0ILAS.N != lane0Cfg.N) + { + *mismatch |= 0x0100; + } + + if (lane0ILAS.CS != lane0Cfg.CS) + { + *mismatch |= 0x0200; + } + + if (lane0ILAS.NP != lane0Cfg.NP) + { + *mismatch |= 0x0400; + } + + if (lane0ILAS.S != lane0Cfg.S) + { + *mismatch |= 0x0800; + } + + if (lane0ILAS.CF != lane0Cfg.CF) + { + *mismatch |= 0x1000; + } + + if (lane0ILAS.HD != lane0Cfg.HD) + { + *mismatch |= 0x2000; + } + + if (lane0ILAS.FCHK0 != lane0Cfg.FCHK0) + { + *mismatch |= 0x4000; + } + + if (*mismatch) + { + *mismatch |= 0x8000; + CMB_writeToLog(ADIHAL_LOG_WARNING, device->spiSettings->chipSelectIndex, MYKONOS_ERR_JESD204B_ILAS_MISMATCH, + getMykonosErrorMessage(MYKONOS_ERR_JESD204B_ILAS_MISMATCH)); + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief Select data to inject into the Rx framer input (ADC data or Loopback data from deframer output) + * + * This function allows inputting deframed data (IQ samples) from the Tx data path into the Rx framer. + * For this to work correctly, the IQ data rate of the Tx data path must match the Rx IQ data rate. + * Framer/Deframer JESD204 config parameters can vary as long as the Rx and Tx IQ rates match. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device A pointer to the device settings structure + * \param dataSource 0 = ADC data at Rx Framer input, 1 = Deframed Tx JESD204 IQ samples input into Rx framer + * + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_setRxFramerDataSource(mykonosDevice_t *device, uint8_t dataSource) +{ + uint8_t enableLoopBack = 0; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setRxFramerDataSource()\n"); +#endif + + enableLoopBack = (dataSource > 0) ? 1 : 0; + + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_FRAMER_CONFIG_LOOPBACK_XBAR_REV, enableLoopBack, 0x10, 4); + + return MYKONOS_ERR_OK; +} + +/** + * \brief Select data to inject into the ObsRx framer input (ADC data or Loopback data from deframer output) + * + * This function allows inputting deframed data (IQ samples) from the Tx data path into the Obs Rx framer. + * For this to work correctly, the IQ data rate of the Tx data path must match the ORx IQ data rate. + * Framer/Deframer JESD204 config parameters can vary as long as the Obs Rx and Tx IQ rates match. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device A pointer to the device settings structure + * \param dataSource 0 = ADC data at ObsRx Framer input, 1 = Deframed Tx JESD204 IQ samples input into Obs Rx framer + * + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_setObsRxFramerDataSource(mykonosDevice_t *device, uint8_t dataSource) +{ + uint8_t enableLoopBack = 0; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setObsRxFramerDataSource()\n"); +#endif + + enableLoopBack = (dataSource > 0) ? 1 : 0; + + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_CONFIG_LOOPBACK_XBAR_REV, enableLoopBack, 0x10, 4); + + return MYKONOS_ERR_OK; +} + +/** + * \brief Runs the Mykonos initialization calibrations + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * ENUM mykonosInitCalibrations_t can be used to OR together to generate the calMask parameter. + * + * calMask Bit | Calibration + * ------------|---------------------- + * 0 | Tx BB Filter + * 1 | ADC Tuner + * 2 | TIA 3dB Corner + * 3 | DC Offset + * 4 | Tx Attenuation Delay + * 5 | Rx Gain Delay + * 6 | Flash Cal + * 7 | Path Delay + * 8 | Tx LO Leakage Internal + * 9 | Tx LO Leakage External + * 10 | Tx QEC Init + * 11 | LoopBack Rx LO Delay + * 12 | LoopBack Rx Rx QEC Init + * 13 | Rx LO Delay + * 14 | Rx QEC Init + * 15 | DPD Init + * 16 | Tx CLGC (Closed Loop Gain Control) + * 17 | Tx VSWR Init + * [31-18] | Ignored - Future space for new calibrations + * + * \param device A pointer to the device settings structure + * \param calMask A bitmask that informs the Mykonos ARM processor which calibrations to run + * + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_runInitCals(mykonosDevice_t *device, uint32_t calMask) +{ + mykonosErr_t retVal = MYKONOS_ERR_OK; + const uint8_t RUNINITCALS_OPCODE = 0x02; + uint8_t payload[4] = {0}; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_runInitCals()\n"); +#endif + + payload[0] = (uint8_t)(calMask & 0xFF); + payload[1] = (uint8_t)((calMask >> 8) & 0xFF); + payload[2] = (uint8_t)((calMask >> 16) & 0xFF); + payload[3] = (uint8_t)((calMask >> 24) & 0xFF); + + retVal = MYKONOS_sendArmCommand(device, RUNINITCALS_OPCODE, &payload[0], sizeof(payload)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief Blocking waits for the Mykonos initialization calibrations to complete + * + * The *errorFlag and *errorCode parameters are optional. If the pointers are + * set to null, no values will be returned. If the function returns an error + * that the init calibration failed, use the MYKONOS_getInitCalStatus() function + * to get more detailed information about why the init cal failed. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device A pointer to the device settings structure + * \param timeoutMs A timeout value in Ms to wait for the calibrations to complete + * \param errorFlag A 3bit error flag that helps identify what went wrong in the ARM. 0=No Error + * \param errorCode The value represents the init calibration object ID that caused a failure. + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_WAIT_INITCALS_ARMERROR ARM returned error unrelated to init cals + */ +mykonosErr_t MYKONOS_waitInitCals(mykonosDevice_t *device, uint32_t timeoutMs, uint8_t *errorFlag, uint8_t *errorCode) +{ + mykonosErr_t retVal = MYKONOS_ERR_OK; + mykonosErr_t retValCalStatus = MYKONOS_ERR_OK; + uint8_t cmdStatusByte = 0; + uint8_t _errorFlag = 0; /* Local version of parameter */ + mykonosInitCalStatus_t initCalStatus = {0}; + + const uint8_t INITCALS_CAL_ERROR = 0x07; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_waitInitCals()\n"); +#endif + + /* Clear before making any calls that can throw errors */ + if (errorFlag != NULL) + { + *errorFlag = 0; + } + + /* Clear before making any calls that can throw errors */ + if (errorCode != NULL) + { + *errorCode = 0; + } + + retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_RUNINIT_OPCODE, timeoutMs, &cmdStatusByte); + _errorFlag = cmdStatusByte >> 1; /* remove pending bit in [0], error flag is in bits [3:1] */ + + if (errorFlag != NULL) + { + *errorFlag = _errorFlag; + } + + if (retVal != MYKONOS_ERR_OK) + { + if (_errorFlag == INITCALS_CAL_ERROR) + { + /* return Error code if a calibration had an error */ + retValCalStatus = MYKONOS_getInitCalStatus(device, &initCalStatus); + if (retValCalStatus == MYKONOS_ERR_OK) + { + if (errorCode != NULL) + { + *errorCode = initCalStatus.initErrCal; + } + } + + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_WAIT_INITCALS_CALFAILED, + getMykonosErrorMessage(MYKONOS_ERR_WAIT_INITCALS_CALFAILED)); + return MYKONOS_ERR_WAIT_INITCALS_CALFAILED; + } + else if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_WAIT_INITCALS_ARMERROR, + getMykonosErrorMessage(MYKONOS_ERR_WAIT_INITCALS_ARMERROR)); + return MYKONOS_ERR_WAIT_INITCALS_ARMERROR; + } + } + + /* Same logic if MYKONOS_waitArmCmdStatus() did not return an error, but cmdStatusByte shows an ARM error */ + if (_errorFlag == INITCALS_CAL_ERROR) + { + /* return Error code if a calibration had an error */ + retValCalStatus = MYKONOS_getInitCalStatus(device, &initCalStatus); + if (retValCalStatus == MYKONOS_ERR_OK) + { + if (errorCode != NULL) + { + *errorCode = initCalStatus.initErrCal; + } + } + + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_WAIT_INITCALS_CALFAILED, + getMykonosErrorMessage(MYKONOS_ERR_WAIT_INITCALS_CALFAILED)); + return MYKONOS_ERR_WAIT_INITCALS_CALFAILED; + } + else if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_WAIT_INITCALS_ARMERROR, + getMykonosErrorMessage(MYKONOS_ERR_WAIT_INITCALS_ARMERROR)); + return MYKONOS_ERR_WAIT_INITCALS_ARMERROR; + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief Aborts from an on going ARM init calibration operation. + * + * The ARM init calibrations can take several seconds. If for any reason the Baseband processor + * needs to stop the running ARM calibration sequence, call this function. The *calsCompleted + * parameter is an option parameter that will return which cals completed before the abort + * command was received. If *calsCompleted is a null pointer, no value will be returned. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device A pointer to the device settings structure + * \param calsCompleted A bitmask is returned which describes which cals completed during the previous + * MYKONOS_runInitCals() call. + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_ABORT_INITCALS_NULL_PARAM Function parameter calsCompleted has NULL pointer + */ +mykonosErr_t MYKONOS_abortInitCals(mykonosDevice_t *device, uint32_t *calsCompleted) +{ + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint32_t timeoutMs = 1000; //1 second timeout + uint8_t cmdStatusByte = 0; + uint8_t payload = 0x43; /* object ID to get INIT_CAL_DONE status */ + uint8_t calCompleteBitField[4] = {0, 0, 0, 0}; + + retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_ABORT_OPCODE, 0, 0); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; /* Will return if mailbox busy bit is busy for more than 2 seconds */ + } + + retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_ABORT_OPCODE, timeoutMs, &cmdStatusByte); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; /* Will return if timeout occurred */ + } + + /* Read back Calibration Completion status */ + retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_GET_OPCODE, &payload, sizeof(payload)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; /* Will return if mailbox busy bit is busy for more than 2 seconds */ + } + + retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_GET_OPCODE, timeoutMs, &cmdStatusByte); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; /* Will return if timeout occurred */ + } + + retVal = MYKONOS_readArmMem(device, (MYKONOS_ADDR_ARM_START_DATA_ADDR + 4), &calCompleteBitField[0], 4, 1); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + if (calsCompleted != NULL) + { + *calsCompleted = ((uint32_t)(calCompleteBitField[3]) << 24) | ((uint32_t)(calCompleteBitField[2]) << 16) | ((uint32_t)(calCompleteBitField[1]) << 8) + | ((uint32_t)(calCompleteBitField[0])); + } + else + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_ABORT_INITCALS_NULL_PARAM, + getMykonosErrorMessage(MYKONOS_ERR_ABORT_INITCALS_NULL_PARAM)); + return MYKONOS_ERR_ABORT_INITCALS_NULL_PARAM; + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief Gets the device initialization calibration status + * + * This function requests the init cal status information from the Mykonos ARM + * processor. The ARM returns information including a bitmask that describes + * which calibrations have completed during the last cal of runInitCals, as + * well as the init cals that have run successfully since loading the ARM. If + * an ARM error does occur during one of the init calibrations, the initErrCal + * member returns the object ID of the failing calibration. The initErrCode + * returns the specific ARM error code that caused that calibration to fail. + * The calsMinimum structure member describes the minimum set of init calibrations + * required to complete by the ARM before it will allow the device to move to + * the radioOn state. + * + * Dependencies + * - device->spiSettings + * - device->spiSettings->chipSelectIndex + * + * \param device A pointer to the device settings structure + * \param initCalStatus Pointer to a structure that returns cal status information such as cals completed since last run, and init error codes + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_GETINITCALSTATUS_NULL_PARAM if initCalStatus parameter is a NULL pointer + * \retval MYKONOS_ERR_GETINITCALSTATUS_ARMERROR if ARM returned an error while requesting the init cal status information + */ +mykonosErr_t MYKONOS_getInitCalStatus(mykonosDevice_t *device, mykonosInitCalStatus_t *initCalStatus) +{ + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint8_t cmdStatusByte = 0; + uint8_t calStatusArray[14] = {0}; + uint8_t payload[1] = {MYKONOS_ARM_OBJECTID_INIT_CAL_DONE}; + + uint32_t timeoutMs = 1000; + + /* Verify function parameter pointer is not NULL */ + if (initCalStatus == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETINITCALSTATUS_NULL_PARAM, + getMykonosErrorMessage(MYKONOS_ERR_GETINITCALSTATUS_NULL_PARAM)); + return MYKONOS_ERR_GETINITCALSTATUS_NULL_PARAM; + } + + retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_GET_OPCODE, &payload[0], sizeof(payload)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; /* Will return if mailbox busy bit is busy for more than 2 seconds */ + } + + retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_GET_OPCODE, timeoutMs, &cmdStatusByte); + if (retVal != MYKONOS_ERR_OK) + { + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETINITCALSTATUS_ARMERROR, + getMykonosErrorMessage(MYKONOS_ERR_GETINITCALSTATUS_ARMERROR)); + return MYKONOS_ERR_GETINITCALSTATUS_ARMERROR; + } + + return retVal; /* Will return if timeout occurred */ + } + + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETINITCALSTATUS_ARMERROR, + getMykonosErrorMessage(MYKONOS_ERR_GETINITCALSTATUS_ARMERROR)); + return MYKONOS_ERR_GETINITCALSTATUS_ARMERROR; + } + + retVal = MYKONOS_readArmMem(device, MYKONOS_ADDR_ARM_START_DATA_ADDR, &calStatusArray[0], sizeof(calStatusArray), 1); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + initCalStatus->calsDoneLifetime = ((uint32_t)(calStatusArray[3]) << 24) | ((uint32_t)(calStatusArray[2]) << 16) | ((uint32_t)(calStatusArray[1]) << 8) + | ((uint32_t)(calStatusArray[0])); + initCalStatus->calsDoneLastRun = ((uint32_t)(calStatusArray[7]) << 24) | ((uint32_t)(calStatusArray[6]) << 16) | ((uint32_t)(calStatusArray[5]) << 8) + | ((uint32_t)(calStatusArray[4])); + initCalStatus->calsMinimum = ((uint32_t)(calStatusArray[11]) << 24) | ((uint32_t)(calStatusArray[10]) << 16) | ((uint32_t)(calStatusArray[9]) << 8) + | ((uint32_t)(calStatusArray[8])); + initCalStatus->initErrCal = calStatusArray[12]; + initCalStatus->initErrCode = calStatusArray[13]; + + return MYKONOS_ERR_OK; +} + +/** + * \brief Instructs the ARM processor to move the radio state to the Radio ON state + * + * When the ARM to the Radio On state, the enabled Rx and Tx signal chains will power up, + * and the ARM tracking calibrations will begin. To exit this state back to a low power, + * offline state, call the MYKONOS_radioOff() function. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device Pointer to the device settings structure + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_ARM_RADIOON_FAILED ARM returned error running this command + */ +mykonosErr_t MYKONOS_radioOn(mykonosDevice_t *device) +{ + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint32_t timeoutMs = 1000; //1 second timeout + uint8_t cmdStatusByte = 0; + + retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_RADIOON_OPCODE, 0, 0); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; /* Will return if mailbox busy bit is busy for more than 2 seconds */ + } + + retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_RADIOON_OPCODE, timeoutMs, &cmdStatusByte); + if (retVal != MYKONOS_ERR_OK) + { + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_ARM_RADIOON_FAILED, + getMykonosErrorMessage(MYKONOS_ERR_ARM_RADIOON_FAILED)); + return MYKONOS_ERR_ARM_RADIOON_FAILED; + } + + return retVal; /* Will return if timeout occurred */ + } + + /* If ARM command error flag is 2, the command was not accepted, RUN_INIT must complete first */ + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_ARM_RADIOON_FAILED, getMykonosErrorMessage(MYKONOS_ERR_ARM_RADIOON_FAILED)); + return MYKONOS_ERR_ARM_RADIOON_FAILED; + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief Instructs the ARM processor to move the radio state to the off state + * + * When the ARM moves from the Radio On state to Radio Off (Idle) the ARM tracking calibrations + * are stopped and the TxEnable/RxEnable, etc GPIO control pins will be ignored. This will also + * keep the receive and transmit chains powered down until the MYKONOS_radioOn() function + * is called again. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device Pointer to the device settings structure + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_ARM_RADIOOFF_FAILED ARM returned error running this command + */ +mykonosErr_t MYKONOS_radioOff(mykonosDevice_t *device) +{ + mykonosErr_t retVal = MYKONOS_ERR_OK; + const uint8_t ABORTCAL_OPCODE = 0x00; + uint32_t timeoutMs = 1000; //1 second timeout + uint8_t cmdStatusByte = 0; + + retVal = MYKONOS_sendArmCommand(device, ABORTCAL_OPCODE, 0, 0); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; /* Will return if mailbox busy bit is busy for more than 2 seconds */ + } + + retVal = MYKONOS_waitArmCmdStatus(device, ABORTCAL_OPCODE, timeoutMs, &cmdStatusByte); + if (retVal != MYKONOS_ERR_OK) + { + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_ARM_RADIOOFF_FAILED, + getMykonosErrorMessage(MYKONOS_ERR_ARM_RADIOOFF_FAILED)); + return MYKONOS_ERR_ARM_RADIOOFF_FAILED; + } + + return retVal; /* Will return if timeout occurred */ + } + + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_ARM_RADIOOFF_FAILED, getMykonosErrorMessage(MYKONOS_ERR_ARM_RADIOOFF_FAILED)); + return MYKONOS_ERR_ARM_RADIOOFF_FAILED; + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief Reads the current ARM radio state + * + * Currently, *radioStatus only returns data in the lower 8 bits, but + * is defined as a 32bit status to allow for more information to be returned + * in the future. + * + * radioStatus | Bitfield + * -------------|------------------ + * [1:0] | State[1:0], 0=POWERUP, 1=READY, 2=INIT, 3=RADIO ON + * [3:2] | unused + * [4] | TDD_nFDD , 1= TDD, 0=FDD + * [7:5] | unused + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device Pointer to the device settings structure + * \param radioStatus The current ARM radio state is returned in this parameter + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_GETRADIOSTATE_NULL_PARAM Function parameter radioStatus has a NULL pointer + */ +mykonosErr_t MYKONOS_getRadioState(mykonosDevice_t *device, uint32_t *radioStatus) +{ + uint8_t status = 0; + + /* if radioStatus is not null */ + if (radioStatus != NULL) + { + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_ARM_OPCODE_STATE_0, &status); + *radioStatus = (uint32_t)status; + } + else + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETRADIOSTATE_NULL_PARAM, + getMykonosErrorMessage(MYKONOS_ERR_GETRADIOSTATE_NULL_PARAM)); + return MYKONOS_ERR_GETRADIOSTATE_NULL_PARAM; + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief Sets which ARM tracking cals are enabled during the radioOn state. + * + * This command must be called during radioOff state. If called during radioOn, + * an error will be returned. The enum mykonosTrackingCalibrations_t can be used to + * OR together to form the enableMask parameter. + * + * enableMask | Bit description + * ------------|------------ + * [0] | TRACK_RX1_QEC + * [1] | TRACK_RX2_QEC + * [2] | TRACK_ORX1_QEC + * [3] | TRACK_ORX2_QEC + * [4] | TRACK_TX1_LOL + * [5] | TRACK_TX2_LOL + * [6] | TRACK_TX1_QEC + * [7] | TRACK_TX2_QEC + * [8] | TRACK_TX1_DPD + * [9] | TRACK_TX2_DPD + * [10] | TRACK_TX1_CLGC + * [11] | TRACK_TX2_CLGC + * [12] | TRACK_TX1_VSWR + * [13] | TRACK_TX2_VSWR + * [16] | TRACK_ORX1_QEC_SNLO + * [17] | TRACK_ORX2_QEC_SNLO + * [18] | TRACK_SRX_QEC + * + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device Pointer to the device settings structure + * \param enableMask A bitmask that selects which cals to run during radioOn state. + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_EN_TRACKING_CALS_ARMSTATE_ERROR Error: Tracking cals can only be enabled in the radioOff state. + * \retval MYKONOS_ERR_EN_TRACKING_CALS_ARMERROR ARM returned error when executing this command + */ +mykonosErr_t MYKONOS_enableTrackingCals(mykonosDevice_t *device, uint32_t enableMask) +{ + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint8_t armData[4] = {0, 0, 0, 0}; + uint8_t extData[4] = {MYKONOS_ARM_OBJECTID_CALSCHEDULER, 0x00, 0x00, 0x04}; //Target ARM Object ID, Offset LSB, Offset MSB, Length + uint32_t timeoutMs = 0; + uint8_t cmdStatusByte = 0; + uint32_t radioStatus = 0; + uint8_t allowTx1AttenUpdates = 0; + uint8_t allowTx2AttenUpdates = 0; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_enableTrackingCals()\n"); +#endif + + /* read radio state to make sure ARM is in radioOff /IDLE */ + retVal = MYKONOS_getRadioState(device, &radioStatus); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* throw error if not in radioOff/IDLE state */ + if ((radioStatus & 0x03) != MYKONOS_ARM_SYSTEMSTATE_IDLE) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_EN_TRACKING_CALS_ARMSTATE_ERROR, + getMykonosErrorMessage(MYKONOS_ERR_EN_TRACKING_CALS_ARMSTATE_ERROR)); + return MYKONOS_ERR_EN_TRACKING_CALS_ARMSTATE_ERROR; + } + + /* In the ARM, DPD tracking and CLGC tracking share the same cal. Must + * set extra enable bits in ARM Memory to tell which cal to run. */ + retVal = enableDpdTracking(device, ((enableMask & (uint32_t)TRACK_TX1_DPD) ? 1 : 0), ((enableMask & (uint32_t)TRACK_TX2_DPD) ? 1 : 0)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + if (((device->profilesValid & TX_PROFILE_VALID) > 0) && (device->tx->clgcConfig != NULL)) + { + allowTx1AttenUpdates = device->tx->clgcConfig->allowTx1AttenUpdates; + allowTx2AttenUpdates = device->tx->clgcConfig->allowTx2AttenUpdates; + } + else + { + allowTx1AttenUpdates = 0; + allowTx2AttenUpdates = 0; + } + + retVal = enableClgcTracking(device, ((allowTx1AttenUpdates > 0) ? 1 : 0), ((allowTx2AttenUpdates > 0) ? 1 : 0)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + armData[0] = (uint8_t)(enableMask & 0xFF); + armData[1] = (uint8_t)((enableMask >> 8) & 0xFF); + armData[2] = (uint8_t)((enableMask >> 16) & 0xFF); + armData[3] = (uint8_t)((enableMask >> 24) & 0xFF); + retVal = MYKONOS_writeArmMem(device, MYKONOS_ADDR_ARM_START_DATA_ADDR, &armData[0], sizeof(armData)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_WRITECFG_OPCODE, &extData[0], sizeof(extData)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + timeoutMs = 1000; + retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_WRITECFG_OPCODE, timeoutMs, &cmdStatusByte); + if (retVal != MYKONOS_ERR_OK) + { + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_EN_TRACKING_CALS_ARMERROR, + getMykonosErrorMessage(MYKONOS_ERR_EN_TRACKING_CALS_ARMERROR)); + return MYKONOS_ERR_EN_TRACKING_CALS_ARMERROR; + } + + return retVal; + } + + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_EN_TRACKING_CALS_ARMERROR, + getMykonosErrorMessage(MYKONOS_ERR_EN_TRACKING_CALS_ARMERROR)); + return MYKONOS_ERR_EN_TRACKING_CALS_ARMERROR; + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief Reschedules a tracking calibration to run. Can be used to + * override the tracking calibration timer and force a tracking calibration to run. + * Can be used to reschedule a tracking calibration after a tracking calibration + * error has been detected. Only one tracking calibration object can be scheduled + * per channel per function call. + * + * \pre Command can be called in either Radio On or Radio Off state. ARM must be + * initialized. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device Pointer to the device settings structure + * \param trackingCal Selects the tracking calibration to schedule. + * + * \retval MYKONOS_ERR_RESCHEDULE_TRACK_CAL_INV Not valid calibration passed + * \retval MYKONOS_ERR_RESCHEDULE_TRACK_ARMERRFLAG ARM error + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_rescheduleTrackingCal(mykonosDevice_t *device, mykonosTrackingCalibrations_t trackingCal) +{ + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint8_t extData[3] = {0}; + uint8_t cmdStatusByte = 0; + uint32_t timeoutMs = 1000; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_rescheduleTrackingCal()\n"); +#endif + + switch (trackingCal) + { + case TRACK_RX1_QEC: + extData[1] = MYKONOS_ARM_OBJECTID_RXQEC_TRACKING; + extData[2] = 0; + break; + + case TRACK_RX2_QEC: + extData[1] = MYKONOS_ARM_OBJECTID_RXQEC_TRACKING; + extData[2] = 1; + break; + + case TRACK_ORX1_QEC: + extData[1] = MYKONOS_ARM_OBJECTID_ORXQEC_TRACKING; + extData[2] = 0; + break; + + case TRACK_ORX2_QEC: + extData[1] = MYKONOS_ARM_OBJECTID_ORXQEC_TRACKING; + extData[2] = 1; + break; + + case TRACK_TX1_LOL: + extData[1] = MYKONOS_ARM_OBJECTID_TXLOL_TRACKING; + extData[2] = 0; + break; + + case TRACK_TX2_LOL: + extData[1] = MYKONOS_ARM_OBJECTID_TXLOL_TRACKING; + extData[2] = 1; + break; + + case TRACK_TX1_QEC: + extData[1] = MYKONOS_ARM_OBJECTID_TXQEC_TRACKING; + extData[2] = 0; + break; + + case TRACK_TX2_QEC: + extData[1] = MYKONOS_ARM_OBJECTID_TXQEC_TRACKING; + extData[2] = 1; + break; + + case TRACK_TX1_DPD: + extData[1] = MYKONOS_ARM_OBJECTID_DPDCONFIG; + extData[2] = 0; + break; + + case TRACK_TX2_DPD: + extData[1] = MYKONOS_ARM_OBJECTID_DPDCONFIG; + extData[2] = 1; + break; + + case TRACK_TX1_CLGC: + extData[1] = MYKONOS_ARM_OBJECTID_CLGCCONFIG; + extData[2] = 0; + break; + + case TRACK_TX2_CLGC: + extData[1] = MYKONOS_ARM_OBJECTID_CLGCCONFIG; + extData[2] = 1; + break; + + case TRACK_TX1_VSWR: + extData[1] = MYKONOS_ARM_OBJECTID_VSWRCONFIG; + extData[2] = 0; + break; + + case TRACK_TX2_VSWR: + extData[1] = MYKONOS_ARM_OBJECTID_VSWRCONFIG; + extData[2] = 1; + break; + + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RESCHEDULE_TRACK_CAL_INV, + getMykonosErrorMessage(MYKONOS_ERR_RESCHEDULE_TRACK_CAL_INV)); + return MYKONOS_ERR_RESCHEDULE_TRACK_CAL_INV; + } + + extData[0] = MYKONOS_ARM_OBJECTID_TRACKING_CAL_PENDING; + + /* sending ARM command */ + retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_SET_OPCODE, &extData[0], sizeof(extData)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* check for completion */ + retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_SET_OPCODE, timeoutMs, &cmdStatusByte); + if (retVal != MYKONOS_ERR_OK) + { + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RESCHEDULE_TRACK_ARMERRFLAG, + getMykonosErrorMessage(MYKONOS_ERR_RESCHEDULE_TRACK_ARMERRFLAG)); + return MYKONOS_ERR_RESCHEDULE_TRACK_ARMERRFLAG; + } + + return retVal; + } + + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RESCHEDULE_TRACK_ARMERRFLAG, + getMykonosErrorMessage(MYKONOS_ERR_RESCHEDULE_TRACK_ARMERRFLAG)); + return MYKONOS_ERR_RESCHEDULE_TRACK_ARMERRFLAG; + } + + return retVal; +} + +/** + * \brief Suspend or resume tracking calibrations in RADIO_ON. + * + * This function is used to suspend or resume active tracking calibrations based on the passed mask trackingCals. + * + * \pre Command can be called in Radio On. + * + * trackCals[bit] | Bit description + * ----------------|------------ + * [0] | TRACK_RX1_QEC + * [1] | TRACK_RX2_QEC + * [2] | TRACK_ORX1_QEC + * [3] | TRACK_ORX2_QEC + * [4] | TRACK_TX1_LOL + * [5] | TRACK_TX2_LOL + * [6] | TRACK_TX1_QEC + * [7] | TRACK_TX2_QEC + * [8] | TRACK_TX1_DPD + * [9] | TRACK_TX2_DPD + * [10] | TRACK_TX1_CLGC + * [11] | TRACK_TX2_CLGC + * [12] | TRACK_TX1_VSWR + * [13] | TRACK_TX2_VSWR + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device Pointer to the device settings structure + * \param trackCals Selects the tracking calibrations to suspend or resume during the radio ON state. + * mykonosTrackingCalibrations_t enumerated types are or'd together to form the tracking calibration + * mask word. If the bit is high the calibration will resume, if the bit is low the calibration will be suspended. + * + * \retval MYKONOS_ERR_SETSTATEALL_TRACK_CAL_INV Not valid calibration mask passed for trackCals + * \retval MYKONOS_ERR_SETSTATEALL_TRACK_ARMERRFLAG ARM error + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_setAllTrackCalState(mykonosDevice_t *device, uint32_t trackCals) +{ + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint8_t cfgData[4] = {0}; + uint8_t extData[3] = {MYKONOS_ARM_OBJECTID_TRACKING_CAL_SUSPEND_RESUME, 0x0F, 0}; + uint8_t cmdStatusByte = 0; + uint32_t enTrackCal = 0x00; + uint32_t timeoutMs = 1000; + + const uint32_t TRACKING_MASK = 0x3FFF; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setAllTrackCalState()\n"); +#endif + + /* reading enabled tracking calibrations */ + retVal = MYKONOS_getEnabledTrackingCals(device, &enTrackCal); + + /* trackingCalMask check */ + if (((trackCals | enTrackCal) > enTrackCal) || (trackCals > TRACKING_MASK)) + { + /* invalid cal mask error return, tracking cal not enable so we can not resume it */ + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETSTATEALL_TRACK_CAL_INV, + getMykonosErrorMessage(MYKONOS_ERR_SETSTATEALL_TRACK_CAL_INV)); + return MYKONOS_ERR_SETSTATEALL_TRACK_CAL_INV; + } + + /* convert tracking mask to array of uint8_t type */ + cfgData[0] = (uint8_t)(trackCals & 0xFF); + cfgData[1] = (uint8_t)((trackCals >> 8) & 0xFF); + cfgData[2] = (uint8_t)((trackCals >> 16) & 0x0FF); + cfgData[3] = (uint8_t)((trackCals >> 24) & 0xFF); + + retVal = MYKONOS_writeArmMem(device, MYKONOS_ADDR_ARM_START_DATA_ADDR, &cfgData[0], sizeof(cfgData)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_SET_OPCODE, &extData[0], sizeof(extData)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* check for completion */ + retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_SET_OPCODE, timeoutMs, &cmdStatusByte); + if (retVal != MYKONOS_ERR_OK) + { + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETSTATEALL_TRACK_ARMERRFLAG, + getMykonosErrorMessage(MYKONOS_ERR_SETSTATEALL_TRACK_ARMERRFLAG)); + return MYKONOS_ERR_SETSTATEALL_TRACK_ARMERRFLAG; + } + + return retVal; + } + + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETSTATEALL_TRACK_ARMERRFLAG, + getMykonosErrorMessage(MYKONOS_ERR_SETSTATEALL_TRACK_ARMERRFLAG)); + return MYKONOS_ERR_SETSTATEALL_TRACK_ARMERRFLAG; + } + + return retVal; +} + +/** + * \brief Get the Suspended or Resumed state for tracking calibrations + * + * This function is used to get the suspend or resume state of all active tracking calibrations and the state is stored in trackCals. + * + * \pre Command can be called in Radio On. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device Pointer to the device settings structure + * \param trackCals pointer to store the tracking calibration state. + * If the bit is set then the tracking calibration is resumed and if not set then the tracking cal is suspended, the bit field follows: + * + * trackCals[bit] | Bit description + * ---------------|------------ + * [0] | TRACK_RX1_QEC + * [1] | TRACK_RX2_QEC + * [2] | TRACK_ORX1_QEC + * [3] | TRACK_ORX2_QEC + * [4] | TRACK_TX1_LOL + * [5] | TRACK_TX2_LOL + * [6] | TRACK_TX1_QEC + * [7] | TRACK_TX2_QEC + * [8] | TRACK_TX1_DPD + * [9] | TRACK_TX2_DPD + * [10] | TRACK_TX1_CLGC + * [11] | TRACK_TX2_CLGC + * [12] | TRACK_TX1_VSWR + * [13] | TRACK_TX2_VSWR + * + * \retval MYKONOS_ERR_GETSTATEALL_TRACK_NULL_PARAM Null parameter passed for trackCals + * \retval MYKONOS_ERR_GETSTATEALL_TRACK_ARMERRFLAG ARM error flag set. + * \retval MYKONOS_ERR_GETSTATEALL_TRACK_ARMERROR ARM command error. + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_getAllTrackCalState(mykonosDevice_t *device, uint32_t *trackCals) +{ + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint8_t extData = MYKONOS_ARM_OBJECTID_TRACKING_CAL_SUSPEND_RESUME; + uint8_t armData[4] = {0}; + uint8_t cmdStatusByte = 0; + uint32_t timeoutMs = 1000; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getAllTrackCalState()\n"); +#endif + + /* Check for passed parameter */ + if (trackCals == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETSTATEALL_TRACK_NULL_PARAM, + getMykonosErrorMessage(MYKONOS_ERR_GETSTATEALL_TRACK_NULL_PARAM)); + return MYKONOS_ERR_GETSTATEALL_TRACK_NULL_PARAM; + } + + /* sending ARM command */ + retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_GET_OPCODE, &extData, sizeof(extData)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* check for completion */ + retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_GET_OPCODE, timeoutMs, &cmdStatusByte); + if (retVal != MYKONOS_ERR_OK) + { + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETSTATEALL_TRACK_ARMERRFLAG, + getMykonosErrorMessage(MYKONOS_ERR_GETSTATEALL_TRACK_ARMERRFLAG)); + return MYKONOS_ERR_GETSTATEALL_TRACK_ARMERRFLAG; + } + + return retVal; + } + + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETSTATEALL_TRACK_ARMERRFLAG, + getMykonosErrorMessage(MYKONOS_ERR_GETSTATEALL_TRACK_ARMERRFLAG)); + return MYKONOS_ERR_GETSTATEALL_TRACK_ARMERRFLAG; + } + + /* read 32-bit tracking state from ARM memory */ + retVal = MYKONOS_readArmMem(device, MYKONOS_ADDR_ARM_START_DATA_ADDR, &armData[0], sizeof(armData), 1); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + *trackCals = (uint32_t)armData[0] | ((uint32_t)armData[1] << 8) | ((uint32_t)armData[2] << 16) | ((uint32_t)armData[3] << 24); + + return retVal; +} + +/** + * \brief Suspend or resume individual tracking calibration + * + * \pre The tracking calibration must have been enabled with MYKONOS_enableTrackingCals(), this command can be called in Radio On. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device Pointer to the device settings structure + * \param trackingCal Selects the tracking calibration to resume or suspend. + * \param trackCalState if set then the selected tracking calibration will be resumed and if not set then the tracking cal will be suspended + * + * \retval MYKONOS_ERR_SETSTATE_TRACK_CAL_INV Not valid calibration passed + * \retval MYKONOS_ERR_SETSTATE_TRACK_ARMERRFLAG ARM error + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_setTrackingCalState(mykonosDevice_t *device, mykonosTrackingCalibrations_t trackingCal, uint8_t trackCalState) +{ + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint8_t extData[2] = {0}; + uint8_t cmdStatusByte = 0; + uint8_t suspendTrack = 0x0F; + uint32_t timeoutMs = 1000; + uint32_t enTrackCal = 0x00; + + const uint8_t CHANNEL_1 = 0x00; + const uint8_t CHANNEL_2 = 0x10; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setTrackingCalState()\n"); +#endif + + if (trackCalState > 0) + { + suspendTrack = 0x2F; + } + + /* reading enabled tracking calibrations */ + retVal = MYKONOS_getEnabledTrackingCals(device, &enTrackCal); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* trackingCalMask check */ + if (((uint8_t)trackingCal & enTrackCal) != (uint8_t)trackingCal) + { + /* invalid cal mask error return, tracking cal not enable so we can not resume or suspend it */ + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETSTATE_TRACK_CAL_INV, + getMykonosErrorMessage(MYKONOS_ERR_SETSTATE_TRACK_CAL_INV)); + return MYKONOS_ERR_SETSTATE_TRACK_CAL_INV; + } + + switch (trackingCal) + { + case TRACK_RX1_QEC: + extData[1] = MYKONOS_ARM_OBJECTID_RXQEC_TRACKING & suspendTrack; + extData[1] |= CHANNEL_1; + break; + + case TRACK_RX2_QEC: + extData[1] = MYKONOS_ARM_OBJECTID_RXQEC_TRACKING & suspendTrack; + extData[1] |= CHANNEL_2; + break; + + case TRACK_ORX1_QEC: + extData[1] = MYKONOS_ARM_OBJECTID_ORXQEC_TRACKING & suspendTrack; + extData[1] |= CHANNEL_1; + break; + + case TRACK_ORX2_QEC: + extData[1] = MYKONOS_ARM_OBJECTID_ORXQEC_TRACKING & suspendTrack; + extData[1] |= CHANNEL_2; + break; + + case TRACK_TX1_LOL: + extData[1] = MYKONOS_ARM_OBJECTID_TXLOL_TRACKING & suspendTrack; + extData[1] |= CHANNEL_1; + break; + + case TRACK_TX2_LOL: + extData[1] = MYKONOS_ARM_OBJECTID_TXLOL_TRACKING & suspendTrack; + extData[1] |= CHANNEL_2; + break; + + case TRACK_TX1_QEC: + extData[1] = MYKONOS_ARM_OBJECTID_TXQEC_TRACKING & suspendTrack; + extData[1] |= CHANNEL_1; + break; + + case TRACK_TX2_QEC: + extData[1] = MYKONOS_ARM_OBJECTID_TXQEC_TRACKING & suspendTrack; + extData[1] |= CHANNEL_2; + break; + + case TRACK_TX1_DPD: + extData[1] = MYKONOS_ARM_OBJECTID_DPDCONFIG & suspendTrack; + extData[1] |= CHANNEL_1; + break; + + case TRACK_TX2_DPD: + extData[1] = MYKONOS_ARM_OBJECTID_DPDCONFIG & suspendTrack; + extData[1] |= CHANNEL_2; + break; + + case TRACK_TX1_CLGC: + extData[1] = MYKONOS_ARM_OBJECTID_CLGCCONFIG & suspendTrack; + extData[1] |= CHANNEL_1; + break; + + case TRACK_TX2_CLGC: + extData[1] = MYKONOS_ARM_OBJECTID_CLGCCONFIG & suspendTrack; + extData[1] |= CHANNEL_2; + break; + + case TRACK_TX1_VSWR: + extData[1] = MYKONOS_ARM_OBJECTID_VSWRCONFIG & suspendTrack; + extData[1] |= CHANNEL_1; + break; + + case TRACK_TX2_VSWR: + extData[1] = MYKONOS_ARM_OBJECTID_VSWRCONFIG & suspendTrack; + extData[1] |= CHANNEL_2; + break; + + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETSTATE_TRACK_CAL_INV, + getMykonosErrorMessage(MYKONOS_ERR_SETSTATE_TRACK_CAL_INV)); + return MYKONOS_ERR_SETSTATE_TRACK_CAL_INV; + } + + extData[0] = MYKONOS_ARM_OBJECTID_TRACKING_CAL_SUSPEND_RESUME; + + /* sending ARM command */ + retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_SET_OPCODE, &extData[0], sizeof(extData)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* check for completion */ + retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_SET_OPCODE, timeoutMs, &cmdStatusByte); + if (retVal != MYKONOS_ERR_OK) + { + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETSTATE_TRACK_ARMERRFLAG, + getMykonosErrorMessage(MYKONOS_ERR_SETSTATE_TRACK_ARMERRFLAG)); + return MYKONOS_ERR_SETSTATE_TRACK_ARMERRFLAG; + } + } + + return retVal; +} + +/** + * \brief Get the Suspended or Resumed state for individual tracking calibration + * + * \pre Command can be called in Radio On. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device Pointer to the device settings structure + * \param trackingCal Selects the tracking calibration to get the resumed or suspended state. + * \param trackCalState pointer to store the tracking calibration state, + * if set then the selected tracking calibration is resumed and if not set then the tracking cal is suspended + * + * \retval MYKONOS_ERR_GETSTATE_TRACK_NULL_PARAM Null parameter passed to trackCalState + * \retval MYKONOS_ERR_GETSTATE_TRACK_ARMERRFLAG ARM command error flag set. + * \retval MYKONOS_ERR_GETSTATE_TRACK_ARMERROR ARM command error. + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_getTrackingCalState(mykonosDevice_t *device, mykonosTrackingCalibrations_t trackingCal, uint8_t *trackCalState) +{ + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint8_t extData = MYKONOS_ARM_OBJECTID_TRACKING_CAL_SUSPEND_RESUME; + uint8_t armData[4] = {0}; + uint8_t cmdStatusByte = 0; + uint32_t timeoutMs = 1000; + uint32_t trackMask = 0x00; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getTrackingCalState()\n"); +#endif + + /* Check for passed parameter */ + if (trackCalState == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETSTATE_TRACK_NULL_PARAM, + getMykonosErrorMessage(MYKONOS_ERR_GETSTATE_TRACK_NULL_PARAM)); + return MYKONOS_ERR_GETSTATE_TRACK_NULL_PARAM; + } + + /* sending ARM command */ + retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_GET_OPCODE, &extData, sizeof(extData)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* check for completion */ + retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_GET_OPCODE, timeoutMs, &cmdStatusByte); + if (retVal != MYKONOS_ERR_OK) + { + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETSTATE_TRACK_ARMERRFLAG, + getMykonosErrorMessage(MYKONOS_ERR_GETSTATE_TRACK_ARMERRFLAG)); + return MYKONOS_ERR_GETSTATE_TRACK_ARMERRFLAG; + } + + return retVal; + } + + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETSTATE_TRACK_ARMERRFLAG, + getMykonosErrorMessage(MYKONOS_ERR_GETSTATE_TRACK_ARMERRFLAG)); + return MYKONOS_ERR_GETSTATE_TRACK_ARMERRFLAG; + } + + /* read 32-bit tracking state from ARM memory */ + retVal = MYKONOS_readArmMem(device, MYKONOS_ADDR_ARM_START_DATA_ADDR, &armData[0], sizeof(armData), 1); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + trackMask = (uint32_t)armData[0] | ((uint32_t)armData[1] << 8) | ((uint32_t)armData[2] << 16) | ((uint32_t)armData[3] << 24); + + if (trackMask & (uint32_t)trackingCal) + { + *trackCalState = 1; + } + else + { + *trackCalState = 0; + } + + return retVal; +} + +/** + * \brief Reads back which ARM tracking cals are enabled + * + * enableMask | Bit description + * ------------|---------------------- + * [0] | TRACK_RX1_QEC + * [1] | TRACK_RX2_QEC + * [2] | TRACK_ORX1_QEC + * [3] | TRACK_ORX2_QEC + * [4] | TRACK_TX1_LOL + * [5] | TRACK_TX2_LOL + * [6] | TRACK_TX1_QEC + * [7] | TRACK_TX2_QEC + * [8] | TRACK_TX1_DPD + * [9] | TRACK_TX2_DPD + * [10] | TRACK_TX1_CLGC + * [11] | TRACK_TX2_CLGC + * [12] | TRACK_TX1_VSWR + * [13] | TRACK_TX2_VSWR + * [16] | TRACK_ORX1_QEC_SNLO + * [17] | TRACK_ORX1_QEC_SNLO + * [18] | TRACK_SRX_QEC + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device Pointer to the device settings structure + * \param enableMask Returned bitmask that shows which tracking cals are enabled + * to run during radioOn state. See mykonosTrackingCalibrations_t enum of tracking cals. + * + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_getEnabledTrackingCals(mykonosDevice_t *device, uint32_t *enableMask) +{ + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint8_t armData[4] = {0}; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getEnabledTrackingCals()\n"); +#endif + + /* Ask ARM to read tracking cal enable bits and place in mailbox buffer memory */ + retVal = MYKONOS_readArmConfig(device, MYKONOS_ARM_OBJECTID_CALSCHEDULER, 0, &armData[0], 4); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + *enableMask = ((uint32_t)(armData[0]) | ((uint32_t)(armData[1]) << 8) | ((uint32_t)(armData[2]) << 16) | ((uint32_t)(armData[3]) << 24)); + + return MYKONOS_ERR_OK; +} + +/** + * \brief Returns the tracking calibration pending and error status. + * + * When in radioOn state, the enabled tracking calibrations will set the pending + * flag when the particular calibration is ready to be run, but has not completed + * yet. For Tx tracking cals to complete, the BBIC must set the ObsRx path to + * the INTERNAL CALS mode. If a tracking calibration had an error, the corresponding + * error flag will be asserted. + * + * pendingCalMask | bit Description + * ----------------|-------------------------------------------------------- + * [0] | Rx1 QEC tracking pending + * [1] | Rx1 QEC tracking error + * [2] | Rx2 QEC tracking pending + * [3] | Rx2 QEC tracking error + * [4] | ORx1 QEC tracking pending + * [5] | ORx1 QEC tracking error + * [6] | ORx2 QEC tracking pending + * [7] | ORx2 QEC tracking error + * [8] | Tx1 LOL tracking pending + * [9] | Tx1 LOL tracking error + * [10] | Tx2 LOL tracking pending + * [11] | Tx2 LOL tracking error + * [12] | Tx1 QEC tracking pending + * [13] | Tx1 QEC tracking error + * [14] | Tx2 QEC tracking pending + * [15] | Tx2 QEC tracking error + * [16] | Tx1 DPD tracking pending + * [17] | Tx1 DPD tracking error + * [18] | Tx2 DPD tracking pending + * [19] | Tx2 DPD tracking error + * [20] | Tx1 CLGC tracking pending + * [21] | Tx1 CLGC tracking error + * [22] | Tx2 CLGC tracking pending + * [23] | Tx2 CLGC tracking error + * [24] | Tx1 VSWR tracking pending + * [25] | Tx1 VSWR tracking error + * [26] | Tx2 VSWR tracking pending + * [27] | Tx2 VSWR tracking error + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device Pointer to the device settings structure + * \param pendingCalMask Bit mask that describes which tracking cals are pending + * or had errors + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_GETPENDTRKCALS_NULL_PARAM Function parameter pendingCalMask is a NULL pointer + */ +mykonosErr_t MYKONOS_getPendingTrackingCals(mykonosDevice_t *device, uint32_t *pendingCalMask) +{ + uint8_t readData[4] = {0}; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getPendingTrackingCals()\n"); +#endif + + if (pendingCalMask == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETPENDTRKCALS_NULL_PARAM, + getMykonosErrorMessage(MYKONOS_ERR_GETPENDTRKCALS_NULL_PARAM)); + return MYKONOS_ERR_GETPENDTRKCALS_NULL_PARAM; + } + + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_ARM_OPCODE_STATE_3, &readData[0]); + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_ARM_OPCODE_STATE_4, &readData[1]); + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_ARM_OPCODE_STATE_5, &readData[2]); + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_ARM_OPCODE_STATE_6, &readData[3]); + *pendingCalMask = ((uint32_t)readData[3] << 24) | ((uint32_t)readData[2] << 16) | ((uint32_t)readData[1] << 8) | ((uint32_t)readData[0]); + + return MYKONOS_ERR_OK; +} + +/** + * \brief Returns the status of the TxLOL external tracking calibration + * + * The Tx LOL external tracking calibration is run during the radioOn state. + * The function can be called to read back the status of the TxLOL external + * calibration including metrics like error codes, percentage of data + * collected for current cal, the performance of the cal and the number of + * times the cal has run and updated the hardware. + * + * \pre Before the function is called, the device must be initialized, the ARM + * loaded, and init cals run. These functions can be called in radioOff or + * radioOn state. + * + * \param device Pointer to the device settings structure + * \param txChannel The channel (Tx1/Tx2) whose status is to be read back + * \param txLolStatus Status of the TxLOL external calibration, as a structure + * of type mykonosTxLolStatus_t is returned to this pointer address + * + * \retval MYKONOS_ERR_GETTXLOLSTATUS_NULLPARAM Function parameter mykonosTxLolStatus_t is a NULL pointer + * \retval MYKONOS_ERR_GETTXLOLSTATUS_INV_CH Channel selection not valid + * \retval MYKONOS_ERR_GETTXLOLSTATUS_ARMERRFLAG ARM command error + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_getTxLolStatus(mykonosDevice_t *device, mykonosTxChannels_t txChannel, mykonosTxLolStatus_t *txLolStatus) +{ + uint8_t extData[3] = {MYKONOS_ARM_OBJECTID_CAL_STATUS, MYKONOS_ARM_OBJECTID_TXLOL_TRACKING, 0}; + uint8_t cmdStatusByte = 0; + uint32_t offset = 0; + uint32_t timeoutMs = 0; + uint8_t armReadBack[20] = {0}; + mykonosErr_t retVal = MYKONOS_ERR_OK; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getTxLolStatus()\n"); +#endif + + if (txLolStatus == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETTXLOLSTATUS_NULLPARAM, + getMykonosErrorMessage(MYKONOS_ERR_GETTXLOLSTATUS_NULLPARAM)); + return MYKONOS_ERR_GETTXLOLSTATUS_NULLPARAM; + } + + switch (txChannel) + { + case TX1: + extData[2] = 0; + break; + case TX2: + extData[2] = 1; + break; + default: + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETTXLOLSTATUS_INV_CH, + getMykonosErrorMessage(MYKONOS_ERR_GETTXLOLSTATUS_INV_CH)); + return MYKONOS_ERR_GETTXLOLSTATUS_INV_CH; + } + } + + retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_GET_OPCODE, &extData[0], sizeof(extData)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + timeoutMs = 1000; + retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_GET_OPCODE, timeoutMs, &cmdStatusByte); + if (retVal != MYKONOS_ERR_OK) + { + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETTXLOLSTATUS_ARMERRFLAG, + getMykonosErrorMessage(MYKONOS_ERR_GETTXLOLSTATUS_ARMERRFLAG)); + return MYKONOS_ERR_GETTXLOLSTATUS_ARMERRFLAG; + } + + return retVal; + } + + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETTXLOLSTATUS_ARMERRFLAG, + getMykonosErrorMessage(MYKONOS_ERR_GETTXLOLSTATUS_ARMERRFLAG)); + return MYKONOS_ERR_GETTXLOLSTATUS_ARMERRFLAG; + } + + /* read status from ARM memory */ + offset = 0; + retVal = MYKONOS_readArmMem(device, (MYKONOS_ADDR_ARM_START_DATA_ADDR + offset), &armReadBack[0], sizeof(armReadBack), 1); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* Assign to data structure */ + txLolStatus->errorCode = (((uint32_t)armReadBack[3]) << 24) | (((uint32_t)armReadBack[2]) << 16) | (((uint32_t)armReadBack[1]) << 8) | ((uint32_t)armReadBack[0]); + txLolStatus->percentComplete = (((uint32_t)armReadBack[7]) << 24) | (((uint32_t)armReadBack[6]) << 16) | (((uint32_t)armReadBack[5]) << 8) + | ((uint32_t)armReadBack[4]); + txLolStatus->performanceMetric = (((uint32_t)armReadBack[11]) << 24) | (((uint32_t)armReadBack[10]) << 16) | (((uint32_t)armReadBack[9]) << 8) + | ((uint32_t)armReadBack[8]); + txLolStatus->iterCount = (((uint32_t)armReadBack[15]) << 24) | (((uint32_t)armReadBack[14]) << 16) | (((uint32_t)armReadBack[13]) << 8) | ((uint32_t)armReadBack[12]); + txLolStatus->updateCount = (((uint32_t)armReadBack[19]) << 24) | (((uint32_t)armReadBack[18]) << 16) | (((uint32_t)armReadBack[17]) << 8) + | ((uint32_t)armReadBack[16]); + + return MYKONOS_ERR_OK; +} + +/** + * \brief Returns the status of the TxQEC tracking calibration + * + * The Tx QEC tracking calibration is run during the radioOn state. + * The function can be called to read back the status of the TxQEC + * calibration including metrics like error codes, percentage of data + * collected for current cal, the performance of the cal and the number of + * times the cal has run and updated the hardware. + * + * \pre Before the function is called, the device must be initialized, the ARM + * loaded, and init cals run. These functions can be called in radioOff or + * radioOn state. + * + * \param device Pointer to the device settings structure + * \param txChannel The channel (Tx1/Tx2) whose status is to be read back + * \param txQecStatus Status of the TxQEC external calibration, as a structure + * of type mykonosTxQecStatus_t is returned to this pointer address + * + * \retval MYKONOS_ERR_GETTXQECSTATUS_NULLPARAM Function parameter txQecStatus is a NULL pointer + * \retval MYKONOS_ERR_GETTXQECSTATUS_INV_CH Channel selection not valid + * \retval MYKONOS_ERR_GETTXQECSTATUS_ARMERRFLAG ARM command error + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_getTxQecStatus(mykonosDevice_t *device, mykonosTxChannels_t txChannel, mykonosTxQecStatus_t *txQecStatus) +{ + uint8_t extData[3] = {MYKONOS_ARM_OBJECTID_CAL_STATUS, MYKONOS_ARM_OBJECTID_TXQEC_TRACKING, 0}; + uint8_t cmdStatusByte = 0; + uint32_t offset = 0; + uint32_t timeoutMs = 0; + uint8_t armReadBack[20] = {0}; + mykonosErr_t retVal = MYKONOS_ERR_OK; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getTxQecStatus()\n"); +#endif + + if (txQecStatus == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETTXQECSTATUS_NULLPARAM, + getMykonosErrorMessage(MYKONOS_ERR_GETTXQECSTATUS_NULLPARAM)); + return MYKONOS_ERR_GETTXQECSTATUS_NULLPARAM; + } + + switch (txChannel) + { + case TX1: + extData[2] = 0; + break; + case TX2: + extData[2] = 1; + break; + default: + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETTXQECSTATUS_INV_CH, + getMykonosErrorMessage(MYKONOS_ERR_GETTXQECSTATUS_INV_CH)); + return MYKONOS_ERR_GETTXQECSTATUS_INV_CH; + } + } + + retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_GET_OPCODE, &extData[0], sizeof(extData)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + timeoutMs = 1000; + retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_GET_OPCODE, timeoutMs, &cmdStatusByte); + if (retVal != MYKONOS_ERR_OK) + { + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETTXQECSTATUS_ARMERRFLAG, + getMykonosErrorMessage(MYKONOS_ERR_GETTXQECSTATUS_ARMERRFLAG)); + return MYKONOS_ERR_GETTXQECSTATUS_ARMERRFLAG; + } + + return retVal; + } + + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETTXQECSTATUS_ARMERRFLAG, + getMykonosErrorMessage(MYKONOS_ERR_GETTXQECSTATUS_ARMERRFLAG)); + return MYKONOS_ERR_GETTXQECSTATUS_ARMERRFLAG; + } + + /* read status from ARM memory */ + offset = 0; + retVal = MYKONOS_readArmMem(device, (MYKONOS_ADDR_ARM_START_DATA_ADDR + offset), &armReadBack[0], sizeof(armReadBack), 1); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* Assign to data structure */ + txQecStatus->errorCode = (((uint32_t)armReadBack[3]) << 24) | (((uint32_t)armReadBack[2]) << 16) | (((uint32_t)armReadBack[1]) << 8) | ((uint32_t)armReadBack[0]); + txQecStatus->percentComplete = (((uint32_t)armReadBack[7]) << 24) | (((uint32_t)armReadBack[6]) << 16) | (((uint32_t)armReadBack[5]) << 8) + | ((uint32_t)armReadBack[4]); + txQecStatus->performanceMetric = (((uint32_t)armReadBack[11]) << 24) | (((uint32_t)armReadBack[10]) << 16) | (((uint32_t)armReadBack[9]) << 8) + | ((uint32_t)armReadBack[8]); + txQecStatus->iterCount = (((uint32_t)armReadBack[15]) << 24) | (((uint32_t)armReadBack[14]) << 16) | (((uint32_t)armReadBack[13]) << 8) | ((uint32_t)armReadBack[12]); + txQecStatus->updateCount = (((uint32_t)armReadBack[19]) << 24) | (((uint32_t)armReadBack[18]) << 16) | (((uint32_t)armReadBack[17]) << 8) + | ((uint32_t)armReadBack[16]); + + return MYKONOS_ERR_OK; +} + +/** + * \brief Returns the status of the RxQEC tracking calibration + * + * The Rx QEC tracking calibration is run during the radioOn state. + * The function can be called to read back the status of the RxQEC external + * calibration including metrics like error codes, percentage of data + * collected for current cal, the performance of the cal and the number of + * times the cal has run and updated the hardware. + * + * \pre Before the function is called, the device must be initialized, the ARM + * loaded, and init cals run. These functions can be called in radioOff or + * radioOn state. + * + * \param device Pointer to the device settings structure + * \param rxChannel The channel (Rx1/Rx2) whose status is to be read back + * \param rxQecStatus Status of the RxQEC calibration, as a structure + * of type mykonosRxQecStatus_t is returned to this pointer address + * + * \retval MYKONOS_ERR_GETRXQECSTATUS_NULLPARAM Function parameter rxQecStatus is a NULL pointer + * \retval MYKONOS_ERR_GETRXQECSTATUS_INV_CH Channel selection not valid + * \retval MYKONOS_ERR_GETRXQECSTATUS_ARMERRFLAG ARM command error + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_getRxQecStatus(mykonosDevice_t *device, mykonosRxChannels_t rxChannel, mykonosRxQecStatus_t *rxQecStatus) +{ + uint8_t extData[3] = {MYKONOS_ARM_OBJECTID_CAL_STATUS, MYKONOS_ARM_OBJECTID_RXQEC_TRACKING, 0}; + uint8_t cmdStatusByte = 0; + uint32_t offset = 0; + uint32_t timeoutMs = 0; + uint8_t armReadBack[20] = {0}; + mykonosErr_t retVal = MYKONOS_ERR_OK; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getRxQecStatus()\n"); +#endif + + if (rxQecStatus == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETRXQECSTATUS_NULLPARAM, + getMykonosErrorMessage(MYKONOS_ERR_GETRXQECSTATUS_NULLPARAM)); + return MYKONOS_ERR_GETRXQECSTATUS_NULLPARAM; + } + + switch (rxChannel) + { + case RX1: + extData[2] = 0; + break; + case RX2: + extData[2] = 1; + break; + default: + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETRXQECSTATUS_INV_CH, + getMykonosErrorMessage(MYKONOS_ERR_GETRXQECSTATUS_INV_CH)); + return MYKONOS_ERR_GETRXQECSTATUS_INV_CH; + } + } + + retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_GET_OPCODE, &extData[0], sizeof(extData)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + timeoutMs = 1000; + retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_GET_OPCODE, timeoutMs, &cmdStatusByte); + if (retVal != MYKONOS_ERR_OK) + { + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETRXQECSTATUS_ARMERRFLAG, + getMykonosErrorMessage(MYKONOS_ERR_GETRXQECSTATUS_ARMERRFLAG)); + return MYKONOS_ERR_GETRXQECSTATUS_ARMERRFLAG; + } + + return retVal; + } + + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETRXQECSTATUS_ARMERRFLAG, + getMykonosErrorMessage(MYKONOS_ERR_GETRXQECSTATUS_ARMERRFLAG)); + return MYKONOS_ERR_GETRXQECSTATUS_ARMERRFLAG; + } + + /* read status from ARM memory */ + offset = 0; + retVal = MYKONOS_readArmMem(device, (MYKONOS_ADDR_ARM_START_DATA_ADDR + offset), &armReadBack[0], sizeof(armReadBack), 1); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* Assign to data structure */ + rxQecStatus->errorCode = (((uint32_t)armReadBack[3]) << 24) | (((uint32_t)armReadBack[2]) << 16) | (((uint32_t)armReadBack[1]) << 8) | ((uint32_t)armReadBack[0]); + rxQecStatus->percentComplete = (((uint32_t)armReadBack[7]) << 24) | (((uint32_t)armReadBack[6]) << 16) | (((uint32_t)armReadBack[5]) << 8) + | ((uint32_t)armReadBack[4]); + rxQecStatus->selfcheckIrrDb = (((uint32_t)armReadBack[11]) << 24) | (((uint32_t)armReadBack[10]) << 16) | (((uint32_t)armReadBack[9]) << 8) + | ((uint32_t)armReadBack[8]); + rxQecStatus->iterCount = (((uint32_t)armReadBack[15]) << 24) | (((uint32_t)armReadBack[14]) << 16) | (((uint32_t)armReadBack[13]) << 8) | ((uint32_t)armReadBack[12]); + rxQecStatus->updateCount = (((uint32_t)armReadBack[19]) << 24) | (((uint32_t)armReadBack[18]) << 16) | (((uint32_t)armReadBack[17]) << 8) + | ((uint32_t)armReadBack[16]); + + return MYKONOS_ERR_OK; +} + +/** + * \brief Returns the status of the ORxQEC tracking calibration + * + * The ORx QEC tracking calibration is run during the radioOn state. + * The function can be called to read back the status of the ORxQEC external + * calibration including metrics like error codes, percentage of data + * collected for current cal, the performance of the cal and the number of + * times the cal has run and updated the hardware. + * + * \pre Before the function is called, the device must be initialized, the ARM + * loaded, and init cals run. These functions can be called in radioOff or + * radioOn state. + * + * \param device Pointer to the device settings structure + * \param orxChannel The channel whose status is to be read back + * \param orxQecStatus Status of the ORxQEC external calibration, as a structure + * of type mykonosOrxQecStatus_t is returned to this pointer address + * + * \retval MYKONOS_ERR_GETORXQECSTATUS_NULLPARAM Function parameter orxQecStatus is a NULL pointer + * \retval MYKONOS_ERR_GETORXQECSTATUS_INV_CH Channel selection not valid + * \retval MYKONOS_ERR_GETORXQECSTATUS_ARMERRFLAG ARM command error + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_getOrxQecStatus(mykonosDevice_t *device, mykonosObsRxChannels_t orxChannel, mykonosOrxQecStatus_t *orxQecStatus) +{ + uint8_t extData[3] = {MYKONOS_ARM_OBJECTID_CAL_STATUS, MYKONOS_ARM_OBJECTID_ORXQEC_TRACKING, 0}; + uint8_t cmdStatusByte = 0; + uint32_t offset = 0; + uint32_t timeoutMs = 0; + uint8_t armReadBack[20] = {0}; + mykonosErr_t retVal = MYKONOS_ERR_OK; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getOrxQecStatus()\n"); +#endif + + if (orxQecStatus == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETORXQECSTATUS_NULLPARAM, + getMykonosErrorMessage(MYKONOS_ERR_GETORXQECSTATUS_NULLPARAM)); + return MYKONOS_ERR_GETORXQECSTATUS_NULLPARAM; + } + + switch (orxChannel) + { + case OBS_RX1_TXLO: + case OBS_RX1_SNIFFERLO: + extData[2] = 0; + break; + case OBS_RX2_TXLO: + case OBS_RX2_SNIFFERLO: + extData[2] = 1; + break; + default: + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETORXQECSTATUS_INV_CH, + getMykonosErrorMessage(MYKONOS_ERR_GETORXQECSTATUS_INV_CH)); + return MYKONOS_ERR_GETORXQECSTATUS_INV_CH; + } + } + + retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_GET_OPCODE, &extData[0], sizeof(extData)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + timeoutMs = 1000; + retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_GET_OPCODE, timeoutMs, &cmdStatusByte); + if (retVal != MYKONOS_ERR_OK) + { + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETORXQECSTATUS_ARMERRFLAG, + getMykonosErrorMessage(MYKONOS_ERR_GETORXQECSTATUS_ARMERRFLAG)); + return MYKONOS_ERR_GETORXQECSTATUS_ARMERRFLAG; + } + + return retVal; + } + + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETORXQECSTATUS_ARMERRFLAG, + getMykonosErrorMessage(MYKONOS_ERR_GETORXQECSTATUS_ARMERRFLAG)); + return MYKONOS_ERR_GETORXQECSTATUS_ARMERRFLAG; + } + + /* read status from ARM memory */ + offset = 0; + retVal = MYKONOS_readArmMem(device, (MYKONOS_ADDR_ARM_START_DATA_ADDR + offset), &armReadBack[0], sizeof(armReadBack), 1); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* Assign to data structure */ + orxQecStatus->errorCode = (((uint32_t)armReadBack[3]) << 24) | (((uint32_t)armReadBack[2]) << 16) | (((uint32_t)armReadBack[1]) << 8) | ((uint32_t)armReadBack[0]); + orxQecStatus->percentComplete = (((uint32_t)armReadBack[7]) << 24) | (((uint32_t)armReadBack[6]) << 16) | (((uint32_t)armReadBack[5]) << 8) + | ((uint32_t)armReadBack[4]); + orxQecStatus->selfcheckIrrDb = (((uint32_t)armReadBack[11]) << 24) | (((uint32_t)armReadBack[10]) << 16) | (((uint32_t)armReadBack[9]) << 8) + | ((uint32_t)armReadBack[8]); + orxQecStatus->iterCount = (((uint32_t)armReadBack[15]) << 24) | (((uint32_t)armReadBack[14]) << 16) | (((uint32_t)armReadBack[13]) << 8) + | ((uint32_t)armReadBack[12]); + orxQecStatus->updateCount = (((uint32_t)armReadBack[19]) << 24) | (((uint32_t)armReadBack[18]) << 16) | (((uint32_t)armReadBack[17]) << 8) + | ((uint32_t)armReadBack[16]); + + return MYKONOS_ERR_OK; +} + +/** + * \brief Selects the Sniffer RF input to use for the observation receiver when in ObsRx pin mode and ORX_MODE = SNIFFER(4) + * + * This function is only valid when using the ObsRx Pin mode. In pin mode, 3 GPIO pins select an Observation Rx source. + * See mykonosObsRxChannels_t enum values less than 7. When the ORX_MODE GPIO pins are set to 4 for Sniffer, Sniffer inputs + * A, B, and C can be chosen by calling this function. This function can be called any time after the ARM is loaded and running. + * It can be called in radioOn or radioOff state. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device Pointer to the device settings structure + * \param snifferChannel Desired channel to set. This channel will be enabled when ORX_MODE = SNIFFER. + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_SET_ARMGPIO_PINS_ARMERROR ARM returned an error + */ +mykonosErr_t MYKONOS_setSnifferChannel(mykonosDevice_t *device, mykonosSnifferChannel_t snifferChannel) +{ + uint8_t armData[2] = {0}; + uint32_t timeoutMs = 0; + uint8_t cmdStatusByte = 0; + mykonosErr_t retVal = MYKONOS_ERR_OK; + + armData[0] = 0x6A; /* SET SRX_SOURCE ARM object ID */ + armData[1] = (uint8_t)snifferChannel; + + retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_SET_OPCODE, &armData[0], sizeof(armData)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + timeoutMs = 1000; + retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_SET_OPCODE, timeoutMs, &cmdStatusByte); + if (retVal != MYKONOS_ERR_OK) + { + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SET_ARMGPIO_PINS_ARMERROR, + getGpioMykonosErrorMessage(MYKONOS_ERR_SET_ARMGPIO_PINS_ARMERROR)); + retVal = (mykonosErr_t)MYKONOS_ERR_SET_ARMGPIO_PINS_ARMERROR; + } + + return retVal; + } + + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SET_ARMGPIO_PINS_ARMERROR, + getGpioMykonosErrorMessage(MYKONOS_ERR_SET_ARMGPIO_PINS_ARMERROR)); + return (mykonosErr_t)MYKONOS_ERR_SET_ARMGPIO_PINS_ARMERROR; + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief Resets the ARM processor and performs initialization + * + * Sets ARM Run = 0, Disables parity checks, sets ARM and SPI reg clock selects, + * resets ARM, and enables ARM SPI register access + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - device->rx->rxProfile->iqRate_kHz + * - device->deviceClock_kHz + * - device->rx->rxProfile->rfBandwidth_Hz + * - device->tx->txProfile->rfBandwidth_Hz + * - device->rx->rxProfile->rxFirDecimation + * - device->rx->rxProfile->rhb1Decimation + * - device->spiSettings + * + * \param device Pointer to the device settings structure + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_INITARM_INV_VCODIV + * \retval MYKONOS_ERR_INITARM_INV_REGCLK Could not calculate a valid ARM Register clock divider + * \retval MYKONOS_ERR_INITARM_INV_ARMCLK_PARAM Could not calculate a valid ARM clock divider + */ +mykonosErr_t MYKONOS_initArm(mykonosDevice_t *device) +{ + uint8_t regClkSel = 0; + uint8_t armClkSel = 0; + uint32_t hsClkRateDiv4or5_Khz = 0; + uint32_t hb1Clk = 0; + uint32_t vcoDivTimes10 = 1; + uint8_t adcDiv = 0; + mykonosErr_t retVal = MYKONOS_ERR_OK; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_initArm()\n"); +#endif + + /* Finish init - this is part of init that must run after Multi Chip Sync */ + retVal = MYKONOS_initSubRegisterTables(device); + if (retVal != MYKONOS_ERR_OK) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, retVal, getMykonosErrorMessage(retVal)); + return retVal; + } + + switch (device->clocks->clkPllVcoDiv) + { + case VCODIV_1: + vcoDivTimes10 = 10; + break; + case VCODIV_1p5: + vcoDivTimes10 = 15; + break; + case VCODIV_2: + vcoDivTimes10 = 20; + break; + case VCODIV_3: + vcoDivTimes10 = 30; + break; + default: + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INITARM_INV_VCODIV, + getMykonosErrorMessage(MYKONOS_ERR_INITARM_INV_VCODIV)); + return MYKONOS_ERR_INITARM_INV_VCODIV; + } + } + + hsClkRateDiv4or5_Khz = device->clocks->clkPllVcoFreq_kHz * 10 / vcoDivTimes10 / 20; + + /* If ADC divider is set, divide hsClkRateDiv4or5_kHz by 2 (ADC divider) */ + CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_CLOCK_CONTROL_1, &adcDiv, 0x01, 0); + hb1Clk = (adcDiv == 1) ? (hsClkRateDiv4or5_Khz >> 1) : (hsClkRateDiv4or5_Khz); + + /* the ARM clock should not exceed 250 Mhz */ + if (hb1Clk <= 250000) + { + armClkSel = 0x00; + } + else if (hb1Clk > 250000 && hb1Clk <= 500000) + { + armClkSel = 0x02; + } + else if (hb1Clk > 500000 && hb1Clk <= 1000000) + { + armClkSel = 0x04; + } + else + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INITARM_INV_ARMCLK_PARAM, + getMykonosErrorMessage(MYKONOS_ERR_INITARM_INV_ARMCLK_PARAM)); + return MYKONOS_ERR_INITARM_INV_ARMCLK_PARAM; + } + + /* the SPI read reg clock must be equal or less than 100MHz and the SPI write reg clock must be less equal or less than 200 Mhz*/ + if (hb1Clk <= 100000) + { + regClkSel = 0x00; + } + else if (hb1Clk > 100000 && hb1Clk <= 200000) + { + regClkSel = 0x04; + } + else if (hb1Clk > 200000 && hb1Clk <= 400000) + { + regClkSel = 0x09; + } + else if (hb1Clk > 400000 && hb1Clk <= 800000) + { + regClkSel = 0x0E; + } + else + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INITARM_INV_REGCLK, getMykonosErrorMessage(MYKONOS_ERR_INITARM_INV_REGCLK)); + return MYKONOS_ERR_INITARM_INV_REGCLK; + } + + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_CTL_1, 0x8C); /* arm_debug_enable[7]=1, mem_hresp_mask[3]=1, auto_incr[2]=1, arm_m3_run[0]=0 */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_CLK_CTL, armClkSel |= 0x41); /* setting the ARM clock rate, resetting the PC, and enabling the ARM clock */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_CLK_CTL, armClkSel &= ~0x40); /* maintaining the ARM clock rate, disabling the PC reset, and maintaining ARM clock enable */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_BRIDGE_CLK_CTL, regClkSel); /* setting the SPI read and write clock rates */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AHB_SPI_BRIDGE, 0x13); /* blockout_window_size[4:1] = 9, ahb_spi_bridge_enable[0] = 1 */ + + retVal = MYKONOS_writeArmProfile(device); + if (retVal != MYKONOS_ERR_OK) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, retVal, getMykonosErrorMessage(retVal)); + return retVal; + } + + retVal = MYKONOS_loadAdcProfiles(device); + if (retVal != MYKONOS_ERR_OK) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, retVal, getMykonosErrorMessage(retVal)); + return retVal; + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief Loads binary byte array into ARM program memory + * + * This function assumes the ARM auto increment bit is set in 0x0D00[2]. Valid memory + * addresses are: Program Memory (0x01000000 - 0x01017FFF) + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - device->spiSettings + * + * \param device is structure pointer to the Mykonos data structure containing settings + * \param binary is a byte array containing ARM program memory data bytes (directly from .bin file) + * \param count is the number of bytes in the byte array + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_LOADBIN_NULL_PARAM Function parameter binary has a NULL pointer + * \retval MYKONOS_ERR_LOADBIN_INVALID_BYTECOUNT Count parameter must be 98304 bytes + */ +mykonosErr_t MYKONOS_loadArmFromBinary(mykonosDevice_t *device, uint8_t *binary, uint32_t count) +{ + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint8_t stackPtr[4] = {0}; + uint8_t bootAddr[4] = {0}; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_loadArmFromBinary()\n"); +#endif + + if (binary == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_LOADBIN_NULL_PARAM, getMykonosErrorMessage(MYKONOS_ERR_LOADBIN_NULL_PARAM)); + return MYKONOS_ERR_LOADBIN_NULL_PARAM; + } + + if (count != 98304) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_LOADBIN_INVALID_BYTECOUNT, + getMykonosErrorMessage(MYKONOS_ERR_LOADBIN_INVALID_BYTECOUNT)); + return MYKONOS_ERR_LOADBIN_INVALID_BYTECOUNT; + } + else + { + /* extraction of stack pointer and boot address from top of array */ + stackPtr[0] = binary[0]; + stackPtr[1] = binary[1]; + stackPtr[2] = binary[2]; + stackPtr[3] = binary[3]; + + bootAddr[0] = binary[4]; + bootAddr[1] = binary[5]; + bootAddr[2] = binary[6]; + bootAddr[3] = binary[7]; + + /* writing binary data to ARM memory */ + retVal = MYKONOS_writeArmMem(device, MYKONOS_ADDR_ARM_START_PROG_ADDR, &binary[0], count); + } + + if (retVal != MYKONOS_ERR_OK) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, retVal, getMykonosErrorMessage(retVal)); + return retVal; + } + else + { + /* writing the stack pointer address */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_STACK_PTR_BYTE_0, stackPtr[0]); /* stack pointer [7:0] */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_STACK_PTR_BYTE_1, stackPtr[1]); /* stack pointer [15:8] */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_STACK_PTR_BYTE_2, stackPtr[2]); /* stack pointer [23:16] */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_STACK_PTR_BYTE_3, stackPtr[3]); /* stack pointer [31:24] */ + + /* writing the boot address */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_BOOT_ADDR_BYTE_0, bootAddr[0]); /* boot address [7:0] */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_BOOT_ADDR_BYTE_1, bootAddr[1]); /* boot address [15:8] */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_BOOT_ADDR_BYTE_2, bootAddr[2]); /* boot address [23:16] */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_BOOT_ADDR_BYTE_3, bootAddr[3]); /* boot address [31:24] */ + + /* setting the ARM run bit */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_CTL_1, 0x8D); /* arm_debug_enable[7]=1, mem_hresp_mask[3]=1, auto_incr[2]=1, arm_m3_run[0]=1 */ + } + + /* verifying ARM checksum */ + if ((retVal = MYKONOS_verifyArmChecksum(device)) != MYKONOS_ERR_OK) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, retVal, getMykonosErrorMessage(retVal)); + return retVal; + } + + /* verifying ARM state is in MYKONOS_ARM_READY state, otherwise return error */ + if ((retVal = MYKONOS_checkArmState(device, MYK_ARM_READY)) != MYKONOS_ERR_OK) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, retVal, getMykonosErrorMessage(retVal)); + return retVal; + } + + /* Setup ARM GPIO pins and program ARMs radio control structure */ + if ((retVal = (mykonosErr_t)MYKONOS_setArmGpioPins(device)) != MYKONOS_ERR_OK) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, retVal, getMykonosErrorMessage(retVal)); + return retVal; + } + + if ((retVal = MYKONOS_setRadioControlPinMode(device)) != MYKONOS_ERR_OK) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, retVal, getMykonosErrorMessage(retVal)); + return retVal; + } + + /* Set the default ObsRx Path source for when the device moves to RadioOn */ + if ((retVal = MYKONOS_setDefaultObsRxPath(device, device->obsRx->defaultObsRxChannel)) != MYKONOS_ERR_OK) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, retVal, getMykonosErrorMessage(retVal)); + return retVal; + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief Loads binary byte array into ARM program memory. This API function allows user to load the ARM concurrently. + * This is specially to reduce the system initialization time. + * + * \pre MYKONOS_initArm() function must be called before calling this API. + * + * \post after calling this function the user must verify: + * Arm Checksum using MYKONOS_verifyArmChecksum(mykonosDevice_t *device) + * verify ARM state is in MYKONOS_ARM_READY state using MYKONOS_checkArmState(device, MYK_ARM_READY); + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - device->spiSettings + * + * \param device is structure pointer to the Mykonos data structure containing settings + * \param binary is a byte array containing ARM program memory data bytes (directly from .bin file) + * \param count is the number of bytes in the byte array + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_LOADARMCON_NULL_PARAM Function parameter binary has a NULL pointer + * \retval MYKONOS_ERR_LOADARMCON_INVALID_BYTECOUNT Count parameter must be 98304 bytes + * \retval MYKONOS_ERR_ARM_INV_ADDR_PARM Invalid memory address + */ +mykonosErr_t MYKONOS_loadArmConcurrent(mykonosDevice_t *device, uint8_t *binary, uint32_t count) +{ + uint8_t stackPtr[4] = {0}; + uint8_t bootAddr[4] = {0}; + uint32_t i; + uint32_t address = MYKONOS_ADDR_ARM_START_PROG_ADDR; + +#if MYK_ENABLE_SPIWRITEARRAY == 1 + uint32_t addrIndex = 0; + uint32_t dataIndex = 0; + uint32_t spiBufferSize = MYK_SPIWRITEARRAY_BUFFERSIZE; + uint16_t addrArray[MYK_SPIWRITEARRAY_BUFFERSIZE] = {0}; +#endif + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_loadArmConcurrent()\n"); +#endif + + if (binary == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_LOADARMCON_NULL_PARAM, getMykonosErrorMessage(MYKONOS_ERR_LOADARMCON_NULL_PARAM)); + return MYKONOS_ERR_LOADARMCON_NULL_PARAM; + } + + if (count != 98304) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_LOADARMCON_INVALID_BYTECOUNT, + getMykonosErrorMessage(MYKONOS_ERR_LOADARMCON_INVALID_BYTECOUNT)); + return MYKONOS_ERR_LOADARMCON_INVALID_BYTECOUNT; + } + else + { + /* extraction of stack pointer and boot address from top of array */ + stackPtr[0] = binary[0]; + stackPtr[1] = binary[1]; + stackPtr[2] = binary[2]; + stackPtr[3] = binary[3]; + + bootAddr[0] = binary[4]; + bootAddr[1] = binary[5]; + bootAddr[2] = binary[6]; + bootAddr[3] = binary[7]; + + /* set auto increment address bit */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_CTL_1, 0x8C); + + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_ADDR_BYTE_0, (uint8_t)((address) >> 2)); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_ADDR_BYTE_1, (uint8_t)(address >> 10)); + + /* start write at correct byte offset */ + /* write data is located at SPI address 0xD04=data[7:0], 0xD05=data[15:8], 0xD06=data[23:16], 0xD07=data[31:24] */ + /* with address auto increment set, after x407 is written, the address will automatically increment */ + +#if (MYK_ENABLE_SPIWRITEARRAY == 0) + + for (i = 0; i < byteCount; i++) + { + CMB_SPIWriteByte(device->spiSettings, (MYKONOS_ADDR_ARM_DATA_BYTE_0 | (((address & 0x3) + i) % 4)), data[i]); + } + +#elif (MYK_ENABLE_SPIWRITEARRAY == 1) + + addrIndex = 0; + dataIndex = 0; + for (i = 0; i < count; i++) + { + addrArray[addrIndex++] = (MYKONOS_ADDR_ARM_DATA_BYTE_0 | (((address & 0x3) + i) % 4)); + + if (addrIndex == spiBufferSize) + { + CMB_SPIWriteBytes(device->spiSettings, &addrArray[0], &binary[dataIndex], addrIndex); + dataIndex = dataIndex + addrIndex; + addrIndex = 0; + } + } + + if (addrIndex > 0) + { + CMB_SPIWriteBytes(device->spiSettings, &addrArray[0], &binary[dataIndex], addrIndex); + } + +#endif + + /* writing the stack pointer address */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_STACK_PTR_BYTE_0, stackPtr[0]); /* stack pointer [7:0] */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_STACK_PTR_BYTE_1, stackPtr[1]); /* stack pointer [15:8] */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_STACK_PTR_BYTE_2, stackPtr[2]); /* stack pointer [23:16] */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_STACK_PTR_BYTE_3, stackPtr[3]); /* stack pointer [31:24] */ + + /* writing the boot address */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_BOOT_ADDR_BYTE_0, bootAddr[0]); /* boot address [7:0] */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_BOOT_ADDR_BYTE_1, bootAddr[1]); /* boot address [15:8] */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_BOOT_ADDR_BYTE_2, bootAddr[2]); /* boot address [23:16] */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_BOOT_ADDR_BYTE_3, bootAddr[3]); /* boot address [31:24] */ + + /* setting the ARM run bit */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_CTL_1, 0x8D); + + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief Verifies the ARM checksum value + * + * The checksum which is written into the .hex file is verified with the calculated checksum + * in the Mykonos ARM after the hex file has been loaded + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is structure pointer to the Mykonos data structure containing settings + * + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_verifyArmChecksum(mykonosDevice_t *device) +{ + uint32_t buildTimeChecksum = 0x00000000; + uint32_t calculatedChecksum = 0x00000000; + uint8_t buildData[4] = {0}; + uint8_t calcData[4] = {0}; + mykonosErr_t retVal = MYKONOS_ERR_OK; + + const uint8_t CHECKSUM_BYTES = 0x4; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_verifyArmChecksum()\n"); +#endif + + /* disabling auto increment and reading four (4) bytes at ARM checksum memory location */ + retVal = MYKONOS_readArmMem(device, MYKONOS_ADDR_ARM_BUILD_CHKSUM_ADDR, buildData, CHECKSUM_BYTES, 0); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + /* determining build time checksum */ + buildTimeChecksum = (((uint32_t)buildData[3] << 24) | ((uint32_t)buildData[2] << 16) | ((uint32_t)buildData[1] << 8) | (uint32_t)buildData[0]); + + /* using 200 msec timeout for exit out of while loop [maximum checksum calculation time = 5 ms] */ + CMB_setTimeout_ms(200); + + /* determining calculated checksum */ + do + { + if ((retVal = MYKONOS_readArmMem(device, MYKONOS_ADDR_ARM_CALC_CHKSUM_ADDR, calcData, CHECKSUM_BYTES, 0)) != MYKONOS_ERR_OK) + { + return retVal; + } + calculatedChecksum = (((uint32_t)calcData[3] << 24) | ((uint32_t)calcData[2] << 16) | ((uint32_t)calcData[1] << 8) | (uint32_t)calcData[0]); + } while ((!calculatedChecksum) && (!CMB_hasTimeoutExpired())); + + /* performing consistency check */ + if (buildTimeChecksum == calculatedChecksum) + { + return MYKONOS_ERR_OK; + } + else + { + return MYKONOS_ERR_ARM_INVALID_BUILDCHKSUM; + } +} + +/** + * \brief Verifies the ARM status once it is start running + * + * Wait for ARM to go into radio state, if takes longer there is and ARM error + * get error in Application layer calling MYKONOS_getRadioState() + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is structure pointer to the Mykonos data structure containing settings + * \param armStateCheck if the ARM is not in this state it will return an error, + * + * \retval MYKONOS_ERR_ARMSTATE_EXCEPTION ARM system problem has been detected. + * \retval MYKONOS_ERR_ARMSTATE_CAL_ERROR ARM has detected an error in the tracking calibrations. + * \retval MYKONOS_ERR_ARMSTATE_EXCEPTION ARM has detected an illegal profile. + * \retval MYKONOS_ERR_WAITARMCSTATE_TIMEOUT Timeout occurred in check ARM state. + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_checkArmState(mykonosDevice_t *device, mykonosArmState_t armStateCheck) +{ + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint32_t armStatus = 0x00; + uint32_t armStatusMapped = 0x00; + uint32_t timeoutMs = 500; /* 500ms timeOut */ + uint8_t endCheck = 0x00; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_checkArmState()\n"); +#endif + + CMB_setTimeout_ms(timeoutMs); + + do + { + if ((retVal = MYKONOS_getRadioState(device, &armStatus)) != MYKONOS_ERR_OK) + { + return retVal; + } + + /* Mapping of the armStatus bit to the enum value. */ + switch(armStatus) + { + case 0: + armStatusMapped = (uint32_t)MYK_ARM_POWERUP; + break; + case 1: + armStatusMapped = (uint32_t)MYK_ARM_READY; + break; + case 2: + armStatusMapped = (uint32_t)MYK_ARM_IDLE; + break; + case 3: + armStatusMapped = (uint32_t)MYK_ARM_RADIO_ON; + break; + case 4: + armStatusMapped = (uint32_t)MYK_ARM_PROFILE_ERROR; + break; + default: + armStatusMapped = armStatus; + break; + } + + if (armStateCheck && armStatusMapped) + { + retVal = MYKONOS_ERR_OK; + break; + } + + if (CMB_hasTimeoutExpired()) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_WAITARMCSTATE_TIMEOUT, + getMykonosErrorMessage(MYKONOS_ERR_WAITARMCSTATE_TIMEOUT)); + retVal = MYKONOS_ERR_WAITARMCSTATE_TIMEOUT; + break; + } + + switch (armStatusMapped) + { + /* this cases are not ARM errors */ + case MYK_ARM_POWERUP: + case MYK_ARM_READY: + case MYK_ARM_IDLE: + case MYK_ARM_RADIO_ON: + break; + + case MYK_ARM_PROFILE_ERROR: + /* return error directly */ + retVal = MYKONOS_ERR_ARMSTATE_PROFILE_ERROR; + endCheck = 1; + break; + + case MYK_ARM_CAL_ERROR: + /* return error directly */ + retVal = MYKONOS_ERR_ARMSTATE_CAL_ERROR; + endCheck = 1; + break; + + case MYK_ARM_EXCEPTION: + /* return error directly */ + retVal = MYKONOS_ERR_ARMSTATE_EXCEPTION; + endCheck = 1; + break; + + case (uint32_t)MYK_ARM_EXCEPTION | (uint32_t)MYK_ARM_PROFILE_ERROR: + /* return error directly */ + retVal = MYKONOS_ERR_ARMSTATE_EXCEPTION; + endCheck = 1; + break; + + default: + endCheck = 0; + break; + } + + } while (!endCheck); + + return retVal; +} + +/** + * \brief Reads back the version of the ARM binary loaded into the Mykonos ARM memory + * + * This function reads the ARM memory to read back the major.minor.releaseCandidate + * version for the ARM binary loaded into ARM memory. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is structure pointer to the Mykonos data structure containing settings + * \param majorVer The Major version is returned in this parameter + * \param minorVer The Minor version is returned in this parameter + * \param rcVer The release candidate version (build number) is returned in this parameter + * \param buildType The Type of the build [Debug / Test_Object / Release] + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_GETARMVER_NULL_PARM One of the function parameters has a NULL pointer + */ +mykonosErr_t MYKONOS_getArmVersion(mykonosDevice_t *device, uint8_t *majorVer, uint8_t *minorVer, uint8_t *rcVer, mykonosBuild_t *buildType) +{ + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint8_t ver[5] = {0}; + uint32_t fullVersion = 0; + uint8_t validBuilds = 0x05; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getArmVersion()\n"); +#endif + + if ((majorVer == NULL) || (minorVer == NULL) || (rcVer == NULL)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETARMVER_NULL_PARM, getMykonosErrorMessage(MYKONOS_ERR_GETARMVER_NULL_PARM)); + return MYKONOS_ERR_GETARMVER_NULL_PARM; + } + + retVal = MYKONOS_readArmMem(device, MYKONOS_ADDR_ARM_VERSION, &ver[0], sizeof(ver), 1); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + fullVersion = ((uint32_t)(ver[0]) | (uint32_t)((uint32_t)(ver[1]) << 8) | (uint32_t)((uint32_t)(ver[2]) << 16) | (uint32_t)((uint32_t)(ver[3]) << 24)); + *rcVer = (uint8_t)(fullVersion % 100); + *minorVer = (uint8_t)((fullVersion / 100) % 100); + *majorVer = (uint8_t)(fullVersion / 10000); + + switch (ver[4] & validBuilds) + { + case MYK_BUILD_DEBUG: + *buildType = MYK_BUILD_DEBUG; + break; + case MYK_BUILD_TEST_OBJECT: + *buildType = MYK_BUILD_TEST_OBJECT; + break; + default: + *buildType = MYK_BUILD_RELEASE; + break; + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief This function will configure DPD settings + * + * A DPD-enabled transceiver is required for DPD to be enabled. The DPD has several user + * adjustable settings that can be configured before running the runInitCals + * with the calMask set for the DPD init cal. Call this function with desired + * settings set before running the DPD init cal or enabling DPD tracking. + * + * This function can be called in either Radio On or Off state. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - device->profilesValid + * - device->tx->dpdConfig (All members) + * + * + * \retval MYKONOS_ERR_CFGDPD_TXORX_PROFILE_INV ERROR: to use these features, a valid Tx and ORx profile must exist in the device data structure + * \retval MYKONOS_ERR_CFGDPD_NULL_DPDCFGSTRUCT ERROR: device->tx->dpdConfig is a NULL pointer + * \retval MYKONOS_ERR_CFGDPD_INV_DPDDAMPING ERROR: damping parameter is out of range + * \retval MYKONOS_ERR_CFGDPD_INV_DPDSAMPLES ERROR: samples parameter is out of range + * \retval MYKONOS_ERR_CFGDPD_INV_NUMWEIGHTS ERROR: numWeights parameter is out of range (0-3) + * \retval MYKONOS_ERR_CFGDPD_INV_MODELVERSION ERROR: modelVersion parameter is out of range (0-3) + * \retval MYKONOS_ERR_CFGDPD_INV_DPDOUTLIERTHRESH ERROR: outlierThreshold parameter is out of range + * \retval MYKONOS_ERR_CFGDPD_INV_DPD_ADDDELAY ERROR: additionalDelayOffset parameter is out of range + * \retval MYKONOS_ERR_CFGDPD_INV_PNSEQLEVEL ERROR: pathDelayPnSeqLevel parameter is out of range + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_configDpd(mykonosDevice_t *device) +{ + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint8_t armFieldValue[6] = {0}; + uint8_t byteOffset = 0; + uint16_t negPnLevel = 0; + uint8_t highPowerModelUpdate = 0; + uint8_t robustModeling = 0; + uint32_t radioStatus = 0; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_configDpd()\n"); +#endif + + /* DPD requires Tx and ORx enabled, throw error if both are not enabled */ + if ((device->profilesValid & (TX_PROFILE_VALID | ORX_PROFILE_VALID)) != (TX_PROFILE_VALID | ORX_PROFILE_VALID)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGDPD_TXORX_PROFILE_INV, + getMykonosErrorMessage(MYKONOS_ERR_CFGDPD_TXORX_PROFILE_INV)); + return MYKONOS_ERR_CFGDPD_TXORX_PROFILE_INV; + } + + if (device->tx->dpdConfig == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGDPD_NULL_DPDCFGSTRUCT, + getMykonosErrorMessage(MYKONOS_ERR_CFGDPD_NULL_DPDCFGSTRUCT)); + return MYKONOS_ERR_CFGDPD_NULL_DPDCFGSTRUCT; + } + + /* check DPD damping and samples parameters */ + if (device->tx->dpdConfig->damping > 15) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGDPD_INV_DPDDAMPING, + getMykonosErrorMessage(MYKONOS_ERR_CFGDPD_INV_DPDDAMPING)); + return MYKONOS_ERR_CFGDPD_INV_DPDDAMPING; + } + + if ((device->tx->dpdConfig->samples < 64) || (device->tx->dpdConfig->samples > 32768)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGDPD_INV_DPDSAMPLES, + getMykonosErrorMessage(MYKONOS_ERR_CFGDPD_INV_DPDSAMPLES)); + return MYKONOS_ERR_CFGDPD_INV_DPDSAMPLES; + } + + if (device->tx->dpdConfig->numWeights > 3) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGDPD_INV_NUMWEIGHTS, + getMykonosErrorMessage(MYKONOS_ERR_CFGDPD_INV_NUMWEIGHTS)); + return MYKONOS_ERR_CFGDPD_INV_NUMWEIGHTS; + } + + if (device->tx->dpdConfig->modelVersion > 3) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGDPD_INV_MODELVERSION, + getMykonosErrorMessage(MYKONOS_ERR_CFGDPD_INV_MODELVERSION)); + return MYKONOS_ERR_CFGDPD_INV_MODELVERSION; + } + + highPowerModelUpdate = (device->tx->dpdConfig->highPowerModelUpdate > 0) ? 1 : 0; + robustModeling = (device->tx->dpdConfig->robustModeling > 0) ? 1 : 0; + + armFieldValue[0] = (uint8_t)(((device->tx->dpdConfig->numWeights & 3) << 4) | (device->tx->dpdConfig->damping & 0xF)); + armFieldValue[1] = (uint8_t)((robustModeling << 3) | (highPowerModelUpdate << 2) | (device->tx->dpdConfig->modelVersion & 3)); + armFieldValue[2] = (device->tx->dpdConfig->samples & 0xFF); + armFieldValue[3] = ((device->tx->dpdConfig->samples >> 8) & 0xFF); + byteOffset = 0; + retVal = MYKONOS_writeArmConfig(device, MYKONOS_ARM_OBJECTID_DPDCONFIG, byteOffset, &armFieldValue[0], 4); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* set DPD outlier threshold parameter */ + if ((device->tx->dpdConfig->outlierThreshold < 1) || (device->tx->dpdConfig->outlierThreshold > 8192)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGDPD_INV_DPDOUTLIERTHRESH, + getMykonosErrorMessage(MYKONOS_ERR_CFGDPD_INV_DPDOUTLIERTHRESH)); + return MYKONOS_ERR_CFGDPD_INV_DPDOUTLIERTHRESH; + } + + armFieldValue[0] = (device->tx->dpdConfig->outlierThreshold & 0xFF); + armFieldValue[1] = ((device->tx->dpdConfig->outlierThreshold >> 8) & 0xFF); + byteOffset = 10; + retVal = MYKONOS_writeArmConfig(device, MYKONOS_ARM_OBJECTID_DPDCONFIG, byteOffset, &armFieldValue[0], 2); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* set DPD Model Prior Weight parameter */ + if (device->tx->dpdConfig->modelPriorWeight > 32) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGDPD_INV_DPDPRIORWEIGHT, + getMykonosErrorMessage(MYKONOS_ERR_CFGDPD_INV_DPDPRIORWEIGHT)); + return MYKONOS_ERR_CFGDPD_INV_DPDPRIORWEIGHT; + } + armFieldValue[0] = (device->tx->dpdConfig->modelPriorWeight & 0xFF); + armFieldValue[1] = 0; + byteOffset = 12; + retVal = MYKONOS_writeArmConfig(device, MYKONOS_ARM_OBJECTID_DPDCONFIG, byteOffset, &armFieldValue[0], 2); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* no need to verify weights min/max as all int8 values are valid */ + armFieldValue[0] = (uint8_t)(device->tx->dpdConfig->weights[0].real); + armFieldValue[1] = (uint8_t)(device->tx->dpdConfig->weights[0].imag); + armFieldValue[2] = (uint8_t)(device->tx->dpdConfig->weights[1].real); + armFieldValue[3] = (uint8_t)(device->tx->dpdConfig->weights[1].imag); + armFieldValue[4] = (uint8_t)(device->tx->dpdConfig->weights[2].real); + armFieldValue[5] = (uint8_t)(device->tx->dpdConfig->weights[2].imag); + + byteOffset = 14; + retVal = MYKONOS_writeArmConfig(device, MYKONOS_ARM_OBJECTID_DPDCONFIG, byteOffset, &armFieldValue[0], 6); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* set DPD additional delay offset parameter */ + if ((device->tx->dpdConfig->additionalDelayOffset < -64) || (device->tx->dpdConfig->additionalDelayOffset > 64)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGDPD_INV_DPD_ADDDELAY, + getMykonosErrorMessage(MYKONOS_ERR_CFGDPD_INV_DPD_ADDDELAY)); + return MYKONOS_ERR_CFGDPD_INV_DPD_ADDDELAY; + } + + /* read radio state to make sure ARM is in radioOff /IDLE */ + retVal = MYKONOS_getRadioState(device, &radioStatus); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* Radio state check */ + if (((radioStatus & 0x03) == MYKONOS_ARM_SYSTEMSTATE_IDLE) || ((radioStatus & 0x03) == MYKONOS_ARM_SYSTEMSTATE_READY)) + { + armFieldValue[0] = (uint8_t)(device->tx->dpdConfig->additionalDelayOffset & 0xFF); + armFieldValue[1] = (uint8_t)(((uint16_t)device->tx->dpdConfig->additionalDelayOffset >> 8) & 0xFF); + byteOffset = 2; + retVal = MYKONOS_writeArmConfig(device, MYKONOS_ARM_OBJECTID_DPDINIT_CONFIG, byteOffset, &armFieldValue[0], 2); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + if ((device->tx->dpdConfig->pathDelayPnSeqLevel < 1) || (device->tx->dpdConfig->pathDelayPnSeqLevel > 8191)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGDPD_INV_PNSEQLEVEL, + getMykonosErrorMessage(MYKONOS_ERR_CFGDPD_INV_PNSEQLEVEL)); + return MYKONOS_ERR_CFGDPD_INV_PNSEQLEVEL; + } + + /* Set Path Delay PN sequence amplitude - positive and negative */ + armFieldValue[0] = (uint8_t)(device->tx->dpdConfig->pathDelayPnSeqLevel & 0xFF); + armFieldValue[1] = (uint8_t)((device->tx->dpdConfig->pathDelayPnSeqLevel >> 8) & 0xFF); + + negPnLevel = ((~device->tx->dpdConfig->pathDelayPnSeqLevel) + 1); /* times -1 */ + armFieldValue[2] = (uint8_t)(negPnLevel & 0xFF); + armFieldValue[3] = (uint8_t)(((negPnLevel) >> 8) & 0xFF); + byteOffset = 10; + retVal = MYKONOS_writeArmConfig(device, MYKONOS_ARM_OBJECTID_DPDINIT_CONFIG, byteOffset, &armFieldValue[0], 4); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + } + else + { + /* record warning about not updated members */ + CMB_writeToLog(ADIHAL_LOG_WARNING, device->spiSettings->chipSelectIndex, MYKONOS_WRN_RADIO_ON_NOT_MODIFIABLE, + getMykonosErrorMessage(MYKONOS_WRN_RADIO_ON_NOT_MODIFIABLE)); + } + + return MYKONOS_ERR_OK; +} + +/* \brief Reads the DPD config structure from ARM memory + * + * This function reads the DPD structure + * from ARM memory and returns in the device->tx->dpdConfig structure. + * + * A DPD-enabled transceiver is required for DPD to be enabled. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - device->profilesValid + * - device->tx->dpdConfig (All members) + * + * \param device is structure pointer to the Mykonos data structure containing settings + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_GETDPDCFG_TXORX_PROFILE_INV Error: Tx and ORx profiles must be valid for DPD functions + * \retval MYKONOS_ERR_GETDPDCFG_NULL_DPDCFGSTRUCT Error: NULL pointer to device->tx->dpdConfig structure + */ +mykonosErr_t MYKONOS_getDpdConfig(mykonosDevice_t *device) +{ + uint16_t byteOffset = 0; + uint8_t armMem[20] = {0}; + mykonosErr_t retVal = MYKONOS_ERR_OK; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getDpdConfig()\n"); +#endif + + /* DPD requires Tx and ORx enabled, throw error if both are not enabled */ + if ((device->profilesValid & (TX_PROFILE_VALID | ORX_PROFILE_VALID)) != (TX_PROFILE_VALID | ORX_PROFILE_VALID)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETDPDCFG_TXORX_PROFILE_INV, + getMykonosErrorMessage(MYKONOS_ERR_GETDPDCFG_TXORX_PROFILE_INV)); + return MYKONOS_ERR_GETDPDCFG_TXORX_PROFILE_INV; + } + + if (device->tx->dpdConfig == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETDPDCFG_NULL_DPDCFGSTRUCT, + getMykonosErrorMessage(MYKONOS_ERR_GETDPDCFG_NULL_DPDCFGSTRUCT)); + return MYKONOS_ERR_GETDPDCFG_NULL_DPDCFGSTRUCT; + } + + byteOffset = 0; + retVal = MYKONOS_readArmConfig(device, MYKONOS_ARM_OBJECTID_DPDCONFIG, byteOffset, &armMem[0], 20); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + device->tx->dpdConfig->damping = (armMem[0] & 0x0F); + device->tx->dpdConfig->numWeights = ((armMem[0] >> 4) & 0x03); + + device->tx->dpdConfig->modelVersion = (armMem[1] & 0x03); + device->tx->dpdConfig->highPowerModelUpdate = ((armMem[1] >> 2) & 0x01); + device->tx->dpdConfig->robustModeling = 0; + device->tx->dpdConfig->samples = ((uint16_t)(armMem[3]) << 8) | (uint16_t)(armMem[2]); + + device->tx->dpdConfig->outlierThreshold = ((uint16_t)(armMem[11]) << 8) | (uint16_t)(armMem[10]); + device->tx->dpdConfig->modelPriorWeight = armMem[12]; + device->tx->dpdConfig->weights[0].real = (int8_t)(armMem[14]); + device->tx->dpdConfig->weights[0].imag = (int8_t)(armMem[15]); + device->tx->dpdConfig->weights[1].real = (int8_t)(armMem[16]); + device->tx->dpdConfig->weights[1].imag = (int8_t)(armMem[17]); + device->tx->dpdConfig->weights[2].real = (int8_t)(armMem[18]); + device->tx->dpdConfig->weights[2].imag = (int8_t)(armMem[19]); + + byteOffset = 2; + retVal = MYKONOS_readArmConfig(device, MYKONOS_ARM_OBJECTID_DPDINIT_CONFIG, byteOffset, &armMem[0], 2); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + device->tx->dpdConfig->additionalDelayOffset = (int16_t)(((uint16_t)(armMem[1]) << 8) | (uint16_t)(armMem[0])); + + byteOffset = 10; + retVal = MYKONOS_readArmConfig(device, MYKONOS_ARM_OBJECTID_DPDINIT_CONFIG, byteOffset, &armMem[0], 2); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + device->tx->dpdConfig->pathDelayPnSeqLevel = (((uint16_t)(armMem[1]) << 8) | (uint16_t)(armMem[0])); + + return MYKONOS_ERR_OK; +} + +/** + * \brief This function reads the DPD calibration status from the Mykonos ARM processor. + * + * The dpdStatus is read back from the ARM processor and returned in the function + * parameter dpdStatus. + * + * A DPD-enabled transceiver is required for this feature to be enabled. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is structure pointer to the Mykonos data structure containing settings + * \param txChannel Desired Transmit channel to read back DPD status for (Valid ENUM values: TX1 or TX2 only) + * \param dpdStatus Pointer to a structure to return the status information to + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_GETDPDSTATUS_NULLPARAM dpdStatus function parameter is a NULL pointer + * \retval MYKONOS_ERR_GETDPDSTATUS_INV_CH txChannel parameter is a non-supported value. + * \retval MYKONOS_ERR_GETDPDSTATUS_ARMERRFLAG ARM reported an error while processing the GET ARM command + */ +mykonosErr_t MYKONOS_getDpdStatus(mykonosDevice_t *device, mykonosTxChannels_t txChannel, mykonosDpdStatus_t *dpdStatus) +{ + uint8_t extData[3] = {MYKONOS_ARM_OBJECTID_CAL_STATUS, MYKONOS_ARM_OBJECTID_DPDCONFIG, 0}; + uint8_t armData[64] = {0}; + uint32_t timeoutMs = 0; + uint8_t cmdStatusByte = 0; + uint8_t channelSelect = 0; + mykonosErr_t retVal = MYKONOS_ERR_OK; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getDpdStatus()\n"); +#endif + + if (dpdStatus == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETDPDSTATUS_NULLPARAM, + getMykonosErrorMessage(MYKONOS_ERR_GETDPDSTATUS_NULLPARAM)); + return MYKONOS_ERR_GETDPDSTATUS_NULLPARAM; + } + + switch (txChannel) + { + case TX1: + channelSelect = 0; + break; + case TX2: + channelSelect = 1; + break; + default: + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETDPDSTATUS_INV_CH, + getMykonosErrorMessage(MYKONOS_ERR_GETDPDSTATUS_INV_CH)); + return MYKONOS_ERR_GETDPDSTATUS_INV_CH; + } + } + + extData[2] = channelSelect; + + retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_GET_OPCODE, &extData[0], sizeof(extData)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + timeoutMs = 1000; + retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_GET_OPCODE, timeoutMs, &cmdStatusByte); + if (retVal != MYKONOS_ERR_OK) + { + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETDPDSTATUS_ARMERRFLAG, + getMykonosErrorMessage(MYKONOS_ERR_GETDPDSTATUS_ARMERRFLAG)); + return MYKONOS_ERR_GETDPDSTATUS_ARMERRFLAG; + } + + return retVal; + } + + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETDPDSTATUS_ARMERRFLAG, + getMykonosErrorMessage(MYKONOS_ERR_GETDPDSTATUS_ARMERRFLAG)); + return MYKONOS_ERR_GETDPDSTATUS_ARMERRFLAG; + } + + /* read status from ARM memory */ + retVal = MYKONOS_readArmMem(device, MYKONOS_ADDR_ARM_START_DATA_ADDR, &armData[0], sizeof(armData), 1); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + dpdStatus->dpdErrorStatus = ((uint32_t)(armData[1]) << 8) | (uint32_t)(armData[0]); /* Only lower 16 bits */ + dpdStatus->dpdTrackCount = ((uint32_t)(armData[11]) << 24) | ((uint32_t)(armData[10]) << 16) | ((uint32_t)(armData[9]) << 8) | (uint32_t)(armData[8]); + dpdStatus->dpdModelErrorPercent = ((uint32_t)(armData[15]) << 24) | ((uint32_t)(armData[14]) << 16) | ((uint32_t)(armData[13]) << 8) | (uint32_t)(armData[12]); + dpdStatus->dpdExtPathDelay = ((uint32_t)(armData[26]) * 16) + (uint32_t)(armData[24]); + dpdStatus->dpdMaxAdaptationCurrent = ((uint16_t)(armData[41]) << 8) + (uint16_t)(armData[40]); + dpdStatus->dpdMaxAdaptation = ((uint16_t)(armData[43]) << 8) + (uint16_t)(armData[42]); + dpdStatus->dpdIterCount = ((uint32_t)(armData[47]) << 24) | ((uint32_t)(armData[46]) << 16) | ((uint32_t)(armData[45]) << 8) | (uint32_t)(armData[44]); + + return MYKONOS_ERR_OK; +} + +/** + * \brief This private helper function called during RadioOff, will allow DPD tracking to be scheduled + * by the ARM when back in the RadioOn state. + * + * This function sets a flag in the ARM memory that if the enableDpd tracking cal mask + * and this setting are both set, then the ARM will schedule DPD tracking to occur + * in the radioOn ARM state. + * + * A DPD-enabled transceiver is required for DPD to be enabled. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - device->tx->dpdConfig + * + * \param device is structure pointer to the Mykonos data structure containing settings + * \param tx1Enable 0=disable DPD Tx1 tracking, 1= enable DPD Tx1 tracking + * \param tx2Enable 0=disable DPD Tx2 tracking, 1= enable DPD Tx2 tracking + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_EN_DPDTRACKING_ARMSTATE_ERROR ARM is not in the RadioOff state, call MYKONOS_radioOff() + */ +static mykonosErr_t enableDpdTracking(mykonosDevice_t *device, uint8_t tx1Enable, uint8_t tx2Enable) +{ + uint32_t radioStatus = 0; + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint8_t enableBit[4] = {0}; + uint8_t byteOffset = 20; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_enableDpdTracking()\n"); +#endif + + /* read radio state to make sure ARM is in radioOff /IDLE */ + retVal = MYKONOS_getRadioState(device, &radioStatus); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* throw error if not in radioOff/IDLE state */ + if (((radioStatus & 0x03) != MYKONOS_ARM_SYSTEMSTATE_IDLE) && ((radioStatus & 0x03) != MYKONOS_ARM_SYSTEMSTATE_READY)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_EN_DPDTRACKING_ARMSTATE_ERROR, + getMykonosErrorMessage(MYKONOS_ERR_EN_DPDTRACKING_ARMSTATE_ERROR)); + return MYKONOS_ERR_EN_DPDTRACKING_ARMSTATE_ERROR; + } + + enableBit[0] = (tx1Enable > 0) ? 1 : 0; + enableBit[1] = 0; + enableBit[2] = (tx2Enable > 0) ? 1 : 0; + enableBit[3] = 0; + + retVal = MYKONOS_writeArmConfig(device, MYKONOS_ARM_OBJECTID_DPDCONFIG, byteOffset, &enableBit[0], 4); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief This function will allow loading of the DPD model file. + * + * This function writes a copy of the user's DPD model to ARM memory and instructs the ARM to install that DPD model + * into hardware. Note that initializing the device will over write DPD model data. Note that the DPD model being + * restored must match the PA for which it is configured. Restoring a DPD model to a different PA than for which it + * is configured will not yield the desired performance. The user is responsible to insure the DPD model matches the + * PA configuration. + * + * \param device Structure pointer to the Mykonos data structure containing settings + * \param txChannel Desired transmit channel to which to write the DPD model file (Valid ENUM type mykonosTxChannels_t: TX1 or TX2 or TX1_TX2) + * \param modelDataBuffer Pointer to the user buffer containing the history/model data to be loaded to a txChannel + * Valid sizes: 182 bytes for a single model load to either TX1 or TX2. + * 364 bytes for a dual model load to both TX1_TX2, where the TX1 model data will occupy the first 182 bytes + * and TX2 model data will occupy the second 182 bytes. + * \param modelNumberBytes Total buffer size of the user history/model data buffer. Allowed sizes are 182 bytes for TX1 or TX2 and + * 364 bytes for TX1_TX2. + * + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_RESTDPDMOD_WRONGBUFFERSIZE User suppled modelNumberBytes size is incorrect. TX1 or TX2 = 182, TX1_TX2 = 364 + * \retval MYKONOS_ERR_RESTDPDMOD_INVALID_TXCHANNEL User supplied txChannel does not match TX1 or TX2 or TX1_TX2 + * \retval MYKONOS_ERR_RESTDPDMOD_ARMERRFLAG ARM returned error for Set ARM Command + */ +mykonosErr_t MYKONOS_restoreDpdModel(mykonosDevice_t *device, mykonosTxChannels_t txChannel, uint8_t *modelDataBuffer, uint32_t modelNumberBytes) +{ + uint32_t radioStatus = 0; + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint8_t armData[4] = {0}; + uint32_t armBufferAddr = 0; + uint8_t *bufferPtr = 0; + uint8_t extendedData[4] = {0}; + uint8_t cmdStatusByte = 0; + + const uint8_t RESTORE = 0x08; + const uint32_t timeoutMs = 1000; + const uint32_t MODEL_SIZE = 182; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_restoreDpdModel()\n"); +#endif + + /* read radio state to make sure ARM is in radioOff /IDLE */ + retVal = MYKONOS_getRadioState(device, &radioStatus); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + if (txChannel == TX1) + { + /* check for single valid provided buffer size */ + if (modelNumberBytes != MODEL_SIZE) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RESTDPDMOD_WRONGBUFFERSIZE, + getMykonosErrorMessage(MYKONOS_ERR_RESTDPDMOD_WRONGBUFFERSIZE)); + return MYKONOS_ERR_RESTDPDMOD_WRONGBUFFERSIZE; + } + + /* retrieve the arm TX1 model buffer address */ + retVal = MYKONOS_readArmMem(device, (MYKONOS_ADDR_ARM_START_PROG_ADDR + MYKONOS_ADDR_TX1_DPD_MODEL_INDIRECT_PTR), &armData[0], 4, 1); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + armBufferAddr = (((uint32_t)armData[0]) | (((uint32_t)armData[1]) << 8) | (((uint32_t)armData[2]) << 16) | (((uint32_t)armData[3]) << 24)); + + /* write the TX1 model */ + bufferPtr = modelDataBuffer; + retVal = MYKONOS_writeArmMem(device, armBufferAddr, bufferPtr, MODEL_SIZE); /* write TX1 model */ + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + }/*end TX1 */ + + else if (txChannel == TX2) + { + /* check for single valid provided buffer size */ + if (modelNumberBytes != MODEL_SIZE) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RESTDPDMOD_WRONGBUFFERSIZE, + getMykonosErrorMessage(MYKONOS_ERR_RESTDPDMOD_WRONGBUFFERSIZE)); + return MYKONOS_ERR_RESTDPDMOD_WRONGBUFFERSIZE; + } + + /* retrieve the arm TX2 model buffer address */ + retVal = MYKONOS_readArmMem(device, (MYKONOS_ADDR_ARM_START_PROG_ADDR + MYKONOS_ADDR_TX2_DPD_MODEL_INDIRECT_PTR), &armData[0], 4, 1); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + armBufferAddr = (((uint32_t)armData[0]) | (((uint32_t)armData[1]) << 8) | (((uint32_t)armData[2]) << 16) | (((uint32_t)armData[3]) << 24)); + + /* write the TX2 model */ + bufferPtr = modelDataBuffer; + retVal = MYKONOS_writeArmMem(device, armBufferAddr, bufferPtr, MODEL_SIZE); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + }/* end TX2 */ + + /* check for dual txChannel type */ + else if (txChannel == TX1_TX2) + { + /* check for single valid provided buffer size */ + if (modelNumberBytes != (2 * MODEL_SIZE)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RESTDPDMOD_WRONGBUFFERSIZE, + getMykonosErrorMessage(MYKONOS_ERR_RESTDPDMOD_WRONGBUFFERSIZE)); + return MYKONOS_ERR_RESTDPDMOD_WRONGBUFFERSIZE; + } + + /* retrieve the arm TX1 model buffer address */ + retVal = MYKONOS_readArmMem(device, (MYKONOS_ADDR_ARM_START_PROG_ADDR + MYKONOS_ADDR_TX1_DPD_MODEL_INDIRECT_PTR), &armData[0], 4, 1); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + armBufferAddr = (((uint32_t)armData[0]) | (((uint32_t)armData[1]) << 8) | (((uint32_t)armData[2]) << 16) | (((uint32_t)armData[3]) << 24)); + + /* write the TX1 model */ + bufferPtr = modelDataBuffer; + retVal = MYKONOS_writeArmMem(device, armBufferAddr, bufferPtr, MODEL_SIZE); /* write TX1 model */ + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + bufferPtr += MODEL_SIZE; + + /* retrieve the arm TX2 model buffer address */ + retVal = MYKONOS_readArmMem(device, (MYKONOS_ADDR_ARM_START_PROG_ADDR + MYKONOS_ADDR_TX2_DPD_MODEL_INDIRECT_PTR), &armData[0], 4, 1); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + armBufferAddr = (((uint32_t)armData[0]) | (((uint32_t)armData[1]) << 8) | (((uint32_t)armData[2]) << 16) | (((uint32_t)armData[3]) << 24)); + + /* write the TX2 model */ + retVal = MYKONOS_writeArmMem(device, armBufferAddr, bufferPtr, MODEL_SIZE); /* write TX2 model */ + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + }/*end two txChannel model data load */ + + /* invalid txChannel for this API command */ + else + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RESTDPDMOD_INVALID_TXCHANNEL, + getMykonosErrorMessage(MYKONOS_ERR_RESTDPDMOD_INVALID_TXCHANNEL)); + return MYKONOS_ERR_RESTDPDMOD_INVALID_TXCHANNEL; + }/* end invalid txChannel check */ + + /* instruct ARM to load DPD Model */ + extendedData[0] = MYKONOS_ARM_OBJECTID_GS_TRACKCALS; + extendedData[1] = MYKONOS_ARM_DPD_RESET; + extendedData[2] = (uint8_t)txChannel + RESTORE; + + retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_SET_OPCODE, &extendedData[0], sizeof(extendedData)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* wait max of 1sec for command to complete */ + retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_SET_OPCODE, timeoutMs, &cmdStatusByte); + if (retVal != MYKONOS_ERR_OK) + { + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RESTDPDMOD_ARMERRFLAG, + getMykonosErrorMessage(MYKONOS_ERR_RESTDPDMOD_ARMERRFLAG)); + return MYKONOS_ERR_RESTDPDMOD_ARMERRFLAG; + } + return retVal; + } + + return MYKONOS_ERR_OK; +} + + +/** + * \brief This function called during RadioOff, will allow retrieval of the DPD model file. + * + * This function reads a copy of the DPD model from ARM memory to user memory specified by the modelDataBuffer pointer. + * The user must provide the correct buffer size with the modelNumberBytes argument. + * + * \param device is structure pointer to the Mykonos data structure containing settings + * \param txChannel Desired Transmit channel to read back DPD status for (Valid ENUM type mykonosTxChannels_t: TX1 or TX2 or TX1_TX2) + * \param modelDataBuffer a pointer to the user buffer where the model data is to be written. + * Valid sizes: 182 bytes for a single model load to either TX1 or TX2. + * 364 bytes for a dual model load to both TX1_TX2, where the TX1 model data will occupy the first 182 bytes + * and TX2 model data will occupy the second 182 bytes. + * \param modelNumberBytes is the total buffer size of the user model data buffer. Allowed sizes are 182 bytes for TX1 or TX2 and + * 364 bytes for TX1_TX2. + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_SAVEDPDMODEL_ARMSTATE_ERROR ARM is not in the RadioOff state, call MYKONOS_radioOff() + * \retval MYKONOS_ERR_SAVEDPDMODEL_BUFFERSIZE_ERROR suppled modelNumberBytes size is incorrect. TX1 or TX2 = 182, TX1_TX2 = 364 + * \retval MYKONOS_ERR_SAVEDPDMODEL_INVALID_TXCHANNEL_ERROR supplied txChannel does not match TX1 or TX2 or TX1_TX2 + */ +mykonosErr_t MYKONOS_saveDpdModel(mykonosDevice_t *device, mykonosTxChannels_t txChannel, uint8_t *modelDataBuffer, uint32_t modelNumberBytes) +{ + uint32_t radioStatus = 0; + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint16_t modelSize = 0; + uint8_t armData[4] = {0}; + uint32_t armBufferAddr = 0; + + const uint32_t MODEL_SIZE = 182; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_saveDpdModel()\n"); +#endif + + /* read radio state to make sure ARM is in radioOff /IDLE */ + retVal = MYKONOS_getRadioState(device, &radioStatus); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* throw error if not in radioOff/IDLE state */ + if (((radioStatus & 0x03) != MYKONOS_ARM_SYSTEMSTATE_IDLE) && ((radioStatus & 0x03) != MYKONOS_ARM_SYSTEMSTATE_READY)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SAVDPDMOD_ARMSTATE, getMykonosErrorMessage(MYKONOS_ERR_SAVDPDMOD_ARMSTATE)); /* radio not off or initialized */ + return MYKONOS_ERR_SAVDPDMOD_ARMSTATE; + } + + if (txChannel == TX1) + { + /* check for single valid provided buffer size */ + if (modelNumberBytes != MODEL_SIZE) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SAVDPDMOD_WRONGBUFFERSIZE, + getMykonosErrorMessage(MYKONOS_ERR_SAVDPDMOD_WRONGBUFFERSIZE)); + return MYKONOS_ERR_SAVDPDMOD_WRONGBUFFERSIZE; /* wrong buffer size */ + } + + /* retrieve the arm TX1 model buffer address */ + retVal = MYKONOS_readArmMem(device, MYKONOS_ADDR_ARM_START_PROG_ADDR + MYKONOS_ADDR_TX1_DPD_MODEL_WORKING_PTR, &armData[0], 4, 1); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + armBufferAddr = (((uint32_t)armData[0]) | (((uint32_t)armData[1]) << 8) | (((uint32_t)armData[2]) << 16) | (((uint32_t)armData[3]) << 24)); + + /* read the TX1 model */ + retVal = MYKONOS_readArmMem(device, armBufferAddr, modelDataBuffer, MODEL_SIZE, 1); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + modelDataBuffer += modelSize; + }/*end TX1 */ + + else if (txChannel == TX2) + { + /* check for single valid provided buffer size */ + if (modelNumberBytes != MODEL_SIZE) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SAVDPDMOD_WRONGBUFFERSIZE, + getMykonosErrorMessage(MYKONOS_ERR_SAVDPDMOD_WRONGBUFFERSIZE)); + return MYKONOS_ERR_SAVDPDMOD_WRONGBUFFERSIZE; /* wrong buffer size */ + } + + /* retrieve the arm TX2 model buffer address */ + retVal = MYKONOS_readArmMem(device, MYKONOS_ADDR_ARM_START_PROG_ADDR + MYKONOS_ADDR_TX2_DPD_MODEL_WORKING_PTR, &armData[0], 4, 1); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + armBufferAddr = (((uint32_t)armData[0]) | (((uint32_t)armData[1]) << 8) | (((uint32_t)armData[2]) << 16) | (((uint32_t)armData[3]) << 24)); + + /* read the TX2 model */ + retVal = MYKONOS_readArmMem(device, armBufferAddr, modelDataBuffer, MODEL_SIZE, 1); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + }/*end TX2 */ + + /* check for dual txChannel type */ + else if (txChannel == TX1_TX2) + { + /* check for single valid provided buffer size */ + if (modelNumberBytes != (2 * MODEL_SIZE)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SAVDPDMOD_WRONGBUFFERSIZE, + getMykonosErrorMessage(MYKONOS_ERR_SAVDPDMOD_WRONGBUFFERSIZE)); + return MYKONOS_ERR_SAVDPDMOD_WRONGBUFFERSIZE; /* wrong buffer size */ + } + + /* retrieve the arm TX1 model buffer address */ + retVal = MYKONOS_readArmMem(device, MYKONOS_ADDR_ARM_START_PROG_ADDR + MYKONOS_ADDR_TX1_DPD_MODEL_WORKING_PTR, &armData[0], 4, 1); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + armBufferAddr = (((uint32_t)armData[0]) | (((uint32_t)armData[1]) << 8) | (((uint32_t)armData[2]) << 16) | (((uint32_t)armData[3]) << 24)); + + /* read the TX1 model */ + retVal = MYKONOS_readArmMem(device, armBufferAddr, modelDataBuffer, MODEL_SIZE, 1); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + modelDataBuffer += MODEL_SIZE; + + /* retrieve the arm TX2 model buffer address */ + retVal = MYKONOS_readArmMem(device, MYKONOS_ADDR_ARM_START_PROG_ADDR + MYKONOS_ADDR_TX2_DPD_MODEL_WORKING_PTR, &armData[0], 4, 1); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + armBufferAddr = (((uint32_t)armData[0]) | (((uint32_t)armData[1]) << 8) | (((uint32_t)armData[2]) << 16) | (((uint32_t)armData[3]) << 24)); + + /* read the TX2 model */ + retVal = MYKONOS_readArmMem(device, armBufferAddr, modelDataBuffer, MODEL_SIZE, 1); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + }/* end TX1_TX2 txChannel */ + + /* invalid txChannel for this API command */ + else + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SAVDPDMOD_INVALID_TXCHANNEL, + getMykonosErrorMessage(MYKONOS_ERR_SAVDPDMOD_INVALID_TXCHANNEL)); + return MYKONOS_ERR_SAVDPDMOD_INVALID_TXCHANNEL; /* invalid txChannel */ + }/* end invalid txChannel check */ + + return MYKONOS_ERR_OK; +} + +/** + * \brief This function sets the state of the DPD actuator. + * + * This function can be called in either Radio On or Off state. + * + * \pre A DPD-enabled transceiver is required for DPD to be enabled. DPD init cal has been run and DPD tracking enable. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is structure pointer to the Mykonos data structure containing settings + * \param txChannel Desired Transmit channel to set the Actuator State (Valid ENUM values: TX1, TX2 or TX1_TX2) + * \param actState Desired actuator state for the DPD, valid states are 0-disable and 1-enable + * + * \retval MYKONOS_ERR_SETDPDACT_INV_TXCHANNEL ERROR: Tx channel is not valid (Valid ENUM values: TX1, TX2 or TX1_TX2) + * \retval MYKONOS_ERR_SETDPDACT_INV_STATE ERROR: Invalid Actuator state, valid states are 0-disable and 1-enable. + * \retval MYKONOS_ERR_SETDPDACT_ARMERRFLAG ERROR: ARM command flag error set + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_setDpdActState(mykonosDevice_t *device, mykonosTxChannels_t txChannel, uint8_t actState) +{ + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint32_t timeoutMs = 1000; + uint8_t extData[3] = {0}; + uint8_t actuatorSet = 0x00; + uint8_t cmdStatusByte = 0; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setDpdActState()\n"); +#endif + + switch (txChannel) + { + case TX1: + break; + case TX2: + break; + case TX1_TX2: + break; + + default: + /* this function allow single channel gain only */ + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETDPDACT_INV_TXCHANNEL, + getMykonosErrorMessage(MYKONOS_ERR_SETDPDACT_INV_TXCHANNEL)); + return MYKONOS_ERR_SETDPDACT_INV_TXCHANNEL; + } + switch (actState) + { + case 0: + actuatorSet = DISABLE_DPD_ACTUATOR; + break; + case 1: + actuatorSet = ENABLE_DPD_ACTUATOR; + break; + + default: + /* this function allow single channel gain only */ + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETDPDACT_INV_STATE, + getMykonosErrorMessage(MYKONOS_ERR_SETDPDACT_INV_STATE)); + return MYKONOS_ERR_SETDPDACT_INV_STATE; + } + + extData[0] = MYKONOS_ARM_OBJECTID_TRACKING_CAL_CONTROL; + extData[1] = actuatorSet; + extData[2] = (uint8_t)txChannel; + + retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_SET_OPCODE, &extData[0], sizeof(extData)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* check for completion */ + retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_SET_OPCODE, timeoutMs, &cmdStatusByte); + if (retVal != MYKONOS_ERR_OK) + { + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETDPDACT_ARMERRFLAG, + getMykonosErrorMessage(MYKONOS_ERR_SETDPDACT_ARMERRFLAG)); + return MYKONOS_ERR_SETDPDACT_ARMERRFLAG; + } + + return retVal; + } + + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETDPDACT_ARMERRFLAG, + getMykonosErrorMessage(MYKONOS_ERR_SETDPDACT_ARMERRFLAG)); + return MYKONOS_ERR_SETDPDACT_ARMERRFLAG; + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief This function resets the DPD model. + * + * This function allows the user to reset the DPD actuator and prior model in radioOn or radioOff mode. + * The reset can restore prior model if the parameter passed is set to 2: this resets DPD first and then restores the previously loaded + * model into ARM memory for use with subsequent iterations of DPD. + * + * If reset is 1 then the reset function just reset the DPD actuator and not use any model. + * + * \pre A DPD-enabled transceiver is required for DPD to be enabled. DPD init cal has been run and DPD tracking enable. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is structure pointer to the Mykonos data structure containing settings + * \param txChannel Desired Transmit channel to be reseted (Valid ENUM values: TX1, TX2 or TX1_TX2) + * \param reset is the required reset condition that is needed, the available options are given by the enum + * ::mykonosDpdResetMode_t + * + * \retval MYKONOS_ERR_RESETDPD_INV_TXCHANNEL: Tx channel is not valid (Valid ENUM values: TX1, TX2 or TX1_TX2) + * \retval MYKONOS_ERR_RESETDPD_WRONG_PARAM ERROR: reset parameter is not valid (Valid values: MYK_DPD_RESET_FULL, MYK_DPD_RESET_PRIOR or MYK_DPD_RESET_CORRELATOR) + * \retval MYKONOS_ERR_RESETDPD_ARMERRFLAG ERROR: ARM command flag error set + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_resetDpd(mykonosDevice_t *device, mykonosTxChannels_t txChannel, mykonosDpdResetMode_t reset) +{ + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint32_t timeoutMs = 1000; + uint8_t extData[3] = {0}; + uint8_t cmdStatusByte = 0; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_resetDpd()\n"); +#endif + + switch (txChannel) + { + case TX1: + break; + case TX2: + break; + case TX1_TX2: + break; + + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RESETDPD_INV_TXCHANNEL, + getMykonosErrorMessage(MYKONOS_ERR_RESETDPD_INV_TXCHANNEL)); + return MYKONOS_ERR_RESETDPD_INV_TXCHANNEL; + } + + if ((reset >= MYK_DPD_RESET_END) || (reset == MYK_DPD_NO_ACTION)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RESETDPD_WRONG_PARAM, + getMykonosErrorMessage(MYKONOS_ERR_RESETDPD_WRONG_PARAM)); + return MYKONOS_ERR_RESETDPD_WRONG_PARAM; + } + + /* instruct ARM to reset DPD Model */ + extData[0] = MYKONOS_ARM_OBJECTID_GS_TRACKCALS; + extData[1] = MYKONOS_ARM_DPD_RESET; + extData[2] = (uint8_t)(reset << 2) + (uint8_t)txChannel; + + retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_SET_OPCODE, &extData[0], sizeof(extData)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* wait max of 1sec for command to complete */ + retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_SET_OPCODE, timeoutMs, &cmdStatusByte); + if (retVal != MYKONOS_ERR_OK) + { + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RESETDPD_ARMERRFLAG, + getMykonosErrorMessage(MYKONOS_ERR_RESETDPD_ARMERRFLAG)); + return MYKONOS_ERR_RESETDPD_ARMERRFLAG; + } + return retVal; + } + + return MYKONOS_ERR_OK; +} +/** + * \brief This function will configure CLGC settings + * + * A DPD-enabled transceiver is required for CLGC to be enabled. The CLGC has several user + * adjustable settings that can be configured before running the runInitCals + * with the calMask set for the CLGC init cal. Call this function with desired + * settings set before running the CLGC init cal or enabling CLGC tracking. + * + * This function can be called in either Radio On or Off state. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - device->profilesValid + * - device->tx->clgcConfig (All members) + * + * \retval MYKONOS_ERR_CFGCLGC_TXORX_PROFILE_INV ERROR: Tx and ObsRx profiles must be valid to use the CLGC feature + * \retval MYKONOS_ERR_CFGCLGC_NULL_CLGCCFGSTRUCT ERROR: CLGC config structure pointer is null in device->tx->clgcConfig + * \retval MYKONOS_ERR_CFGCLGC_INV_DESIREDGAIN ERROR: CLGC tx1DesiredGain or tx2DesiredGain parameter is out of range + * \retval MYKONOS_ERR_CFGCLGC_INV_TXATTENLIMIT ERROR: CLGC tx1AttenLimit or tx2AttenLimit parameter is out of range + * \retval MYKONOS_ERR_CFGCLGC_INV_CLGC_CTRLRATIO ERROR: clgcControlRatio parameter is out of range + * \retval MYKONOS_ERR_CFGCLGC_INV_THRESHOLD Error: tx1RelThreshold or tx2RelThreshold parameter is out of range + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_configClgc(mykonosDevice_t *device) +{ + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint8_t armFieldValue[4] = {0}; + uint8_t byteOffset = 0; + uint16_t negPnLevel = 0; + uint32_t radioStatus = 0x00; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_configClgc()\n"); +#endif + + /* CLGC requires Tx and ORx enabled, throw error if both are not enabled */ + if ((device->profilesValid & (TX_PROFILE_VALID | ORX_PROFILE_VALID)) != (TX_PROFILE_VALID | ORX_PROFILE_VALID)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGCLGC_TXORX_PROFILE_INV, + getMykonosErrorMessage(MYKONOS_ERR_CFGCLGC_TXORX_PROFILE_INV)); + return MYKONOS_ERR_CFGCLGC_TXORX_PROFILE_INV; + } + + if (device->tx->clgcConfig == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGCLGC_NULL_CLGCCFGSTRUCT, + getMykonosErrorMessage(MYKONOS_ERR_CFGCLGC_NULL_CLGCCFGSTRUCT)); + return MYKONOS_ERR_CFGCLGC_NULL_CLGCCFGSTRUCT; + } + + /* set CLGC desired gain parameter */ + if ((device->tx->clgcConfig->tx1DesiredGain < -10000) || (device->tx->clgcConfig->tx1DesiredGain > 10000) || (device->tx->clgcConfig->tx2DesiredGain < -10000) + || (device->tx->clgcConfig->tx2DesiredGain > 10000)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGCLGC_INV_DESIREDGAIN, + getMykonosErrorMessage(MYKONOS_ERR_CFGCLGC_INV_DESIREDGAIN)); + return MYKONOS_ERR_CFGCLGC_INV_DESIREDGAIN; + } + + armFieldValue[0] = (device->tx->clgcConfig->tx1DesiredGain & 0xFF); + armFieldValue[1] = (((uint16_t)device->tx->clgcConfig->tx1DesiredGain >> 8) & 0xFF); + armFieldValue[2] = (device->tx->clgcConfig->tx2DesiredGain & 0xFF); + armFieldValue[3] = (((uint16_t)device->tx->clgcConfig->tx2DesiredGain >> 8) & 0xFF); + + byteOffset = 0; + retVal = MYKONOS_writeArmConfig(device, MYKONOS_ARM_OBJECTID_CLGCCONFIG, byteOffset, &armFieldValue[0], sizeof(armFieldValue)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* set CLGC Tx Atten limit parameter */ + if ((device->tx->clgcConfig->tx1AttenLimit > 40) || (device->tx->clgcConfig->tx2AttenLimit > 40)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGCLGC_INV_TXATTENLIMIT, + getMykonosErrorMessage(MYKONOS_ERR_CFGCLGC_INV_TXATTENLIMIT)); + return MYKONOS_ERR_CFGCLGC_INV_TXATTENLIMIT; + } + + armFieldValue[0] = (device->tx->clgcConfig->tx1AttenLimit & 0xFF); + armFieldValue[1] = ((device->tx->clgcConfig->tx1AttenLimit >> 8) & 0xFF); + armFieldValue[2] = (device->tx->clgcConfig->tx2AttenLimit & 0xFF); + armFieldValue[3] = ((device->tx->clgcConfig->tx2AttenLimit >> 8) & 0xFF); + + byteOffset = 8; + retVal = MYKONOS_writeArmConfig(device, MYKONOS_ARM_OBJECTID_CLGCCONFIG, byteOffset, &armFieldValue[0], sizeof(armFieldValue)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* set CLGC Control Ratio parameter */ + if ((device->tx->clgcConfig->tx1ControlRatio < 1) || (device->tx->clgcConfig->tx1ControlRatio > 100) || (device->tx->clgcConfig->tx2ControlRatio < 1) + || (device->tx->clgcConfig->tx2ControlRatio > 100)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGCLGC_INV_CLGC_CTRLRATIO, + getMykonosErrorMessage(MYKONOS_ERR_CFGCLGC_INV_CLGC_CTRLRATIO)); + return MYKONOS_ERR_CFGCLGC_INV_CLGC_CTRLRATIO; + } + + armFieldValue[0] = (device->tx->clgcConfig->tx1ControlRatio & 0xFF); + armFieldValue[1] = ((device->tx->clgcConfig->tx1ControlRatio >> 8) & 0xFF); + armFieldValue[2] = (device->tx->clgcConfig->tx2ControlRatio & 0xFF); + armFieldValue[3] = ((device->tx->clgcConfig->tx2ControlRatio >> 8) & 0xFF); + + byteOffset = 12; + retVal = MYKONOS_writeArmConfig(device, MYKONOS_ARM_OBJECTID_CLGCCONFIG, byteOffset, &armFieldValue[0], sizeof(armFieldValue)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* set enable threshold for channel 1 */ + armFieldValue[0] = (device->tx->clgcConfig->tx1RelThresholdEn > 0) ? 1 : 0; + byteOffset = 0x24; + retVal = MYKONOS_writeArmConfig(device, MYKONOS_ARM_OBJECTID_CLGCCONFIG, byteOffset, &armFieldValue[0], 1); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* set enable threshold for channel 2 */ + armFieldValue[0] = (device->tx->clgcConfig->tx2RelThresholdEn > 0) ? 1 : 0; + byteOffset = 0x26; + retVal = MYKONOS_writeArmConfig(device, MYKONOS_ARM_OBJECTID_CLGCCONFIG, byteOffset, &armFieldValue[0], 1); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* set thresholds */ + if ((device->tx->clgcConfig->tx1RelThreshold > 10000) || (device->tx->clgcConfig->tx2RelThreshold > 10000)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGCLGC_INV_THRESHOLD, + getMykonosErrorMessage(MYKONOS_ERR_CFGCLGC_INV_THRESHOLD)); + return MYKONOS_ERR_CFGCLGC_INV_THRESHOLD; + } + + /* set threshold for channel 1 */ + armFieldValue[0] = (device->tx->clgcConfig->tx1RelThreshold & 0xFF); + armFieldValue[1] = ((device->tx->clgcConfig->tx1RelThreshold >> 8) & 0xFF); + byteOffset = 0x28; + retVal = MYKONOS_writeArmConfig(device, MYKONOS_ARM_OBJECTID_CLGCCONFIG, byteOffset, &armFieldValue[0], 2); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* set threshold for channel 2 */ + armFieldValue[0] = (device->tx->clgcConfig->tx2RelThreshold & 0xFF); + armFieldValue[1] = ((device->tx->clgcConfig->tx2RelThreshold >> 8) & 0xFF); + byteOffset = 0x2A; + retVal = MYKONOS_writeArmConfig(device, MYKONOS_ARM_OBJECTID_CLGCCONFIG, byteOffset, &armFieldValue[0], 2); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + if ((device->tx->clgcConfig->pathDelayPnSeqLevel < 1) || (device->tx->clgcConfig->pathDelayPnSeqLevel > 8191)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGCLGC_INV_PNSEQLEVEL, + getMykonosErrorMessage(MYKONOS_ERR_CFGCLGC_INV_PNSEQLEVEL)); + return MYKONOS_ERR_CFGCLGC_INV_PNSEQLEVEL; + } + + /* read radio state to make sure ARM is in radioOff /IDLE */ + retVal = MYKONOS_getRadioState(device, &radioStatus); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* Radio state check */ + if (((radioStatus & 0x03) == MYKONOS_ARM_SYSTEMSTATE_IDLE) || ((radioStatus & 0x03) == MYKONOS_ARM_SYSTEMSTATE_READY)) + { + /* set CLGC additional delay offset parameter (init cal)*/ + if ((device->tx->clgcConfig->additionalDelayOffset < -64) || (device->tx->clgcConfig->additionalDelayOffset > 64)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGCLGC_INV_CLGC_ADDDELAY, + getMykonosErrorMessage(MYKONOS_ERR_CFGCLGC_INV_CLGC_ADDDELAY)); + return MYKONOS_ERR_CFGCLGC_INV_CLGC_ADDDELAY; + } + + armFieldValue[0] = (device->tx->clgcConfig->additionalDelayOffset & 0xFF); + armFieldValue[1] = (((uint16_t)device->tx->clgcConfig->additionalDelayOffset >> 8) & 0xFF); + byteOffset = 2; + retVal = MYKONOS_writeArmConfig(device, MYKONOS_ARM_OBJECTID_CLGCINIT_CONFIG, byteOffset, &armFieldValue[0], 2); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + if ((device->tx->clgcConfig->pathDelayPnSeqLevel < 1) || (device->tx->clgcConfig->pathDelayPnSeqLevel > 8191)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGCLGC_INV_PNSEQLEVEL, + getMykonosErrorMessage(MYKONOS_ERR_CFGCLGC_INV_PNSEQLEVEL)); + return MYKONOS_ERR_CFGCLGC_INV_PNSEQLEVEL; + } + + /* Can not be changed in radio on */ + /* Set Path Delay PN sequence amplitude - positive and negative (init cal)*/ + armFieldValue[0] = (device->tx->clgcConfig->pathDelayPnSeqLevel & 0xFF); + armFieldValue[1] = ((device->tx->clgcConfig->pathDelayPnSeqLevel >> 8) & 0xFF); + + negPnLevel = ((~device->tx->clgcConfig->pathDelayPnSeqLevel) + 1); /* times -1 */ + armFieldValue[2] = (negPnLevel & 0xFF); + armFieldValue[3] = (((negPnLevel) >> 8) & 0xFF); + byteOffset = 10; + retVal = MYKONOS_writeArmConfig(device, MYKONOS_ARM_OBJECTID_CLGCINIT_CONFIG, byteOffset, &armFieldValue[0], sizeof(armFieldValue)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + retVal = enableClgcTracking(device, ((device->tx->clgcConfig->allowTx1AttenUpdates > 0) ? 1 : 0), ((device->tx->clgcConfig->allowTx2AttenUpdates > 0) ? 1 : 0)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + } + else + { + /* record warning about not updated members */ + CMB_writeToLog(ADIHAL_LOG_WARNING, device->spiSettings->chipSelectIndex, MYKONOS_WRN_RADIO_ON_NOT_MODIFIABLE, + getMykonosErrorMessage(MYKONOS_WRN_RADIO_ON_NOT_MODIFIABLE)); + } + + return MYKONOS_ERR_OK; +} + +/* \brief Reads the CLGC config structure from ARM memory + * + * This function reads the Closed Loop Gain Control structure + * from ARM memory and returns in the device->tx->clgcConfig structure. + * + * A DPD-enabled transceiver is required for CLGC to be enabled. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - device->profilesValid + * - device->tx->clgcConfig (All members) + * + * \param device is structure pointer to the Mykonos data structure containing settings + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_GETCLGCCFG_TXORX_PROFILE_INV Error: Tx and ORx profiles must be valid for CLGC functions + * \retval MYKONOS_ERR_GETCLGCCFG_NULL_CFGSTRUCT Error: NULL pointer to device->tx->clgcConfig structure + */ +mykonosErr_t MYKONOS_getClgcConfig(mykonosDevice_t *device) +{ + uint16_t byteOffset = 0; + uint8_t armMem[16] = {0}; + mykonosErr_t retVal = MYKONOS_ERR_OK; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getClgcConfig()\n"); +#endif + + /* CLGC requires Tx and ORx enabled, throw error if both are not enabled */ + if ((device->profilesValid & (TX_PROFILE_VALID | ORX_PROFILE_VALID)) != (TX_PROFILE_VALID | ORX_PROFILE_VALID)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETCLGCCFG_TXORX_PROFILE_INV, + getMykonosErrorMessage(MYKONOS_ERR_GETCLGCCFG_TXORX_PROFILE_INV)); + return MYKONOS_ERR_GETCLGCCFG_TXORX_PROFILE_INV; + } + + if (device->tx->clgcConfig == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETCLGCCFG_NULL_CFGSTRUCT, + getMykonosErrorMessage(MYKONOS_ERR_GETCLGCCFG_NULL_CFGSTRUCT)); + return MYKONOS_ERR_GETCLGCCFG_NULL_CFGSTRUCT; + } + + byteOffset = 0; + retVal = MYKONOS_readArmConfig(device, MYKONOS_ARM_OBJECTID_CLGCCONFIG, byteOffset, &armMem[0], sizeof(armMem)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + device->tx->clgcConfig->tx1DesiredGain = (int16_t)(((uint16_t)(armMem[1]) << 8) | (uint16_t)(armMem[0])); + device->tx->clgcConfig->tx2DesiredGain = (int16_t)(((uint16_t)(armMem[3]) << 8) | (uint16_t)(armMem[2])); + device->tx->clgcConfig->tx1AttenLimit = (((uint16_t)(armMem[9]) << 8) | (uint16_t)(armMem[8])); + device->tx->clgcConfig->tx2AttenLimit = (((uint16_t)(armMem[11]) << 8) | (uint16_t)(armMem[10])); + device->tx->clgcConfig->tx1ControlRatio = (((uint16_t)(armMem[13]) << 8) | (uint16_t)(armMem[12])); + device->tx->clgcConfig->tx2ControlRatio = (((uint16_t)(armMem[15]) << 8) | (uint16_t)(armMem[14])); + + byteOffset = 2; + retVal = MYKONOS_readArmConfig(device, MYKONOS_ARM_OBJECTID_CLGCINIT_CONFIG, byteOffset, &armMem[0], 2); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + device->tx->clgcConfig->additionalDelayOffset = (int16_t)(((uint16_t)(armMem[1]) << 8) | (uint16_t)(armMem[0])); + + byteOffset = 10; + retVal = MYKONOS_readArmConfig(device, MYKONOS_ARM_OBJECTID_CLGCINIT_CONFIG, byteOffset, &armMem[0], 2); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + device->tx->clgcConfig->pathDelayPnSeqLevel = (((uint16_t)(armMem[1]) << 8) | (uint16_t)(armMem[0])); + + /* need to figure out if this are the right addresses */ + byteOffset = 0x24; + retVal = MYKONOS_readArmConfig(device, MYKONOS_ARM_OBJECTID_CLGCCONFIG, byteOffset, &armMem[0], 1); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + device->tx->clgcConfig->tx1RelThresholdEn = (uint8_t)armMem[0]; + + byteOffset = 0x26; + retVal = MYKONOS_readArmConfig(device, MYKONOS_ARM_OBJECTID_CLGCCONFIG, byteOffset, &armMem[0], 1); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + device->tx->clgcConfig->tx2RelThresholdEn = (uint8_t)armMem[0]; + + byteOffset = 0x28; + retVal = MYKONOS_readArmConfig(device, MYKONOS_ARM_OBJECTID_CLGCCONFIG, byteOffset, &armMem[0], 2); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + device->tx->clgcConfig->tx1RelThreshold = (((uint16_t)(armMem[1]) << 8) | (uint16_t)(armMem[0])); + + byteOffset = 0x2A; + retVal = MYKONOS_readArmConfig(device, MYKONOS_ARM_OBJECTID_CLGCCONFIG, byteOffset, &armMem[0], 2); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + device->tx->clgcConfig->tx2RelThreshold = (((uint16_t)(armMem[1]) << 8) | (uint16_t)(armMem[0])); + + return MYKONOS_ERR_OK; +} + +/** + * \brief This function reads the CLGC calibration status from the Mykonos ARM processor. + * + * The Closed Loop Gain Control Status is read back from the ARM processor and + * returned in the function parameter clgcStatus. + * + * A DPD-enabled transceiver is required for this feature to be enabled. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is structure pointer to the Mykonos data structure containing settings + * \param txChannel Desired Transmit channel to read back CLGC status for (Valid ENUM values: TX1 or TX2 only) + * \param clgcStatus Pointer to a structure to return the status information to + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_GETCLGCSTATUS_NULLPARAM clgcStatus function parameter is a NULL pointer + * \retval MYKONOS_ERR_GETCLGCSTATUS_INV_CH txChannel parameter is a non supported value. + * \retval MYKONOS_ERR_GETCLGCSTATUS_ARMERRFLAG ARM reported an error while processing the GET ARM command + */ +mykonosErr_t MYKONOS_getClgcStatus(mykonosDevice_t *device, mykonosTxChannels_t txChannel, mykonosClgcStatus_t *clgcStatus) +{ + uint8_t extData[3] = {MYKONOS_ARM_OBJECTID_CAL_STATUS, MYKONOS_ARM_OBJECTID_CLGCCONFIG, 0}; + uint8_t armData[52] = {0}; + uint32_t timeoutMs = 0; + uint8_t cmdStatusByte = 0; + uint32_t offset = 0; + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint8_t channelSelect = 0; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getClgcStatus()\n"); +#endif + + if (clgcStatus == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETCLGCSTATUS_NULLPARAM, + getMykonosErrorMessage(MYKONOS_ERR_GETCLGCSTATUS_NULLPARAM)); + return MYKONOS_ERR_GETCLGCSTATUS_NULLPARAM; + } + + switch (txChannel) + { + case TX1: + channelSelect = 0; + break; + case TX2: + channelSelect = 1; + break; + default: + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETCLGCSTATUS_INV_CH, + getMykonosErrorMessage(MYKONOS_ERR_GETCLGCSTATUS_INV_CH)); + return MYKONOS_ERR_GETCLGCSTATUS_INV_CH; + } + } + + extData[2] = channelSelect; + + retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_GET_OPCODE, &extData[0], sizeof(extData)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + timeoutMs = 1000; + retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_GET_OPCODE, timeoutMs, &cmdStatusByte); + if (retVal != MYKONOS_ERR_OK) + { + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETCLGCSTATUS_ARMERRFLAG, + getMykonosErrorMessage(MYKONOS_ERR_GETCLGCSTATUS_ARMERRFLAG)); + return MYKONOS_ERR_GETCLGCSTATUS_ARMERRFLAG; + } + + return retVal; + } + + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETCLGCSTATUS_ARMERRFLAG, + getMykonosErrorMessage(MYKONOS_ERR_GETCLGCSTATUS_ARMERRFLAG)); + return MYKONOS_ERR_GETCLGCSTATUS_ARMERRFLAG; + } + + /* read status from ARM memory */ + offset = 0; + retVal = MYKONOS_readArmMem(device, (MYKONOS_ADDR_ARM_START_DATA_ADDR + offset), &armData[0], sizeof(armData), 1); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + clgcStatus->errorStatus = ((uint32_t)(armData[3]) << 24) | ((uint32_t)(armData[2]) << 16) | ((uint32_t)(armData[1]) << 8) | (uint32_t)(armData[0]); + clgcStatus->desiredGain = (int32_t)(((uint32_t)(armData[23]) << 24) | ((uint32_t)(armData[22]) << 16) | ((uint32_t)(armData[21]) << 8) | (uint32_t)(armData[20])); + clgcStatus->currentGain = (int32_t)(((uint32_t)(armData[27]) << 24) | ((uint32_t)(armData[26]) << 16) | ((uint32_t)(armData[25]) << 8) | (uint32_t)(armData[24])); + clgcStatus->txGain = ((uint32_t)(armData[39]) << 24) | ((uint32_t)(armData[38]) << 16) | ((uint32_t)(armData[37]) << 8) | (uint32_t)(armData[36]); + clgcStatus->txRms = (int32_t)(((uint32_t)(armData[43]) << 24) | ((uint32_t)(armData[42]) << 16) | ((uint32_t)(armData[41]) << 8) | (uint32_t)(armData[40])); + clgcStatus->orxRms = (int32_t)(((uint32_t)(armData[47]) << 24) | ((uint32_t)(armData[46]) << 16) | ((uint32_t)(armData[45]) << 8) | (uint32_t)(armData[44])); + clgcStatus->trackCount = ((uint32_t)(armData[51]) << 24) | ((uint32_t)(armData[50]) << 16) | ((uint32_t)(armData[49]) << 8) | (uint32_t)(armData[48]); + + return retVal; +} + +/** + * \brief This private helper function called during RadioOff, will allow CLGC tracking to be scheduled + * by the ARM when back in the RadioOn state. + * + * This function sets a flag in the ARM memory that if the enableDpd tracking cal mask + * and this setting are both set, then the ARM will schedule closed loop gain control + * tracking to occur in the radioOn ARM state. + * + * A DPD-enabled transceiver is required for this feature to be enabled. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - device->tx->dpdConfig + * + * \param device is structure pointer to the Mykonos data structure containing settings + * \param tx1Enable 0=disable CLGC Tx1 tracking, 1= enable CLGC Tx1 tracking + * \param tx2Enable 0=disable CLGC Tx2 tracking, 1= enable CLGC Tx2 tracking + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_EN_CLGCTRACKING_ARMSTATE_ERROR ARM is not in the RadioOff state, call MYKONOS_radioOff() + */ +static mykonosErr_t enableClgcTracking(mykonosDevice_t *device, uint8_t tx1Enable, uint8_t tx2Enable) +{ + uint32_t radioStatus = 0; + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint8_t enableBit[4] = {0}; + uint8_t byteOffset = 4; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_enableClgcTracking()\n"); +#endif + + /* read radio state to make sure ARM is in radioOff /IDLE */ + retVal = MYKONOS_getRadioState(device, &radioStatus); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* throw error if not in radioOff/IDLE state */ + if (((radioStatus & 0x03) != MYKONOS_ARM_SYSTEMSTATE_IDLE) && ((radioStatus & 0x03) != MYKONOS_ARM_SYSTEMSTATE_READY)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_EN_CLGCTRACKING_ARMSTATE_ERROR, + getMykonosErrorMessage(MYKONOS_ERR_EN_CLGCTRACKING_ARMSTATE_ERROR)); + return MYKONOS_ERR_EN_CLGCTRACKING_ARMSTATE_ERROR; + } + + enableBit[0] = (tx1Enable > 0) ? 1 : 0; + enableBit[1] = 0; + enableBit[2] = (tx2Enable > 0) ? 1 : 0; + enableBit[3] = 0; + + retVal = MYKONOS_writeArmConfig(device, MYKONOS_ARM_OBJECTID_CLGCCONFIG, byteOffset, &enableBit[0], 4); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief This function updates the CLGC desired gain parameter. + * + * This function can be called in either Radio On or Off state. + * + * \pre A DPD-enabled transceiver is required for CLGC to be enabled. CLGC init cal has been run and CLGC tracking enable. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is structure pointer to the Mykonos data structure containing settings + * \param txChannel Desired Transmit channel to set the (Valid ENUM values: TX1 or TX2 only) + * \param gain Total gain and attenuation (dB * 100) for the selected channel txChannel + * + * \retval MYKONOS_ERR_SETCLGCGAIN_INV_TXCHANNEL ERROR: Tx channel is not valid (Valid ENUM values: TX1 or TX2 only) + * \retval MYKONOS_ERR_SETCLGCGAIN_TRACK_ARMERRFLAG ERROR: ARM command flag error set + * \retval MYKONOS_ERR_SETCLGCGAIN_INV_DESIREDGAIN ERROR: CLGC gain parameter is out of range, valid range is from -10000 to 10000. + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_setClgcGain(mykonosDevice_t *device, mykonosTxChannels_t txChannel, int16_t gain) +{ + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint32_t timeoutMs = 1000; + uint8_t extData[4] = {0}; + uint8_t clcgChannel = 0x00; + uint8_t cmdStatusByte = 0; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setClgcGain()\n"); +#endif + + /* Range check for desired gain parameter */ + if ((gain < -10000) || (gain > 10000)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETCLGCGAIN_INV_DESIREDGAIN, + getMykonosErrorMessage(MYKONOS_ERR_SETCLGCGAIN_INV_DESIREDGAIN)); + return MYKONOS_ERR_SETCLGCGAIN_INV_DESIREDGAIN; + } + + switch (txChannel) + { + case TX1: + clcgChannel = SET_CLGC_DESIRED_GAIN_1; + break; + case TX2: + clcgChannel = SET_CLGC_DESIRED_GAIN_2; + break; + + default: + /* this function allow single channel gain only */ + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETCLGCGAIN_INV_TXCHANNEL, + getMykonosErrorMessage(MYKONOS_ERR_SETCLGCGAIN_INV_TXCHANNEL)); + return MYKONOS_ERR_SETCLGCGAIN_INV_TXCHANNEL; + } + + extData[0] = MYKONOS_ARM_OBJECTID_TRACKING_CAL_CONTROL; + extData[1] = clcgChannel; + extData[2] = (gain & 0xFF); + extData[3] = (((uint16_t)gain >> 8) & 0xFF); + + retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_SET_OPCODE, &extData[0], sizeof(extData)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* check for completion */ + retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_SET_OPCODE, timeoutMs, &cmdStatusByte); + if (retVal != MYKONOS_ERR_OK) + { + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETCLGCGAIN_TRACK_ARMERRFLAG, + getMykonosErrorMessage(MYKONOS_ERR_SETCLGCGAIN_TRACK_ARMERRFLAG)); + return MYKONOS_ERR_SETCLGCGAIN_TRACK_ARMERRFLAG; + } + + return retVal; + } + + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETCLGCGAIN_TRACK_ARMERRFLAG, + getMykonosErrorMessage(MYKONOS_ERR_SETCLGCGAIN_TRACK_ARMERRFLAG)); + return MYKONOS_ERR_SETCLGCGAIN_TRACK_ARMERRFLAG; + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief This function, when called during RadioOff, will configure VSWR settings + * + * A DPD-enabled transceiver is required for VSWR to be enabled. The VSWR has several user + * adjustable settings that can be configured before running the runInitCals + * with the calMask set for the VSWR init cal. Call this function with desired + * settings set before running the VSWR init cal or enabling VSWR tracking. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - device->profilesValid + * - device->tx->vswrConfig (All members) + * + * \retval MYKONOS_ERR_CFGVSWR_TXORX_PROFILE_INV ERROR: Tx and ObsRx profiles must be valid to use the VSWR feature + * \retval MYKONOS_ERR_CFGVSWR_NULL_VSWRCFGSTRUCT ERROR: CLGC config structure pointer is null in device->tx->clgcConfig + * \retval MYKONOS_ERR_CFGVSWR_ARMSTATE_ERROR ERROR: ARM is not in the IDLE(radioOff) or Ready state. + */ +mykonosErr_t MYKONOS_configVswr(mykonosDevice_t *device) +{ + uint32_t radioStatus = 0; + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint8_t armFieldValue[16] = {0}; + uint8_t byteOffset = 0; + uint16_t negPnLevel = 0; + + const uint8_t ENABLE_VSWR = 1; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_configVswr()\n"); +#endif + + /* VSWR requires Tx and ORx enabled, throw error if both are not enabled */ + if ((device->profilesValid & (TX_PROFILE_VALID | ORX_PROFILE_VALID)) != (TX_PROFILE_VALID | ORX_PROFILE_VALID)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGVSWR_TXORX_PROFILE_INV, + getMykonosErrorMessage(MYKONOS_ERR_CFGVSWR_TXORX_PROFILE_INV)); + return MYKONOS_ERR_CFGVSWR_TXORX_PROFILE_INV; + } + + if (device->tx->vswrConfig == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGVSWR_NULL_VSWRCFGSTRUCT, + getMykonosErrorMessage(MYKONOS_ERR_CFGVSWR_NULL_VSWRCFGSTRUCT)); + return MYKONOS_ERR_CFGVSWR_NULL_VSWRCFGSTRUCT; + } + + /* read radio state to make sure ARM is in radioOff /IDLE */ + retVal = MYKONOS_getRadioState(device, &radioStatus); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* throw error if not in radioOff/IDLE state */ + if (((radioStatus & 0x03) != MYKONOS_ARM_SYSTEMSTATE_IDLE) && ((radioStatus & 0x03) != MYKONOS_ARM_SYSTEMSTATE_READY)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGVSWR_ARMSTATE_ERROR, + getMykonosErrorMessage(MYKONOS_ERR_CFGVSWR_ARMSTATE_ERROR)); + return MYKONOS_ERR_CFGVSWR_ARMSTATE_ERROR; + } + + /* range check valid 3p3 GPIO pin */ + if ((device->tx->vswrConfig->tx1VswrSwitchGpio3p3Pin > 11) || (device->tx->vswrConfig->tx2VswrSwitchGpio3p3Pin > 11)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGVSWR_INV_3P3GPIOPIN, + getMykonosErrorMessage(MYKONOS_ERR_CFGVSWR_INV_3P3GPIOPIN)); + return MYKONOS_ERR_CFGVSWR_INV_3P3GPIOPIN; + } + + armFieldValue[0] = ENABLE_VSWR; + armFieldValue[1] = 0; + armFieldValue[2] = ENABLE_VSWR; + armFieldValue[3] = 0; + armFieldValue[4] = (device->tx->vswrConfig->tx1VswrSwitchGpio3p3Pin & 0xFF); + armFieldValue[5] = 0; + armFieldValue[6] = (device->tx->vswrConfig->tx2VswrSwitchGpio3p3Pin & 0xFF); + armFieldValue[7] = 0; + armFieldValue[8] = (device->tx->vswrConfig->tx1VswrSwitchPolarity > 0) ? 1 : 0; + armFieldValue[9] = 0; + armFieldValue[10] = (device->tx->vswrConfig->tx2VswrSwitchPolarity > 0) ? 1 : 0; + armFieldValue[11] = 0; + armFieldValue[12] = device->tx->vswrConfig->tx1VswrSwitchDelay_us; /* support full 0 to 255 us range */ + armFieldValue[13] = 0; + armFieldValue[14] = device->tx->vswrConfig->tx2VswrSwitchDelay_us; /* support full 0 to 255 us range */ + armFieldValue[15] = 0; + byteOffset = 0; + retVal = MYKONOS_writeArmConfig(device, MYKONOS_ARM_OBJECTID_VSWRCONFIG, byteOffset, &armFieldValue[0], 16); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* set VSWR additional delay offset parameter (init cal)*/ + if ((device->tx->vswrConfig->additionalDelayOffset < -64) || (device->tx->vswrConfig->additionalDelayOffset > 64)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGVSWR_INV_VSWR_ADDDELAY, + getMykonosErrorMessage(MYKONOS_ERR_CFGVSWR_INV_VSWR_ADDDELAY)); + return MYKONOS_ERR_CFGVSWR_INV_VSWR_ADDDELAY; + } + + armFieldValue[0] = (device->tx->vswrConfig->additionalDelayOffset & 0xFF); + armFieldValue[1] = (((uint16_t)device->tx->vswrConfig->additionalDelayOffset >> 8) & 0xFF); + byteOffset = 2; + retVal = MYKONOS_writeArmConfig(device, MYKONOS_ARM_OBJECTID_VSWRINIT_CONFIG, byteOffset, &armFieldValue[0], 2); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + if ((device->tx->vswrConfig->pathDelayPnSeqLevel < 1) || (device->tx->vswrConfig->pathDelayPnSeqLevel > 8191)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGVSWR_INV_PNSEQLEVEL, + getMykonosErrorMessage(MYKONOS_ERR_CFGVSWR_INV_PNSEQLEVEL)); + return MYKONOS_ERR_CFGVSWR_INV_PNSEQLEVEL; + } + + /* Set Path Delay PN sequence amplitude - positive and negative (init cal)*/ + armFieldValue[0] = (device->tx->vswrConfig->pathDelayPnSeqLevel & 0xFF); + armFieldValue[1] = ((device->tx->vswrConfig->pathDelayPnSeqLevel >> 8) & 0xFF); + + negPnLevel = ((~device->tx->vswrConfig->pathDelayPnSeqLevel) + 1); /* times -1 */ + armFieldValue[2] = (negPnLevel & 0xFF); + armFieldValue[3] = (((negPnLevel) >> 8) & 0xFF); + byteOffset = 10; + + /* Set for Tx1 channel */ + retVal = MYKONOS_writeArmConfig(device, MYKONOS_ARM_OBJECTID_VSWRINIT_CONFIG, byteOffset, &armFieldValue[0], 4); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* Set for Tx2 channel */ + byteOffset = 30; + retVal = MYKONOS_writeArmConfig(device, MYKONOS_ARM_OBJECTID_VSWRINIT_CONFIG, byteOffset, &armFieldValue[0], 4); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + return MYKONOS_ERR_OK; +} + +/* \brief Reads the VSWR config structure from ARM memory + * + * This function reads the VSWR structure + * from ARM memory and returns in the device->tx->vswrConfig structure. + * + * A DPD-enabled transceiver is required for VSWR to be enabled. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - device->profilesValid + * - device->tx->vswrConfig (All members) + * + * \param device is structure pointer to the Mykonos data structure containing settings + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_GETVSWRCFG_TXORX_PROFILE_INV Error: Tx and ORx profiles must be valid for VSWR functions + * \retval MYKONOS_ERR_GETVSWRCFG_NULL_CFGSTRUCT Error: NULL pointer to device->tx->vswrConfig structure + */ +mykonosErr_t MYKONOS_getVswrConfig(mykonosDevice_t *device) +{ + uint16_t byteOffset = 0; + uint8_t armMem[12] = {0}; + mykonosErr_t retVal = MYKONOS_ERR_OK; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getVswrConfig()\n"); +#endif + + /* VSWR requires Tx and ORx enabled, throw error if both are not enabled */ + if ((device->profilesValid & (TX_PROFILE_VALID | ORX_PROFILE_VALID)) != (TX_PROFILE_VALID | ORX_PROFILE_VALID)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETVSWRCFG_TXORX_PROFILE_INV, + getMykonosErrorMessage(MYKONOS_ERR_GETVSWRCFG_TXORX_PROFILE_INV)); + return MYKONOS_ERR_GETVSWRCFG_TXORX_PROFILE_INV; + } + + if (device->tx->vswrConfig == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETVSWRCFG_NULL_CFGSTRUCT, + getMykonosErrorMessage(MYKONOS_ERR_GETVSWRCFG_NULL_CFGSTRUCT)); + return MYKONOS_ERR_GETVSWRCFG_NULL_CFGSTRUCT; + } + + byteOffset = 4; + retVal = MYKONOS_readArmConfig(device, MYKONOS_ARM_OBJECTID_VSWRCONFIG, byteOffset, &armMem[0], sizeof(armMem)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + device->tx->vswrConfig->tx1VswrSwitchGpio3p3Pin = armMem[0]; + device->tx->vswrConfig->tx2VswrSwitchGpio3p3Pin = armMem[2]; + device->tx->vswrConfig->tx1VswrSwitchPolarity = armMem[4]; + device->tx->vswrConfig->tx2VswrSwitchPolarity = armMem[6]; + device->tx->vswrConfig->tx1VswrSwitchDelay_us = armMem[8]; + device->tx->vswrConfig->tx2VswrSwitchDelay_us = armMem[10]; + + byteOffset = 2; + retVal = MYKONOS_readArmConfig(device, MYKONOS_ARM_OBJECTID_VSWRINIT_CONFIG, byteOffset, &armMem[0], 2); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + device->tx->vswrConfig->additionalDelayOffset = (int16_t)(((uint16_t)(armMem[1]) << 8) | (uint16_t)(armMem[0])); + + byteOffset = 10; + retVal = MYKONOS_readArmConfig(device, MYKONOS_ARM_OBJECTID_VSWRINIT_CONFIG, byteOffset, &armMem[0], 2); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + device->tx->vswrConfig->pathDelayPnSeqLevel = (((uint16_t)(armMem[1]) << 8) | (uint16_t)(armMem[0])); + + return MYKONOS_ERR_OK; +} + +/** + * \brief This function reads the VSWR calibration status from the Mykonos ARM processor. + * + * The VSWR Status is read back from the ARM processor and + * returned in the function parameter vswrStatus. + * + * A DPD-enabled transceiver is required for this feature to be enabled. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is structure pointer to the Mykonos data structure containing settings + * \param txChannel Desired Transmit channel to read back VSWR status for (Valid ENUM values: TX1 or TX2 only) + * \param vswrStatus Pointer to a structure to return the status information to + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_GETVSWRSTATUS_NULLPARAM vswrStatus function parameter is a NULL pointer + * \retval MYKONOS_ERR_GETVSWRSTATUS_INV_CH txChannel parameter is a non supported value. + * \retval MYKONOS_ERR_GETVSWRSTATUS_ARMERRFLAG ARM reported an error while processing the GET ARM command + */ +mykonosErr_t MYKONOS_getVswrStatus(mykonosDevice_t *device, mykonosTxChannels_t txChannel, mykonosVswrStatus_t *vswrStatus) +{ + uint8_t extData[3] = {MYKONOS_ARM_OBJECTID_CAL_STATUS, MYKONOS_ARM_OBJECTID_VSWRCONFIG, 0}; + uint8_t armData[64] = {0}; + uint32_t timeoutMs = 0; + uint8_t cmdStatusByte = 0; + uint32_t offset = 0; + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint8_t channelSelect = 0; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getVswrStatus()\n"); +#endif + + if (vswrStatus == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETVSWRSTATUS_NULLPARAM, + getMykonosErrorMessage(MYKONOS_ERR_GETVSWRSTATUS_NULLPARAM)); + return MYKONOS_ERR_GETVSWRSTATUS_NULLPARAM; + } + + switch (txChannel) + { + case TX1: + channelSelect = 0; + break; + case TX2: + channelSelect = 1; + break; + default: + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETVSWRSTATUS_INV_CH, + getMykonosErrorMessage(MYKONOS_ERR_GETVSWRSTATUS_INV_CH)); + return MYKONOS_ERR_GETVSWRSTATUS_INV_CH; + } + } + + extData[2] = channelSelect; + + retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_GET_OPCODE, &extData[0], sizeof(extData)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + timeoutMs = 1000; + retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_GET_OPCODE, timeoutMs, &cmdStatusByte); + if (retVal != MYKONOS_ERR_OK) + { + /* throw more specific error message instead of returning error code from waitArmCmdStatus */ + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETVSWRSTATUS_ARMERRFLAG, + getMykonosErrorMessage(MYKONOS_ERR_GETVSWRSTATUS_ARMERRFLAG)); + return MYKONOS_ERR_GETVSWRSTATUS_ARMERRFLAG; + } + + return retVal; + } + + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETVSWRSTATUS_ARMERRFLAG, + getMykonosErrorMessage(MYKONOS_ERR_GETVSWRSTATUS_ARMERRFLAG)); + return MYKONOS_ERR_GETVSWRSTATUS_ARMERRFLAG; + } + + /* read status from ARM memory */ + offset = 0; + retVal = MYKONOS_readArmMem(device, (MYKONOS_ADDR_ARM_START_DATA_ADDR + offset), &armData[0], sizeof(armData), 1); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + vswrStatus->errorStatus = ((uint32_t)(armData[3]) << 24) | ((uint32_t)(armData[2]) << 16) | ((uint32_t)(armData[1]) << 8) | (uint32_t)(armData[0]); + vswrStatus->forwardGainRms_dB = (int32_t)(((uint32_t)(armData[23]) << 24) | ((uint32_t)(armData[22]) << 16) | ((uint32_t)(armData[21]) << 8) | (uint32_t)(armData[20])); + vswrStatus->forwardGainReal = (int32_t)(((uint32_t)(armData[27]) << 24) | ((uint32_t)(armData[26]) << 16) | ((uint32_t)(armData[25]) << 8) | (uint32_t)(armData[24])); + vswrStatus->forwardGainImag = (int32_t)(((uint32_t)(armData[31]) << 24) | ((uint32_t)(armData[30]) << 16) | ((uint32_t)(armData[29]) << 8) | (uint32_t)(armData[28])); + vswrStatus->reflectedGainRms_dB = (int32_t)(((uint32_t)(armData[35]) << 24) | ((uint32_t)(armData[34]) << 16) | ((uint32_t)(armData[33]) << 8) | (uint32_t)(armData[32])); + vswrStatus->reflectedGainReal = (int32_t)(((uint32_t)(armData[39]) << 24) | ((uint32_t)(armData[38]) << 16) | ((uint32_t)(armData[37]) << 8) | (uint32_t)(armData[36])); + vswrStatus->reflectedGainImag = (int32_t)(((uint32_t)(armData[43]) << 24) | ((uint32_t)(armData[42]) << 16) | ((uint32_t)(armData[41]) << 8) | (uint32_t)(armData[40])); + vswrStatus->trackCount = ((uint32_t)(armData[63]) << 24) | ((uint32_t)(armData[62]) << 16) | ((uint32_t)(armData[61]) << 8) | (uint32_t)(armData[60]); + vswrStatus->vswr_forward_tx_rms = (int32_t)(((uint32_t)(armData[47]) << 24) | ((uint32_t)(armData[46]) << 16) | ((uint32_t)(armData[45]) << 8) | (uint32_t)(armData[44])); + vswrStatus->vswr_forward_orx_rms = (int32_t)(((uint32_t)(armData[51]) << 24) | ((uint32_t)(armData[50]) << 16) | ((uint32_t)(armData[49]) << 8) | (uint32_t)(armData[48])); + vswrStatus->vswr_reflection_tx_rms = (int32_t)(((uint32_t)(armData[55]) << 24) | ((uint32_t)(armData[54]) << 16) | ((uint32_t)(armData[53]) << 8) | (uint32_t)(armData[52])); + vswrStatus->vswr_reflection_orx_rms = (int32_t)(((uint32_t)(armData[59]) << 24) | ((uint32_t)(armData[58]) << 16) | ((uint32_t)(armData[57]) << 8) | (uint32_t)(armData[56])); + + return MYKONOS_ERR_OK; +} + +/** + * \brief Read from the Mykonos ARM program or data memory + * + * Valid memory addresses are: Program Memory (0x01000000 - 0x01017FFF), + * Data Memory (0x20000000 - 0x2000FFFF) + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - device->spiSettings + * + * \param device is structure pointer to the Mykonos data structure containing settings + * \param address The 32bit ARM address to read from. + * \param returnData Byte(uint8_t) array containing the data read from the ARM memory. + * \param bytesToRead Number of bytes in the returnData array. + * \param autoIncrement is boolean flag to enable or disable autoincrement of ARM register address + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_READARMMEM_INV_ADDR_PARM ARM memory address is out of range + * + */ +mykonosErr_t MYKONOS_readArmMem(mykonosDevice_t *device, uint32_t address, uint8_t *returnData, uint32_t bytesToRead, uint8_t autoIncrement) +{ + uint8_t dataMem; + uint32_t i; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_readArmMem()\n"); +#endif + + /* check that start and stop address are in valid range */ + if ((!(address >= MYKONOS_ADDR_ARM_START_PROG_ADDR && address <= MYKONOS_ADDR_ARM_END_PROG_ADDR)) + && !(address >= MYKONOS_ADDR_ARM_START_DATA_ADDR && address <= MYKONOS_ADDR_ARM_END_DATA_ADDR)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_READARMMEM_INV_ADDR_PARM, + getMykonosErrorMessage(MYKONOS_ERR_READARMMEM_INV_ADDR_PARM)); + return MYKONOS_ERR_READARMMEM_INV_ADDR_PARM; + } + + if ((!(((address + bytesToRead - 1) >= MYKONOS_ADDR_ARM_START_PROG_ADDR) && (address + bytesToRead - 1) <= MYKONOS_ADDR_ARM_END_PROG_ADDR)) + && (!(((address + bytesToRead - 1) >= MYKONOS_ADDR_ARM_START_DATA_ADDR) && (address + bytesToRead - 1) <= MYKONOS_ADDR_ARM_END_DATA_ADDR))) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_READARMMEM_INV_ADDR_PARM, + getMykonosErrorMessage(MYKONOS_ERR_READARMMEM_INV_ADDR_PARM)); + return MYKONOS_ERR_READARMMEM_INV_ADDR_PARM; + } + + if (address >= MYKONOS_ADDR_ARM_START_DATA_ADDR && address <= MYKONOS_ADDR_ARM_END_DATA_ADDR) + { + dataMem = 1; + } + else + { + dataMem = 0; + } + + /* NOT assuming auto increment bit is already set from MYKONOS_initARM function call */ + /* setting auto increment address bit if autoIncrement evaluates true */ + if (autoIncrement) + { + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_ARM_CTL_1, 0x01, 0x04, 2); + } + else + { + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_ARM_CTL_1, 0x00, 0x04, 2); + } + + /* setting up for ARM read */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_ARM_CTL_1, 0x01, 0x20, 5); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_ADDR_BYTE_0, (uint8_t)((address) >> 2)); /* write address[9:2] */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_ADDR_BYTE_1, (uint8_t)(address >> 10) | (uint8_t)(dataMem << 7)); /* write address[15:10] */ + + /* start read-back at correct byte offset */ + /* read data is located at SPI address 0xD04=data[7:0], 0xD05=data[15:8], 0xD06=data[23:16], 0xD07=data[31:24]. */ + /* with address auto increment set, after xD07 is read, the address will automatically increment */ + /* without address auto increment set, 0x4 must be added to the address for correct indexing */ + if (autoIncrement) + { + for (i = 0; i < bytesToRead; i++) + { + CMB_SPIReadByte(device->spiSettings, (MYKONOS_ADDR_ARM_DATA_BYTE_0 | (((address & 0x3) + i) % 4)), &returnData[i]); + } + } + else + { + for (i = 0; i < bytesToRead; i++) + { + CMB_SPIReadByte(device->spiSettings, (MYKONOS_ADDR_ARM_DATA_BYTE_0 | (((address & 0x3) + i) % 4)), &returnData[i]); + + if ((MYKONOS_ADDR_ARM_DATA_BYTE_0 | (((address & 0x3) + i) % 4)) == MYKONOS_ADDR_ARM_DATA_BYTE_3) + { + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_ADDR_BYTE_0, (uint8_t)(((address + 0x4) & 0x3FF) >> 2)); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_ADDR_BYTE_1, ((address + 0x4) & 0x1FC00U) >> 10 | (uint8_t)(dataMem << 7)); + } + } + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief Write to the Mykonos ARM program or data memory + * + * Valid memory addresses are: Program Memory (0x01000000 - 0x01017FFF), + * Data Memory (0x20000000 - 0x2000FFFF) + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - device->spiSettings + * + * \param device is structure pointer to the Mykonos data structure containing settings + * \param address The 32bit ARM address to write to. + * \param data Byte(uint8_t) array containing the data to write to the ARM memory. + * \param byteCount Number of bytes in the data array. + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_WRITEARMMEM_NULL_PARM Function parameter data has NULL pointer when byteCount is >0 + * \retval MYKONOS_ERR_WRITEARMMEM_INV_ADDR_PARM ARM memory address is out of range of valid ARM memory + */ +mykonosErr_t MYKONOS_writeArmMem(mykonosDevice_t *device, uint32_t address, uint8_t *data, uint32_t byteCount) +{ + /* write address, then data with auto increment enabled. */ + uint8_t dataMem; + uint32_t i; + +#if MYK_ENABLE_SPIWRITEARRAY == 1 + uint32_t addrIndex = 0; + uint32_t dataIndex = 0; + uint32_t spiBufferSize = MYK_SPIWRITEARRAY_BUFFERSIZE; + uint16_t addrArray[MYK_SPIWRITEARRAY_BUFFERSIZE] = {0}; +#endif + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_writeArmMem()\n"); +#endif + + if ((data == NULL) && (byteCount > 0)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_WRITEARMMEM_NULL_PARM, + getMykonosErrorMessage(MYKONOS_ERR_WRITEARMMEM_NULL_PARM)); + return MYKONOS_ERR_WRITEARMMEM_NULL_PARM; + } + + if ((!(address >= MYKONOS_ADDR_ARM_START_PROG_ADDR && address <= MYKONOS_ADDR_ARM_END_PROG_ADDR)) + && !(address >= MYKONOS_ADDR_ARM_START_DATA_ADDR && address <= MYKONOS_ADDR_ARM_END_DATA_ADDR)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_WRITEARMMEM_INV_ADDR_PARM, + getMykonosErrorMessage(MYKONOS_ERR_WRITEARMMEM_INV_ADDR_PARM)); + return MYKONOS_ERR_WRITEARMMEM_INV_ADDR_PARM; + } + + if ((!(((address + byteCount - 1) >= MYKONOS_ADDR_ARM_START_PROG_ADDR) && ((address + byteCount - 1) <= MYKONOS_ADDR_ARM_END_PROG_ADDR))) + && (!(((address + byteCount - 1) >= MYKONOS_ADDR_ARM_START_DATA_ADDR) && ((address + byteCount - 1) <= MYKONOS_ADDR_ARM_END_DATA_ADDR)))) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_WRITEARMMEM_INV_ADDR_PARM, + getMykonosErrorMessage(MYKONOS_ERR_WRITEARMMEM_INV_ADDR_PARM)); + return MYKONOS_ERR_WRITEARMMEM_INV_ADDR_PARM; + } + + if (address >= MYKONOS_ADDR_ARM_START_DATA_ADDR && address <= MYKONOS_ADDR_ARM_END_DATA_ADDR) + { + dataMem = 1; + } + else + { + dataMem = 0; + } + + /* set auto increment address bit */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_ARM_CTL_1, 0x01, 0x04, 2); + + /* writing the address */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_ARM_CTL_1, 0x00, 0x20, 5); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_ADDR_BYTE_0, (uint8_t)((address) >> 2)); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_ADDR_BYTE_1, (uint8_t)(address >> 10) | (uint8_t)(dataMem << 7)); + + /* start write at correct byte offset */ + /* write data is located at SPI address 0xD04=data[7:0], 0xD05=data[15:8], 0xD06=data[23:16], 0xD07=data[31:24] */ + /* with address auto increment set, after x407 is written, the address will automatically increment */ + +#if (MYK_ENABLE_SPIWRITEARRAY == 0) + + for (i = 0; i < byteCount; i++) + { + CMB_SPIWriteByte(device->spiSettings, (MYKONOS_ADDR_ARM_DATA_BYTE_0 | (((address & 0x3) + i) % 4)), data[i]); + } + +#elif (MYK_ENABLE_SPIWRITEARRAY == 1) + + addrIndex = 0; + dataIndex = 0; + for (i = 0; i < byteCount; i++) + { + addrArray[addrIndex++] = (MYKONOS_ADDR_ARM_DATA_BYTE_0 | (((address & 0x3) + i) % 4)); + + if (addrIndex == spiBufferSize) + { + CMB_SPIWriteBytes(device->spiSettings, &addrArray[0], &data[dataIndex], addrIndex); + dataIndex = dataIndex + addrIndex; + addrIndex = 0; + } + } + + if (addrIndex > 0) + { + CMB_SPIWriteBytes(device->spiSettings, &addrArray[0], &data[dataIndex], addrIndex); + } + +#endif + + return MYKONOS_ERR_OK; +} + +/** + * \brief Low level helper function used by Mykonos API to write the ARM memory config structures + * + * Normally this function should not be required to be used directly by the BBIC. This is a helper + * function used by other Mykonos API commands to write settings into the ARM memory. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - device->spiSettings + * + * \param device is structure pointer to the Mykonos data structure containing settings + * \param objectId ARM id of a particular structure or setting in ARM memory + * \param offset Byte offset from the start of the objectId's memory location in ARM memory + * \param data A byte array containing data to write to the ARM memory buffer. + * \param byteCount Number of bytes in the data array (Valid size = 1-255 bytes) + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_WRITEARMCFG_ARMERRFLAG ARM write config command failed with a nonzero error code + */ +mykonosErr_t MYKONOS_writeArmConfig(mykonosDevice_t *device, uint8_t objectId, uint16_t offset, uint8_t *data, uint8_t byteCount) +{ + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint8_t extendedData[4] = {0}; /* ARM Object id, byte offset LSB, offset MSB = 0, copy 2 bytes */ + uint32_t timeoutMs = 1000; + uint8_t cmdStatusByte = 0; + + retVal = MYKONOS_writeArmMem(device, MYKONOS_ADDR_ARM_START_DATA_ADDR, &data[0], byteCount); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + extendedData[0] = objectId; + extendedData[1] = (offset & 0xFF); + extendedData[2] = ((offset >> 8) & 0xFF); + extendedData[3] = byteCount; + retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_WRITECFG_OPCODE, &extendedData[0], sizeof(extendedData)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_WRITECFG_OPCODE, timeoutMs, &cmdStatusByte); + if (retVal != MYKONOS_ERR_OK) + { + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_WRITEARMCFG_ARMERRFLAG, + getMykonosErrorMessage(MYKONOS_ERR_WRITEARMCFG_ARMERRFLAG)); + return MYKONOS_ERR_WRITEARMCFG_ARMERRFLAG; + } + + return retVal; + } + + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_WRITEARMCFG_ARMERRFLAG, + getMykonosErrorMessage(MYKONOS_ERR_WRITEARMCFG_ARMERRFLAG)); + return MYKONOS_ERR_WRITEARMCFG_ARMERRFLAG; + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief Low level helper function used by Mykonos API to read the ARM memory config structures + * + * Normally this function should not be required to be used directly by the BBIC. This is a helper + * function used by other Mykonos API commands to read settings from the ARM memory. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - device->spiSettings + * + * \param device is structure pointer to the Mykonos data structure containing settings + * \param objectId ARM id of a particular structure or setting in ARM memory + * \param offset Byte offset from the start of the objectId's memory location in ARM memory + * \param data A byte array containing data to write to the ARM memory buffer. + * \param byteCount Number of bytes in the data array (Valid size = 1-255 bytes) + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_READARMCFG_ARMERRFLAG ARM read config command failed with a nonzero error code + */ +mykonosErr_t MYKONOS_readArmConfig(mykonosDevice_t *device, uint8_t objectId, uint16_t offset, uint8_t *data, uint8_t byteCount) +{ + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint8_t extendedData[4] = {0}; /* ARM Object id, byte offset LSB, offset MSB = 0, copy 2 bytes */ + uint32_t timeoutMs = 1000; + uint8_t cmdStatusByte = 0; + const uint8_t AUTO_INCREMENT = 1; + extendedData[0] = objectId; + extendedData[1] = (offset & 0xFF); + extendedData[2] = ((offset >> 8) & 0xFF); + extendedData[3] = byteCount; + + retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_READCFG_OPCODE, &extendedData[0], sizeof(extendedData)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_READCFG_OPCODE, timeoutMs, &cmdStatusByte); + if (retVal != MYKONOS_ERR_OK) + { + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_READARMCFG_ARMERRFLAG, + getMykonosErrorMessage(MYKONOS_ERR_READARMCFG_ARMERRFLAG)); + return MYKONOS_ERR_READARMCFG_ARMERRFLAG; + } + + return retVal; + } + + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_READARMCFG_ARMERRFLAG, + getMykonosErrorMessage(MYKONOS_ERR_READARMCFG_ARMERRFLAG)); + return MYKONOS_ERR_READARMCFG_ARMERRFLAG; + } + + retVal = MYKONOS_readArmMem(device, MYKONOS_ADDR_ARM_START_DATA_ADDR, &data[0], byteCount, AUTO_INCREMENT); + + return retVal; +} + +/** + * \brief Sends a command to the Mykonos ARM processor + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - device->spiSettings + * + * \param device is structure pointer to the Mykonos data structure containing settings + * \param opCode Value (0-30, even only) indicating the desired function to run in the ARM. + * \param extendedData A byte array containing extended data to write to the ARM command interface. + * \param extendedDataNumBytes Number of bytes in the extendedData array (Valid size = 0-4 bytes) + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_ARMCMD_NULL_PARM Function parameter extendedData is NULL and extendedDataNumBytes is positive + * \retval MYKONOS_ERR_ARMCMD_INV_OPCODE_PARM ARM opcode is out of range (valid 0-30, even only) + * \retval MYKONOS_ERR_ARMCMD_INV_NUMBYTES_PARM Number of extended bytes parameter is out of range (valid 0-4) + * \retval MYKONOS_ERR_TIMEDOUT_ARMMAILBOXBUSY ARM control interface is busy, command could not be executed by ARM + */ +mykonosErr_t MYKONOS_sendArmCommand(mykonosDevice_t *device, uint8_t opCode, uint8_t *extendedData, uint8_t extendedDataNumBytes) +{ + uint8_t armCommandBusy = 0; + uint8_t i = 0; + uint16_t extCmdByteStartAddr = MYKONOS_ADDR_ARM_EXT_CMD_BYTE_1; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_sendArmCommand()\n"); +#endif + + if ((extendedData == NULL) && (extendedDataNumBytes > 0)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_ARMCMD_NULL_PARM, getMykonosErrorMessage(MYKONOS_ERR_ARMCMD_NULL_PARM)); + return MYKONOS_ERR_ARMCMD_NULL_PARM; + } + + /* check for even-numbered opCodes only including opcode 0, but not must be greater than opCode 30 */ + if ((opCode != 0) && ((opCode % 2) || (opCode > 30))) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_ARMCMD_INV_OPCODE_PARM, + getMykonosErrorMessage(MYKONOS_ERR_ARMCMD_INV_OPCODE_PARM)); + return MYKONOS_ERR_ARMCMD_INV_OPCODE_PARM; + } + + /* the number of valid extended data bytes is from 0-4 */ + if (extendedDataNumBytes > 4) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_ARMCMD_INV_NUMBYTES_PARM, + getMykonosErrorMessage(MYKONOS_ERR_ARMCMD_INV_NUMBYTES_PARM)); + return MYKONOS_ERR_ARMCMD_INV_NUMBYTES_PARM; + } + + /* setting a 2 sec timeout for mailbox busy bit to be clear (can't send an arm mailbox command until mailbox is ready) */ + CMB_setTimeout_ms(2000); + + do + { + CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_ARM_CMD, &armCommandBusy, 0x80, 7); + + if (CMB_hasTimeoutExpired()) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_TIMEDOUT_ARMMAILBOXBUSY, + getMykonosErrorMessage(MYKONOS_ERR_TIMEDOUT_ARMMAILBOXBUSY)); + return MYKONOS_ERR_TIMEDOUT_ARMMAILBOXBUSY; + } + } while (armCommandBusy); + + if (extendedDataNumBytes) + { + for (i = 0; i < extendedDataNumBytes; i++) + { + CMB_SPIWriteByte(device->spiSettings, extCmdByteStartAddr + i, extendedData[i]); + } + } + + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_CMD, opCode); + + return MYKONOS_ERR_OK; +} + +/** + * \brief Reads the Mykonos ARM 64-bit command status register + * + * A 64-bit status register consisting of a pending bit and three-bit error type is read one byte at + * a time for opcodes 0-30. The function parses the pending bits and error bits into + * two (2) separate 16-bit words containing pending bits, and error bits if the error type > 0 + * The words are weighted according to each even-numbered opcode from 0-30, + * where, 0x0001 = opcode '0', 0x0002 = opcode '2', 0x0004 = opcode '4', 0x0008 = opcode '6' and so on. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is a pointer to the device settings structure + * \param errorWord 16-bit error word comprised of weighted bits according to each opcode number + * The weighted bit = '1' if error type > 0, '0' if OK + * \param statusWord 16-bit pending bits word comprised of weighted bits according to each opcode number + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_READARMCMDSTATUS_NULL_PARM Function parameters errorWord or statusWord have a NULL pointer + */ +mykonosErr_t MYKONOS_readArmCmdStatus(mykonosDevice_t *device, uint16_t *errorWord, uint16_t *statusWord) +{ + uint8_t i = 0; + uint8_t bytes[8] = {0}; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_readArmCmdStatus()\n"); +#endif + + if (errorWord == NULL || statusWord == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_READARMCMDSTATUS_NULL_PARM, + getMykonosErrorMessage(MYKONOS_ERR_READARMCMDSTATUS_NULL_PARM)); + return MYKONOS_ERR_READARMCMDSTATUS_NULL_PARM; + } + + /* making sure the errorWord and statusWord are clear */ + *errorWord = 0; + *statusWord = 0; + + /* read in the entire 64-bit status register into a byte array for parsing */ + for (i = 0; i < 8; i++) + { + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_ARM_CMD_STATUS_0 + i, &bytes[i]); + } + + /* parse the byte array for pending bits and error types and generate statusWord and errorWord bits */ + for (i = 0; i < 8; i++) + { + *statusWord |= (uint16_t)((uint16_t)(((bytes[i] & 0x10) >> 3) | (bytes[i] & 0x01)) << (i * 2)); + + if (bytes[i] & 0x0E) + { + *errorWord |= (uint16_t)(0x0001 << (i * 2)); + } + else if (bytes[i] & 0xE0) + { + *errorWord |= (uint16_t)(0x0002 << (i * 2)); + } + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief Isolated byte read of the Mykonos ARM 64-bit command status register based on the opcode + * + * A single byte read is performed on the 64-bit command status register according to + * the opcode of interest. The pending bit and the error type are extracted from the status + * register and returned as a single byte in the lower nibble. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is a pointer to the device settings structure + * \param opCode Valid values are even increments from 0-30. The ARM opCode is used to determine which status register byte to read + * \param cmdStatByte returns cmdStatByte[3:1] = error type, cmdStatByte[0] = pending flag for selected opCode + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_READARMCMDSTATUSBYTE_NULL_PARM Function parameter cmdStatByte has NULL pointer + * \retval MYKONOS_ERR_READARMCMDSTATUS_INV_OPCODE_PARM ARM opcode is out of range (valid 0-30, even only) + */ +mykonosErr_t MYKONOS_readArmCmdStatusByte(mykonosDevice_t *device, uint8_t opCode, uint8_t *cmdStatByte) +{ + uint8_t cmdByteIndex = 0; + uint8_t cmdByte = 0; + +#if 0 +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_readArmCmdStatByte()\n"); +#endif +#endif + + if (cmdStatByte == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_READARMCMDSTATUSBYTE_NULL_PARM, + getMykonosErrorMessage(MYKONOS_ERR_READARMCMDSTATUSBYTE_NULL_PARM)); + return MYKONOS_ERR_READARMCMDSTATUSBYTE_NULL_PARM; + } + + /* check for even-numbered opCodes only including opcode 0, but not must be greater than opCode 30 */ + if ((opCode != 0) && ((opCode % 2) || (opCode > 30))) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_READARMCMDSTATUS_INV_OPCODE_PARM, + getMykonosErrorMessage(MYKONOS_ERR_READARMCMDSTATUS_INV_OPCODE_PARM)); + return MYKONOS_ERR_READARMCMDSTATUS_INV_OPCODE_PARM; + } + else + { + cmdByteIndex = (opCode / 4); + + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_ARM_CMD_STATUS_0 + cmdByteIndex, &cmdByte); + + if ((opCode / 2) % 2) + { + *cmdStatByte = ((cmdByte >> 4) & 0x0F); + } + else + { + *cmdStatByte = (cmdByte & 0x0F); + } + + return MYKONOS_ERR_OK; + } +} + +/** + * \brief Mykonos ARM command status wait function polls command status until opcode completes + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is a pointer to the device settings structure + * \param opCode Valid values are even increments from 0-30. The ARM opCode is used to determine which pending bit to wait for + * \param timeoutMs conveys the time-out period in milliseconds + * \param cmdStatByte returns cmdStatByte[3:1] = error type, cmdStatByte[0] = pending flag for selected opCode + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_ARMCMDSTATUS_NULL_PARM Function parameter cmdStatByte has NULL pointer + * \retval MYKONOS_ERR_ARMCMDSTATUS_INV_OPCODE_PARM Invalid ARM opcode (valid 0-30, even numbers only) + * \retval MYKONOS_ERR_ARMCMDSTATUS_ARMERROR ARM Mailbox error flag for requested opcode returned a nonzero error flag + * \retval MYKONOS_ERR_WAITARMCMDSTATUS_TIMEOUT Timeout occurred before ARM command completed + */ +mykonosErr_t MYKONOS_waitArmCmdStatus(mykonosDevice_t *device, uint8_t opCode, uint32_t timeoutMs, uint8_t *cmdStatByte) +{ + mykonosErr_t retVal = MYKONOS_ERR_OK; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_waitArmCmdStatus()\n"); +#endif + + if (cmdStatByte == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_ARMCMDSTATUS_NULL_PARM, + getMykonosErrorMessage(MYKONOS_ERR_ARMCMDSTATUS_NULL_PARM)); + return MYKONOS_ERR_ARMCMDSTATUS_NULL_PARM; + } + + /* check for even-numbered opCodes only including opcode 0, but not must be greater than opCode 30 */ + if ((opCode != 0) && ((opCode % 2) || (opCode > 30))) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_ARMCMDSTATUS_INV_OPCODE_PARM, + getMykonosErrorMessage(MYKONOS_ERR_ARMCMDSTATUS_INV_OPCODE_PARM)); + return MYKONOS_ERR_ARMCMDSTATUS_INV_OPCODE_PARM; + } + + /* start wait */ + CMB_setTimeout_ms(timeoutMs); + + do + { + retVal = MYKONOS_readArmCmdStatusByte(device, opCode, cmdStatByte); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* If error flag is non zero in [3:1], - return error */ + if ((*cmdStatByte & 0x0E) > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_ARMCMDSTATUS_ARMERROR, + getMykonosErrorMessage(MYKONOS_ERR_ARMCMDSTATUS_ARMERROR)); + return MYKONOS_ERR_ARMCMDSTATUS_ARMERROR; + } + + if (CMB_hasTimeoutExpired()) + { + return MYKONOS_ERR_WAITARMCMDSTATUS_TIMEOUT; + } + } while (*cmdStatByte & 0x01); + + return MYKONOS_ERR_OK; +} + +/** + * \brief Mykonos ARM configuration write + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is a pointer to the device settings structure + * + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_writeArmProfile(mykonosDevice_t *device) +{ + const uint8_t length = 100; + + int32_t i = 0; + uint8_t vcoDiv = 0; + uint8_t hsDiv = 0; + uint16_t channelsEnabled = 0; + uint8_t cfgData[100] = {0}; + + mykonosErr_t retVal = MYKONOS_ERR_OK; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_writeArmConfig()\n"); +#endif + + /* reading in required mykonosDevice_t structure data into array - not pretty but it works */ + for (i = 0; i < 4; i++) + { + cfgData[i] = (uint8_t)(((device->clocks->deviceClock_kHz * 1000) >> (i * 8)) & 0x000000FF); + } + + for (i = 4; i < 8; i++) + { + cfgData[i] = (uint8_t)(((device->clocks->clkPllVcoFreq_kHz) >> ((i - 4) * 8)) & 0x000000FF); + } + + vcoDiv = (uint8_t)(device->clocks->clkPllVcoDiv); + hsDiv = device->clocks->clkPllHsDiv; + + cfgData[8] = vcoDiv; /* uint8_t vco_div */ + cfgData[9] = hsDiv; /* uint8_t hs_div */ + + channelsEnabled |= ((uint16_t)device->tx->txChannels & 0x03); + channelsEnabled |= ((uint16_t)device->rx->rxChannels & 0x03) << 2; + if (device->profilesValid & ORX_PROFILE_VALID) + { + channelsEnabled |= (((uint16_t)device->obsRx->obsRxChannelsEnable & 3) << 4); + } + + if (device->profilesValid & SNIFF_PROFILE_VALID) + { + channelsEnabled |= ((((uint16_t)device->obsRx->obsRxChannelsEnable >> 2) & 7) << 6); + } + + for (i = 10; i < 12; i++) + { + cfgData[i] = (uint8_t)((channelsEnabled >> ((i - 10) * 8)) & 0xFF); + } + + cfgData[12] = ((device->rx->rxPllUseExternalLo & 0x01) << 1) | (device->tx->txPllUseExternalLo & 0x01); + cfgData[13] = 0x00; /* Not used...padding */ + cfgData[14] = 0x00; /* Not used...padding */ + cfgData[15] = 0x00; /* Not used...padding */ + + if (device->profilesValid & TX_PROFILE_VALID) + { + /* start of Tx profile data */ + cfgData[16] = (uint8_t)device->tx->txProfile->dacDiv; + cfgData[17] = device->tx->txProfile->txFirInterpolation; + cfgData[18] = device->tx->txProfile->thb1Interpolation; + cfgData[19] = device->tx->txProfile->thb2Interpolation; + + for (i = 20; i < 24; i++) + { + cfgData[i] = (uint8_t)(((device->tx->txProfile->iqRate_kHz * 1000) >> ((i - 20) * 8)) & 0x000000FF); + } + + for (i = 24; i < 28; i++) + { + cfgData[i] = (uint8_t)(((device->tx->txProfile->primarySigBandwidth_Hz) >> ((i - 24) * 8)) & 0x000000FF); + } + + for (i = 28; i < 32; i++) + { + cfgData[i] = (uint8_t)(((device->tx->txProfile->rfBandwidth_Hz) >> ((i - 28) * 8)) & 0x000000FF); + } + + for (i = 32; i < 36; i++) + { + cfgData[i] = (uint8_t)(((device->tx->txProfile->txDac3dBCorner_kHz) >> ((i - 32) * 8)) & 0x000000FF); + } + + for (i = 36; i < 40; i++) + { + cfgData[i] = (uint8_t)(((device->tx->txProfile->txBbf3dBCorner_kHz * 1000) >> ((i - 36) * 8)) & 0x000000FF); + } + } + else + { + cfgData[16] = 0; + cfgData[17] = 0; + cfgData[18] = 0; + cfgData[19] = 0; + cfgData[20] = 0; + cfgData[21] = 0; + cfgData[22] = 0; + cfgData[23] = 0; + cfgData[24] = 0; + cfgData[25] = 0; + cfgData[26] = 0; + cfgData[27] = 0; + cfgData[28] = 0; + cfgData[29] = 0; + cfgData[30] = 0; + cfgData[31] = 0; + cfgData[32] = 0; + cfgData[33] = 0; + cfgData[34] = 0; + cfgData[35] = 0; + cfgData[36] = 0; + cfgData[37] = 0; + cfgData[38] = 0; + cfgData[39] = 0; + } + + if (device->profilesValid & RX_PROFILE_VALID) + { + /* start of Rx profile data */ + cfgData[40] = device->rx->rxProfile->adcDiv; + cfgData[41] = device->rx->rxProfile->rxFirDecimation; + cfgData[42] = device->rx->rxProfile->rxDec5Decimation; + cfgData[43] = device->rx->rxProfile->rhb1Decimation; + + for (i = 44; i < 48; i++) + { + cfgData[i] = (uint8_t)(((device->rx->rxProfile->iqRate_kHz * 1000) >> ((i - 44) * 8)) & 0x000000FF); + } + + for (i = 48; i < 52; i++) + { + /* sig bw placeholder */ + cfgData[i] = (uint8_t)(((device->rx->rxProfile->rfBandwidth_Hz) >> ((i - 48) * 8)) & 0x000000FF); + } + + for (i = 52; i < 56; i++) + { + cfgData[i] = (uint8_t)(((device->rx->rxProfile->rfBandwidth_Hz) >> ((i - 52) * 8)) & 0x000000FF); + } + + for (i = 56; i < 60; i++) + { + cfgData[i] = (uint8_t)(((device->rx->rxProfile->rxBbf3dBCorner_kHz * 1000) >> ((i - 56) * 8)) & 0x000000FF); + } + } + else + { + cfgData[40] = 0; + cfgData[41] = 0; + cfgData[42] = 0; + cfgData[43] = 0; + cfgData[44] = 0; + cfgData[45] = 0; + cfgData[46] = 0; + cfgData[47] = 0; + cfgData[48] = 0; + cfgData[49] = 0; + cfgData[50] = 0; + cfgData[51] = 0; + cfgData[52] = 0; + cfgData[53] = 0; + cfgData[54] = 0; + cfgData[55] = 0; + cfgData[56] = 0; + cfgData[57] = 0; + cfgData[58] = 0; + cfgData[59] = 0; + } + + if (device->profilesValid & ORX_PROFILE_VALID) + { + /* start of ObsRx profile data */ + cfgData[60] = device->obsRx->orxProfile->adcDiv; + cfgData[61] = device->obsRx->orxProfile->rxFirDecimation; + cfgData[62] = device->obsRx->orxProfile->rxDec5Decimation; + cfgData[63] = device->obsRx->orxProfile->rhb1Decimation; + + for (i = 64; i < 68; i++) + { + cfgData[i] = (uint8_t)(((device->obsRx->orxProfile->iqRate_kHz * 1000) >> ((i - 64) * 8)) & 0x000000FF); + } + + for (i = 68; i < 72; i++) + { + /* sig bw placeholder */ + cfgData[i] = (uint8_t)(((device->obsRx->orxProfile->rfBandwidth_Hz) >> ((i - 68) * 8)) & 0x000000FF); + } + + for (i = 72; i < 76; i++) + { + cfgData[i] = (uint8_t)(((device->obsRx->orxProfile->rfBandwidth_Hz) >> ((i - 72) * 8)) & 0x000000FF); + } + + for (i = 76; i < 80; i++) + { + cfgData[i] = (uint8_t)(((device->obsRx->orxProfile->rxBbf3dBCorner_kHz * 1000) >> ((i - 76) * 8)) & 0x000000FF); + } + } + else + { + cfgData[60] = 0; + cfgData[61] = 0; + cfgData[62] = 0; + cfgData[63] = 0; + cfgData[64] = 0; + cfgData[65] = 0; + cfgData[66] = 0; + cfgData[67] = 0; + cfgData[68] = 0; + cfgData[69] = 0; + cfgData[70] = 0; + cfgData[71] = 0; + cfgData[72] = 0; + cfgData[73] = 0; + cfgData[74] = 0; + cfgData[75] = 0; + cfgData[76] = 0; + cfgData[77] = 0; + cfgData[78] = 0; + cfgData[79] = 0; + } + + if (device->profilesValid & SNIFF_PROFILE_VALID) + { + /* start of SnRx profile data */ + cfgData[80] = device->obsRx->snifferProfile->adcDiv; + cfgData[81] = device->obsRx->snifferProfile->rxFirDecimation; + cfgData[82] = device->obsRx->snifferProfile->rxDec5Decimation; + cfgData[83] = device->obsRx->snifferProfile->rhb1Decimation; + + for (i = 84; i < 88; i++) + { + cfgData[i] = (uint8_t)(((device->obsRx->snifferProfile->iqRate_kHz * 1000) >> ((i - 84) * 8)) & 0x000000FF); + } + + for (i = 88; i < 92; i++) + { + /* sig bw placeholder */ + cfgData[i] = (uint8_t)(((device->obsRx->snifferProfile->rfBandwidth_Hz) >> ((i - 88) * 8)) & 0x000000FF); + } + + for (i = 92; i < 96; i++) + { + cfgData[i] = (uint8_t)(((device->obsRx->snifferProfile->rfBandwidth_Hz) >> ((i - 92) * 8)) & 0x000000FF); + } + + for (i = 96; i < 100; i++) + { + cfgData[i] = (uint8_t)(((device->obsRx->snifferProfile->rxBbf3dBCorner_kHz * 1000) >> ((i - 96) * 8)) & 0x000000FF); + } + } + else + { + cfgData[80] = 0; + cfgData[81] = 0; + cfgData[82] = 0; + cfgData[83] = 0; + cfgData[84] = 0; + cfgData[85] = 0; + cfgData[86] = 0; + cfgData[87] = 0; + cfgData[88] = 0; + cfgData[89] = 0; + cfgData[90] = 0; + cfgData[91] = 0; + cfgData[92] = 0; + cfgData[93] = 0; + cfgData[94] = 0; + cfgData[95] = 0; + cfgData[96] = 0; + cfgData[97] = 0; + cfgData[98] = 0; + cfgData[99] = 0; + } + + /* writing to the ARM memory with the array data */ + retVal = MYKONOS_writeArmMem(device, MYKONOS_ADDR_ARM_START_DATA_ADDR, &cfgData[0], length); + + return retVal; +} + +/** + * \brief Function called automatically that loads the ADC profiles into the ARM + * + * User should not need to call this function normally. It is called automatically + * during MYKONOS_initArm() to load the ADC profiles (tunes the ADC performance). + * + * Rx ADC profile is only loaded if the Rx Profile is valid, ORx ADC profile is + * only loaded if the ORx Profile is valid. Sniffer ADC profile is only loaded + * if the Sniffer profile is valid. The Loopback ADC profile is always + * loaded. If Tx profile is valid, the loopback ADC profile is chosen based + * on the Tx Primary Signal bandwidth. If no valid Tx Profile, the Rx profile + * is used to set the Loopback ADC profile. Else, ORx, then sniffer profiles + * are used to set the loopback ADC profile. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device Pointer to the device settings structure + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_LOAD_ADCPROFILE_INV_VCODIV Mykonos CLKPLL has invalid VCO divider in the clocks structure + * \retval MYKONOS_ERR_LOAD_ADCPROFILE_MISSING_ORX_PROFILE When Tx Profile used, a matching ORx Profile must be provided with a valid ADC divider. + * The ORx digital filters and clock dividers are used with the Loopback Rx path for Tx calibrations. + * \retval MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_RXREQUIRED ADC Profile Lookup table does not have a match + * for current Rx Profile settings. Custom ADC profile required + * \retval MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_ORXREQUIRED ADC Profile Lookup table does not have a match + * for current ORx Profile settings. Custom ADC profile required + * \retval MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_SNRXREQUIRED ADC Profile Lookup table does not have a match + * for current Sniffer Rx Profile settings. Custom ADC profile required + * \retval MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_LBREQUIRED ADC Profile Lookup table does not have a match + * for Loopback passband BW and ADC Clock frequency settings. Custom ADC profile required + * \retval MYKONOS_ERR_LOAD_ADCPROFILE_RXADCDIV_ZERO Rx Profile has invalid ADC divider = 0, causing a divide by zero error + * \retval MYKONOS_ERR_LOAD_ADCPROFILE_ORXADCDIV_ZERO ORx profile has invalid ADC divider = 0, causing a divide by zero error + * \retval MYKONOS_ERR_LOAD_ADCPROFILE_SNRX_ADCDIV_ZERO Sniffer profile has invalid ADC divider = 0, causing a divide by zero error + * \retval MYKONOS_ERR_LOAD_RXADCPROFILE_ARMMEM_FAILED Error returned while trying to write Rx ADC profile to ARM memory + * \retval MYKONOS_ERR_LOAD_ORXADCPROFILE_ARMMEM_FAILED Error returned while trying to write ORx ADC profile to ARM memory + * \retval MYKONOS_ERR_LOAD_SNRXADCPROFILE_ARMMEM_FAILED Error returned while trying to write Sniffer ADC profile into ARM memory + * \retval MYKONOS_ERR_LOAD_LBADCPROFILE_ARMMEM_FAILED Error returned while trying to write Loopback ADC profile into ARM memory + */ +mykonosErr_t MYKONOS_loadAdcProfiles(mykonosDevice_t *device) +{ + uint8_t adcProfile[32] = {0}; + uint8_t i = 0; + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint32_t hsDigClk_MHz = 0; + uint32_t adcClk_MHz = 0; + uint32_t vcoDiv = 0; + uint32_t vcoDivTimes10 = 10; + uint8_t profileIndex = 0; + const uint8_t ARM_CONFIG_OFFSET = 100; /* number of bytes written in MYKONOS_writeArmProfile() to ARM memory */ + + const uint8_t NUM_ADCPROFILE_COEFS = 16; + const uint8_t NUM_ADC_PROFILES = 20; + static const uint16_t adcProfileLut[20][18] = { + /* Max RFBW, ADCCLK_MHz, adcProfile[16] */ + { 20, 491, 1494, 564, 201, 98, 1280, 134, 945, 40, 529, 10, 326, 39, 30, 16, 9, 201}, + { 60, 983, 712, 462, 201, 98, 1280, 291, 1541, 149, 1054, 46, 645, 34, 48, 32, 18, 193}, + { 75, 983, 680, 477, 201, 98, 1280, 438, 1577, 242, 1046, 73, 636, 30, 48, 31, 18, 192}, + {100, 983, 655, 446, 201, 98, 1280, 336, 1631, 334, 1152, 207, 733, 33, 48, 32, 21, 212}, + { 75, 1228, 569, 369, 201, 98, 1280, 291, 1541, 149, 1320, 58, 807, 34, 48, 40, 23, 189}, + {100, 1228, 534, 386, 201, 98, 1280, 491, 1591, 279, 1306, 104, 792, 28, 48, 39, 23, 187}, + {160, 1228, 491, 375, 201, 98, 1280, 514, 1728, 570, 1455, 443, 882, 27, 48, 39, 25, 205}, + {200, 1228, 450, 349, 201, 98, 1280, 730, 1626, 818, 1476, 732, 834, 20, 41, 36, 24, 200}, + { 80, 1250, 555, 365, 201, 98, 1280, 317, 1547, 165, 1341, 65, 819, 33, 48, 40, 24, 188}, + {102, 1250, 524, 379, 201, 98, 1280, 494, 1592, 281, 1328, 107, 805, 28, 48, 40, 23, 187}, + { 80, 1333, 526, 339, 201, 98, 1280, 281, 1539, 143, 1433, 60, 877, 35, 48, 43, 25, 188}, + {217, 1333, 414, 321, 201, 98, 1280, 730, 1626, 818, 1603, 794, 905, 20, 41, 40, 26, 199}, + { 75, 1474, 486, 302, 199, 98, 1280, 206, 1523, 101, 1578, 47, 977, 37, 48, 48, 28, 186}, + {100, 1474, 465, 311, 201, 98, 1280, 353, 1556, 187, 1581, 86, 964, 32, 48, 47, 28, 185}, + {150, 1474, 436, 296, 190, 98, 1280, 336, 1631, 334, 1638, 293, 1102, 33, 48, 46, 31, 205}, + { 40, 1536, 479, 285, 190, 98, 1280, 112, 1505, 53, 1574, 25, 1026, 40, 48, 48, 29, 186}, + {100, 1536, 450, 297, 193, 98, 1280, 328, 1550, 171, 1586, 79, 1006, 33, 48, 48, 29, 184}, + {150, 1536, 421, 283, 182, 98, 1280, 313, 1620, 306, 1638, 269, 1153, 34, 48, 46, 33, 204}, + {200, 1536, 392, 299, 180, 98, 1280, 514, 1728, 570, 1638, 498, 1104, 27, 48, 44, 32, 200}, + {240, 1536, 366, 301, 178, 98, 1280, 686, 1755, 818, 1638, 742, 1056, 22, 45, 41, 31, 196}}; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_loadAdcProfiles\n"); +#endif + + vcoDiv = (uint32_t)device->clocks->clkPllVcoDiv; + switch (vcoDiv) + { + case VCODIV_1: + vcoDivTimes10 = 10; + break; + case VCODIV_1p5: + vcoDivTimes10 = 15; + break; + case VCODIV_2: + vcoDivTimes10 = 20; + break; + case VCODIV_3: + vcoDivTimes10 = 30; + break; + default: + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_LOAD_ADCPROFILE_INV_VCODIV, + getMykonosErrorMessage(MYKONOS_ERR_LOAD_ADCPROFILE_INV_VCODIV)); + return MYKONOS_ERR_LOAD_ADCPROFILE_INV_VCODIV; + } + } + + hsDigClk_MHz = device->clocks->clkPllVcoFreq_kHz / vcoDivTimes10 / 100 / device->clocks->clkPllHsDiv; + + /* If Tx Profile is valid, set loopback ADC profile based on Tx primary signal BW */ + if ((device->profilesValid & TX_PROFILE_VALID) > 0) + { + /* If custom profile, load it */ + if (device->obsRx->customLoopbackAdcProfile != NULL) + { + for (i = 0; i < NUM_ADCPROFILE_COEFS; i++) + { + adcProfile[i * 2] = device->obsRx->customLoopbackAdcProfile[i] & 0xFF; + adcProfile[i * 2 + 1] = (device->obsRx->customLoopbackAdcProfile[i] >> 8) & 0xFF; + } + } + else + { + /* Tx requires ORx profile is configured */ + if (((device->profilesValid & TX_PROFILE_VALID) > 0) && ((device->profilesValid & ORX_PROFILE_VALID) == 0)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_LOAD_ADCPROFILE_MISSING_ORX_PROFILE, + getMykonosErrorMessage(MYKONOS_ERR_LOAD_ADCPROFILE_MISSING_ORX_PROFILE)); + return MYKONOS_ERR_LOAD_ADCPROFILE_MISSING_ORX_PROFILE; + } + + if (device->obsRx->orxProfile->adcDiv == 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_LOAD_ADCPROFILE_ORXADCDIV_ZERO, + getMykonosErrorMessage(MYKONOS_ERR_LOAD_ADCPROFILE_ORXADCDIV_ZERO)); + return MYKONOS_ERR_LOAD_ADCPROFILE_ORXADCDIV_ZERO; + } + + adcClk_MHz = hsDigClk_MHz / device->obsRx->orxProfile->adcDiv; + + /* find correct ADC profile in the LUT */ + profileIndex = NUM_ADC_PROFILES; + for (i = 0; i < NUM_ADC_PROFILES; i++) + { + /* Find a row in the LUT that matches the ADC clock frequency */ + if ((adcProfileLut[i][1] == adcClk_MHz) && (adcProfileLut[i][0] >= (device->tx->txProfile->primarySigBandwidth_Hz / 1000000))) + { + profileIndex = i; + break; + } + } + + /* Verify that a profile was found in the LUT, if not return error */ + /* In this case a custom profile would need to be passed in */ + if (profileIndex >= NUM_ADC_PROFILES) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_LBREQUIRED, + getMykonosErrorMessage(MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_LBREQUIRED)); + return MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_LBREQUIRED; + } + + for (i = 0; i < NUM_ADCPROFILE_COEFS; i++) + { + adcProfile[i * 2] = adcProfileLut[profileIndex][i + 2] & 0xFF; + adcProfile[i * 2 + 1] = (adcProfileLut[profileIndex][i + 2] >> 8) & 0xFF; + } + } + + /* writing to the ARM memory: Set Loopback ADC Profile based on Tx Primary signal Bandwidth */ + retVal = MYKONOS_writeArmMem(device, MYKONOS_ADDR_ARM_START_DATA_ADDR + ARM_CONFIG_OFFSET + 96, &adcProfile[0], sizeof(adcProfile)); + if (retVal) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_LOAD_LBADCPROFILE_ARMMEM_FAILED, + getMykonosErrorMessage(MYKONOS_ERR_LOAD_LBADCPROFILE_ARMMEM_FAILED)); + return MYKONOS_ERR_LOAD_LBADCPROFILE_ARMMEM_FAILED; + } + } + + if ((device->profilesValid & RX_PROFILE_VALID) > 0) + { + /* If custom profile, load it */ + if (device->rx->rxProfile->customAdcProfile != NULL) + { + for (i = 0; i < NUM_ADCPROFILE_COEFS; i++) + { + adcProfile[i * 2] = device->rx->rxProfile->customAdcProfile[i] & 0xFF; + adcProfile[i * 2 + 1] = (device->rx->rxProfile->customAdcProfile[i] >> 8) & 0xFF; + } + } + else + { + if (device->rx->rxProfile->adcDiv == 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_LOAD_ADCPROFILE_RXADCDIV_ZERO, + getMykonosErrorMessage(MYKONOS_ERR_LOAD_ADCPROFILE_RXADCDIV_ZERO)); + return MYKONOS_ERR_LOAD_ADCPROFILE_RXADCDIV_ZERO; + } + + adcClk_MHz = hsDigClk_MHz / device->rx->rxProfile->adcDiv; + + /* find correct ADC profile in the LUT */ + profileIndex = NUM_ADC_PROFILES; + for (i = 0; i < NUM_ADC_PROFILES; i++) + { + /* Find a row in the LUT that matches the ADC clock frequency */ + if ((adcProfileLut[i][1] == adcClk_MHz) && (adcProfileLut[i][0] >= (device->rx->rxProfile->rfBandwidth_Hz / 1000000))) + { + profileIndex = i; + break; + } + } + + /* Verify that a profile was found in the LUT, if not return error */ + /* In this case a custom profile would need to be passed in */ + if (profileIndex >= NUM_ADC_PROFILES) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_RXREQUIRED, + getMykonosErrorMessage(MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_RXREQUIRED)); + return MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_RXREQUIRED; + } + + for (i = 0; i < NUM_ADCPROFILE_COEFS; i++) + { + adcProfile[i * 2] = adcProfileLut[profileIndex][i + 2] & 0xFF; + adcProfile[i * 2 + 1] = (adcProfileLut[profileIndex][i + 2] >> 8) & 0xFF; + } + } + + /* writing to the ARM memory with ADC Profile for Rx path */ + retVal = MYKONOS_writeArmMem(device, MYKONOS_ADDR_ARM_START_DATA_ADDR + ARM_CONFIG_OFFSET, &adcProfile[0], sizeof(adcProfile)); + if (retVal) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_LOAD_RXADCPROFILE_ARMMEM_FAILED, + getMykonosErrorMessage(MYKONOS_ERR_LOAD_RXADCPROFILE_ARMMEM_FAILED)); + return MYKONOS_ERR_LOAD_RXADCPROFILE_ARMMEM_FAILED; + } + + /* writing to the ARM memory: Set Loopback ADC Profile = Rx ADC Profile ONLY if Tx profile is not valid */ + if ((device->profilesValid & TX_PROFILE_VALID) == 0) + { + retVal = MYKONOS_writeArmMem(device, MYKONOS_ADDR_ARM_START_DATA_ADDR + ARM_CONFIG_OFFSET + 96, &adcProfile[0], sizeof(adcProfile)); + if (retVal) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_LOAD_LBADCPROFILE_ARMMEM_FAILED, + getMykonosErrorMessage(MYKONOS_ERR_LOAD_LBADCPROFILE_ARMMEM_FAILED)); + return MYKONOS_ERR_LOAD_LBADCPROFILE_ARMMEM_FAILED; + } + } + } + + if ((device->profilesValid & ORX_PROFILE_VALID) > 0) + { + /* If custom profile, load it */ + if (device->obsRx->orxProfile->customAdcProfile != NULL) + { + for (i = 0; i < NUM_ADCPROFILE_COEFS; i++) + { + adcProfile[i * 2] = device->obsRx->orxProfile->customAdcProfile[i] & 0xFF; + adcProfile[i * 2 + 1] = (device->obsRx->orxProfile->customAdcProfile[i] >> 8) & 0xFF; + } + } + else + { + if (device->obsRx->orxProfile->adcDiv == 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_LOAD_ADCPROFILE_ORXADCDIV_ZERO, + getMykonosErrorMessage(MYKONOS_ERR_LOAD_ADCPROFILE_ORXADCDIV_ZERO)); + return MYKONOS_ERR_LOAD_ADCPROFILE_ORXADCDIV_ZERO; + } + + adcClk_MHz = hsDigClk_MHz / device->obsRx->orxProfile->adcDiv; + + /* find correct ADC profile in the LUT */ + profileIndex = NUM_ADC_PROFILES; + for (i = 0; i < NUM_ADC_PROFILES; i++) + { + /* Find a row in the LUT that matches the ADC clock frequency */ + if ((adcProfileLut[i][1] == adcClk_MHz) && (adcProfileLut[i][0] >= (device->obsRx->orxProfile->rfBandwidth_Hz / 1000000))) + { + profileIndex = i; + break; + } + } + + /* Verify that a profile was found in the LUT, if not return error */ + /* In this case a custom profile would need to be passed in */ + if (profileIndex >= NUM_ADC_PROFILES) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_ORXREQUIRED, + getMykonosErrorMessage(MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_ORXREQUIRED)); + return MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_ORXREQUIRED; + } + + for (i = 0; i < NUM_ADCPROFILE_COEFS; i++) + { + adcProfile[i * 2] = adcProfileLut[profileIndex][i + 2] & 0xFF; + adcProfile[i * 2 + 1] = (adcProfileLut[profileIndex][i + 2] >> 8) & 0xFF; + } + } + + /* writing to the ARM memory with ADC Profile for ORx path */ + retVal = MYKONOS_writeArmMem(device, MYKONOS_ADDR_ARM_START_DATA_ADDR + ARM_CONFIG_OFFSET + 32, &adcProfile[0], sizeof(adcProfile)); + if (retVal) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_LOAD_ORXADCPROFILE_ARMMEM_FAILED, + getMykonosErrorMessage(MYKONOS_ERR_LOAD_ORXADCPROFILE_ARMMEM_FAILED)); + return MYKONOS_ERR_LOAD_ORXADCPROFILE_ARMMEM_FAILED; + } + + /* If Rx and Tx Profiles are not valid, set Loopback ADC profile to ORx ADC Profile */ + if (((device->profilesValid & TX_PROFILE_VALID) == 0) && ((device->profilesValid & RX_PROFILE_VALID) == 0)) + { + retVal = MYKONOS_writeArmMem(device, MYKONOS_ADDR_ARM_START_DATA_ADDR + ARM_CONFIG_OFFSET + 96, &adcProfile[0], sizeof(adcProfile)); + if (retVal) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_LOAD_LBADCPROFILE_ARMMEM_FAILED, + getMykonosErrorMessage(MYKONOS_ERR_LOAD_LBADCPROFILE_ARMMEM_FAILED)); + return MYKONOS_ERR_LOAD_LBADCPROFILE_ARMMEM_FAILED; + } + } + } + + if ((device->profilesValid & SNIFF_PROFILE_VALID) > 0) + { + /* If custom profile, load it */ + if (device->obsRx->snifferProfile->customAdcProfile != NULL) + { + for (i = 0; i < NUM_ADCPROFILE_COEFS; i++) + { + adcProfile[i * 2] = device->obsRx->snifferProfile->customAdcProfile[i] & 0xFF; + adcProfile[i * 2 + 1] = (device->obsRx->snifferProfile->customAdcProfile[i] >> 8) & 0xFF; + } + } + else + { + + if (device->obsRx->snifferProfile->adcDiv == 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_LOAD_ADCPROFILE_SNRX_ADCDIV_ZERO, + getMykonosErrorMessage(MYKONOS_ERR_LOAD_ADCPROFILE_SNRX_ADCDIV_ZERO)); + return MYKONOS_ERR_LOAD_ADCPROFILE_SNRX_ADCDIV_ZERO; + } + + adcClk_MHz = hsDigClk_MHz / device->obsRx->snifferProfile->adcDiv; + + /* find correct ADC profile in the LUT */ + profileIndex = NUM_ADC_PROFILES; + for (i = 0; i < NUM_ADC_PROFILES; i++) + { + /* Find a row in the LUT that matches the ADC clock frequency */ + if ((adcProfileLut[i][1] == adcClk_MHz) && (adcProfileLut[i][0] >= (device->obsRx->snifferProfile->rfBandwidth_Hz / 1000000))) + { + profileIndex = i; + break; + } + } + + /* Verify that a profile was found in the LUT, if not return error */ + /* In this case a custom profile would need to be passed in */ + if (profileIndex >= NUM_ADC_PROFILES) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_SNRXREQUIRED, + getMykonosErrorMessage(MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_SNRXREQUIRED)); + return MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_SNRXREQUIRED; + } + + for (i = 0; i < NUM_ADCPROFILE_COEFS; i++) + { + adcProfile[i * 2] = adcProfileLut[profileIndex][i + 2] & 0xFF; + adcProfile[i * 2 + 1] = (adcProfileLut[profileIndex][i + 2] >> 8) & 0xFF; + } + } + + /* writing to the ARM memory with ADC Profile for sniffer Rx path */ + retVal = MYKONOS_writeArmMem(device, MYKONOS_ADDR_ARM_START_DATA_ADDR + ARM_CONFIG_OFFSET + 64, &adcProfile[0], sizeof(adcProfile)); + if (retVal) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_LOAD_SNRXADCPROFILE_ARMMEM_FAILED, + getMykonosErrorMessage(MYKONOS_ERR_LOAD_SNRXADCPROFILE_ARMMEM_FAILED)); + return MYKONOS_ERR_LOAD_SNRXADCPROFILE_ARMMEM_FAILED; + } + + /* If Tx, Rx, and ORx Profiles are not valid, set Loopback ADC profile to Sniffer Rx ADC Profile */ + if (((device->profilesValid & TX_PROFILE_VALID) == 0) && ((device->profilesValid & RX_PROFILE_VALID) == 0) && ((device->profilesValid & ORX_PROFILE_VALID) == 0)) + { + retVal = MYKONOS_writeArmMem(device, MYKONOS_ADDR_ARM_START_DATA_ADDR + ARM_CONFIG_OFFSET + 96, &adcProfile[0], sizeof(adcProfile)); + if (retVal) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_LOAD_LBADCPROFILE_ARMMEM_FAILED, + getMykonosErrorMessage(MYKONOS_ERR_LOAD_LBADCPROFILE_ARMMEM_FAILED)); + return MYKONOS_ERR_LOAD_LBADCPROFILE_ARMMEM_FAILED; + } + } + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief Helper function to calculate commonly used digital clock frequencies in the device + * + * User should not need to call this function normally. It is called automatically + * within other API functions to calculate the main digital clock. If the pointers + * to the return parameters are NULL, that calculation will be skipped and not + * returned. + * + * + * Dependencies + * -device->clocks->clkPllVcoFreq_kHz; + * -device->clocks->clkPllVcoDiv; + * -device->clocks->clkPllHsDiv; + * + * \param device Pointer to the device settings structure + * \param hsDigClk_kHz Return value for the calculated Mykonos high speed Digital clock at the output of the CLKPLL in kHz + * \param hsDigClkDiv4or5_kHz Return value for the Mykonos high speed digital clock divided by 4 or 5 in kHz + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_CALCDIGCLK_NULLDEV_PARAM device parameter is a NULL pointer + * \retval MYKONOS_ERR_CALCDIGCLK_NULL_CLKSTRUCT device->clocks structure is a NULL pointer + * \retval MYKONOS_ERR_CLKPLL_INV_VCODIV Invalid CLKPLL VCO divider in device->clocks->clkPllVcoDiv + * \retval MYKONOS_ERR_CLKPLL_INV_HSDIV Invalid CLKPLL High speed divider in device->clocks->clkPllHsDiv + */ +static mykonosErr_t MYKONOS_calculateDigitalClocks(mykonosDevice_t *device, uint32_t *hsDigClk_kHz, uint32_t *hsDigClkDiv4or5_kHz) +{ + uint32_t hsclkRate_kHz = 0; + uint32_t clkPllVcoFrequency_kHz = 0; + mykonosVcoDiv_t vcoDiv = VCODIV_1; + uint8_t hsDiv = 4; + + if (device == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, 0, MYKONOS_ERR_CALCDIGCLK_NULLDEV_PARAM, getMykonosErrorMessage(MYKONOS_ERR_CALCDIGCLK_NULLDEV_PARAM)); + return MYKONOS_ERR_CALCDIGCLK_NULLDEV_PARAM; + } + + if ((device->clocks == NULL)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CALCDIGCLK_NULL_CLKSTRUCT, + getMykonosErrorMessage(MYKONOS_ERR_CALCDIGCLK_NULL_CLKSTRUCT)); + return MYKONOS_ERR_CALCDIGCLK_NULL_CLKSTRUCT; + } + + clkPllVcoFrequency_kHz = device->clocks->clkPllVcoFreq_kHz; + vcoDiv = device->clocks->clkPllVcoDiv; + hsDiv = device->clocks->clkPllHsDiv; + + switch (vcoDiv) + { + case VCODIV_1: + hsclkRate_kHz = clkPllVcoFrequency_kHz; + break; + case VCODIV_1p5: + hsclkRate_kHz = (clkPllVcoFrequency_kHz / 15) * 10; + break; + case VCODIV_2: + hsclkRate_kHz = clkPllVcoFrequency_kHz >> 1; + break; + case VCODIV_3: + hsclkRate_kHz = (clkPllVcoFrequency_kHz / 30) * 10; + break; + default: + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CLKPLL_INV_VCODIV, getMykonosErrorMessage(MYKONOS_ERR_CLKPLL_INV_VCODIV)); + return MYKONOS_ERR_CLKPLL_INV_VCODIV; + } + } + + switch (hsDiv) + { + case 4: + hsDiv = 4; + break; + case 5: + hsDiv = 5; + break; + default: + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CLKPLL_INV_HSDIV, getMykonosErrorMessage(MYKONOS_ERR_CLKPLL_INV_HSDIV)); + return MYKONOS_ERR_CLKPLL_INV_HSDIV; + } + } + + if (hsDigClk_kHz != NULL) + { + *hsDigClk_kHz = hsclkRate_kHz / hsDiv; + } + + if (hsDigClkDiv4or5_kHz != NULL) + { + /* This digital div 4 or 5 is always mutually exclusive with the HS Divider (4 or 5) to always + * create a /20 from the hsclk. + */ + *hsDigClkDiv4or5_kHz = hsclkRate_kHz / 20; + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief Performs reset to the External Tx LO Leakage tracking calibration channel estimate + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device Pointer to the Mykonos device data structure containing settings + * \param channelSel Enum selects the channel to reset + * + * \retval MYKONOS_ERR_RESET_TXLOL_INV_PARAM Selected channel is not valid + * \retval MYKONOS_ERR_RESET_TXLOL_ARMERROR ARM error + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_resetExtTxLolChannel(mykonosDevice_t *device, mykonosTxChannels_t channelSel) +{ + const uint8_t TXLOL_RESET_CHANNEL_ESTIMATE = 0x01; + const uint32_t GETTXLOLSTATUS_TIMEOUT_MS = 1000; + + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint8_t extData[3] = {MYKONOS_ARM_OBJECTID_GS_TRACKCALS, TXLOL_RESET_CHANNEL_ESTIMATE, 0}; + uint8_t cmdStatusByte = 0; + uint8_t armErrorFlag = 0; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_resetExtTxLolChannel()\n"); +#endif + + /* Check Channel */ + switch (channelSel) + { + case TX1: + extData[2] = 0x01; + break; + case TX2: + extData[2] = 0x02; + break; + case TX1_TX2: + extData[2] = 0x03; + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RESET_TXLOL_INV_PARAM, + getMykonosErrorMessage(MYKONOS_ERR_RESET_TXLOL_INV_PARAM)); + return MYKONOS_ERR_RESET_TXLOL_INV_PARAM; + } + + /* throw error if not in the right state */ + retVal = MYKONOS_checkArmState(device, (MYK_ARM_IDLE | MYK_ARM_RADIO_ON)); + if (retVal) + { + return retVal; + } + + retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_SET_OPCODE, &extData[0], sizeof(extData)); + if (retVal) + { + return retVal; + } + retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_SET_OPCODE, GETTXLOLSTATUS_TIMEOUT_MS, &cmdStatusByte); + + /* Error check WaitArmCmdStatus return */ + armErrorFlag = (cmdStatusByte >> 1); + if (armErrorFlag > 0) + { + return MYKONOS_ERR_RESET_TXLOL_ARMERROR; + } + + return retVal; +} + +/** + * \brief Configures the Radio power up/down control for Rx and Tx paths to be controlled by pins + * (TX1/2_ENABLE, RX1/2_ENABLE, and GPIO pins) or an API function call. + * + * The BBP should not have to call this as it will automatically be setup at the end of the + * MYKONOS_loadArmFromBinary() function call. If the BBP wishes to change the radio power up/down + * control method this function can be called again to change the configuration while + * the ARM is in the radioOff state. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - device->auxIo->armGpio->useRx2EnablePin + * - device->auxIo->armGpio->useTx2EnablePin + * - device->auxIo->armGpio->txRxPinMode + * - device->auxIo->armGpio->orxPinMode + * + * \param device is a pointer to the device settings structure + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_SET_RADIOCTRL_PINS_ARMERROR ARM returned an error and did not accept the command. + */ +mykonosErr_t MYKONOS_setRadioControlPinMode(mykonosDevice_t *device) +{ + uint8_t extData[4] = {0x81, 0, 0, 4}; /*Object ID 0x81 (radio control structure), offset lsb, offset msb, length*/ + uint8_t armRadioControlStruct[4] = {0}; + uint32_t timeoutMs = 0; + uint8_t cmdStatusByte = 0; + mykonosErr_t retval = MYKONOS_ERR_OK; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setRadioControlPinMode()\n"); +#endif + + /* write ARM radio control structure to enable pin mode/command mode */ + if (device->auxIo->armGpio->useRx2EnablePin > 0) + { + armRadioControlStruct[0] = 0x01; + } + + if (device->auxIo->armGpio->useTx2EnablePin > 0) + { + armRadioControlStruct[1] = 0x01; + } + + if (device->auxIo->armGpio->txRxPinMode > 0) + { + armRadioControlStruct[2] = 0x01; + } + + if (device->auxIo->armGpio->orxPinMode > 0) + { + armRadioControlStruct[3] = 0x01; + } + + retval = MYKONOS_writeArmMem(device, MYKONOS_ADDR_ARM_START_DATA_ADDR, &armRadioControlStruct[0], sizeof(armRadioControlStruct)); + if (retval != MYKONOS_ERR_OK) + { + return retval; + } + + retval = MYKONOS_sendArmCommand(device, MYKONOS_ARM_WRITECFG_OPCODE, &extData[0], sizeof(extData)); + if (retval != MYKONOS_ERR_OK) + { + return retval; + } + + timeoutMs = 1000; + retval = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_WRITECFG_OPCODE, timeoutMs, &cmdStatusByte); + if (retval != MYKONOS_ERR_OK) + { + return retval; + } + + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SET_RADIOCTRL_PINS_ARMERROR, + getMykonosErrorMessage(MYKONOS_ERR_SET_RADIOCTRL_PINS_ARMERROR)); + return MYKONOS_ERR_SET_RADIOCTRL_PINS_ARMERROR; + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief Sets the measure count which is the number of samples taken before DC offset correction is applied for the given RF channel. + * This value should be changed after ARM initialization. + * channel can be one of the following ( ::mykonosDcOffsetChannels_t ). + * + * Channel | Channel description + * ------------------------|-------------------------------- + * MYK_DC_OFFSET_RX_CHN | Selects Rx channel + * MYK_DC_OFFSET_ORX_CHN | Selects ORx channel + * MYK_DC_OFFSET_SNF_CHN | Selects Sniffer channel + * + * The total duration 'tCount' is calculated as, + * [tCount = (measureCount * 1024) / IQ data rate of the channel]. + * There is a minimum limit for the value of measureCount, the value passed should satisfy the condition 'tCount > 800us'. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device Pointer to the Mykonos device data structure containing settings + * \param channel Receive channel to be selected. + * \param measureCount Value to be configured for the selected channel which is the number of samples taken before DC offset correction is applied. + * + * \retval MYKONOS_ERR_DC_OFFSET_INV_CHAN channel passed to the function is invalid, refer mykonosDcOffsetChannels_t enum for valid channels. + * \retval MYKONOS_ERR_SET_RF_DC_OFFSET_INV_MEASURECNT measurement count value passed is invalid + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_SET_RF_DC_OFFSET_MEASURECNT_MIN_LIMIT The measureCount value passed is less than the minimum limit allowed. + */ +mykonosErr_t MYKONOS_setRfDcOffsetCnt(mykonosDevice_t *device, mykonosDcOffsetChannels_t channel, uint16_t measureCount) +{ + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint16_t REG_ADDRESS_H = 0; /* Address for Higher byte */ + uint16_t REG_ADDRESS_L = 0; /* Address for Lower byte */ + uint16_t MEASURE_CNT_RANGE = 0xFFFF; /* Mask for measure count range checking */ + + const uint8_t MEASURE_CNT_H = (measureCount & 0xFF00) >> 8; /* Higher byte of the measure count */ + const uint8_t MEASURE_CNT_L = measureCount & 0x00FF; /* Lower byte of the measure count */ + + /* Calculation of Total Duration [ tCount = (measureCount * 0x400) / IQ data rate cycles ] */ + const uint8_t FACTOR = 10; + uint32_t tCount = (measureCount << FACTOR); /* precalculations for Total duration in us */ + uint32_t IQ_RATE = 0; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setRfDcOffsetCnt()\n"); +#endif + + /* check for channel and update the appropriate register address */ + switch (channel) + { + case MYK_DC_OFFSET_RX_CHN: + REG_ADDRESS_H = MYKONOS_ADDR_RFDC_MEASURE_COUNT_2; + REG_ADDRESS_L = MYKONOS_ADDR_RFDC_MEASURE_COUNT_1; + IQ_RATE = device->rx->rxProfile->iqRate_kHz / 1000; /* IQ Rate to calculate total duration */ + break; + case MYK_DC_OFFSET_ORX_CHN: + REG_ADDRESS_H = MYKONOS_ADDR_RFDC_ORX_MEASURE_COUNT_2; + REG_ADDRESS_L = MYKONOS_ADDR_RFDC_ORX_MEASURE_COUNT_1; + IQ_RATE = device->obsRx->orxProfile->iqRate_kHz / 1000; /* IQ Rate to calculate total duration */ + break; + case MYK_DC_OFFSET_SNF_CHN: + REG_ADDRESS_H = MYKONOS_ADDR_RFDC_SNF_MEASURE_COUNT_2; + REG_ADDRESS_L = MYKONOS_ADDR_RFDC_SNF_MEASURE_COUNT_1; + /* measureCount for Sniffer should be 10 bit */ + MEASURE_CNT_RANGE= 0x03FF; + IQ_RATE = device->obsRx->snifferProfile->iqRate_kHz / 1000; /* IQ Rate to calculate total duration */ + break; + + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DC_OFFSET_INV_CHAN, + getMykonosErrorMessage(MYKONOS_ERR_DC_OFFSET_INV_CHAN)); + return MYKONOS_ERR_DC_OFFSET_INV_CHAN; + } + + tCount = (tCount / IQ_RATE); /* Calculating total duration in us */ + if (tCount < 800) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SET_RF_DC_OFFSET_MEASURECNT_MIN_LIMIT, + getMykonosErrorMessage(MYKONOS_ERR_SET_RF_DC_OFFSET_MEASURECNT_MIN_LIMIT)); + return MYKONOS_ERR_SET_RF_DC_OFFSET_MEASURECNT_MIN_LIMIT ; + } + + if ((measureCount < 0x11) || (measureCount & ~MEASURE_CNT_RANGE)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SET_RF_DC_OFFSET_INV_MEASURECNT, + getMykonosErrorMessage(MYKONOS_ERR_SET_RF_DC_OFFSET_INV_MEASURECNT)); + return MYKONOS_ERR_SET_RF_DC_OFFSET_INV_MEASURECNT ; + } + + CMB_SPIWriteField(device->spiSettings, REG_ADDRESS_H, MEASURE_CNT_H, ((MEASURE_CNT_RANGE >>8) & 0xFF),0); + CMB_SPIWriteByte(device->spiSettings, REG_ADDRESS_L, MEASURE_CNT_L); + + return retVal; +} + +/** + * \brief retrieves the measure count which is the number of samples taken before DC offset correction is applied for the given Rf channel. + * channel can be one of the following ( ::mykonosDcOffsetChannels_t ). + * + * Channel | Channel description + * ------------------------|-------------------------------- + * MYK_DC_OFFSET_RX_CHN | Selects Rx channel + * MYK_DC_OFFSET_ORX_CHN | Selects ORx channel + * MYK_DC_OFFSET_SNF_CHN | Selects Sniffer channel + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device Pointer to the Mykonos device data structure containing settings + * \param channel receive channel to be selected. + * \param measureCount pointer to the variable to store the read value. + * + * \retval MYKONOS_ERR_DC_OFFSET_INV_CHAN channel passed to the function is invalid, refer mykonosDcOffsetChannels_t enum for valid channels. + * \retval MYKONOS_ERR_SET_RF_DC_OFFSET_NULL_MEASURECNT passed pointer of measureCount is NULL + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_getRfDcOffsetCnt(mykonosDevice_t *device, mykonosDcOffsetChannels_t channel, uint16_t *measureCount) +{ + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint16_t REG_ADDRESS_H = 0; /* Address for Higher byte */ + uint16_t REG_ADDRESS_L = 0; /* Address for Lower byte */ + uint16_t MEASURE_CNT_RANGE = 0xFFFF; /* Mask for measure count range checking */ + uint16_t mCount = 0; /* Temporary variable to store readback from register. */ + uint8_t readbackData = 0; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getRfDcOffsetCnt()\n"); +#endif + + switch (channel) + { + case MYK_DC_OFFSET_RX_CHN: + REG_ADDRESS_H = MYKONOS_ADDR_RFDC_MEASURE_COUNT_2; + REG_ADDRESS_L = MYKONOS_ADDR_RFDC_MEASURE_COUNT_1; + break; + case MYK_DC_OFFSET_ORX_CHN: + REG_ADDRESS_H = MYKONOS_ADDR_RFDC_ORX_MEASURE_COUNT_2; + REG_ADDRESS_L = MYKONOS_ADDR_RFDC_ORX_MEASURE_COUNT_1; + break; + case MYK_DC_OFFSET_SNF_CHN: + REG_ADDRESS_H = MYKONOS_ADDR_RFDC_SNF_MEASURE_COUNT_2; + REG_ADDRESS_L = MYKONOS_ADDR_RFDC_SNF_MEASURE_COUNT_1; + /* measureCount for Sniffer should be 10 bit */ + MEASURE_CNT_RANGE= 0x03FF; + break; + + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DC_OFFSET_INV_CHAN, + getMykonosErrorMessage(MYKONOS_ERR_DC_OFFSET_INV_CHAN)); + return MYKONOS_ERR_DC_OFFSET_INV_CHAN; + } + + if (measureCount == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GET_RF_DC_OFFSET_NULL_MEASURECNT, + getMykonosErrorMessage(MYKONOS_ERR_GET_RF_DC_OFFSET_NULL_MEASURECNT)); + return MYKONOS_ERR_GET_RF_DC_OFFSET_NULL_MEASURECNT; + } + + /* Store Higher byte of measureCount */ + CMB_SPIReadField(device->spiSettings, REG_ADDRESS_H, &readbackData, ((MEASURE_CNT_RANGE >>8) & 0xFF),0); + mCount = readbackData; + mCount = mCount << 8; + + /* Store Lower byte of measureCount */ + readbackData = 0; + CMB_SPIReadByte(device->spiSettings, REG_ADDRESS_L, &readbackData); + mCount = mCount | readbackData; + + *measureCount = mCount; + + return retVal; +} + +/** + * \brief Sets M-Shift value which is the Corner frequency of Rx notch filter for the given channel. + * channel can be one of the following ( ::mykonosDcOffsetChannels_t ). + * + * Channel | Channel description + * ------------------------|-------------------------------- + * MYK_DC_OFFSET_RX_CHN | Selects Rx channel + * MYK_DC_OFFSET_ORX_CHN | Selects ORx channel + * MYK_DC_OFFSET_SNF_CHN | Selects Sniffer channel + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device Pointer to the Mykonos device data structure containing settings + * \param channel receive channel to be selected. + * \param mShift value to be configured for the given channel + * + * \retval MYKONOS_ERR_DC_OFFSET_INV_CHAN channel passed to the function is invalid, refer mykonosDcOffsetChannels_t enum for valid channels. + * \retval MYKONOS_ERR_SET_DIG_DC_OFFSET_INV_MSHIFT mShift value passed is invalid. + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_setDigDcOffsetMShift(mykonosDevice_t *device, mykonosDcOffsetChannels_t channel, uint8_t mShift) +{ + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint16_t REG_ADDRESS = 0; + + const uint8_t MSHIFT_MIN_RANGE= 0x08; + const uint8_t MSHIFT_MAX_RANGE= 0x14; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setDigDcOffsetMShift()\n"); +#endif + + if ((mShift < MSHIFT_MIN_RANGE) || (mShift > MSHIFT_MAX_RANGE)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SET_DIG_DC_OFFSET_INV_MSHIFT, + getMykonosErrorMessage(MYKONOS_ERR_SET_DIG_DC_OFFSET_INV_MSHIFT)); + return MYKONOS_ERR_SET_DIG_DC_OFFSET_INV_MSHIFT; + } + + /* check channel and set the address */ + switch (channel) + { + case MYK_DC_OFFSET_RX_CHN: + REG_ADDRESS = MYKONOS_ADDR_DIGITAL_DC_OFFSET_SHIFT; + break; + case MYK_DC_OFFSET_ORX_CHN: + REG_ADDRESS = MYKONOS_ADDR_DIGITAL_DC_OFFSET_CH3_DPD_M_SHIFT; + break; + case MYK_DC_OFFSET_SNF_CHN: + REG_ADDRESS = MYKONOS_ADDR_DIGITAL_DC_OFFSET_SNF; + break; + + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DC_OFFSET_INV_CHAN, + getMykonosErrorMessage(MYKONOS_ERR_DC_OFFSET_INV_CHAN)); + return MYKONOS_ERR_DC_OFFSET_INV_CHAN; + } + + CMB_SPIWriteField(device->spiSettings, REG_ADDRESS, mShift, 0x1F, 0); + + return retVal; +} + +/** + * \brief retrieves the M-Shift value which is the Corner frequency of Rx notch filter for the given channel. + * channel can be one of the following ( ::mykonosDcOffsetChannels_t ). + * + * Channel | Channel description + * ------------------------|-------------------------------- + * MYK_DC_OFFSET_RX_CHN | Selects Rx channel + * MYK_DC_OFFSET_ORX_CHN | Selects ORx channel + * MYK_DC_OFFSET_SNF_CHN | Selects Sniffer channel + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device Pointer to the Mykonos device data structure containing settings + * \param channel receive channel to be selected. + * \param mShift Pointer to the variable to store mshift value of the given channel + * + * \retval MYKONOS_ERR_DC_OFFSET_INV_CHAN channel passed to the function is invalid, refer mykonosDcOffsetChannels_t enum for valid channels. + * \retval MYKONOS_ERR_GET_DIG_DC_OFFSET_NULL_MSHIFT mShift pointer is NULL + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_getDigDcOffsetMShift(mykonosDevice_t *device, mykonosDcOffsetChannels_t channel, uint8_t *mShift) +{ + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint16_t REG_ADDRESS = 0x0; + uint8_t readbackData = 0x0; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getDigDcOffsetMShift()\n"); +#endif + + if (mShift == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GET_DIG_DC_OFFSET_NULL_MSHIFT, + getMykonosErrorMessage(MYKONOS_ERR_GET_DIG_DC_OFFSET_NULL_MSHIFT)); + return MYKONOS_ERR_GET_DIG_DC_OFFSET_NULL_MSHIFT; + } + + /* check for the channel and set the address */ + switch (channel) + { + case MYK_DC_OFFSET_RX_CHN: + REG_ADDRESS = MYKONOS_ADDR_DIGITAL_DC_OFFSET_SHIFT; + break; + case MYK_DC_OFFSET_ORX_CHN: + REG_ADDRESS = MYKONOS_ADDR_DIGITAL_DC_OFFSET_CH3_DPD_M_SHIFT; + break; + case MYK_DC_OFFSET_SNF_CHN: + REG_ADDRESS = MYKONOS_ADDR_DIGITAL_DC_OFFSET_SNF; + break; + + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DC_OFFSET_INV_CHAN, + getMykonosErrorMessage(MYKONOS_ERR_DC_OFFSET_INV_CHAN)); + return MYKONOS_ERR_DC_OFFSET_INV_CHAN; + } + + CMB_SPIReadField(device->spiSettings, REG_ADDRESS, &readbackData, 0x1F,0); + + *mShift = readbackData; + + return retVal; +} + +/** + * \brief Sets the RF PLL loop filter bandwith. + * + * \pre Command should be called in Radio Off state. ARM must be initialized. + * + * \post Loop filter should lock successfully + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - device->spiSettings + * + * \param device is structure pointer to the MYKONOS data structure containing settings + * \param pllName Name of the PLL to configure.RX_PLL and TX_PLL can be configured.SNIFFER_PLL can not be configured. + * \param loopBandwidth_kHz Desired RF pll bandwith to be set. The valid values range of loopBandwidth_kHz for Rx and Tx is 50 to 750.For SRX valid values lies from 500 to 750. + * \param stability PLL Loop stability to be set.The valid values range of stability is from 3 to 15. + * + * \return MYKONOS_ERR_OK Function completed successfully + * \return MYKONOS_ERR_SETRFPLL_LF_ARMERROR ARM Command to set RF PLL loop filter bandwidth failed + * \return MYKONOS_ERR_SETRFPLL_LF_INV_TXRX_LOOPBANDWIDTH Invalid Tx/Rx value bandwith + * \return MYKONOS_ERR_SETRFPLL_LF_PLLNAME Invalid pllName requested + * \return MYKONOS_ERR_SETRFPLL_LF_INV_STABILITY Invalid stability range, valid range is 3-15 + */ +mykonosErr_t MYKONOS_setRfPllLoopFilter(mykonosDevice_t *device, mykonosRfPllName_t pllName, uint16_t loopBandwidth_kHz, uint8_t stability) +{ + const uint8_t SETCMD_OPCODE = 0x0A; + const uint8_t SET_PLL_BANDWIDTH = 0x6D; + const uint16_t LOOP_BW_HIGH = 750; + + uint16_t LOOP_BW_LOW = 50; + uint8_t extData[4] = {0}; + uint8_t cmdStatusByte = 0; + mykonosErr_t retVal = MYKONOS_ERR_OK; + mykonosErr_t errLoopBw = MYKONOS_ERR_OK; + uint32_t timeoutMs = 1000; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setRfPllLoopFilter()\n"); +#endif + + switch (pllName) + { + case RX_PLL: + extData[1] = 0x00; + LOOP_BW_LOW = 50; + errLoopBw = MYKONOS_ERR_SETRFPLL_LF_INV_TXRX_LOOPBANDWIDTH; + break; + case TX_PLL: + extData[1] = 0x10; + LOOP_BW_LOW = 50; + errLoopBw = MYKONOS_ERR_SETRFPLL_LF_INV_TXRX_LOOPBANDWIDTH; + break; + case SNIFFER_PLL: +#if 0 /* Set for Sniffer PLL loop bandwidth is not supported */ + extData[1] = 0x20; + LOOP_BW_LOW = 500; + errLoopBw = MYKONOS_ERR_SETRFPLL_LF_INV_SNF_LOOPBANDWIDTH; + break; +#endif + default: + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETRFPLL_LF_PLLNAME, + getMykonosErrorMessage(MYKONOS_ERR_SETRFPLL_LF_PLLNAME)); + return MYKONOS_ERR_SETRFPLL_LF_PLLNAME; + } + } + + /* Range check for loopBandwidth - Should be between 50kHz and 750kHz for TX/RX and between 500kHz and 750 for SRX*/ + if ((loopBandwidth_kHz< LOOP_BW_LOW) || (loopBandwidth_kHz >LOOP_BW_HIGH)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, errLoopBw, + getMykonosErrorMessage(errLoopBw)); + return errLoopBw; + } + + /* Range check for stability - Should be between 3 and 15 */ + if ((stability < 3) || (stability > 15)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETRFPLL_LF_INV_STABILITY, + getMykonosErrorMessage(MYKONOS_ERR_SETRFPLL_LF_INV_STABILITY)); + return MYKONOS_ERR_SETRFPLL_LF_INV_STABILITY; + } + + /* Generate payload for SET command */ + extData[0] = SET_PLL_BANDWIDTH; + /*left shift and truncate left side*/ + extData[1] |= stability; + extData[2] = (uint8_t)(loopBandwidth_kHz & 0xFF); //full first byte + extData[3] = (uint8_t)(loopBandwidth_kHz >> 8); //two extra bits + + /* executing the SET command */ + retVal = MYKONOS_sendArmCommand(device, SETCMD_OPCODE, &extData[0], sizeof(extData)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* waiting for command to complete */ + retVal = MYKONOS_waitArmCmdStatus(device, SETCMD_OPCODE, timeoutMs, &cmdStatusByte); + + /* performing command status check */ + if (retVal != MYKONOS_ERR_OK) + { + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETRFPLL_LF_ARMERROR, + getMykonosErrorMessage(MYKONOS_ERR_SETRFPLL_LF_ARMERROR)); + return MYKONOS_ERR_SETRFPLL_LF_ARMERROR; + } + + return retVal; + } + + return retVal; +} + +/** + * \brief Gets the RF PLL loop filter bandwidth and stability. + * + * This function is used to get the RF PLL loop bandwidth. It can get the RX PLL, TX PLL + * Sniffer PLL. + * + * \pre Command can be called in Radio Off state or On state. ARM must be initialized. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - device->spiSettings + * - device->clocks->deviceClock_kHz + * + * \param device is structure pointer to the MYKONOS data structure containing settings + * \param pllName Name of the PLL for which to read the frequency + * \param loopBandwidth_kHz RF PLL loop bandwidth for the PLL specified + * \param stability RF PLL loop stability + * + * \retval MYKONOS_ERR_OK Function completed successfully + * \retval MYKONOS_ERR_GETRFPLL_LF_INV_PLLNAME Invalid PLL name, can not get PLL frequency. Use PLL name ENUM. + * \retval MYKONOS_ERR_GETRFPLL_LF_ARMERROR ARM Command to get RF PLL frequency failed + * \retval MYKONOS_ERR_GETRFPLL_LF_NULLPARAM input parameter is NULL + */ +mykonosErr_t MYKONOS_getRfPllLoopFilter(mykonosDevice_t *device, mykonosRfPllName_t pllName, uint16_t *loopBandwidth_kHz, uint8_t *stability) +{ + const uint8_t GET_PLL_BANDWIDTH = 0x6D; + + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint8_t armData[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + uint8_t extData[2] = {GET_PLL_BANDWIDTH, 0}; + uint32_t timeoutMs = 0; + uint8_t cmdStatusByte = 0; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getRfPllLoopFilter()\n"); +#endif + + /* Check for NULL */ + if ((loopBandwidth_kHz == NULL)|| (stability == NULL)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETRFPLL_LF_NULLPARAM, + getMykonosErrorMessage(MYKONOS_ERR_GETRFPLL_LF_NULLPARAM)); + return MYKONOS_ERR_GETRFPLL_LF_NULLPARAM; + } + + switch(pllName) + { + case RX_PLL: extData[1] = 0x00; break; + case TX_PLL: extData[1] = 0x10; break; + case SNIFFER_PLL: extData[1] = 0x20; break; + default: + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETRFPLL_LF_INV_PLLNAME, + getMykonosErrorMessage(MYKONOS_ERR_GETRFPLL_LF_INV_PLLNAME)); + return MYKONOS_ERR_GETRFPLL_LF_INV_PLLNAME; + } + } + /* executing the GET command */ + retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_GET_OPCODE, &extData[0], sizeof(extData)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + timeoutMs = 1000; + + /* waiting for command to complete */ + retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_GET_OPCODE, timeoutMs, &cmdStatusByte); + + /* performing command status check */ + if (retVal != MYKONOS_ERR_OK) + { + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETRFPLL_LF_ARMERROR, + getMykonosErrorMessage(MYKONOS_ERR_GETRFPLL_LF_ARMERROR)); + return MYKONOS_ERR_GETRFPLL_LF_ARMERROR; + } + + return retVal; + } + + /* Read from ARM memory */ + retVal = MYKONOS_readArmMem(device, MYKONOS_ADDR_ARM_START_DATA_ADDR, &armData[0], 8, 1); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + /* Assign to variables */ + *stability = armData[3]; + *loopBandwidth_kHz = (((uint16_t)armData[1]) << 8) | ((uint16_t)armData[0]); + + return MYKONOS_ERR_OK; +} + +/** + * \brief Enable/ Disable Digital DC Offset channels using the channel mask. + * The mask can be a combination of the following channel values ( ::mykonosRxDcOffsettEn_t ). + * + * Channel | Value | Channel description + * -------------------------|---------|-------------------------- + * MYK_DC_OFFSET_ALL_OFF | 0x00 | Disable all the channels + * MYK_DC_OFFSET_RX1 | 0x01 | Enables Rx1 + * MYK_DC_OFFSET_RX2 | 0x02 | Enables Rx1 + * MYK_DC_OFFSET_SNF | 0x04 | Enables Sniffer + * MYK_DC_OFFSET_ORX | 0x08 | Enables ORx + * MYK_DC_OFFSET_AVAILABLE | 0x0F | Enables all the channels + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device Pointer to the Mykonos device data structure containing settings + * \param enableMask with bits of channels to be enabled. + * + * \retval MYKONOS_ERR_DIG_DC_OFFSET_INV_ENABLE_MASK enable mask passed to the function is invalid, refer mykonosRxDcOffsettEn_t enum. + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_setDigDcOffsetEn(mykonosDevice_t *device, uint8_t enableMask) +{ + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint16_t REG_ADDRESS = 0x00; + uint8_t dataToWrite = 0x00; + + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setDigDcOffsetEn()\n"); +#endif + + if (enableMask & ~((uint8_t)MYK_DC_OFFSET_AVAILABLE)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DIG_DC_OFFSET_INV_ENABLE_MASK, + getMykonosErrorMessage(MYKONOS_ERR_DIG_DC_OFFSET_INV_ENABLE_MASK)); + return MYKONOS_ERR_DIG_DC_OFFSET_INV_ENABLE_MASK; + } + + REG_ADDRESS = MYKONOS_ADDR_DIGITAL_DC_OFFSET_CONFIG; /* Address for Rx Digital tracking Enable bits register */ + if (enableMask & ((uint8_t)MYK_DC_OFFSET_RX1 | (uint8_t)MYK_DC_OFFSET_RX2)) /* Enable / Disable Rx1 and/or Rx2 */ + { + dataToWrite |= ((enableMask & ((uint8_t)MYK_DC_OFFSET_RX1 |(uint8_t) MYK_DC_OFFSET_RX2)) << 1 ); + } + CMB_SPIWriteField(device->spiSettings, REG_ADDRESS, dataToWrite, 0x06,0); /* Write RX enable bits to the register */ + + dataToWrite = 0x0; /* Reset dataToWrite */ + REG_ADDRESS = MYKONOS_DIGITAL_DC_OFFSET_CH3_TRACKING; /* Address for ORx and Sniffer Digital trackingEnable bits register */ + if (enableMask & ((uint8_t)MYK_DC_OFFSET_SNF | (uint8_t)MYK_DC_OFFSET_ORX)) /* Check for channel ORx and/or Sniffer */ + { + dataToWrite |= ((enableMask & ((uint8_t)MYK_DC_OFFSET_SNF | (uint8_t)MYK_DC_OFFSET_ORX))>>2); + } + CMB_SPIWriteField(device->spiSettings, REG_ADDRESS, dataToWrite, 0x03,0); /* Write Loopback, ORx and Sniffer enable bits to the register */ + + return retVal; +} + +/** + * \brief reads Enable/ Disable channels Digital DC Offset and returns a mask of it. + * The mask returned will be a combination of the following channel values ( ::mykonosRxDcOffsettEn_t ). + * + * Channel | Value | Channel description + * -------------------------|---------|-------------------------- + * MYK_DC_OFFSET_ALL_OFF | 0x00 | All channels are disabled + * MYK_DC_OFFSET_RX1 | 0x01 | Rx1 is enabled + * MYK_DC_OFFSET_RX2 | 0x02 | Rx2 is enabled + * MYK_DC_OFFSET_SNF | 0x04 | Sniffer is enabled + * MYK_DC_OFFSET_ORX | 0x08 | ORx is enabled + * MYK_DC_OFFSET_AVAILABLE | 0x0F | All channels are enabled + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device Pointer to the Mykonos device data structure containing settings + * \param enableMask pointer to the variable to store Enable mask of channels + * + * \retval MYKONOS_ERR_DIG_DC_OFFSET_NULL_ENABLE_MASK enableMask is NULL + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_getDigDcOffsetEn(mykonosDevice_t *device,uint8_t *enableMask) +{ + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint16_t REG_ADDRESS = 0; + uint8_t readbackData = 0; + uint8_t enableMaskData = 0; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getDigDcOffsetEn()\n"); +#endif + + if (enableMask == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DIG_DC_OFFSET_NULL_ENABLE_MASK, + getMykonosErrorMessage(MYKONOS_ERR_DIG_DC_OFFSET_NULL_ENABLE_MASK)); + return MYKONOS_ERR_DIG_DC_OFFSET_NULL_ENABLE_MASK; + } + + REG_ADDRESS = MYKONOS_ADDR_DIGITAL_DC_OFFSET_CONFIG; /* register address of Rx1 and Rx2 enable bits*/ + CMB_SPIReadField(device->spiSettings, REG_ADDRESS, &readbackData, 0x06,0); + enableMaskData |= (readbackData>>1); /* adjust bits to match channel :refer enum mykonosRfDcOffsettEn_t. */ + + readbackData = 0x00; + REG_ADDRESS = MYKONOS_DIGITAL_DC_OFFSET_CH3_TRACKING; /* register address of Orx and sniffer enable bits*/ + CMB_SPIReadField(device->spiSettings, REG_ADDRESS, &readbackData, 0x03,0); + enableMaskData |= (uint8_t)(readbackData<<2); /* adjust bits to match channel :refer enum mykonosRfDcOffsettEn_t. */ + + *enableMask = enableMaskData; + + return retVal; +} + +/** + * \brief This function will configure the path delay settings for all the features: + * DPD, VSWR and CLGC. + * + * A DPD device is required. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - device->profilesValid + * + * \param device Pointer to the Mykonos device data structure containing settings + * \param pathDelay pointer to structure of type ::mykonosPathdelay_t to be programmed + * + * \retval MYKONOS_ERR_SET_PATH_DELAY_NULL_PARAM pathDelay is null + * \retval MYKONOS_ERR_SET_PATH_DELAY_PARAM_OUT_OF_RANGE path delay valid range is from 0 to 4095 at 1/16 sample resolution of ORx sample rate + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_setPathDelay(mykonosDevice_t *device, mykonosPathdelay_t *pathDelay) +{ + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint8_t armFieldValue[16] = {0}; + uint8_t extData[3] = {(uint8_t)MYKONOS_ARM_OBJECTID_TRACKING_CAL_CONTROL, (uint8_t)SET_PATH_DELAY, 0}; + uint8_t writeSize = 0; + uint8_t fifoDel[4] = {0}; + uint8_t interpIndex[4] = {0}; + uint32_t *delPointer = &pathDelay->forwardPathDelayCh1; + uint8_t i = 0; + + const uint32_t RANGE_PATH_DELAY = 4095; + const uint8_t PATH_DELAY_SIZE = 4; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setPathDelay()\n"); +#endif + + if (pathDelay == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SET_PATH_DELAY_NULL_PARAM, + getMykonosErrorMessage(MYKONOS_ERR_SET_PATH_DELAY_NULL_PARAM)); + return MYKONOS_ERR_SET_PATH_DELAY_NULL_PARAM; + } + + /* Loop to set the ARM memory data */ + for (i = 0; i < PATH_DELAY_SIZE ; i++) + { + /* Verify all the data in the structure is in range */ + if (*delPointer > RANGE_PATH_DELAY) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SET_PATH_DELAY_PARAM_OUT_OF_RANGE, + getMykonosErrorMessage(MYKONOS_ERR_SET_PATH_DELAY_PARAM_OUT_OF_RANGE)); + return MYKONOS_ERR_SET_PATH_DELAY_PARAM_OUT_OF_RANGE; + } + + fifoDel[i] = (uint8_t)(*delPointer >> 4); + interpIndex[i] = (uint8_t)(*delPointer - (fifoDel[i] * 16)); + + delPointer++; + } + + if ((device->tx->vswrConfig == NULL) || ((pathDelay->reversePathDelayCh1 == 0) && (pathDelay->reversePathDelayCh2 == 0))) + { + armFieldValue[0] = interpIndex[0]; + armFieldValue[1] = 0; + armFieldValue[2] = fifoDel[0]; + armFieldValue[3] = 0; + armFieldValue[4] = interpIndex[2]; + armFieldValue[5] = 0; + armFieldValue[6] = fifoDel[2]; + armFieldValue[7] = 0; + extData[2] = 0; + writeSize = 8; + } + else + { + armFieldValue[0] = interpIndex[0]; + armFieldValue[1] = 0; + armFieldValue[2] = fifoDel[0]; + armFieldValue[3] = 0; + armFieldValue[4] = interpIndex[2]; + armFieldValue[5] = 0; + armFieldValue[6] = fifoDel[2]; + armFieldValue[7] = 0; + armFieldValue[8] = interpIndex[1]; + armFieldValue[9] = 0; + armFieldValue[10] = fifoDel[1]; + armFieldValue[11] = 0; + armFieldValue[12] = interpIndex[3]; + armFieldValue[13] = 0; + armFieldValue[14] = fifoDel[3]; + armFieldValue[15] = 0; + extData[2] = 1; + writeSize = 16; + } + + retVal = MYKONOS_writeArmMem(device, MYKONOS_ADDR_ARM_START_DATA_ADDR, &armFieldValue[0], writeSize); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_SET_OPCODE, &extData[0], sizeof(extData)); + + return retVal; +} + +/** + * \brief This function will read the current path delay settings for the selected calibration. + * + * A DPD-enabled transceiver is required + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - device->profilesValid + * + * \param device Pointer to the Mykonos device data structure containing settings + * \param select path delay status selection from ::mykonosPathDelaySel_t + * \param pathDelay pointer to structure of type ::mykonosPathdelay_t to store the read back path delay + * + * \retval MYKONOS_ERR_GET_PATH_DELAY_NULL_PARAM pathDelay is null + * \retval MYKONOS_ERR_GET_PATH_DELAY_INVALID_SELECTION invalid selection for getting the path delay, valid selections are given by mykonosPathDelaySel_t + * \retval MYKONOS_ERR_GET_PATH_DELAY_ARMERRFLAG Arm error while reading path delay for the selected calibration status + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_getPathDelay(mykonosDevice_t *device, mykonosPathDelaySel_t select, mykonosPathdelay_t *pathDelay) +{ + uint8_t extData[3] = {(uint8_t)MYKONOS_ARM_OBJECTID_CAL_STATUS, (uint8_t)MYKONOS_ARM_OBJECTID_VSWRCONFIG, 0}; + uint8_t armData[80] = {0}; + uint32_t timeoutMs = 0; + uint8_t cmdStatusByte = 0; + uint32_t *delPointer = &pathDelay->forwardPathDelayCh1; + uint8_t channel = 0; + uint8_t addr[4] = {0}; + mykonosErr_t retVal = MYKONOS_ERR_OK; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getPathDelay()\n"); +#endif + + if (pathDelay == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GET_PATH_DELAY_NULL_PARAM, + getMykonosErrorMessage(MYKONOS_ERR_GET_PATH_DELAY_NULL_PARAM)); + return MYKONOS_ERR_GET_PATH_DELAY_NULL_PARAM; + } + + switch (select) + { + case MYK_DPD_PATH_DELAY: + extData[1] = MYKONOS_ARM_OBJECTID_DPDCONFIG; + addr[0] = 24; + addr[1] = 26; + addr[2] = 0; + addr[3] = 0; + break; + case MYK_CLGC_PATH_DELAY: + extData[1] = MYKONOS_ARM_OBJECTID_CLGCCONFIG; + addr[0] = 60; + addr[1] = 62; + addr[2] = 0; + addr[3] = 0; + break; + case MYK_VSWR_PATH_DELAY: + extData[1] = MYKONOS_ARM_OBJECTID_VSWRCONFIG; + addr[0] = 72; + addr[1] = 74; + addr[2] = 76; + addr[3] = 78; + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GET_PATH_DELAY_INVALID_SELECTION, + getMykonosErrorMessage(MYKONOS_ERR_GET_PATH_DELAY_INVALID_SELECTION)); + return MYKONOS_ERR_GET_PATH_DELAY_INVALID_SELECTION; + } + + /* reading 2 channels, channel being the channel selector */ + for (channel = 0; channel < 2; channel++) + { + if (channel) + { + delPointer++; + } + + extData[2] = channel; + + retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_GET_OPCODE, &extData[0], sizeof(extData)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + timeoutMs = 1000; + retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_GET_OPCODE, timeoutMs, &cmdStatusByte); + if (retVal != MYKONOS_ERR_OK) + { + /* throw more specific error message instead of returning error code from waitArmCmdStatus */ + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GET_PATH_DELAY_ARMERRFLAG, + getMykonosErrorMessage(MYKONOS_ERR_GET_PATH_DELAY_ARMERRFLAG)); + return MYKONOS_ERR_GET_PATH_DELAY_ARMERRFLAG; + } + + return retVal; + } + + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GET_PATH_DELAY_ARMERRFLAG, + getMykonosErrorMessage(MYKONOS_ERR_GET_PATH_DELAY_ARMERRFLAG)); + return MYKONOS_ERR_GET_PATH_DELAY_ARMERRFLAG; + } + + /* read status from ARM memory */ + retVal = MYKONOS_readArmMem(device, MYKONOS_ADDR_ARM_START_DATA_ADDR, &armData[0], sizeof(armData), 1); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + *delPointer = ((uint32_t)(armData[addr[1]]) * 16) + (uint32_t)(armData[addr[0]]); + delPointer++; + if ((addr[2] != 0) && (addr[3] != 0)) + { + /* reverse path delay only applies to VSWR */ + *delPointer = ((uint32_t)(armData[addr[3]]) * 16) + (uint32_t)(armData[addr[2]]); + } + else + { + /* the rest of path delays will not have a reverse delay value */ + *delPointer = 0; + } + } + + return retVal; +} + +/** + * \brief This function reads the current error counters for all the DPD error codes from ::mykonosDpdErrors_t. + * + * A DPD-enabled transceiver is required + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - device->profilesValid + * + * \param device Pointer to the Mykonos device data structure containing settings + * \param txChannel Tx channel selection from ::mykonosTxChannels_t + * \param dpdErrCnt pointer to structure of type ::mykonosDpdErrorCounters_t to store the read back error counters + * + * \retval MYKONOS_ERR_GETDPD_ERROR_CNT_NULLPARAM dpdErrCnt is null + * \retval MYKONOS_ERR_GETDPD_ERROR_CNT_INV_CH invalid selection for getting the error counters tx channel, only valid values are Tx1 and Tx2 + * \retval MYKONOS_ERR_GETDPD_ERROR_CNT_ARMERRFLAG Arm error while reading the error counters for the DPD status + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_getDpdErrorCounters(mykonosDevice_t *device, mykonosTxChannels_t txChannel, mykonosDpdErrorCounters_t *dpdErrCnt) +{ + uint8_t extData[3] = {MYKONOS_ARM_OBJECTID_CAL_STATUS, MYKONOS_ARM_OBJECTID_DPDCONFIG, 0}; + uint8_t armData[200] = {0}; + uint32_t timeoutMs = 0; + uint8_t cmdStatusByte = 0; + uint8_t loop = 0; + uint8_t index = 0; + uint8_t channelSelect = 0; + mykonosErr_t retVal = MYKONOS_ERR_OK; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getDpdErrorCounters()\n"); +#endif + + if (dpdErrCnt == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETDPD_ERROR_CNT_NULLPARAM, + getMykonosErrorMessage(MYKONOS_ERR_GETDPD_ERROR_CNT_NULLPARAM)); + return MYKONOS_ERR_GETDPD_ERROR_CNT_NULLPARAM; + } + + switch (txChannel) + { + case TX1: + channelSelect = 0; + break; + case TX2: + channelSelect = 1; + break; + default: + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETDPD_ERROR_CNT_INV_CH, + getMykonosErrorMessage(MYKONOS_ERR_GETDPD_ERROR_CNT_INV_CH)); + return MYKONOS_ERR_GETDPD_ERROR_CNT_INV_CH; + } + } + + extData[2] = channelSelect; + + retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_GET_OPCODE, &extData[0], sizeof(extData)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + timeoutMs = 1000; + retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_GET_OPCODE, timeoutMs, &cmdStatusByte); + if (retVal != MYKONOS_ERR_OK) + { + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETDPD_ERROR_CNT_ARMERRFLAG, + getMykonosErrorMessage(MYKONOS_ERR_GETDPD_ERROR_CNT_ARMERRFLAG)); + return MYKONOS_ERR_GETDPD_ERROR_CNT_ARMERRFLAG; + } + + return retVal; + } + + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETDPD_ERROR_CNT_ARMERRFLAG, + getMykonosErrorMessage(MYKONOS_ERR_GETDPD_ERROR_CNT_ARMERRFLAG)); + return MYKONOS_ERR_GETDPD_ERROR_CNT_ARMERRFLAG; + } + + /* read status from ARM memory */ + retVal = MYKONOS_readArmMem(device, MYKONOS_ADDR_ARM_START_DATA_ADDR, &armData[0], sizeof(armData), 1); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + dpdErrCnt->dpdErrorCount = ((uint32_t)(armData[67]) << 24) | ((uint32_t)(armData[66]) << 16) | ((uint32_t)(armData[65]) << 8) | (uint32_t)(armData[64]); + index = 68; + for (loop = 1; loop < (uint8_t)MYK_DPD_ERROR_END; loop++) + { + dpdErrCnt->errorCounter[loop] = ((uint32_t)(armData[index + 3]) << 24) | ((uint32_t)(armData[index + 2]) << 16) | ((uint32_t)(armData[index + 1]) << 8) | (uint32_t)(armData[index]); + index +=4; + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief DPD feature to set the bypassing actuator when Tx signal power is below a programmable threshold given in + * ::mykonosDpdBypassConfig_t lowPowerActuatorBypassLevel. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - device->profilesValid + * + * \param device Pointer to the Mykonos device data structure containing settings + * \param actConfig Pointer to actuator structure of type ::mykonosDpdBypassConfig_t which contains the settings to be programmed + * + * \retval MYKONOS_ERR_SETDPDACT_NULL_ACTSTRUCT passed structure is null + * \retval MYKONOS_ERR_SETDPDACT_INV_ACTMODE invalid mode in actConfig->lowPowerActuatorBypassMode for valid modes ::mykonosDpdResetMode_t + * \retval MYKONOS_ERR_SETDPDACT_INV_LEVEL actConfig->lowPowerActuatorBypassLevel outside the range, valid range is 0 to 6000 (0 to 60dB) + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_setDpdBypassConfig(mykonosDevice_t *device, mykonosDpdBypassConfig_t *actConfig) +{ + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint8_t armFieldValue[4] = {0}; + uint8_t byteOffset = 62; + + const uint16_t LEVEL_RANGE_CHECK = 6000; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setDpdBypassConfig()\n"); +#endif + + if (actConfig == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETDPDACT_NULL_ACTSTRUCT, + getMykonosErrorMessage(MYKONOS_ERR_SETDPDACT_NULL_ACTSTRUCT)); + return MYKONOS_ERR_SETDPDACT_NULL_ACTSTRUCT; + } + + if (actConfig->bypassActuatorMode >= MYK_DPD_RESET_END) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETDPDACT_INV_ACTMODE, + getMykonosErrorMessage(MYKONOS_ERR_SETDPDACT_INV_ACTMODE)); + return MYKONOS_ERR_SETDPDACT_INV_ACTMODE; + } + + if (actConfig->bypassActuatorLevel > LEVEL_RANGE_CHECK) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETDPDACT_INV_LEVEL, + getMykonosErrorMessage(MYKONOS_ERR_SETDPDACT_INV_LEVEL)); + return MYKONOS_ERR_SETDPDACT_INV_LEVEL; + } + + armFieldValue[0] = (actConfig->bypassActuatorEn > 0) ? 1 : 0; + armFieldValue[1] = (uint8_t)(actConfig->bypassActuatorMode); + armFieldValue[2] = (uint8_t)(actConfig->bypassActuatorLevel & 0xFF); + armFieldValue[3] = (uint8_t)((actConfig->bypassActuatorLevel >> 8) & 0xFF); + + retVal = MYKONOS_writeArmConfig(device, MYKONOS_ARM_OBJECTID_DPDCONFIG, byteOffset, &armFieldValue[0], sizeof(armFieldValue)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + return MYKONOS_ERR_OK; +} + +/** + * \brief Get configuration for bypassing DPD actuator + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - device->profilesValid + * + * \param device Pointer to the Mykonos device data structure containing settings + * \param actConfig actuator structure of type ::mykonosDpdBypassConfig_t + * + * \retval MYKONOS_ERR_GETDPDACT_NULL_ACTSTRUCT passed structure is null + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_getDpdBypassConfig(mykonosDevice_t *device, mykonosDpdBypassConfig_t *actConfig) +{ + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint8_t armFieldValue[4] = {0}; + uint8_t byteOffset = 62; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getDpdBypassConfig()\n"); +#endif + + if (actConfig == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETDPDACT_NULL_ACTSTRUCT, + getMykonosErrorMessage(MYKONOS_ERR_GETDPDACT_NULL_ACTSTRUCT)); + return MYKONOS_ERR_GETDPDACT_NULL_ACTSTRUCT; + } + + retVal = MYKONOS_readArmConfig(device, MYKONOS_ARM_OBJECTID_DPDCONFIG, byteOffset, &armFieldValue[0], sizeof(armFieldValue)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + actConfig->bypassActuatorEn = armFieldValue[0]; + actConfig->bypassActuatorMode = (mykonosDpdResetMode_t)armFieldValue[1]; + actConfig->bypassActuatorLevel = (uint16_t)(((uint16_t)(armFieldValue[3]) << 8) | (uint16_t)(armFieldValue[2])); + + return MYKONOS_ERR_OK; +} + +/** + * \brief DPD feature to set the actuator gain difference check. + * If the gain before and after the actuator exceeds the value actCheck->actuatorGainCheckLevel an error will be issued + * and the actuator will reset depending on the actCheck->actuatorGainCheckMode. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - device->profilesValid + * + * \param device Pointer to the Mykonos device data structure containing settings + * \param actCheck Pointer to structure of type mykonosDpdActuatorCheck_t which contains the settings to be programmed + * + * \retval MYKONOS_ERR_SETDPDACTCHECK_NULL_ACTSTRUCT passed structure is null + * \retval MYKONOS_ERR_SETDPDACTCHECK_INV_ACTMODE invalid mode in actCheck->actuatorGainCheckMode for valid modes ::mykonosDpdResetMode_t + * \retval MYKONOS_ERR_SETDPDACTCHECK_INV_LEVEL actCheck->actuatorGainCheckLevel outside the range, valid range is from 0 to 3000 (0 to 30dB) + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_setDpdActuatorCheck(mykonosDevice_t *device, mykonosDpdActuatorCheck_t *actCheck) +{ + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint8_t armFieldValue[4] = {0}; + uint8_t byteOffset = 58; + + const uint16_t LEVEL_RANGE_CHECK = 3000; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setDpdActuatorCheck()\n"); +#endif + + if (actCheck == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETDPDACTCHECK_NULL_ACTSTRUCT, + getMykonosErrorMessage(MYKONOS_ERR_SETDPDACTCHECK_NULL_ACTSTRUCT)); + return MYKONOS_ERR_SETDPDACTCHECK_NULL_ACTSTRUCT; + } + + if (actCheck->actuatorGainCheckMode >= MYK_DPD_RESET_END) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETDPDACTCHECK_INV_ACTMODE, + getMykonosErrorMessage(MYKONOS_ERR_SETDPDACTCHECK_INV_ACTMODE)); + return MYKONOS_ERR_SETDPDACTCHECK_INV_ACTMODE; + } + + if (actCheck->actuatorGainCheckLevel > LEVEL_RANGE_CHECK) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETDPDACTCHECK_INV_LEVEL, + getMykonosErrorMessage(MYKONOS_ERR_SETDPDACTCHECK_INV_LEVEL)); + return MYKONOS_ERR_SETDPDACTCHECK_INV_LEVEL; + } + + armFieldValue[0] = (actCheck->actuatorGainCheckEn > 0) ? 1 : 0; + armFieldValue[1] = (uint8_t)(actCheck->actuatorGainCheckMode); + armFieldValue[2] = (uint8_t)(actCheck->actuatorGainCheckLevel & 0xFF); + armFieldValue[3] = (uint8_t)((actCheck->actuatorGainCheckLevel >> 8) & 0xFF); + + retVal = MYKONOS_writeArmConfig(device, MYKONOS_ARM_OBJECTID_DPDCONFIG, byteOffset, &armFieldValue[0], sizeof(armFieldValue)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + return MYKONOS_ERR_OK; +} + + +/** + * \brief Get configuration for DPD actuator check + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - device->profilesValid + * + * \param device Pointer to the Mykonos device data structure containing settings + * \param actCheck Pointer to structure of type mykonosDpdActuatorCheck_t which will contain the programmed settings + * + * \retval MYKONOS_ERR_GETDPDACTCHECK_NULL_ACTSTRUCT passed structure is null + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_getDpdActuatorCheck(mykonosDevice_t *device, mykonosDpdActuatorCheck_t *actCheck) +{ + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint8_t armFieldValue[4] = {0}; + uint8_t byteOffset = 58; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getDpdActuatorCheck()\n"); +#endif + + if (actCheck == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETDPDACTCHECK_NULL_ACTSTRUCT, + getMykonosErrorMessage(MYKONOS_ERR_GETDPDACTCHECK_NULL_ACTSTRUCT)); + return MYKONOS_ERR_GETDPDACTCHECK_NULL_ACTSTRUCT; + } + + retVal = MYKONOS_readArmConfig(device, MYKONOS_ARM_OBJECTID_DPDCONFIG, byteOffset, &armFieldValue[0], sizeof(armFieldValue)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + actCheck->actuatorGainCheckEn = armFieldValue[0]; + actCheck->actuatorGainCheckMode = (mykonosDpdResetMode_t)armFieldValue[1]; + actCheck->actuatorGainCheckLevel = (uint16_t)(((uint16_t)(armFieldValue[3]) << 8) | (uint16_t)(armFieldValue[2])); + + return MYKONOS_ERR_OK; +} + + +/** + * \brief CLGC feature to set the TX attenuation tuning range to a relative range around a nominal value + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - device->profilesValid + * + * \param device Pointer to the Mykonos device data structure containing settings + * \param attRangeCfg Pointer to structure of type mykonosClgcAttenTuningConfig_t which contains the settings to be programmed + * + * \retval MYKONOS_ERR_CFGCLGC_TXORX_PROFILE_INV Tx and ObsRx profiles must be valid to use the CLGC feature + * \retval MYKONOS_ERR_CLGCATTENTUNCFG_NULL_ATTRANGECFGSTRUCT Passed structure is null + * \retval MYKONOS_ERR_CLGCATTENTUNCFG_INVALID_MODE Invalid mode in attRangeCfg member, for valid modes ::mykonosClgcAttenTuningMode_t + * \retval MYKONOS_ERR_CLGCATTENTUNCFG_INVALID_PRESET Invalid AttenTuningPreset in attRangeCfg member, valid range is from 0 to 839 (0 to 41.95dB) + * \retval MYKONOS_ERR_CLGCATTENTUNCFG_INVALID_RANGE Invalid AttenTuningRange in attRangeCfg member, valid range is from 0 to 420 (0 to 21dB) + * \retval MYKONOS_ERR_CLGCATTENTUNCFG_INVALID_TX1_SETTINGS Invalid Tx1 AttenTuningRange and AttenTuningPreset combination + * \retval MYKONOS_ERR_CLGCATTENTUNCFG_INVALID_TX2_SETTINGS Invalid Tx2 AttenTuningRange and AttenTuningPreset combination + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_setClgcAttenTuningConfig(mykonosDevice_t *device, mykonosClgcAttenTuningConfig_t *attRangeCfg) +{ + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint8_t armFieldValue[10] = {0}; + uint8_t byteOffset = 0x2C; + + const uint16_t PRESET_CHECK = 840; + const uint16_t RANGE_CHECK = 420; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setClgcAttenTuningConfig()\n"); +#endif + + /* CLGC requires Tx and ORx enabled, throw error if both are not enabled */ + if ((device->profilesValid & (TX_PROFILE_VALID | ORX_PROFILE_VALID)) != (TX_PROFILE_VALID | ORX_PROFILE_VALID)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGCLGC_TXORX_PROFILE_INV, + getMykonosErrorMessage(MYKONOS_ERR_CFGCLGC_TXORX_PROFILE_INV)); + return MYKONOS_ERR_CFGCLGC_TXORX_PROFILE_INV; + } + + if (attRangeCfg == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CLGCATTENTUNCFG_NULL_ATTRANGECFGSTRUCT, + getMykonosErrorMessage(MYKONOS_ERR_CLGCATTENTUNCFG_NULL_ATTRANGECFGSTRUCT)); + return MYKONOS_ERR_CLGCATTENTUNCFG_NULL_ATTRANGECFGSTRUCT; + } + + /* Range checks */ + if ((attRangeCfg->tx1AttenTuningLimitMode >= MYK_CLGC_ATTEN_END) || (attRangeCfg->tx2AttenTuningLimitMode >= MYK_CLGC_ATTEN_END)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CLGCATTENTUNCFG_INVALID_MODE, + getMykonosErrorMessage(MYKONOS_ERR_CLGCATTENTUNCFG_INVALID_MODE)); + return MYKONOS_ERR_CLGCATTENTUNCFG_INVALID_MODE; + } + + if ((attRangeCfg->tx1AttenTuningPreset >= PRESET_CHECK) || (attRangeCfg->tx2AttenTuningPreset >= PRESET_CHECK)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CLGCATTENTUNCFG_INVALID_PRESET, + getMykonosErrorMessage(MYKONOS_ERR_CLGCATTENTUNCFG_INVALID_PRESET)); + return MYKONOS_ERR_CLGCATTENTUNCFG_INVALID_PRESET; + } + + if ((attRangeCfg->tx1AttenTuningRange > RANGE_CHECK) || (attRangeCfg->tx2AttenTuningRange > RANGE_CHECK)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CLGCATTENTUNCFG_INVALID_RANGE, + getMykonosErrorMessage(MYKONOS_ERR_CLGCATTENTUNCFG_INVALID_RANGE)); + return MYKONOS_ERR_CLGCATTENTUNCFG_INVALID_RANGE; + } + + if (((attRangeCfg->tx1AttenTuningPreset - attRangeCfg->tx1AttenTuningRange) < 0) || + ((attRangeCfg->tx1AttenTuningPreset + attRangeCfg->tx1AttenTuningRange) > PRESET_CHECK)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CLGCATTENTUNCFG_INVALID_TX1_SETTINGS, + getMykonosErrorMessage(MYKONOS_ERR_CLGCATTENTUNCFG_INVALID_TX1_SETTINGS)); + return MYKONOS_ERR_CLGCATTENTUNCFG_INVALID_TX1_SETTINGS; + } + + if (((attRangeCfg->tx2AttenTuningPreset - attRangeCfg->tx2AttenTuningRange) < 0) || + ((attRangeCfg->tx2AttenTuningPreset + attRangeCfg->tx2AttenTuningRange) > PRESET_CHECK)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CLGCATTENTUNCFG_INVALID_TX2_SETTINGS, + getMykonosErrorMessage(MYKONOS_ERR_CLGCATTENTUNCFG_INVALID_TX2_SETTINGS)); + return MYKONOS_ERR_CLGCATTENTUNCFG_INVALID_TX2_SETTINGS; + } + + armFieldValue[0] = (uint8_t)(attRangeCfg->tx1AttenTuningLimitMode & 0xFF); + armFieldValue[1] = (uint8_t)(attRangeCfg->tx2AttenTuningLimitMode & 0xFF); + armFieldValue[2] = (uint8_t)(attRangeCfg->tx1AttenTuningPreset & 0xFF); + armFieldValue[3] = (uint8_t)((attRangeCfg->tx1AttenTuningPreset >> 8) & 0xFF); + armFieldValue[4] = (uint8_t)(attRangeCfg->tx2AttenTuningPreset & 0xFF); + armFieldValue[5] = (uint8_t)((attRangeCfg->tx2AttenTuningPreset >> 8) & 0xFF); + armFieldValue[6] = (uint8_t)(attRangeCfg->tx1AttenTuningRange & 0xFF); + armFieldValue[7] = (uint8_t)((attRangeCfg->tx1AttenTuningRange >> 8) & 0xFF); + armFieldValue[8] = (uint8_t)(attRangeCfg->tx2AttenTuningRange & 0xFF); + armFieldValue[9] = (uint8_t)((attRangeCfg->tx2AttenTuningRange >> 8) & 0xFF); + + retVal = MYKONOS_writeArmConfig(device, MYKONOS_ARM_OBJECTID_CLGCCONFIG, byteOffset, &armFieldValue[0], sizeof(armFieldValue)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + return MYKONOS_ERR_OK; +} + + +/** + * \brief Get configuration for CLGC Tx attenuation tuning range. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - device->profilesValid + * + * \param device Pointer to the Mykonos device data structure containing settings + * \param attRangeCfg Pointer to structure of type mykonosClgcAttenTuningConfig_t which will contain the programmed settings + * + * \retval MYKONOS_ERR_CLGCATTENTUNCFGGET_NULL_ATTRANGECFGSTRUCT passed structure is null + * \retval MYKONOS_ERR_OK Function completed successfully + */ +mykonosErr_t MYKONOS_getClgcAttenTuningConfig(mykonosDevice_t *device, mykonosClgcAttenTuningConfig_t *attRangeCfg) +{ + mykonosErr_t retVal = MYKONOS_ERR_OK; + uint8_t armFieldValue[10] = {0}; + uint8_t byteOffset = 0x2C; + +#if (MYKONOS_VERBOSE == 1) + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getClgcAttenTuningConfig()\n"); +#endif + + if (attRangeCfg == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CLGCATTENTUNCFGGET_NULL_ATTRANGECFGSTRUCT, + getMykonosErrorMessage(MYKONOS_ERR_CLGCATTENTUNCFGGET_NULL_ATTRANGECFGSTRUCT)); + return MYKONOS_ERR_CLGCATTENTUNCFGGET_NULL_ATTRANGECFGSTRUCT; + } + + retVal = MYKONOS_readArmConfig(device, MYKONOS_ARM_OBJECTID_CLGCCONFIG, byteOffset, &armFieldValue[0], sizeof(armFieldValue)); + if (retVal != MYKONOS_ERR_OK) + { + return retVal; + } + + attRangeCfg->tx1AttenTuningLimitMode = (mykonosClgcAttenTuningMode_t)armFieldValue[0]; + attRangeCfg->tx2AttenTuningLimitMode = (mykonosClgcAttenTuningMode_t)armFieldValue[1]; + attRangeCfg->tx1AttenTuningPreset = (uint16_t)(((uint16_t)(armFieldValue[3]) << 8) | (uint16_t)(armFieldValue[2])); + attRangeCfg->tx2AttenTuningPreset = (uint16_t)(((uint16_t)(armFieldValue[5]) << 8) | (uint16_t)(armFieldValue[4])); + attRangeCfg->tx1AttenTuningRange = (uint16_t)(((uint16_t)(armFieldValue[7]) << 8) | (uint16_t)(armFieldValue[6])); + attRangeCfg->tx2AttenTuningRange = (uint16_t)(((uint16_t)(armFieldValue[9]) << 8) | (uint16_t)(armFieldValue[8])); + + return MYKONOS_ERR_OK; +} diff --git a/df_datalink_ge/src/hardware/mykonos/mykonos.h b/df_datalink_ge/src/hardware/mykonos/mykonos.h new file mode 100644 index 0000000..b852b58 --- /dev/null +++ b/df_datalink_ge/src/hardware/mykonos/mykonos.h @@ -0,0 +1,277 @@ +/*! + * \file mykonos.h + * \brief Contains macro definitions and function prototypes for mykonos.c + * + * Mykonos API version: 1.5.2.3566 + */ + +/** +* \page Disclaimer Legal Disclaimer +* Copyright 2015-2017 Analog Devices Inc. +* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file. +* +*/ + +#ifndef _MYKONOS_LIB_H_ +#define _MYKONOS_LIB_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "t_mykonos.h" +#include "mykonos_version.h" + +#define TX_PROFILE_VALID 0x01 +#define RX_PROFILE_VALID 0x02 +#define ORX_PROFILE_VALID 0x04 +#define SNIFF_PROFILE_VALID 0x08 + +/* + **************************************************************************** + * General Initialization functions + **************************************************************************** + */ +mykonosErr_t MYKONOS_resetDevice(mykonosDevice_t *device); +mykonosErr_t MYKONOS_getDeviceRev(mykonosDevice_t *device, uint8_t *revision); +mykonosErr_t MYKONOS_getProductId(mykonosDevice_t *device, uint8_t *productId); +mykonosErr_t MYKONOS_setSpiSettings(mykonosDevice_t *device); +mykonosErr_t MYKONOS_verifyDeviceDataStructure(mykonosDevice_t *device); +mykonosErr_t MYKONOS_verifyProfiles(mykonosDevice_t *device); +mykonosErr_t MYKONOS_initialize(mykonosDevice_t *device); +mykonosErr_t MYKONOS_waitForEvent(mykonosDevice_t *device, waitEvent_t waitEvent, uint32_t timeout_us); +mykonosErr_t MYKONOS_readEventStatus(mykonosDevice_t *device, waitEvent_t waitEvent, uint8_t *eventDone); +mykonosErr_t MYKONOS_getApiVersion (mykonosDevice_t *device, uint32_t *siVer, uint32_t *majorVer, uint32_t *minorVer, uint32_t *buildVer); + +/* + ***************************************************************************** + * PLL / Synthesizer functions + ***************************************************************************** + */ +mykonosErr_t MYKONOS_initDigitalClocks(mykonosDevice_t *device); +mykonosErr_t MYKONOS_setRfPllFrequency(mykonosDevice_t *device, mykonosRfPllName_t pllName, uint64_t rfPllLoFrequency_Hz); +mykonosErr_t MYKONOS_getRfPllFrequency(mykonosDevice_t *device, mykonosRfPllName_t pllName, uint64_t *rfPllLoFrequency_Hz); +mykonosErr_t MYKONOS_checkPllsLockStatus(mykonosDevice_t *device, uint8_t *pllLockStatus); +mykonosErr_t MYKONOS_setRfPllLoopFilter(mykonosDevice_t *device, mykonosRfPllName_t pllName, uint16_t loopBandwidth_kHz, uint8_t stability); +mykonosErr_t MYKONOS_getRfPllLoopFilter(mykonosDevice_t *device, mykonosRfPllName_t pllName, uint16_t *loopBandwidth_kHz, uint8_t *stability); +/* + ***************************************************************************** + * ARM Processor Control Functions + ***************************************************************************** + */ +mykonosErr_t MYKONOS_initArm(mykonosDevice_t *device); +mykonosErr_t MYKONOS_loadArmFromBinary(mykonosDevice_t *device, uint8_t *binary, uint32_t count); +mykonosErr_t MYKONOS_loadArmConcurrent(mykonosDevice_t *device, uint8_t *binary, uint32_t count); +mykonosErr_t MYKONOS_verifyArmChecksum(mykonosDevice_t *device); +mykonosErr_t MYKONOS_checkArmState(mykonosDevice_t *device, mykonosArmState_t armStateCheck); +mykonosErr_t MYKONOS_getArmVersion(mykonosDevice_t *device, uint8_t *majorVer, uint8_t *minorVer, uint8_t *rcVer, mykonosBuild_t *buildType); + +mykonosErr_t MYKONOS_configDpd(mykonosDevice_t *device); +mykonosErr_t MYKONOS_getDpdConfig(mykonosDevice_t *device); +mykonosErr_t MYKONOS_getDpdStatus(mykonosDevice_t *device, mykonosTxChannels_t txChannel, mykonosDpdStatus_t *dpdStatus); +mykonosErr_t MYKONOS_restoreDpdModel(mykonosDevice_t *device, mykonosTxChannels_t txChannel, uint8_t *modelDataBuffer, uint32_t modelNumberBytes); +mykonosErr_t MYKONOS_saveDpdModel(mykonosDevice_t *device, mykonosTxChannels_t txChannel, uint8_t *modelDataBuffer, uint32_t modelNumberBytes); +mykonosErr_t MYKONOS_setDpdActState(mykonosDevice_t *device, mykonosTxChannels_t txChannel, uint8_t actState); +mykonosErr_t MYKONOS_resetDpd(mykonosDevice_t *device, mykonosTxChannels_t txChannel, mykonosDpdResetMode_t reset); +mykonosErr_t MYKONOS_setDpdBypassConfig(mykonosDevice_t *device, mykonosDpdBypassConfig_t *actConfig); +mykonosErr_t MYKONOS_getDpdBypassConfig(mykonosDevice_t *device, mykonosDpdBypassConfig_t *actConfig); +mykonosErr_t MYKONOS_setDpdActuatorCheck(mykonosDevice_t *device, mykonosDpdActuatorCheck_t *actCheck); +mykonosErr_t MYKONOS_getDpdActuatorCheck(mykonosDevice_t *device, mykonosDpdActuatorCheck_t *actCheck); + +mykonosErr_t MYKONOS_setClgcAttenTuningConfig(mykonosDevice_t *device, mykonosClgcAttenTuningConfig_t *attRangeCfg); +mykonosErr_t MYKONOS_getClgcAttenTuningConfig(mykonosDevice_t *device, mykonosClgcAttenTuningConfig_t *attRangeCfg); + +mykonosErr_t MYKONOS_configClgc(mykonosDevice_t *device); +mykonosErr_t MYKONOS_getClgcConfig(mykonosDevice_t *device); +mykonosErr_t MYKONOS_getClgcStatus(mykonosDevice_t *device, mykonosTxChannels_t txChannel, mykonosClgcStatus_t *clgcStatus); +mykonosErr_t MYKONOS_setClgcGain(mykonosDevice_t *device, mykonosTxChannels_t txChannel, int16_t gain); + +mykonosErr_t MYKONOS_configVswr(mykonosDevice_t *device); +mykonosErr_t MYKONOS_getVswrConfig(mykonosDevice_t *device); +mykonosErr_t MYKONOS_getVswrStatus(mykonosDevice_t *device, mykonosTxChannels_t txChannel, mykonosVswrStatus_t *vswrStatus); + +mykonosErr_t MYKONOS_runInitCals(mykonosDevice_t *device, uint32_t calMask); +mykonosErr_t MYKONOS_waitInitCals(mykonosDevice_t *device, uint32_t timeoutMs, uint8_t *errorFlag, uint8_t *errorCode); +mykonosErr_t MYKONOS_abortInitCals(mykonosDevice_t *device, uint32_t *calsCompleted); +mykonosErr_t MYKONOS_getInitCalStatus(mykonosDevice_t *device, mykonosInitCalStatus_t *initCalStatus); + +mykonosErr_t MYKONOS_resetExtTxLolChannel(mykonosDevice_t *device, mykonosTxChannels_t channelSel); + +mykonosErr_t MYKONOS_radioOn(mykonosDevice_t *device); +mykonosErr_t MYKONOS_radioOff(mykonosDevice_t *device); +mykonosErr_t MYKONOS_getRadioState(mykonosDevice_t *device, uint32_t *radioStatus); +mykonosErr_t MYKONOS_enableTrackingCals(mykonosDevice_t *device, uint32_t enableMask); +mykonosErr_t MYKONOS_rescheduleTrackingCal(mykonosDevice_t *device, mykonosTrackingCalibrations_t trackingCal); +mykonosErr_t MYKONOS_setAllTrackCalState(mykonosDevice_t *device, uint32_t trackingCalMask); +mykonosErr_t MYKONOS_getAllTrackCalState(mykonosDevice_t *device, uint32_t *trackCals); +mykonosErr_t MYKONOS_setTrackingCalState(mykonosDevice_t *device, mykonosTrackingCalibrations_t trackingCal, uint8_t trackCalState); +mykonosErr_t MYKONOS_getTrackingCalState(mykonosDevice_t *device, mykonosTrackingCalibrations_t trackingCal, uint8_t *trackCalState); +mykonosErr_t MYKONOS_getEnabledTrackingCals(mykonosDevice_t *device, uint32_t *enableMask); +mykonosErr_t MYKONOS_getPendingTrackingCals(mykonosDevice_t *device, uint32_t *pendingCalMask); +mykonosErr_t MYKONOS_getTxLolStatus(mykonosDevice_t *device, mykonosTxChannels_t txChannel, mykonosTxLolStatus_t *txLolStatus); +mykonosErr_t MYKONOS_getTxQecStatus(mykonosDevice_t *device, mykonosTxChannels_t txChannel, mykonosTxQecStatus_t *txQecStatus); + +mykonosErr_t MYKONOS_getRxQecStatus(mykonosDevice_t *device, mykonosRxChannels_t rxChannel, mykonosRxQecStatus_t *rxQecStatus); +mykonosErr_t MYKONOS_getOrxQecStatus(mykonosDevice_t *device, mykonosObsRxChannels_t orxChannel, mykonosOrxQecStatus_t *orxQecStatus); + +mykonosErr_t MYKONOS_setSnifferChannel(mykonosDevice_t *device, mykonosSnifferChannel_t snifferChannel); +mykonosErr_t MYKONOS_setRadioControlPinMode(mykonosDevice_t *device); + +mykonosErr_t MYKONOS_setPathDelay(mykonosDevice_t *device, mykonosPathdelay_t *pathDelay); +mykonosErr_t MYKONOS_getPathDelay(mykonosDevice_t *device, mykonosPathDelaySel_t select, mykonosPathdelay_t *pathDelay); + +mykonosErr_t MYKONOS_getDpdErrorCounters(mykonosDevice_t *device, mykonosTxChannels_t txChannel, mykonosDpdErrorCounters_t *dpdErrCnt); + +/* Low level ARM functions */ +mykonosErr_t MYKONOS_readArmMem(mykonosDevice_t *device, uint32_t address, uint8_t *returnData, uint32_t bytesToRead, uint8_t autoIncrement); +mykonosErr_t MYKONOS_writeArmMem(mykonosDevice_t *device, uint32_t address, uint8_t *data, uint32_t byteCount); +mykonosErr_t MYKONOS_writeArmConfig(mykonosDevice_t *device, uint8_t objectId, uint16_t offset, uint8_t *data, uint8_t byteCount); +mykonosErr_t MYKONOS_readArmConfig(mykonosDevice_t *device, uint8_t objectId, uint16_t offset, uint8_t *data, uint8_t byteCount); +mykonosErr_t MYKONOS_sendArmCommand(mykonosDevice_t *device, uint8_t opCode, uint8_t *extendedData, uint8_t extendedDataNumBytes); +mykonosErr_t MYKONOS_readArmCmdStatus(mykonosDevice_t *device, uint16_t *errorWord, uint16_t *statusWord); +mykonosErr_t MYKONOS_readArmCmdStatusByte(mykonosDevice_t *device, uint8_t opCode, uint8_t *cmdStatByte); +mykonosErr_t MYKONOS_waitArmCmdStatus(mykonosDevice_t *device, uint8_t opCode, uint32_t timeoutMs, uint8_t *cmdStatByte); +mykonosErr_t MYKONOS_writeArmProfile(mykonosDevice_t *device); +mykonosErr_t MYKONOS_loadAdcProfiles(mykonosDevice_t *device); + + +/* + ***************************************************************************** + * JESD204B Datapath Functions + ***************************************************************************** + */ +/* Functions to setup the JESD204B IP */ +mykonosErr_t MYKONOS_resetDeframer(mykonosDevice_t *device); +mykonosErr_t MYKONOS_setupSerializers(mykonosDevice_t *device); +mykonosErr_t MYKONOS_setupDeserializers(mykonosDevice_t *device); +mykonosErr_t MYKONOS_setupJesd204bFramer(mykonosDevice_t *device); +mykonosErr_t MYKONOS_setupJesd204bObsRxFramer(mykonosDevice_t *device); +mykonosErr_t MYKONOS_setupJesd204bDeframer(mykonosDevice_t *device); +mykonosErr_t MYKONOS_enableRxFramerLink(mykonosDevice_t *device, uint8_t enable); +mykonosErr_t MYKONOS_enableObsRxFramerLink(mykonosDevice_t *device, uint8_t enable); + +/* Functions to initialize the JESD204B link */ +mykonosErr_t MYKONOS_enableMultichipSync(mykonosDevice_t *device, uint8_t enableMcs, uint8_t *mcsStatus); +mykonosErr_t MYKONOS_enableSysrefToRxFramer(mykonosDevice_t *device, uint8_t enable); +mykonosErr_t MYKONOS_enableSysrefToObsRxFramer(mykonosDevice_t *device, uint8_t enable); +mykonosErr_t MYKONOS_enableSysrefToDeframer(mykonosDevice_t *device, uint8_t enable); + +/* Functions to help debug the JESD204B link */ +mykonosErr_t MYKONOS_readRxFramerStatus(mykonosDevice_t *device, uint8_t *framerStatus); +mykonosErr_t MYKONOS_readOrxFramerStatus(mykonosDevice_t *device, uint8_t *obsFramerStatus); +mykonosErr_t MYKONOS_readDeframerStatus(mykonosDevice_t *device, uint8_t *deframerStatus); +mykonosErr_t MYKONOS_getDeframerFifoDepth(mykonosDevice_t *device, uint8_t *fifoDepth, uint8_t *readEnLmfcCount); + +/* PRBS debug functions */ +mykonosErr_t MYKONOS_enableRxFramerPrbs(mykonosDevice_t *device, mykonosPrbsOrder_t polyOrder, uint8_t enable); +mykonosErr_t MYKONOS_enableObsRxFramerPrbs(mykonosDevice_t *device, mykonosPrbsOrder_t polyOrder, uint8_t enable); +mykonosErr_t MYKONOS_rxInjectPrbsError(mykonosDevice_t *device); +mykonosErr_t MYKONOS_obsRxInjectPrbsError(mykonosDevice_t *device); +mykonosErr_t MYKONOS_enableDeframerPrbsChecker(mykonosDevice_t *device, uint8_t lanes, mykonosPrbsOrder_t polyOrder, uint8_t enable); +mykonosErr_t MYKONOS_clearDeframerPrbsCounters(mykonosDevice_t *device); +mykonosErr_t MYKONOS_readDeframerPrbsCounters(mykonosDevice_t *device, uint8_t counterSelect, uint32_t *prbsErrorCount); + +/* Miscellaneous debug functions */ +mykonosErr_t MYKONOS_jesd204bIlasCheck(mykonosDevice_t *device, uint16_t *mismatch); +mykonosErr_t MYKONOS_setRxFramerDataSource(mykonosDevice_t *device, uint8_t dataSource); +mykonosErr_t MYKONOS_setObsRxFramerDataSource(mykonosDevice_t *device, uint8_t dataSource); + +/* + ***************************************************************************** + * Shared Data path functions + ***************************************************************************** + */ +mykonosErr_t MYKONOS_programFir(mykonosDevice_t *device, mykonosfirName_t filterToProgram, mykonosFir_t *firFilter); +mykonosErr_t MYKONOS_readFir(mykonosDevice_t *device, mykonosfirName_t filterToRead, mykonosFir_t *firFilter); + +/* + ***************************************************************************** + * Rx Data path functions + ***************************************************************************** + */ +mykonosErr_t MYKONOS_programRxGainTable(mykonosDevice_t *device, uint8_t *gainTablePtr, uint8_t numGainIndexesInTable, mykonosGainTable_t rxChannel); +mykonosErr_t MYKONOS_setRx1ManualGain(mykonosDevice_t *device, uint8_t gainIndex); +mykonosErr_t MYKONOS_setRx2ManualGain(mykonosDevice_t *device, uint8_t gainIndex); +mykonosErr_t MYKONOS_getRx1Gain(mykonosDevice_t *device, uint8_t *rx1GainIndex); +mykonosErr_t MYKONOS_getRx2Gain(mykonosDevice_t *device, uint8_t *rx2GainIndex); +mykonosErr_t MYKONOS_setupRxAgc(mykonosDevice_t *device); +mykonosErr_t MYKONOS_resetRxAgc(mykonosDevice_t *device); +mykonosErr_t MYKONOS_setRxAgcMinMaxGainIndex(mykonosDevice_t *device, mykonosRxChannels_t rxChannelSelect, uint8_t maxGainIndex, uint8_t minGainIndex); +mykonosErr_t MYKONOS_setObsRxAgcMinMaxGainIndex(mykonosDevice_t *device, mykonosObsRxChannels_t obsRxChannelSelect, uint8_t maxGainIndex, uint8_t minGainIndex); +mykonosErr_t MYKONOS_setRx1TempGainComp(mykonosDevice_t *device, int16_t rx1TempCompGain_mdB); +mykonosErr_t MYKONOS_getRx1TempGainComp(mykonosDevice_t *device, int16_t *rx1TempCompGain_mdB); +mykonosErr_t MYKONOS_setRx2TempGainComp(mykonosDevice_t *device, int16_t rx2TempCompGain_mdB); +mykonosErr_t MYKONOS_getRx2TempGainComp(mykonosDevice_t *device, int16_t *rx2TempCompGain_mdB); +mykonosErr_t MYKONOS_setObsRxTempGainComp(mykonosDevice_t *device, int16_t obsRxTempCompGain_mdB); +mykonosErr_t MYKONOS_getObsRxTempGainComp(mykonosDevice_t *device, int16_t *obsRxTempCompGain_mdB); +mykonosErr_t MYKONOS_enableRxGainCtrSyncPulse(mykonosDevice_t *device, uint8_t enable); +mykonosErr_t MYKONOS_setRxGainControlMode(mykonosDevice_t *device, mykonosGainMode_t mode); +mykonosErr_t MYKONOS_getRx1DecPower(mykonosDevice_t *device, uint16_t *rx1DecPower_mdBFS); +mykonosErr_t MYKONOS_getRx2DecPower(mykonosDevice_t *device, uint16_t *rx2DecPower_mdBFS); + +/* + ***************************************************************************** + * Observation Rx Data path functions + ***************************************************************************** + */ +mykonosErr_t MYKONOS_setDefaultObsRxPath(mykonosDevice_t *device, mykonosObsRxChannels_t defaultObsRxCh); +mykonosErr_t MYKONOS_setObsRxPathSource(mykonosDevice_t *device, mykonosObsRxChannels_t obsRxCh); +mykonosErr_t MYKONOS_getObsRxPathSource(mykonosDevice_t *device, mykonosObsRxChannels_t *obsRxCh); +mykonosErr_t MYKONOS_setObsRxManualGain(mykonosDevice_t *device, mykonosObsRxChannels_t obsRxCh, uint8_t gainIndex); +mykonosErr_t MYKONOS_getObsRxGain(mykonosDevice_t *device, uint8_t *gainIndex); +mykonosErr_t MYKONOS_setupObsRxAgc(mykonosDevice_t *device); +mykonosErr_t MYKONOS_enableObsRxGainCtrSyncPulse(mykonosDevice_t *device, uint8_t enable); +mykonosErr_t MYKONOS_setObsRxGainControlMode(mykonosDevice_t *device, mykonosGainMode_t mode); +mykonosErr_t MYKONOS_getObsRxDecPower(mykonosDevice_t *device, uint16_t *obsRxDecPower_mdBFS); + +/* + ***************************************************************************** + * Tx Data path functions + ***************************************************************************** + */ +mykonosErr_t MYKONOS_setTx1Attenuation(mykonosDevice_t *device, uint16_t tx1Attenuation_mdB); +mykonosErr_t MYKONOS_setTx2Attenuation(mykonosDevice_t *device, uint16_t tx2Attenuation_mdB); +mykonosErr_t MYKONOS_getTx1Attenuation(mykonosDevice_t *device, uint16_t *tx1Attenuation_mdB); +mykonosErr_t MYKONOS_getTx2Attenuation(mykonosDevice_t *device, uint16_t *tx2Attenuation_mdB); +mykonosErr_t MYKONOS_getTxFilterOverRangeStatus(mykonosDevice_t *device, uint8_t *txFilterStatus); +mykonosErr_t MYKONOS_enableTxNco(mykonosDevice_t *device, uint8_t enable, int32_t tx1ToneFreq_kHz, int32_t tx2ToneFreq_kHz); + +/* + ***************************************************************************** + * PA Protection Functions + ***************************************************************************** + */ +mykonosErr_t MYKONOS_setupPaProtection(mykonosDevice_t *device, uint16_t powerThreshold, uint8_t attenStepSize, uint8_t avgDuration, uint8_t stickyFlagEnable, uint8_t txAttenControlEnable); +mykonosErr_t MYKONOS_enablePaProtection(mykonosDevice_t *device, uint8_t enable); +mykonosErr_t MYKONOS_getDacPower(mykonosDevice_t *device, mykonosTxChannels_t channel, uint16_t *channelPower); +mykonosErr_t MYKONOS_getPaProtectErrorFlagStatus(mykonosDevice_t *device, uint8_t *errorFlagStatus); +mykonosErr_t MYKONOS_clearPaErrorFlag(mykonosDevice_t *device); + +/* + ***************************************************************************** + * Low level functions and helper functions. BBP should not need to call + ***************************************************************************** + */ +const char* getMykonosErrorMessage(mykonosErr_t errorCode); + +mykonosErr_t MYKONOS_initSubRegisterTables(mykonosDevice_t *device); +mykonosErr_t MYKONOS_setTxPfirSyncClk(mykonosDevice_t *device); /* Helper function */ +mykonosErr_t MYKONOS_setRxPfirSyncClk(mykonosDevice_t *device); /* Helper function */ + +/* + ***************************************************************************** + * Functions to configure DC offsets + ***************************************************************************** + */ +mykonosErr_t MYKONOS_setRfDcOffsetCnt(mykonosDevice_t *device, mykonosDcOffsetChannels_t channel, uint16_t measureCount); +mykonosErr_t MYKONOS_getRfDcOffsetCnt(mykonosDevice_t *device, mykonosDcOffsetChannels_t channel, uint16_t *measureCount); +mykonosErr_t MYKONOS_setDigDcOffsetMShift(mykonosDevice_t *device, mykonosDcOffsetChannels_t channel, uint8_t mShift); +mykonosErr_t MYKONOS_getDigDcOffsetMShift(mykonosDevice_t *device, mykonosDcOffsetChannels_t channel, uint8_t *mShift); +mykonosErr_t MYKONOS_setDigDcOffsetEn(mykonosDevice_t *device, uint8_t enableMask); +mykonosErr_t MYKONOS_getDigDcOffsetEn(mykonosDevice_t *device, uint8_t *enableMask); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/df_datalink_ge/src/hardware/mykonos/mykonosMmap.c b/df_datalink_ge/src/hardware/mykonos/mykonosMmap.c new file mode 100644 index 0000000..076be0c --- /dev/null +++ b/df_datalink_ge/src/hardware/mykonos/mykonosMmap.c @@ -0,0 +1,136 @@ +/** + * \file mykonosMmap.c + * \brief Contains the Mykonos memory mapping + * + * Mykonos API version: 1.5.2.3566 + */ + +/** +* \page Disclaimer Legal Disclaimer +* Copyright 2015-2017 Analog Devices Inc. +* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file. +* +*/ + +#include +uint8_t mykonosMmap [] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x13,0x03,0x03,0x13,0x13,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, + 0x00,0xE4,0xE4,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xA5,0xA5,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x00,0xE4,0xE4,0x00,0x00,0x00,0x1F,0x00,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9F,0xE0,0x20,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xF5,0x8F,0x0F,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; +/*!< Mykonos memory map */ diff --git a/df_datalink_ge/src/hardware/mykonos/mykonos_gpio.c b/df_datalink_ge/src/hardware/mykonos/mykonos_gpio.c new file mode 100644 index 0000000..caf1e04 --- /dev/null +++ b/df_datalink_ge/src/hardware/mykonos/mykonos_gpio.c @@ -0,0 +1,5357 @@ +/** + *\file mykonos_gpio.c + * + *\brief Contains Mykonos APIs for transceiver GPIO configuration and control. + * + * Mykonos API version: 1.5.2.3566 + */ + +/** +* \page Disclaimer Legal Disclaimer +* Copyright 2015-2017 Analog Devices Inc. +* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file. +* +*/ + +#include +#include +#include "../common.h" +#include "mykonos.h" +#include "mykonos_gpio.h" +#include "mykonos_macros.h" +#include "mykonos_user.h" + + +/** + * \brief Helper function for return of character string based on 32-bit mykonosGpioErr_t enum value + * + * To save codespace, these error strings are ifdef'd out unless the user + * adds a define MYKONOS_VERBOSE to their workspace. This function can be + * useful for debug. Each function also returns unique error codes to + * make it easier to determine where the code broke. + * + * \param errorCode is enumerated error code value + * + * \return Returns character string based on enumerated value + */ +const char* getGpioMykonosErrorMessage(mykonosGpioErr_t errorCode) +{ +#if MYKONOS_VERBOSE == 0 + return ""; + + #else + + switch (errorCode) + { + case MYKONOS_ERR_GPIO_OK: + return ""; + + case MYKONOS_ERR_EN_MONITOR_OUT_NOT_ENABLED: + return "MYKONOS_setGpioMonitorOut() Mykonos monitor output not enable, please run GPIO setup with the correct setup for enabling the monitor output functionality\n"; + + case MYKONOS_ERR_MONITOR_OUT_INDEX_RANGE: + return "MYKONOS_setGpioMonitorOut()The index specified is incorrect, index available are from 0x01 to 0x42\n"; + + case MYKONOS_ERR_GETGPIOMON_INDEX_NULL_PARM: + return "MYKONOS_getGpioMonitorOut() if the monitorIndex is null.\n"; + + case MYKONOS_ERR_GETGPIOMON_MONITORMASK_NULL_PARM: + return "MYKONOS_getGpioMonitorOut() if the monitorMask is null.\n"; + + case MYKONOS_ERR_MGCRX1_STEP_INV_PARAM: + return "MYKONOS_setRx1GainCtrlPin() An invalid step size has been passed, valid step sizes for increment/decrement is 0-7\n"; + + case MYKONOS_ERR_MGCRX1_GPIO_DECPIN_INV_PARAM: + return "MYKONOS_setRx1GainCtrlPin() An invalid decrement pin has been passed \n"; + + case MYKONOS_ERR_MGCRX1_GPIO_INCPIN_INV_PARAM: + return "MYKONOS_setRx1GainCtrlPin() An invalid increment pin has been passed, \n"; + + case MYKONOS_ERR_MGCRX2_STEP_INV_PARAM: + return "MYKONOS_setRx2GainCtrlPin() An invalid step size has been passed, valid step sizes for increment/decrement is 0-7\n"; + + case MYKONOS_ERR_MGCRX2_GPIO_DECPIN_INV_PARAM: + return "MYKONOS_setRx2GainCtrlPin() An invalid decrement pin has been passed\n"; + + case MYKONOS_ERR_MGCRX2_GPIO_INCPIN_INV_PARAM: + return "MYKONOS_setRx2GainCtrlPin() An invalid increment pin has been passed\n"; + + case MYKONOS_ERR_GETRX1PIN_INCSTEP_NULL_PARM: + return "MYKONOS_getRx1GainCtrlPin() if a null value has been passed to incStep.\n"; + + case MYKONOS_ERR_GETRX1PIN_DECSTEP_NULL_PARM: + return "MYKONOS_getRx1GainCtrlPin() if a null value has been passed to decStep.\n"; + + case MYKONOS_ERR_GETRX1PIN_INCPIN_NULL_PARM: + return "MYKONOS_getRx1GainCtrlPin() if a null value has been passed to rx1GainIncPin.\n"; + + case MYKONOS_ERR_GETRX1PIN_DECPIN_NULL_PARM: + return "MYKONOS_getRx1GainCtrlPin() if a null value has been passed to rx1GainDecPin.\n"; + + case MYKONOS_ERR_GETRX1PIN_EN_NULL_PARM: + return "MYKONOS_getRx1GainCtrlPin() if a null value has been passed to enable.\n"; + + case MYKONOS_ERR_GETRX2PIN_INCSTEP_NULL_PARM: + return "MYKONOS_getRx2GainCtrlPin() if a null value has been passed to incStep.\n"; + + case MYKONOS_ERR_GETRX2PIN_DECSTEP_NULL_PARM: + return "MYKONOS_getRx2GainCtrlPin() if a null value has been passed to decStep.\n"; + + case MYKONOS_ERR_GETRX2PIN_INCPIN_NULL_PARM: + return "MYKONOS_getRx2GainCtrlPin() if a null value has been passed to rx1GainIncPin.\n"; + + case MYKONOS_ERR_GETRX2PIN_DECPIN_NULL_PARM: + return "MYKONOS_getRx2GainCtrlPin() if a null value has been passed to rx1GainDecPin.\n"; + + case MYKONOS_ERR_GETRX2PIN_EN_NULL_PARM: + return "MYKONOS_getRx2GainCtrlPin() if a null value has been passed to enable.\n"; + + case MYKONOS_ERR_TPCTX1_GPIO_STEP_INV_PARAM: + return "MYKONOS_setTx1AttenCtrlPin() An invalid step size has been passed, valid step sizes for att are 0x00-0x1F\n"; + + case MYKONOS_ERR_TPCTX1_GPIO_INCPIN_INV_PARAM: + return "MYKONOS_setTx1AttenCtrlPin() An invalid decrement pin has been passed\n"; + + case MYKONOS_ERR_TPCTX1_GPIO_DECPIN_INV_PARAM: + return "MYKONOS_setTx1AttenCtrlPin() An invalid decrement pin has been passed\n"; + + case MYKONOS_ERR_TPCTX2_GPIO_STEP_INV_PARAM: + return "MYKONOS_setTx2AttenCtrlPin() An invalid step size has been passed, valid step sizes for att are 0x00-0x1F\n"; + + case MYKONOS_ERR_TPCTX2_GPIO_INCPIN_INV_PARAM: + return "MYKONOS_setTx2AttenCtrlPin() An invalid decrement pin has been passed\n"; + + case MYKONOS_ERR_TPCTX2_GPIO_DECPIN_INV_PARAM: + return "MYKONOS_setTx2AttenCtrlPin() An invalid decrement pin has been passed\n"; + + case MYKONOS_ERR_GETTX2PIN_STEP_NULL_PARM: + return "MYKONOS_getTx2AttenCtrlPin() if a null value has been passed to stepSize.\n"; + + case MYKONOS_ERR_GETTX2PIN_INC_NULL_PARM: + return "MYKONOS_getTx2AttenCtrlPin() if a null value has been passed to tx2AttenIncPin.\n"; + + case MYKONOS_ERR_GETTX2PIN_DEC_NULL_PARM: + return "MYKONOS_getTx2AttenCtrlPin() if a null value has been passed to tx2AttenDecPin.\n"; + + case MYKONOS_ERR_GETTX2PIN_EN_NULL_PARM: + return "MYKONOS_getTx2AttenCtrlPin() if a null value has been passed to enable.\n"; + + case MYKONOS_ERR_GETTX2PIN_TX1TX2_NULL_PARM: + return "MYKONOS_getTx2AttenCtrlPin() if a null value has been passed to useTx1ForTx2.\n"; + + case MYKONOS_ERR_GETTX1PIN_STEP_NULL_PARM: + return "MYKONOS_getTx1AttenCtrlPin() if a null value has been passed to stepSize.\n"; + + case MYKONOS_ERR_GETTX1PIN_INC_NULL_PARM: + return "MYKONOS_getTx1AttenCtrlPin() if a null value has been passed to tx1AttenIncPin.\n"; + + case MYKONOS_ERR_GETTX1PIN_DEC_NULL_PARM: + return "MYKONOS_getTx1AttenCtrlPin() if a null value has been passed to tx1AttenDecPin.\n"; + + case MYKONOS_ERR_GETTX1PIN_EN_NULL_PARM: + return "MYKONOS_getTx1AttenCtrlPin() if a null value has been passed to enable.\n"; + + case MYKONOS_ERR_GETTX1PIN_TX1TX2_NULL_PARM: + return "MYKONOS_getTx1AttenCtrlPin() if a null value has been passed to useTx1ForTx2.\n"; + + case MYKONOS_ERR_GPIO_SRC_PARAM_INV: + return "MYKONOS_setGpioSourceCtrl() An invalid source control parameter has been passed\n"; + + case MYKONOS_ERR_GETGPIOSETLEVEL_NULL_PARM: + return "MYKONOS_getGpioSetLevel() gpioPinSetLevel pointer is NULL in function parameter\n"; + + case MYKONOS_ERR_READGPIOSPI_NULL_PARM: + return "MYKONOS_readGpioPinLevel() has a null *gpioPinLevel parameter\n"; + + case MYKONOS_ERR_GETGPIO3V3SPI_NULL_PARM: + return "MYKONOS_getGpio3v3PinLevel() has a null *gpio3v3PinLevel parameter\n"; + + case MYKONOS_ERR_SETUPAUXDAC_NULL_PARAM: + return "MYKONOS_setupAuxDac() has a null device->auxIo pointer\n"; + + case MYKONOS_ERR_GPIO3V3OUTEN_NULL_PARM: + return "MYKONOS_getGpio3v3Oe() has NULL pointer for function parameter gpio3v3OutEn\n;"; + + case MYKONOS_ERR_INV_GP_INT_MASK_PARM: + return "General Purpose Interrupt source mask parameter is invalid\n"; + + case MYKONOS_ERR_GP_INT_STATUS_NULL_PARAM: + return "MYKONOS_readGpInterruptStatus() has NULL status parameter\n"; + + case MYKONOS_ERR_SET_GPIO_3V3_INV_MODE: + return "Invalid GPIO3v3 source control mode\n"; + + case MYKONOS_ERR_SET_GPIO_3V3_INV_SRC_CTRL: + return "gpio3v3 members have invalid value for the GPIO3v3 source control mode.\n"; + + case MYKONOS_ERR_SET_GPIO_1V8_INV_MODE: + return "The GPIO mode enum is not a valid value in MYKONOS_setupGpio\n"; + + case MYKONOS_ERR_GETGPIO3V3OUT_NULL_PARM: + return "MYKONOS_getGpio3v3SetLevel() has NULL pointer for function parameter gpio3v3SetLevel\n"; + + case MYKONOS_ERR_GPIO_OE_INV_PARAM: + return "MYKONOS_setGpioOe() had invalid parameter gpioOutEn (valid range 0 - 0x07FFFF)\n"; + + case MYKONOS_ERR_GETGPIO_OE_NULL_PARM: + return "MYKONOS_getGpioOe() has NULL function parameter\n"; + + case MYKONOS_ERR_WRITEAUXDAC_NULL_AUXIO: + return "device->auxIo structure has NULL pointer in MYKONOS_writeAuxDac()\n"; + + case MYKONOS_ERR_READAUXADC_NULL_PARAM: + return "MYKONOS_readAuxAdc() has NULL function parameter\n"; + + case MYKONOS_ERR_SET_GPIO_3V3_INV_POINTER: + return "Invalid pointer detected in MYKONOS_setupGpio3v3()\n"; + + case MYKONOS_ERR_SET_GPIO_1V8_INV_POINTER: + return "Invalid pointer detected in MYKONOS_setupGpio()\n"; + + case MYKONOS_ERR_SET_ARMGPIO_INV_POINTER: + return "Invalid pointer detected at device->auxIo->armGpio in MYKONOS_setArmGpioPins() \n"; + + case MYKONOS_ERR_SET_ARMGPIO_PINS_ARMERROR: + return "ARM Command Error in MYKONOS_setArmGpioPins()\n"; + + case MYKONOS_ERR_SET_ARMGPIO_PINS_INV_SIGNALID: + return "Invalid Signal ID detected in device->auxIo->armGpio \n"; + + case MYKONOS_ERR_SET_ARMGPIO_PINS_INV_GPIOPIN: + return "Out of range GPIO pin detected \n"; + + case MYKONOS_ERR_SETUPAUXDAC_INV_AUXDACCODE: + return "device->auxIo->auxDacValue, AUXDAC value out of range in MYKONOS_setupAuxDacs()\n"; + + case MYKONOS_ERR_WRITEAUXDAC_INV_AUXDACCODE: + return "auxDacCode value out of range in MYKONOS_writeAuxDac()\n"; + + case MYKONOS_ERR_WRITEAUXDAC_INV_AUXDACINDEX: + return "auxDacIndex value out of range in MYKONOS_writeAuxDac()\n"; + + case MYKONOS_ERR_INV_AUX_ADC_CHAN_PARM: + return "auxAdcChannel value out of range in MYKONOS_setAuxAdcChannel()\n"; + + case MYKONOS_ERR_SETUPAUXADC_INV_VCODIV: + return "device->clocks->clkPllVcoDiv value not supported in MYKONOS_setupAuxAdcs()\n"; + + case MYKONOS_ERR_INV_AUX_ADC_DEC_PARM: + return "adcDecimation value out of range in MYKONOS_setupAuxAdcs()\n"; + + case MYKONOS_ERR_SLICER_INV_RX1_SEL: + return "invalid RX1 GPIO pin selection for Slicer control in MYKONOS_setRxSlicerCtrl()\n"; + + case MYKONOS_ERR_SLICER_INV_RX2_SEL: + return "invalid RX2 GPIO pin selection for Slicer control in MYKONOS_setRxSlicerCtrl()\n"; + + case MYKONOS_ERR_SLICER_STEP_OUT_OF_RANGE: + return "slicer step is out of range for the SLicer control in MYKONOS_setRxSlicerCtrl()\n"; + + case MYKONOS_ERR_SLICER_EN_INV: + return "invalid enable in MYKONOS_setRxSlicerCtrl()\n"; + + case MYKONOS_ERR_SLICER_RX1PIN_NULL_PARM: + return "rx1Pins is null pointer for the passed parameter in MYKONOS_getRxSlicerCtrl()\n"; + + case MYKONOS_ERR_SLICER_RX2PIN_NULL_PARM: + return "rx1Pins is null pointer for the passed parameter in MYKONOS_getRxSlicerCtrl()\n"; + + case MYKONOS_ERR_SLICER_STEP_NULL_PARM: + return "slicerStep is null pointer for the passed parameter in MYKONOS_getRxSlicerCtrl()\n"; + + case MYKONOS_ERR_SLICER_EN_NULL_PARM: + return "enable is null pointer for the passed parameter in MYKONOS_getRxSlicerCtrl()\n"; + + case MYKONOS_ERR_GAINCOMP_NULL_STRUCT: + return "gain compensation structure gainComp is not initialised in MYKONOS_getRxGainCompensation()\n"; + + case MYKONOS_ERR_GAINCOMP_EN_NULL_PARM: + return "enable is null pointer for the passed parameter in MYKONOS_getRxGainCompensation()\n"; + + case MYKONOS_ERR_GAINCOMP_SET_NULL_STRUCT: + return "gain compensation structure gainComp is not initialised in MYKONOS_setRxGainCompensation()\n"; + + case MYKONOS_ERR_GAINCOMP_INV_RX1_OFFSET: + return "gain compensation structure gainComp->rx1Offset is invalid in MYKONOS_setRxGainCompensation()\n"; + + case MYKONOS_ERR_GAINCOMP_INV_RX2_OFFSET: + return "gain compensation structure gainComp->rx2Offset is invalid in MYKONOS_setRxGainCompensation()\n"; + + case MYKONOS_ERR_GAINCOMP_INV_STEP: + return "gain compensation structure gainComp->compStep is invalid in MYKONOS_setRxGainCompensation()\n"; + + case MYKONOS_ERR_GAINCOMP_INV_EN: + return "enable is not valid in MYKONOS_setRxGainCompensation()\n"; + + case MYKONOS_ERR_FLOATFRMT_NULL_STRUCT: + return "floating point formatter structure floatFrmt not initialised in MYKONOS_getFloatPointFrmt()\n"; + + case MYKONOS_ERR_FLOATFRMT_SET_NULL_STRUCT: + return "floating point formatter structure floatFrmt not initialised in MYKONOS_setFloatPointFrmt()\n"; + + case MYKONOS_ERR_FLOATFRMT_INV_ROUND_MODE: + return "floating point formatter structure floatFrmt.roundMode not valid parameter in MYKONOS_setFloatPointFrmt()\n"; + + case MYKONOS_ERR_FLOATFRMT_INV_DATA_FORMAT: + return "floating point formatter structure floatFrmt.dataFormat not valid parameter in MYKONOS_setFloatPointFrmt()\n"; + + case MYKONOS_ERR_FLOATFRMT_INV_ENC_NAN: + return "floating point formatter structure floatFrmt.encNan not valid parameter in MYKONOS_setFloatPointFrmt()\n"; + + case MYKONOS_ERR_FLOATFRMT_INV_EXP_BITS: + return "floating point formatter structure floatFrmt.expBits not valid parameter in MYKONOS_setFloatPointFrmt()\n"; + + case MYKONOS_ERR_FLOATFRMT_INV_LEADING: + return "floating point formatter structure floatFrmt.leading not valid parameter in MYKONOS_setFloatPointFrmt()\n"; + + case MYKONOS_ERR_FLOATFRMT_INV_RX1ATT: + return "not valid rx1 attenuation parameter passed in MYKONOS_setFloatPointFrmt()\n"; + + case MYKONOS_ERR_FLOATFRMT_INV_RX2ATT: + return "not valid rx2 attenuation parameter passed in MYKONOS_setFloatPointFrmt()\n"; + + case MYKONOS_ERR_FLOATFRMT_SET_INV_RX2ATT: + return "not valid rx2 attenuation parameter passed in MYKONOS_setRxEnFloatPntFrmt()\n"; + + case MYKONOS_ERR_FLOATFRMT_SET_INV_RX1ATT: + return "not valid rx1 attenuation parameter passed in MYKONOS_setRxEnFloatPntFrmt()\n"; + + case MYKONOS_ERR_FLOATFRMT_SET_INV_EN: + return "not valid enable parameter passed in MYKONOS_setRxEnFloatPntFrmt()\n"; + + case MYKONOS_ERR_FLOATFRMT_NULL_RX1ATT: + return "null pointer passed for rx1 attenuation in MYKONOS_setRxEnFloatPntFrmt()\n"; + + case MYKONOS_ERR_FLOATFRMT_NULL_RX2ATT: + return "null pointer passed for rx2 attenuation in MYKONOS_setRxEnFloatPntFrmt()\n"; + + case MYKONOS_ERR_FLOATFRMT_NULL_ENABLE: + return "null pointer passed for enable in MYKONOS_setRxEnFloatPntFrmt()\n"; + + case MYKONOS_ERR_SETUPTEMPSENSOR_NULL_PARAM: + return "MYKONOS_setupTempSensor() has NULL function parameter\n"; + + case MYKONOS_ERR_SETUPTEMPSENSOR_INV_TEMPDECIMATION: + return "tempDecimation value out of range in MYKONOS_setupTempSensor()\n"; + + case MYKONOS_ERR_SETUPTEMPSENSOR_INV_TEMPWINDOW: + return "tempWindow value out of range in MYKONOS_setupTempSensor()\n"; + + case MYKONOS_ERR_SETUPTEMPSENSOR_INV_OFFSET: + return "offset value out of range in MYKONOS_setupTempSensor()\n"; + + case MYKONOS_ERR_GETTEMPSENSORCFG_NULL_PARAM: + return "MYKONOS_getTempSensorConfig() has NULL function parameter\n"; + + case MYKONOS_ERR_READTEMPSENSOR_NULL_PARAM: + return "MYKONOS_readTempSensor() has NULL function parameter\n"; + + case MYKONOS_ERR_READTEMPSENSOR_NOT_LOCKED: + return "MYKONOS_readTempSensor() temperature sensor reading is not locked\n"; + + case MYKONOS_ERR_GPIO_HYBRID_RX1_PIN: + return "MYKONOS_setRxHybridGainChangePin() not valid pin has been passed for RX1 hybrid gain control.\n"; + + case MYKONOS_ERR_GPIO_HYBRID_RX2_PIN: + return "MYKONOS_setRxHybridGainChangePin() not valid pin has been passed for RX2 hybrid gain control.\n"; + + case MYKONOS_ERR_GPIO_HYBRID_ORX_PIN: + return "MYKONOS_setObsRxHybridGainChangePin() if invalid pin has been passed for ORX hybrid gain control.\n"; + + case MYKONOS_ERR_AGC_OBS_NOT_IN_HYBRID: + return "MYKONOS_setObsRxHybridGainChangePin() if the observation gain mode is not set to Hybrid.\n"; + + case MYKONOS_ERR_GPIO_HYBRID_RX1_PIN_NULL_PARM: + return "MYKONOS_getRxHybridGainChangePin() null value has been passed to rx1GainChangePin.\n"; + + case MYKONOS_ERR_GPIO_HYBRID_RX2_PIN_NULL_PARM: + return "MYKONOS_getRxHybridGainChangePin() null value has been passed to rx1GainChangePin.\n"; + + case MYKONOS_ERR_GAIN_CONTROL_NOT_HYBRID: + return "MYKONOS_setRxHybridGainChangePin() if gain control is not hybrid.\n"; + + case MYKONOS_ERR_GAIN_CONTROL_NOT_AGC : + return "MYKONOS_setRxAgcEnSyncPin() or MYKONOS_getObsRxAgcEnSyncPin() if the observation gain control mode is not set to AGC.\n"; + + case MYKONOS_ERR_OBS_GAIN_CONTROL_NOT_AGC: + return "MYKONOS_getObsRxAgcEnSyncPin() if the observation gain control mode is not set to AGC.\n"; + + case MYKONOS_ERR_GPIO_AGC_SYNC_RX1_PIN: + return "MYKONOS_setRxAgcEnSyncPin() if invalid pin has been passed for RX1 AGC sync gain control.\n"; + + case MYKONOS_ERR_GPIO_AGC_SYNC_RX2_PIN: + return "MYKONOS_setRxAgcEnSyncPin() if invalid pin has been passed for RX2 AGC sync gain control.\n"; + + case MYKONOS_ERR_GPIO_AGC_SYNC_RX1_PIN_NULL_PARM: + return "MYKONOS_getRxAgcEnSyncPin() if a null value has been passed to rx1AgcSyncPin.\n"; + + case MYKONOS_ERR_GPIO_AGC_SYNC_RX2_PIN_NULL_PARM: + return "MYKONOS_getRxAgcEnSyncPin() if a null value has been passed to rx2AgcSyncPin.\n"; + + case MYKONOS_ERR_GPIO_AGC_SYNC_ORX_PIN: + return "MYKONOS_setObsRxAgcEnSyncPin() if invalid pin has been passed for ORX AGC sync gain control.\n"; + + case MYKONOS_ERR_GPIO_AGC_SYNC_ORX_PIN_NULL_PARM: + return "MYKONOS_getObsRxAgcEnSyncPin() if a null value has been passed to obsRxAgcSyncPin.\n"; + + case MYKONOS_ERR_SLICER_INV_OBS_RX_SEL: + return "Invalid observation channel GPIO pin selection for Slicer control passed to MYKONOS_setObsRxSlicerCtrl().\n"; + + case MYKONOS_ERR_SLICER_OBS_RX_STEP_OUT_OF_RANGE: + return "Slicer step is out of range passed to MYKONOS_setObsRxSlicerCtrl().\n"; + + case MYKONOS_ERR_SLICER_OBS_RX_EN_INV: + return "Invalid enable passed to MYKONOS_setObsRxSlicerCtrl().\n"; + + case MYKONOS_ERR_SLICER_OBS_RXPIN_NULL_PARM: + return "ObsRxPins is null pointer for the passed parameter passed to MYKONOS_getObsRxSlicerCtrl().\n"; + + case MYKONOS_ERR_SLICER_OBS_RX_STEP_NULL_PARM: + return "SlicerStep is null pointer for the passed parameter passed to MYKONOS_getObsRxSlicerCtrl().\n"; + + case MYKONOS_ERR_SLICER_OBS_RX_EN_NULL_PARM: + return "Enable is null pointer for the passed parameter passed to MYKONOS_getObsRxSlicerCtrl().\n"; + + case MYKONOS_ERR_OBS_RX_GAINCOMP_SET_NULL_STRUCT: + return "Gain compensation structure gainComp is not initialised in MYKONOS_setObsRxGainCompensation().\n"; + + case MYKONOS_ERR_OBS_RX_GAINCOMP_INV_OFFSET: + return "Gain compensation structure gainComp->obsRxOffset is invalid in MYKONOS_setObsRxGainCompensation().\n"; + + case MYKONOS_ERR_OBS_RX_GAINCOMP_INV_STEP: + return "Gain compensation structure gainComp->compStep is invalid in MYKONOS_setObsRxGainCompensation().\n"; + + case MYKONOS_ERR_OBS_RX_GAINCOMP_INV_EN: + return "Enable is not valid in MYKONOS_setObsRxGainCompensation().\n"; + + case MYKONOS_ERR_OBS_RX_GAINCOMP_NULL_STRUCT: + return "Observation channel gain compensation structure gainComp is not initialised in MYKONOS_getObsRxGainCompensation().\n"; + + case MYKONOS_ERR_OBS_RX_GAINCOMP_EN_NULL_PARAM: + return "enabled is null pointer for the parameter passed to MYKONOS_getObsRxGainCompensation().\n"; + + case MYKONOS_ERR_GETGPIODRV_NULL_PARAM: + return "Null parameter passed to the function MYKONOS_getGpioDrv().\n"; + + case MYKONOS_ERR_GPIO_DRV_INV_PARAM: + return "GPIO out of range passed to function MYKONOS_setGpioDrv(), valid GPIOs are in the range 0x00000 to 0x7FFFF.\n"; + + case MYKONOS_ERR_GPIO_SLEW_RATE_INV_PARAM: + return "GPIO out of range -valid GPIOs are in the range 0x00000 to 0x7FFFF.\n"; + + case MYKONOS_ERR_GPIO_GETSLEW_NULL_PARAM: + return "Null parameter passed to the function MYKONOS_getGpioSlewRate().\n"; + + case MYKONOS_ERR_CMOS_DRV_NULL_PARAM: + return "Null parameter passed to the function.\n"; + + case MYKONOS_ERR_CMOS_DRV_INV_PARAM: + return "Incorrect drive strength, valid settings are given by mykonosCmosPadDrvStr_t.\n"; + + case MYKONOS_ERR_SPI2_INV_GPIO: + return "if an invalid GPIO pin configuration is passed to MYKONOS_spi2GpioSetup().\n"; + + case MYKONOS_ERR_GET_GPIO_SOURCE_CONTROL_NULL_PARM: + return "Null parameter passed to the function MYKONOS_getGpioSourceCtrl().\n"; + + default: + return "Unknown error was encountered.\n"; + } + + #endif +} + +/** + * \brief This API function configures the monitor output function for the GPIOs + * + * The monitor outputs are grouped in set of nibbles, the user can set + * individual nibbles for having the monitor output function across the available GPIO. + * In order to enable the GPIO monitor function the function setupGpio has to be run and the + * structure should have the proper setup: + * - device->auxIo->gpio->gpioOe = 0xXXXFF the first D7:D0 GPIOs will have the output enable + * - device->auxIo->gpio->gpioSrcCtrl3_0 = GPIO_MONITOR_MODE + * - device->auxIo->gpio->gpioSrcCtrl4_7 = GPIO_MONITOR_MODE + + * + * Dependencies + * - device->spiSettings + * - device->spiSettings->chipSelectIndex + * - device->auxIo->gpio->gpioOe + * - device->auxIo->gpio->gpioSrcCtrl3_0 + * - device->auxIo->gpio->gpioSrcCtrl4_7 + * + * \param device is structure pointer to the Mykonos data structure containing settings + * + * \param monitorIndex which will be the index at which the outputs are going to be set. see table in documentation + * + * \param monitorMask which GPIO outputs are going to active, the available GPIO + * bit 0 will represent MYKGPIO0 and bit 7 will represent MYKGPIO7. + * + * \retval MYKONOS_ERR_MONITOR_OUT_INDEX_RANGE if GPIO Monitor output index is not in table + * \retval MYKONOS_ERR_EN_MONITOR_OUT_NOT_ENABLED if GPIO source control not set for Monitor output + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + */ +mykonosGpioErr_t MYKONOS_setGpioMonitorOut(mykonosDevice_t *device, uint8_t monitorIndex, uint8_t monitorMask) +{ + mykonosGpioErr_t error = MYKONOS_ERR_GPIO_OK; + + const uint8_t INDEX_MASK = 0x42; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setGpioMonitorOut()\n"); +#endif + + /* Error checking for correct index. */ + if (monitorIndex > INDEX_MASK) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_MONITOR_OUT_INDEX_RANGE, + getGpioMykonosErrorMessage(MYKONOS_ERR_MONITOR_OUT_INDEX_RANGE)); + return MYKONOS_ERR_MONITOR_OUT_INDEX_RANGE; + } + + /* Set the GPIO monitor index and the required pin configuration. */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_GPIO_MONITOR_INDEX, monitorIndex); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_GPIO_MONITOR_ENABLE, monitorMask); + + return error; +} + +/** + * \brief This API function reads the GPIO monitor index from Mykonos + * + * The monitor outputs are grouped in two set of nibbles, the user can set + * individual nibbles for having the monitor output function, this nibbles + * will output the monitor output as per the index set. + * + * Dependencies + * - device->spiSettings + * - device->spiSettings->chipSelectIndex + * - GPIO output enable + * - GPIO source control + * + * \param device is structure pointer to the Mykonos data structure containing settings + * \param monitorIndex which will be the index at which the outputs are set to. + * \param monitorMask which will be enable the monitor function. + * + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + * \retval MYKONOS_ERR_GETGPIOMON_INDEX_NULL_PARM if the monitorIndex is null. + * \retval MYKONOS_ERR_GETGPIOMON_MONITORMASK_NULL_PARM if the monitorMask is null. + */ +mykonosGpioErr_t MYKONOS_getGpioMonitorOut(mykonosDevice_t *device, uint8_t *monitorIndex, uint8_t *monitorMask) +{ + mykonosGpioErr_t error = MYKONOS_ERR_GPIO_OK; + + uint8_t indexRd = 0; + uint8_t monMaskRd = 0; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getGpioMonitorOut()\n"); +#endif + + /* Checking for null passed parameters */ + if (monitorIndex == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETGPIOMON_INDEX_NULL_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_GETGPIOMON_INDEX_NULL_PARM)); + return MYKONOS_ERR_GETGPIOMON_INDEX_NULL_PARM; + } + + if (monitorMask == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETGPIOMON_MONITORMASK_NULL_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_GETGPIOMON_MONITORMASK_NULL_PARM)); + return MYKONOS_ERR_GETGPIOMON_MONITORMASK_NULL_PARM; + } + + /* Get GPIO monitor out enable. */ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GPIO_MONITOR_ENABLE, &monMaskRd); + + /* Get the GPIO monitor index and the required pin configuration. */ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GPIO_MONITOR_INDEX, &indexRd); + + /* assigning return values to the pointers passed */ + *monitorMask = monMaskRd; + *monitorIndex = indexRd; + + return error; +} + + + + +/** + * \brief This API function configures the GPIO inputs for controlling RX gain + * + * This API function configures the GPIO input pin and step size to allow the BBP to control gain changes in Rx1 signal chain. + * A high pulse on the 'rx1GainIncPin' in pin control mode will increment the gain by the value set in incStep'. + * A high pulse on the 'rx1GainDecPin' in pin control mode will decrement the gain by the value set in 'decStep'. + * Dependencies + * - device->spiSettings + * - device->spiSettings->chipSelectIndex + + * + * \param device is structure pointer to the Mykonos data structure containing settings + * + * \param incStep This sets the change (increase) in gain index that is applied when the + * increment gain pin (in MGC pin control mode) is pulsed. + * + * \param decStep This configures the decrement in gain index that should be applied + * when the decrement gain pin (in MGC pin control mode) is pulsed. + * + * \param rx1GainIncPin mykonosGpioSelect_t These bits select the GPIO used as the enable for + * the Rx1 Manual Increment gain input according to the following: + * MYKGPIO0 or MYKGPIO10 + * + * \param rx1GainDecPin mykonosGpioSelect_t These bits select the GPIO used as the enable for + * the Rx1 Manual Decrement gain input according to the following: + * MYKGPIO1 or MYKGPIO11 + * + * \param enable 0 = Disable the gain pin control for Rx1 + * 1 = enable the gain pin control for Rx1 + * + * \retval MYKONOS_ERR_MGCRX1_STEP_INV_PARAM if an invalid step size has been passed + * \retval MYKONOS_ERR_MGCRX1_GPIO_INCPIN_INV_PARAM if invalid increment pin has been passed + * \retval MYKONOS_ERR_MGCRX1_GPIO_DECPIN_INV_PARAM if invalid decrement pin has been passed + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + */ +mykonosGpioErr_t MYKONOS_setRx1GainCtrlPin(mykonosDevice_t *device, uint8_t incStep, uint8_t decStep, mykonosGpioSelect_t rx1GainIncPin, mykonosGpioSelect_t rx1GainDecPin, uint8_t enable) +{ + uint8_t wrtPin = 0x00; + uint8_t wrtStep = 0x00; + mykonosGpioErr_t error = MYKONOS_ERR_GPIO_OK; + + const uint8_t SHIFT_CH1 = 0x00; + const uint8_t SHIFT_INC = 0x05; + const uint8_t SHIFT_DEC = 0x02; + const uint8_t MAX_STEP = 0x07; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setRx1GainCtrlPin()\n"); +#endif + + /* If enable then check for the next otherwise go directly to disable */ + if (enable > 0) + { + /* Error checking for correct step. */ + if ((uint8_t)(incStep > MAX_STEP) || (uint8_t)(decStep > MAX_STEP)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_MGCRX1_STEP_INV_PARAM, + getGpioMykonosErrorMessage(MYKONOS_ERR_MGCRX1_STEP_INV_PARAM)); + return MYKONOS_ERR_MGCRX1_STEP_INV_PARAM; + } + + /* Pin configuration assignment*/ + switch (rx1GainIncPin) + { + case MYKGPIO0: + wrtPin |= 0x00; + break; + case MYKGPIO10: + wrtPin |= 0x04; + break; + + default: + return MYKONOS_ERR_MGCRX1_GPIO_INCPIN_INV_PARAM; + } + + switch (rx1GainDecPin) + { + case MYKGPIO1: + wrtPin |= 0x00; + break; + case MYKGPIO11: + wrtPin |= 0x01; + break; + + default: + return MYKONOS_ERR_MGCRX1_GPIO_DECPIN_INV_PARAM; + } + } + + /* Setting increment step. */ + wrtStep = (uint8_t)(incStep<spiSettings, MYKONOS_ADDR_AGC_MANUAL_GAIN_CFG, wrtStep, 0xFD, 0); + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_MANUAL_GAIN_GPIO_SEL, wrtPin, 0x0F, 0); + + return error; +} + +/** + * \brief This API function returns the configuration RX1 gain Pin control + * + * + * Dependencies + * - device->spiSettings + * - device->spiSettings->chipSelectIndex + + * + * \param device is structure pointer to the Mykonos data structure containing settings + * \param incStep will contain the step that is used for increment. + * \param decStep will contain the step that is used for decrement. + * \param rx1GainIncPin this will have the pin used for increment. + * \param rx1GainDecPin this will have the pin used for decrement. + * \param enable will contain the enable status for this channel if it is set to 1 then this + * function is enable for this channel, if it is 0 it is not enable + * + * \retval MYKONOS_ERR_GETRX1PIN_INCSTEP_NULL_PARM if a null value has been passed to incStep + * \retval MYKONOS_ERR_GETRX1PIN_DECSTEP_NULL_PARM if a null value has been passed to decStep + * \retval MYKONOS_ERR_GETRX1PIN_INCPIN_NULL_PARM if a null value has been passed to rx1GainIncPin + * \retval MYKONOS_ERR_GETRX1PIN_DECPIN_NULL_PARM if a null value has been passed to rx1GainDecPin + * \retval MYKONOS_ERR_GETRX1PIN_EN_NULL_PARM if a null value has been passed to enable + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + */ +mykonosGpioErr_t MYKONOS_getRx1GainCtrlPin(mykonosDevice_t *device, uint8_t *incStep, uint8_t *decStep, mykonosGpioSelect_t *rx1GainIncPin, mykonosGpioSelect_t *rx1GainDecPin, uint8_t *enable) +{ + uint8_t readVal = 0x00; + + const uint8_t MASK_GPIO_CH1 = 0x0F; + const uint8_t MASK_EN_CH1 = 0x01; + const uint8_t MASK_STEP_INC = 0xE0; + const uint8_t MASK_STEP_DEC = 0x1C; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getRx1GainCtrlPin()\n"); +#endif + + /* Checking for null passed parameters */ + if (incStep == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETRX1PIN_INCSTEP_NULL_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_GETRX1PIN_INCSTEP_NULL_PARM)); + return MYKONOS_ERR_GETRX1PIN_INCSTEP_NULL_PARM; + } + + if (decStep == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETRX1PIN_DECSTEP_NULL_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_GETRX1PIN_DECSTEP_NULL_PARM)); + return MYKONOS_ERR_GETRX1PIN_DECSTEP_NULL_PARM; + } + + if (rx1GainIncPin == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETRX1PIN_INCPIN_NULL_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_GETRX1PIN_INCPIN_NULL_PARM)); + return MYKONOS_ERR_GETRX1PIN_INCPIN_NULL_PARM; + } + + if (rx1GainDecPin == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETRX1PIN_DECPIN_NULL_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_GETRX1PIN_DECPIN_NULL_PARM)); + return MYKONOS_ERR_GETRX1PIN_DECPIN_NULL_PARM; + } + + if (enable == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETRX1PIN_EN_NULL_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_GETRX1PIN_EN_NULL_PARM)); + return MYKONOS_ERR_GETRX1PIN_EN_NULL_PARM; + } + + /* Getting Pin configuration assignment*/ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_AGC_MANUAL_GAIN_GPIO_SEL, &readVal); + readVal = readVal & MASK_GPIO_CH1; + + if (readVal & 0x04) + { + *rx1GainIncPin = MYKGPIO10; + } + else + { + *rx1GainIncPin = MYKGPIO0; + } + + if (readVal & 0x01) + { + *rx1GainDecPin = MYKGPIO11; + } + else + { + *rx1GainDecPin = MYKGPIO1; + } + + /* Getting Pin configuration assignment*/ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_AGC_MANUAL_GAIN_CFG, &readVal); + + *enable = readVal & MASK_EN_CH1; + + *incStep = (readVal & MASK_STEP_INC) >> 5; + + *decStep = (readVal & MASK_STEP_DEC) >> 2; + + return MYKONOS_ERR_GPIO_OK; +} + +/** + * \brief This API function configures the GPIO inputs for controlling RX gain + * + * This API function configures the GPIO input pin and step size to allow the BBP to control gain changes in Rx2 signal chain. + * A high pulse on the 'rx2GainIncPin' in pin control mode will increment the gain by the value set in incStep'. + * A high pulse on the 'rx2GainDecPin' in pin control mode will decrement the gain by the value set in 'decStep'. + * + * Dependencies + * - device->spiSettings + * - device->spiSettings->chipSelectIndex + + * + * \param device is structure pointer to the Mykonos data structure containing settings + * + * \param incStep This sets the change (increase) in gain index that is applied when the + * increment gain pin (in MGC pin control mode) is pulsed. + * + * \param decStep This configures the decrement in gain index that should be applied + * when the decrement gain pin (in MGC pin control mode) is pulsed. + * + * \param rx2GainIncPin mykonosGpioSelect_t These bits select the GPIO used as the enable for + * the Rx2 Manual Increment gain input according to the following: + * MYKGPIO3 or MYKGPIO13 + * + * \param rx2GainDecPin mykonosGpioSelect_t These bits select the GPIO used as the enable for + * the Rx2 Manual Decrement gain input according to the following: + * MYKGPIO4 or MYKGPIO14 + * + * \param enable 0 = Disable the gain pin control for Rx2 + * 1 = enable the gain pin control for Rx2 + * + * + * \retval MYKONOS_ERR_MGCRX2_STEP_INV_PARAM if an invalid step size is passed + * \retval MYKONOS_ERR_MGCRX2_GPIO_INCPIN_INV_PARAM if invalid increment pin has been passed + * \retval MYKONOS_ERR_MGCRX2_GPIO_DECPIN_INV_PARAM if invalid decrement pin has been passed + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + */ +mykonosGpioErr_t MYKONOS_setRx2GainCtrlPin(mykonosDevice_t *device, uint8_t incStep, uint8_t decStep, mykonosGpioSelect_t rx2GainIncPin, mykonosGpioSelect_t rx2GainDecPin, uint8_t enable) +{ + uint8_t wrtPin = 0x00; + uint8_t wrtStep = 0x00; + mykonosGpioErr_t error = MYKONOS_ERR_GPIO_OK; + + const uint8_t SHIFT_CH2 = 0x01; + const uint8_t SHIFT_INC = 0x5; + const uint8_t SHIFT_DEC = 0x2; + const uint8_t MAX_STEP = 0x07; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setRx2GainCtrlPin()\n"); +#endif + + /* If enable then check for the next otherwise go directly to disable */ + if (enable > 0) + { + /* Error checking for correct step. */ + if ((uint8_t)(incStep > MAX_STEP) || (uint8_t)(decStep > MAX_STEP)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_MGCRX2_STEP_INV_PARAM, + getGpioMykonosErrorMessage(MYKONOS_ERR_MGCRX2_STEP_INV_PARAM)); + return MYKONOS_ERR_MGCRX2_STEP_INV_PARAM; + } + + /* Pin configuration assignment*/ + switch (rx2GainIncPin) + { + case MYKGPIO3: + wrtPin |= 0x00; + break; + case MYKGPIO13: + wrtPin |= 0x40; + break; + + default: + return MYKONOS_ERR_MGCRX2_GPIO_INCPIN_INV_PARAM; + } + + switch (rx2GainDecPin) + { + case MYKGPIO4: + wrtPin |= 0x00; + break; + case MYKGPIO14: + wrtPin |= 0x10; + break; + + default: + return MYKONOS_ERR_MGCRX2_GPIO_DECPIN_INV_PARAM; + } + } + + /* Setting increment step. */ + wrtStep = (uint8_t)(incStep<spiSettings, MYKONOS_ADDR_AGC_MANUAL_GAIN_CFG, wrtStep, 0xFE, 0); + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_MANUAL_GAIN_GPIO_SEL, wrtPin, 0xF0, 0); + + return error; +} + +/** + * \brief This API function returns the configuration RX2 gain Pin control + * + * + * Dependencies + * - device->spiSettings + * - device->spiSettings->chipSelectIndex + + * + * \param device is structure pointer to the Mykonos data structure containing settings + * \param incStep will contain the step that is used for increment. + * \param decStep will contain the step that is used for decrement. + * \param rx2GainIncPin this will have the pin used for increment. + * \param rx2GainDecPin this will have the pin used for decrement. + * \param enable will contain the enable status for this channel if it is set to 1 then this + * function is enable for this channel, if it is 0 it is not enable + * + * \retval MYKONOS_ERR_GETRX2PIN_INCSTEP_NULL_PARM if a null value has been passed to incStep + * \retval MYKONOS_ERR_GETRX2PIN_DECSTEP_NULL_PARM if a null value has been passed to decStep + * \retval MYKONOS_ERR_GETRX2PIN_INCPIN_NULL_PARM if a null value has been passed to rx1GainIncPin + * \retval MYKONOS_ERR_GETRX2PIN_DECPIN_NULL_PARM if a null value has been passed to rx1GainDecPin + * \retval MYKONOS_ERR_GETRX2PIN_EN_NULL_PARM if a null value has been passed to enable + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + */ +mykonosGpioErr_t MYKONOS_getRx2GainCtrlPin(mykonosDevice_t *device, uint8_t *incStep, uint8_t *decStep, mykonosGpioSelect_t *rx2GainIncPin, mykonosGpioSelect_t *rx2GainDecPin, uint8_t *enable) +{ + uint8_t readVal = 0x00; + + const uint8_t MASK_GPIO_CH2 = 0xF0; + const uint8_t MASK_EN_CH2 = 0x02; + const uint8_t MASK_STEP_INC = 0xE0; + const uint8_t MASK_STEP_DEC = 0x1C; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getRx2GainCtrlPin()\n"); +#endif + + /* Checking for null passed parameters */ + if (incStep == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETRX2PIN_INCSTEP_NULL_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_GETRX2PIN_INCSTEP_NULL_PARM)); + return MYKONOS_ERR_GETRX2PIN_INCSTEP_NULL_PARM; + } + + if (decStep == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETRX2PIN_DECSTEP_NULL_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_GETRX2PIN_DECSTEP_NULL_PARM)); + return MYKONOS_ERR_GETRX2PIN_DECSTEP_NULL_PARM; + } + + if (rx2GainIncPin == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETRX2PIN_INCPIN_NULL_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_GETRX2PIN_INCPIN_NULL_PARM)); + return MYKONOS_ERR_GETRX2PIN_INCPIN_NULL_PARM; + } + + if (rx2GainDecPin == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETRX2PIN_DECPIN_NULL_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_GETRX2PIN_DECPIN_NULL_PARM)); + return MYKONOS_ERR_GETRX2PIN_DECPIN_NULL_PARM; + } + + if (enable == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETRX2PIN_EN_NULL_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_GETRX2PIN_EN_NULL_PARM)); + return MYKONOS_ERR_GETRX2PIN_EN_NULL_PARM; + } + + /* Getting Pin configuration assignment*/ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_AGC_MANUAL_GAIN_GPIO_SEL, &readVal); + readVal = readVal & MASK_GPIO_CH2; + + if (readVal & 0x40) + { + *rx2GainIncPin = MYKGPIO13; + } + else + { + *rx2GainIncPin = MYKGPIO3; + } + + if (readVal & 0x10) + { + *rx2GainDecPin = MYKGPIO14; + } + else + { + *rx2GainDecPin = MYKGPIO4; + } + + /* Getting Pin configuration assignment*/ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_AGC_MANUAL_GAIN_CFG, &readVal); + + *enable = (readVal & MASK_EN_CH2) >> 1; + + *incStep = (readVal & MASK_STEP_INC) >> 5; + + *decStep = (readVal & MASK_STEP_DEC) >> 2; + + return MYKONOS_ERR_GPIO_OK; +} + +/** + * \brief This API function set the pins for hybrid gain control + * + * In order to call this function the gain mode should be set to Hybrid. + * The AGC gain change will be controlled with the selected GPIO pin: + * A pulse on the 'rx1GainChangePin' in hybrid pin control will enable the AGC gain change for RX1 + * A pulse on the 'rx2GainChangePin' in hybrid pin control will enable the AGC gain change for RX2 + * + * Dependencies + * - device->spiSettings + * - device->spiSettings->chipSelectIndex + * + * \param device is structure pointer to the Mykonos data structure containing settings + * \param rx1GainChangePin GPIO pin that will be used for hybrid gain change control, the available pins for RX1 channel + * hybrid control are: + * MYKGPIO1 + * MYKGPIO10 + * MYKGPIO11 + * MYKGPIONAN for no GPIO selected + * + * \param rx2GainChangePin GPIO pin that will be used for hybrid gain change control, the available pins for RX2 channel + * hybrid control are: + * MYKGPIO4 + * MYKGPIO10 + * MYKGPIO13 + * MYKGPIONAN for no GPIO selected + * + * \retval MYKONOS_ERR_GAIN_CONTROL_NOT_HYBRID if gain control is not hybrid + * \retval MYKONOS_ERR_GPIO_HYBRID_RX1_PIN if invalid pin has been passed for RX1 hybrid gain control. + * \retval MYKONOS_ERR_GPIO_HYBRID_RX2_PIN if invalid pin has been passed for RX2 hybrid gain control. + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + */ +mykonosGpioErr_t MYKONOS_setRxHybridGainChangePin(mykonosDevice_t *device, mykonosGpioSelect_t rx1GainChangePin, mykonosGpioSelect_t rx2GainChangePin) +{ + uint8_t hybridPinWrite = 0x00; + uint8_t pinRx1 = 0x00; + uint8_t pinRx2 = 0x00; + + const uint8_t HYBRID_RX_PIN_MASK = 0x0F; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setRxHybridGainChangePin()\n"); +#endif + + /* Check if in Hybrid Mode */ + if (device->rx->rxGainCtrl->gainMode != HYBRID) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GAIN_CONTROL_NOT_HYBRID, + getGpioMykonosErrorMessage(MYKONOS_ERR_GAIN_CONTROL_NOT_HYBRID)); + return MYKONOS_ERR_GAIN_CONTROL_NOT_HYBRID; + } + + /* Pin configuration assignment for RX1 and RX2 */ + switch (rx1GainChangePin) + { + case MYKGPIO1: + pinRx1 |= 0x00; + break; + case MYKGPIO10: + pinRx1 |= 0x01; + break; + case MYKGPIO11: + pinRx1 |= 0x02; + break; + case MYKGPIONAN: + pinRx1 |= 0x03; + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_HYBRID_RX1_PIN, + getGpioMykonosErrorMessage(MYKONOS_ERR_GPIO_HYBRID_RX1_PIN)); + return MYKONOS_ERR_GPIO_HYBRID_RX1_PIN; + } + + switch (rx2GainChangePin) + { + case MYKGPIO4: + pinRx2 |= 0x00; + break; + case MYKGPIO10: + pinRx2 |= 0x04; + break; + case MYKGPIO13: + pinRx2 |= 0x08; + break; + case MYKGPIONAN: + pinRx2 |= 0x0C; + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_HYBRID_RX2_PIN, + getGpioMykonosErrorMessage(MYKONOS_ERR_GPIO_HYBRID_RX2_PIN)); + return MYKONOS_ERR_GPIO_HYBRID_RX2_PIN; + } + + /* Setting GPIO control for RX1 and RX2 */ + hybridPinWrite = (pinRx1 | pinRx2); + + /* Writing GPIO pin configuration for hybrid mode. */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_GAIN_CHANGE_GPIO_SEL, hybridPinWrite, HYBRID_RX_PIN_MASK, 0); + + return MYKONOS_ERR_GPIO_OK; +} + + + +/** + * \brief This API function gets the pin configuration for hybrid gain control of RX1 and RX2 + * + * Dependencies + * - device->spiSettings + * - device->spiSettings->chipSelectIndex + * + * \param device is structure pointer to the Mykonos data structure containing settings + * \param rx1GainChangePin Will return the GPIO pin used for Rx1 in hybrid gain control. + * \param rx2GainChangePin Will return the GPIO pin used for Rx2 in hybrid gain control. + * + * \retval MYKONOS_ERR_GPIO_HYBRID_RX1_PIN_NULL_PARM if a null value has been passed to rx1GainChangePin + * \retval MYKONOS_ERR_GPIO_HYBRID_RX2_PIN_NULL_PARM if a null value has been passed to rx2GainChangePin + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + */ +mykonosGpioErr_t MYKONOS_getRxHybridGainChangePin(mykonosDevice_t *device, mykonosGpioSelect_t *rx1GainChangePin, mykonosGpioSelect_t *rx2GainChangePin) +{ + uint8_t hybridPinRead = 0x00; + uint8_t pinRx1 = 0x00; + uint8_t pinRx2 = 0x00; + mykonosGpioSelect_t rx1Pin = MYKGPIONAN; + mykonosGpioSelect_t rx2Pin = MYKGPIONAN; + + const uint8_t MASK_RX1_PIN = 0x03; + const uint8_t MASK_RX2_PIN = 0x0C; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getRxHybridGainChangePin()\n"); +#endif + + /* Checking for null passed parameters */ + if (rx1GainChangePin == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_HYBRID_RX1_PIN_NULL_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_GPIO_HYBRID_RX1_PIN_NULL_PARM)); + return MYKONOS_ERR_GPIO_HYBRID_RX1_PIN_NULL_PARM; + } + + if (rx2GainChangePin == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_HYBRID_RX2_PIN_NULL_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_GPIO_HYBRID_RX2_PIN_NULL_PARM)); + return MYKONOS_ERR_GPIO_HYBRID_RX2_PIN_NULL_PARM; + } + + /* Getting Pin configuration assignment */ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_AGC_GAIN_CHANGE_GPIO_SEL, &hybridPinRead); + pinRx1 = hybridPinRead & MASK_RX1_PIN; + pinRx2 = hybridPinRead & MASK_RX2_PIN; + + /* Pin configuration mapping assignment for RX1 and RX2 */ + switch (pinRx1) + { + case 0x00: + rx1Pin = MYKGPIO1; + break; + case 0x01: + rx1Pin = MYKGPIO10; + break; + case 0x02: + rx1Pin = MYKGPIO11; + break; + default: + rx1Pin = MYKGPIONAN; + break; + } + + switch (pinRx2) + { + case 0x00: + rx2Pin = MYKGPIO4; + break; + case 0x04: + rx2Pin = MYKGPIO10; + break; + case 0x08: + rx2Pin = MYKGPIO13; + break; + default: + rx2Pin = MYKGPIONAN; + break; + } + + /* Setting pins to passed pointers */ + *rx1GainChangePin = rx1Pin; + *rx2GainChangePin = rx2Pin; + + return MYKONOS_ERR_GPIO_OK; +} + + +/** + * \brief This API function set the pins for hybrid gain control + * + * In order to call this function the gain mode should be set to Hybrid. + * The AGC gain change will be controlled with the selected GPIO pin: + * A pulse on the 'obsRxGainChangePin' in hybrid pin control will enable the AGC gain change for observation channel + * + * Dependencies + * - device->spiSettings + * - device->spiSettings->chipSelectIndex + * + * \param device is structure pointer to the Mykonos data structure containing settings + * \param obsRxGainChangePin GPIO pin that will be used for hybrid gain change control, the available pins for observation channel + * hybrid control are: + * MYKGPIO6 + * MYKGPIO10 + * MYKGPIO17 + * MYKGPIONAN for none selected + * + * \retval MYKONOS_ERR_AGC_OBS_NOT_IN_HYBRID if the observation gain mode is not set to Hybrid + * \retval MYKONOS_ERR_GPIO_HYBRID_ORX_PIN if invalid pin has been passed for ORX hybrid gain control. + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + */ +mykonosGpioErr_t MYKONOS_setObsRxHybridGainChangePin(mykonosDevice_t *device, mykonosGpioSelect_t obsRxGainChangePin) +{ + uint8_t hybridPinWrite = 0x00; + uint8_t pinOrx = 0x00; + + const uint8_t HYBRID_ORX_PIN_MASK = 0x30; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setObsRxHybridGainChangePin()\n"); +#endif + + /* Check if in Hybrid Mode */ + if (device->obsRx->orxGainCtrl->gainMode != HYBRID) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_AGC_OBS_NOT_IN_HYBRID, + getGpioMykonosErrorMessage(MYKONOS_ERR_AGC_OBS_NOT_IN_HYBRID)); + return MYKONOS_ERR_AGC_OBS_NOT_IN_HYBRID; + } + + /* Pin configuration assignment for RX1 and RX2 */ + switch (obsRxGainChangePin) + { + case MYKGPIO6: + pinOrx |= 0x00; + break; + case MYKGPIO10: + pinOrx |= 0x10; + break; + case MYKGPIO17: + pinOrx |= 0x20; + break; + case MYKGPIONAN: + pinOrx |= 0x30; + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_HYBRID_ORX_PIN, + getGpioMykonosErrorMessage(MYKONOS_ERR_GPIO_HYBRID_ORX_PIN)); + return MYKONOS_ERR_GPIO_HYBRID_ORX_PIN; + } + + /* Setting GPIO control for observation channel */ + hybridPinWrite = pinOrx; + + /* Writing GPIO pin configuration for hybrid mode. */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_ORX_SNRX_GPIO_SEL, hybridPinWrite, HYBRID_ORX_PIN_MASK, 0); + + return MYKONOS_ERR_GPIO_OK; +} + +/** + * \brief This API function gets the pin configuration for hybrid gain control of observation channel + * + * Dependencies + * - device->spiSettings + * - device->spiSettings->chipSelectIndex + * + * \param device is structure pointer to the Mykonos data structure containing settings + * \param obsRxGainChangePin Will return the GPIO pin used for observation channel in hybrid gain control. + * + * \retval MYKONOS_ERR_GPIO_HYBRID_ORX_PIN_NULL_PARM if a null value has been passed to obsRxGainChangePin + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + */ +mykonosGpioErr_t MYKONOS_getObsRxHybridGainChangePin(mykonosDevice_t *device, mykonosGpioSelect_t *obsRxGainChangePin) +{ + uint8_t hybridPinRead = 0x00; + uint8_t pinOrx = 0x00; + mykonosGpioSelect_t orxPin = MYKGPIONAN; + + const uint8_t MASK_ORX_PIN = 0x30; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getObsRxHybridGainChangePin()\n"); +#endif + + /* Checking for null passed parameters */ + if (obsRxGainChangePin == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_HYBRID_ORX_PIN_NULL_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_GPIO_HYBRID_ORX_PIN_NULL_PARM)); + return MYKONOS_ERR_GPIO_HYBRID_ORX_PIN_NULL_PARM; + } + + /* Getting Pin configuration assignment */ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_AGC_ORX_SNRX_GPIO_SEL, &hybridPinRead); + pinOrx = hybridPinRead & MASK_ORX_PIN; + + /* Pin configuration mapping assignment for RX1 and RX2 */ + switch (pinOrx) + { + case 0x00: + orxPin = MYKGPIO6; + break; + case 0x10: + orxPin = MYKGPIO10; + break; + case 0x20: + orxPin = MYKGPIO17; + break; + default: + orxPin = MYKGPIONAN; + break; + } + + /* Setting pins to passed pointer */ + *obsRxGainChangePin = orxPin; + + return MYKONOS_ERR_GPIO_OK; +} + +/** + * \brief This API function set the pins for sync AGC gain control + * + * In order to call this function the RX gain control should be set to AGC mode. + * The AGC gain sync will be controlled with the selected GPIO pin: + * A pulse on the 'rx1AgcSyncPin' in hybrid pin control will enable the AGC gain sync for RX1 + * A pulse on the 'rx2AgcSyncPin' in hybrid pin control will enable the AGC gain sync for RX2 + * + * Dependencies + * - device->spiSettings + * - device->spiSettings->chipSelectIndex + * + * \param device is structure pointer to the Mykonos data structure containing settings + * \param rx1AgcSyncPin GPIO pin that will be used for AGC sync gain control, the available pins for RX1 channel are: + * MYKGPIO1 + * MYKGPIO10 + * MYKGPIO11 + * MYKGPIONAN for no GPIO selected + * + * \param rx2AgcSyncPin GPIO pin that will be used for AGC sync gain control, the available pins for RX2 channel are: + * MYKGPIO4 + * MYKGPIO10 + * MYKGPIO13 + * MYKGPIONAN for no GPIO selected + * + * \retval MYKONOS_ERR_GAIN_CONTROL_NOT_AGC if the RX gain control mode is not set to AGC. + * \retval MYKONOS_ERR_GPIO_AGC_SYNC_RX1_PIN if invalid pin has been passed for RX1 AGC sync gain control. + * \retval MYKONOS_ERR_GPIO_AGC_SYNC_RX2_PIN if invalid pin has been passed for RX2 AGC sync gain control. + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + */ +mykonosGpioErr_t MYKONOS_setRxAgcEnSyncPin(mykonosDevice_t *device, mykonosGpioSelect_t rx1AgcSyncPin, mykonosGpioSelect_t rx2AgcSyncPin) +{ + uint8_t agcSyncPinWrite = 0x00; + uint8_t pinRx1 = 0x00; + uint8_t pinRx2 = 0x00; + + const uint8_t SYNC_RX_PIN_MASK = 0x0F; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setRxAgcEnSyncPin()\n"); +#endif + + /* Check if in Hybrid Mode */ + if (device->rx->rxGainCtrl->gainMode != AGC) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GAIN_CONTROL_NOT_AGC, + getGpioMykonosErrorMessage(MYKONOS_ERR_GAIN_CONTROL_NOT_AGC)); + return MYKONOS_ERR_GAIN_CONTROL_NOT_AGC; + } + + /* Pin configuration assignment for RX1 and RX2 */ + switch (rx1AgcSyncPin) + { + case MYKGPIO1: + pinRx1 |= 0x00; + break; + case MYKGPIO10: + pinRx1 |= 0x01; + break; + case MYKGPIO11: + pinRx1 |= 0x02; + break; + case MYKGPIONAN: + pinRx1 |= 0x03; + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_AGC_SYNC_RX1_PIN, + getGpioMykonosErrorMessage(MYKONOS_ERR_GPIO_AGC_SYNC_RX1_PIN)); + return MYKONOS_ERR_GPIO_AGC_SYNC_RX1_PIN; + } + + switch (rx2AgcSyncPin) + { + case MYKGPIO4: + pinRx2 |= 0x00; + break; + case MYKGPIO10: + pinRx2 |= 0x04; + break; + case MYKGPIO13: + pinRx2 |= 0x08; + break; + case MYKGPIONAN: + pinRx2 |= 0x0C; + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_AGC_SYNC_RX2_PIN, + getGpioMykonosErrorMessage(MYKONOS_ERR_GPIO_AGC_SYNC_RX2_PIN)); + return MYKONOS_ERR_GPIO_AGC_SYNC_RX2_PIN; + } + + /* Setting GPIO control for RX1 and RX2 */ + agcSyncPinWrite = (pinRx1 | pinRx2); + + /* Writing GPIO pin configuration for Sync AGC. */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_GAIN_CHANGE_GPIO_SEL, agcSyncPinWrite, SYNC_RX_PIN_MASK, 0); + + return MYKONOS_ERR_GPIO_OK; +} + +/** + * \brief This API function gets the GPIO pin configuration for AGC gain sync control of RX1 and RX2 + * + * Dependencies + * - device->spiSettings + * - device->spiSettings->chipSelectIndex + * + * \param device is structure pointer to the Mykonos data structure containing settings + * \param rx1AgcSyncPin Will return the GPIO pin used for RX1 channel AGC gain sync control, + * + * \param rx2AgcSyncPin Will return the GPIO pin used for RX2 channel AGC gain sync control, + * + * \retval MYKONOS_ERR_GPIO_AGC_SYNC_RX1_PIN_NULL_PARM if a null value has been passed to rx1AgcSyncPin + * \retval MYKONOS_ERR_GPIO_AGC_SYNC_RX2_PIN_NULL_PARM if a null value has been passed to rx2AgcSyncPin + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + */ +mykonosGpioErr_t MYKONOS_getRxAgcEnSyncPin(mykonosDevice_t *device, mykonosGpioSelect_t *rx1AgcSyncPin, mykonosGpioSelect_t *rx2AgcSyncPin) +{ + uint8_t agcSyncPinRead = 0x00; + uint8_t pinRx1 = 0x00; + uint8_t pinRx2 = 0x00; + mykonosGpioSelect_t rx1Pin = MYKGPIONAN; + mykonosGpioSelect_t rx2Pin = MYKGPIONAN; + + const uint8_t MASK_RX1_PIN = 0x03; + const uint8_t MASK_RX2_PIN = 0x0C; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getRxHybridGainChangePin()\n"); +#endif + + /* Checking for null passed parameters */ + if (rx1AgcSyncPin == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_AGC_SYNC_RX1_PIN_NULL_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_GPIO_AGC_SYNC_RX1_PIN_NULL_PARM)); + return MYKONOS_ERR_GPIO_AGC_SYNC_RX1_PIN_NULL_PARM; + } + + if (rx2AgcSyncPin == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_AGC_SYNC_RX2_PIN_NULL_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_GPIO_AGC_SYNC_RX2_PIN_NULL_PARM)); + return MYKONOS_ERR_GPIO_AGC_SYNC_RX2_PIN_NULL_PARM; + } + + /* Getting Pin configuration assignment */ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_AGC_GAIN_CHANGE_GPIO_SEL, &agcSyncPinRead); + pinRx1 = agcSyncPinRead & MASK_RX1_PIN; + pinRx2 = agcSyncPinRead & MASK_RX2_PIN; + + /* Pin configuration mapping assignment for RX1 and RX2 */ + switch (pinRx1) + { + case 0x00: + rx1Pin = MYKGPIO1; + break; + case 0x01: + rx1Pin = MYKGPIO10; + break; + case 0x02: + rx1Pin = MYKGPIO11; + break; + default: + rx1Pin = MYKGPIONAN; + break; + } + + switch (pinRx2) + { + case 0x00: + rx2Pin = MYKGPIO4; + break; + case 0x04: + rx2Pin = MYKGPIO10; + break; + case 0x08: + rx2Pin = MYKGPIO13; + break; + default: + rx2Pin = MYKGPIONAN; + break; + } + + /* Setting pins to passed pointers */ + *rx1AgcSyncPin = rx1Pin; + *rx2AgcSyncPin = rx2Pin; + + return MYKONOS_ERR_GPIO_OK; +} + + +/** + * \brief This API function set the pins for AGC gain Sync control + * + * In order to call this function the gain mode should be set to AGC mode. + * The AGC gain sync will be controlled with the selected GPIO pin: + * A pulse on the 'obsRxGainChangePin' in hybrid pin control will enable the AGC gain change for observation channel + * + * Dependencies + * - device->spiSettings + * - device->spiSettings->chipSelectIndex + * + * \param device is structure pointer to the Mykonos data structure containing settings + * \param obsRxAgcSyncPin GPIO pin that will be used for AGC sync gain control, the available pins for observation channel are: + * MYKGPIO6 + * MYKGPIO10 + * MYKGPIO17 + * MYKGPIONAN for none selected + * + * \retval MYKONOS_ERR_OBS_GAIN_CONTROL_NOT_AGC if the observation gain control mode is not set to AGC + * \retval MYKONOS_ERR_GPIO_AGC_SYNC_ORX_PIN if invalid pin has been passed for ORX AGC sync gain control. + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + */ +mykonosGpioErr_t MYKONOS_setObsRxAgcEnSyncPin(mykonosDevice_t *device, mykonosGpioSelect_t obsRxAgcSyncPin) +{ + uint8_t agcSyncPinWrite = 0x00; + uint8_t pinOrx = 0x00; + + const uint8_t SYNC_ORX_PIN_MASK = 0x30; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setObsRxAgcEnSyncPin()\n"); +#endif + + /* Check if in Hybrid Mode */ + if (device->obsRx->orxGainCtrl->gainMode != AGC) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OBS_GAIN_CONTROL_NOT_AGC, + getGpioMykonosErrorMessage(MYKONOS_ERR_OBS_GAIN_CONTROL_NOT_AGC)); + return MYKONOS_ERR_OBS_GAIN_CONTROL_NOT_AGC; + } + + /* Pin configuration assignment for observation channel */ + switch (obsRxAgcSyncPin) + { + case MYKGPIO6: + pinOrx |= 0x00; + break; + case MYKGPIO10: + pinOrx |= 0x10; + break; + case MYKGPIO17: + pinOrx |= 0x20; + break; + case MYKGPIONAN: + pinOrx |= 0x30; + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_AGC_SYNC_ORX_PIN, + getGpioMykonosErrorMessage(MYKONOS_ERR_GPIO_AGC_SYNC_ORX_PIN)); + return MYKONOS_ERR_GPIO_AGC_SYNC_ORX_PIN; + } + + /* Setting GPIO control for observation channel */ + agcSyncPinWrite = pinOrx; + + /* Writing GPIO pin configuration for Sync AGC mode. */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_ORX_SNRX_GPIO_SEL, agcSyncPinWrite, SYNC_ORX_PIN_MASK, 0); + + return MYKONOS_ERR_GPIO_OK; +} + +/** + * \brief This API function gets the pin configuration for AGC Sync gain control of observation channel + * + * Dependencies + * - device->spiSettings + * - device->spiSettings->chipSelectIndex + * + * \param device is structure pointer to the Mykonos data structure containing settings + * \param obsRxAgcSyncPin Will return the GPIO pin used for observation channel AGC gain sync control, + * + * \retval MYKONOS_ERR_GPIO_AGC_SYNC_ORX_PIN_NULL_PARM if a null value has been passed to obsRxAgcSyncPin + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + */ +mykonosGpioErr_t MYKONOS_getObsRxAgcEnSyncPin(mykonosDevice_t *device, mykonosGpioSelect_t *obsRxAgcSyncPin) +{ + uint8_t agcSyncPinRead = 0x00; + uint8_t pinOrx = 0x00; + mykonosGpioSelect_t orxPin = MYKGPIONAN; + + const uint8_t MASK_ORX_PIN = 0x30; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getObsRxAgcEnSyncPin()\n"); +#endif + + /* Checking for null passed parameters */ + if (obsRxAgcSyncPin == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_AGC_SYNC_ORX_PIN_NULL_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_GPIO_AGC_SYNC_ORX_PIN_NULL_PARM)); + return MYKONOS_ERR_GPIO_AGC_SYNC_ORX_PIN_NULL_PARM; + } + + /* Getting Pin configuration assignment */ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_AGC_ORX_SNRX_GPIO_SEL, &agcSyncPinRead); + pinOrx = agcSyncPinRead & MASK_ORX_PIN; + + /* Pin configuration mapping assignment for observation channel */ + switch (pinOrx) + { + case 0x00: + orxPin = MYKGPIO6; + break; + case 0x10: + orxPin = MYKGPIO10; + break; + case 0x20: + orxPin = MYKGPIO17; + break; + default: + orxPin = MYKGPIONAN; + break; + } + + /* Setting pins to passed pointer */ + *obsRxAgcSyncPin = orxPin; + + return MYKONOS_ERR_GPIO_OK; +} + + +/** + * \brief This API function configures the GPIO inputs for controlling Tx attenuation settings + * + * This allows to control the TX attenuation using GPIO inputs. When a low to high transition is + * applied to the configure GPIO input the attenuation will change by the desire step. + * The stepSize parameter will set the attenuation change applied. + * + * + * Dependencies + * - device->spiSettings + * - device->spiSettings->chipSelectIndex + * + * \param device is structure pointer to the Mykonos data structure containing settings + * + * \param stepSize the step that will increase or decrease the Tx1 channel attenuation. + * This parameter sets the change in Tx attenuation for each increment or decrement signal received in incr/decr mode. + * Step of 1 changes attenuation by 0.05dB. + * + * \param tx1AttenIncPin This parameter is the GPIO pin configuration that will be controlling the increment + * of Tx attenuation. Available pins are: + * Tx1 increment: MYKGPIO4 or MYKGPIO12 + * + * \param tx1AttenDecPin This parameter is the GPIO pin configuration that will be controlling the decrement + * of Tx attenuation. Available pins are: + * Tx1 decrement: MYKGPIO5 or MYKGPIO13 + * + * \param enable 0 = Disable the attenuation pin control for Tx1 + * 1 = enable the attenuation pin control for Tx1 + * + * \param useTx1ForTx2 is used to return if TX1 settings are used for TX2 channel. + * + * \retval MYKONOS_ERR_TPCTX1_GPIO_STEP_INV_PARAM if an invalid step size is passed + * \retval MYKONOS_ERR_TPCTX1_GPIO_INCPIN_INV_PARAM if an invalid channel for TX is passed + * \retval MYKONOS_ERR_TPCTX1_GPIO_DECPIN_INV_PARAM if an invalid channel for TX is passed + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + */ +mykonosGpioErr_t MYKONOS_setTx1AttenCtrlPin(mykonosDevice_t *device, uint8_t stepSize, mykonosGpioSelect_t tx1AttenIncPin, mykonosGpioSelect_t tx1AttenDecPin, uint8_t enable, uint8_t useTx1ForTx2) +{ + uint8_t wrtPin = 0; + uint8_t tpcMode = 0x0; + uint8_t tpcMaskTx2 = 0x00; + mykonosGpioErr_t error = MYKONOS_ERR_GPIO_OK; + + const uint8_t TX_INCDEC_MASK = 0x1F; + const uint8_t TX_PIN_MASK = 0x0F; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setTx1AttenCtrlPin()\n"); +#endif + + /* If enable then check for the next otherwise go directly to disable */ + if (enable > 0) + { + /* Error checking for correct step. */ + if (stepSize > TX_INCDEC_MASK) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_TPCTX1_GPIO_STEP_INV_PARAM, + getGpioMykonosErrorMessage(MYKONOS_ERR_TPCTX1_GPIO_STEP_INV_PARAM)); + return MYKONOS_ERR_TPCTX1_GPIO_STEP_INV_PARAM; + } + + /* Pin configuration assignment for Tx1 increments */ + switch (tx1AttenIncPin) + { + case MYKGPIO4: + wrtPin |= 0x00; + break; + case MYKGPIO12: + wrtPin |= 0x01; + break; + + default: + return MYKONOS_ERR_TPCTX1_GPIO_INCPIN_INV_PARAM; + } + + /* Pin configuration assignment for Tx1 decrements */ + switch (tx1AttenDecPin) + { + case MYKGPIO5: + wrtPin |= 0x00; + break; + case MYKGPIO13: + wrtPin |= 0x04; + break; + + default: + return MYKONOS_ERR_TPCTX1_GPIO_DECPIN_INV_PARAM; + } + + /* Setting TPC mode corresponding to the enable */ + tpcMode = 0x03; + + /* Setting TPC control for Tx2 using Tx1 */ + if (useTx1ForTx2 > 0) + { + tpcMode |= 0x1C; + tpcMaskTx2 = 0x1F; + } + else + { + tpcMaskTx2 = 0x13; + } + } + else + { + /* Setting TPC mode corresponding for no Pin control */ + tpcMode = 0x05; + tpcMaskTx2 = 0x1F; + } + + /* Setting increment step. */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_TX_INCR_DECR_WORD, stepSize, TX_INCDEC_MASK, 0); + + /* Set the TPC mode for GPIO control. */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_TX_TPC_CONFIG, tpcMode, tpcMaskTx2, 0); + + /* Set the GPIO input pin configuration and the step size. */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_TX_TPC_GPIO_CFG, wrtPin, TX_PIN_MASK, 0); + + return error; +} + +/** + * \brief This API function returns the configuration TX1 attenuation Pin control + * + * + * Dependencies + * - device->spiSettings + * - device->spiSettings->chipSelectIndex + + * + * \param device is structure pointer to the Mykonos data structure containing settings + * \param stepSize will contain the step that is used for increment and decrement. + * \param tx1AttenIncPin this will have the pin used for increment. + * \param tx1AttenDecPin this will have the pin used for decrement. + * \param enable will contain the enable status for this channel if it is set to 1 then this + * function is enable for this channel, if it is 0 it is not enable + * \param useTx1ForTx2 is used to return if TX1 settings are used for TX2 channel. + * + * \retval MYKONOS_ERR_GETTX1PIN_STEP_NULL_PARM if a null value has been passed to stepSize + * \retval MYKONOS_ERR_GETTX1PIN_INC_NULL_PARM if a null value has been passed to tx1AttenIncPin + * \retval MYKONOS_ERR_GETTX1PIN_DEC_NULL_PARM if a null value has been passed to tx1AttenDecPin + * \retval MYKONOS_ERR_GETTX1PIN_EN_NULL_PARM if a null value has been passed to enable + * \retval MYKONOS_ERR_GETTX1PIN_TX1TX2_NULL_PARM if a null value has been passed to useTx1ForTx2 + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + */ +mykonosGpioErr_t MYKONOS_getTx1AttenCtrlPin(mykonosDevice_t *device, uint8_t *stepSize, mykonosGpioSelect_t *tx1AttenIncPin, mykonosGpioSelect_t *tx1AttenDecPin, uint8_t *enable, uint8_t *useTx1ForTx2) +{ + uint8_t readVal = 0x00; + uint8_t en = 0x00; + + const uint8_t MASK_TPC_CH1 = 0x03; + const uint8_t MASK_TPC_CH1FCH2 = 0x10; + const uint8_t MASK_TPC_STEP = 0x1F; + const uint8_t MASK_TPC_GPIO_CH1 = 0x0F; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getTx1AttenCtrlPin()\n"); +#endif + + /* Checking for null passed parameters */ + if (stepSize == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETTX1PIN_STEP_NULL_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_GETTX1PIN_STEP_NULL_PARM)); + return MYKONOS_ERR_GETTX1PIN_STEP_NULL_PARM; + } + + if (tx1AttenIncPin == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETTX1PIN_INC_NULL_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_GETTX1PIN_INC_NULL_PARM)); + return MYKONOS_ERR_GETTX1PIN_INC_NULL_PARM; + } + + if (tx1AttenDecPin == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETTX1PIN_DEC_NULL_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_GETTX1PIN_DEC_NULL_PARM)); + return MYKONOS_ERR_GETTX1PIN_DEC_NULL_PARM; + } + + if (enable == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETTX1PIN_EN_NULL_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_GETTX1PIN_EN_NULL_PARM)); + return MYKONOS_ERR_GETTX1PIN_EN_NULL_PARM; + } + + if (useTx1ForTx2 == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETTX1PIN_TX1TX2_NULL_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_GETTX1PIN_TX1TX2_NULL_PARM)); + return MYKONOS_ERR_GETTX1PIN_TX1TX2_NULL_PARM; + } + + /* Getting Pin configuration assignment*/ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_TX_TPC_GPIO_CFG, &readVal); + readVal = readVal & MASK_TPC_GPIO_CH1; + + if (readVal & 0x01) + { + *tx1AttenIncPin = MYKGPIO12; + } + else + { + *tx1AttenIncPin = MYKGPIO4; + } + + if (readVal & 0x04) + { + *tx1AttenDecPin = MYKGPIO13; + } + else + { + *tx1AttenDecPin = MYKGPIO5; + } + + /* Getting Pin configuration assignment*/ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_TX_TPC_CONFIG, &readVal); + + en = readVal & MASK_TPC_CH1; + + *enable = (en == MASK_TPC_CH1) ? 1 : 0; + + *useTx1ForTx2 = readVal & MASK_TPC_CH1FCH2; + + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_TX_INCR_DECR_WORD, &readVal); + + *stepSize = readVal & MASK_TPC_STEP; + + return MYKONOS_ERR_GPIO_OK; +} + +/** + * \brief This API function configures the GPIO inputs for controlling Tx attenuation settings + * + * This allows to control the TX attenuation using GPIO inputs. when a low to high transition is + * applied to the configure GPIO input the attenuation will change by the desire step. + * The stepSize parameter will set the attenuation change applied. + * + * + * Dependencies + * - device->spiSettings + * - device->spiSettings->chipSelectIndex + * + * \param device is structure pointer to the Mykonos data structure containing settings + * + * \param stepSize the step that will increase or decrease the Tx2 channel attenuation. + * This parameter sets the change in Tx attenuation for each increment or decrement signal received in incr/decr mode. + * Step of 1 changes attenuation by 0.05dB. + * + * \param tx2AttenIncPin This parameter is the GPIO pin configuration that will be controlling the increment + * of Tx attenuation. Available pins are: + * Tx2 increment: MYKGPIO6 or MYKGPIO14 + * + * \param tx2AttenDecPin This parameter is the GPIO pin configuration that will be controlling the decrement + * of Tx attenuation. Available pins are: + * Tx2 decrement: MYKGPIO7 or MYKGPIO15 + * + * \param enable 0 = Disable the attenuation pin control for Tx2 + * 1 = enable the attenuation pin control for Tx2 + * + * \retval MYKONOS_ERR_TPCTX2_GPIO_STEP_INV_PARAM if an invalid step size is passed + * \retval MYKONOS_ERR_TPCTX2_GPIO_INCPIN_INV_PARAM if an invalid channel for TX is passed + * \retval MYKONOS_ERR_TPCTX2_GPIO_INCPIN_INV_PARAM if an invalid channel for TX is passed + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + */ +mykonosGpioErr_t MYKONOS_setTx2AttenCtrlPin(mykonosDevice_t *device, uint8_t stepSize, mykonosGpioSelect_t tx2AttenIncPin, mykonosGpioSelect_t tx2AttenDecPin, uint8_t enable) +{ + uint8_t wrtPin = 0; + uint8_t tpcMode = 0x0; + mykonosGpioErr_t error = MYKONOS_ERR_GPIO_OK; + + + const uint8_t TX_INCDEC_MASK = 0x1F; + const uint8_t TX2_TPC_MASK = 0x1C; + const uint8_t TX2_WRTPIN = 0xf0; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setTx2AttenCtrlPin()\n"); +#endif + + /* If enable then check for the next otherwise go directly to disable */ + if (enable > 0) + { + /* Error checking for correct step. */ + if (stepSize > TX_INCDEC_MASK) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_TPCTX2_GPIO_STEP_INV_PARAM, + getGpioMykonosErrorMessage(MYKONOS_ERR_TPCTX2_GPIO_STEP_INV_PARAM)); + return MYKONOS_ERR_TPCTX2_GPIO_STEP_INV_PARAM; + } + + /* Pin configuration assignment for Tx2 increments */ + switch (tx2AttenIncPin) + { + case MYKGPIO6: + wrtPin |= 0x00; + break; + case MYKGPIO14: + wrtPin |= 0x10; + break; + + default: + return MYKONOS_ERR_TPCTX2_GPIO_INCPIN_INV_PARAM; + } + + /* Pin configuration assignment for Tx2 decrements */ + switch (tx2AttenDecPin) + { + case MYKGPIO7: + wrtPin |= 0x00; + break; + case MYKGPIO15: + wrtPin |= 0x40; + break; + + default: + return MYKONOS_ERR_TPCTX2_GPIO_DECPIN_INV_PARAM; + } + + /* Setting TPC mode corresponding to the enable */ + tpcMode = 0x0C; + } + else + { + /* Setting TPC mode corresponding for no Pin control */ + tpcMode = 0x05; + } + + /* Setting increment step. */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_TX_INCR_DECR_WORD, stepSize, TX_INCDEC_MASK, 0); + + /* Set the TPC mode for GPIO control. */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_TX_TPC_CONFIG, tpcMode, TX2_TPC_MASK, 0); + + /* Set the GPIO input pin configuration and the step size. */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_TX_TPC_GPIO_CFG, wrtPin, TX2_WRTPIN, 0); + + return error; +} + +/** + * \brief This API function returns the configuration TX2 attenuation Pin control + * + * + * Dependencies + * - device->spiSettings + * - device->spiSettings->chipSelectIndex + + * + * \param device is structure pointer to the Mykonos data structure containing settings + * \param stepSize will contain the step that is used for increment and decrement. + * \param tx2AttenIncPin this will have the pin used for increment. + * \param tx2AttenDecPin this will have the pin used for decrement. + * \param enable will contain the enable status for this channel if it is set to 1 then this + * function is enable for this channel, if it is 0 it is not enable + * \param useTx1ForTx2 is used to return if TX1 settings are used for TX2 channel. + * + * \retval MYKONOS_ERR_GETTX2PIN_STEP_NULL_PARM if a null value has been passed to stepSize + * \retval MYKONOS_ERR_GETTX2PIN_STEP_NULL_PARM if a null value has been passed to tx1AttenIncPin + * \retval MYKONOS_ERR_GETTX2PIN_DEC_NULL_PARM if a null value has been passed to tx1AttenDecPin + * \retval MYKONOS_ERR_GETTX2PIN_EN_NULL_PARM if a null value has been passed to enable + * \retval MYKONOS_ERR_GETTX2PIN_TX1TX2_NULL_PARM if a null value has been passed to useTx1ForTx2 + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + */ +mykonosGpioErr_t MYKONOS_getTx2AttenCtrlPin(mykonosDevice_t *device, uint8_t *stepSize, mykonosGpioSelect_t *tx2AttenIncPin, mykonosGpioSelect_t *tx2AttenDecPin, uint8_t *enable, uint8_t *useTx1ForTx2) +{ + uint8_t readVal = 0x00; + uint8_t en = 0x00; + + const uint8_t MASK_TPC_CH2 = 0x0C; + const uint8_t MASK_TPC_CH1FCH2 = 0x10; + const uint8_t MASK_TPC_STEP = 0x1F; + const uint8_t MASK_TPC_GPIO_CH2 = 0xF0; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getTx2AttenCtrlPin()\n"); +#endif + + /* Checking for null passed parameters */ + if (stepSize == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETTX2PIN_STEP_NULL_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_GETTX2PIN_STEP_NULL_PARM)); + return MYKONOS_ERR_GETTX2PIN_STEP_NULL_PARM; + } + + if (tx2AttenIncPin == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETTX2PIN_INC_NULL_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_GETTX2PIN_INC_NULL_PARM)); + return MYKONOS_ERR_GETTX2PIN_INC_NULL_PARM; + } + + if (tx2AttenDecPin == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETTX2PIN_DEC_NULL_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_GETTX2PIN_DEC_NULL_PARM)); + return MYKONOS_ERR_GETTX2PIN_DEC_NULL_PARM; + } + + if (enable == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETTX2PIN_EN_NULL_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_GETTX2PIN_EN_NULL_PARM)); + return MYKONOS_ERR_GETTX2PIN_EN_NULL_PARM; + } + + if (useTx1ForTx2 == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETTX2PIN_TX1TX2_NULL_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_GETTX2PIN_TX1TX2_NULL_PARM)); + return MYKONOS_ERR_GETTX2PIN_TX1TX2_NULL_PARM; + } + + /* Getting Pin configuration assignment*/ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_TX_TPC_GPIO_CFG, &readVal); + readVal = readVal & MASK_TPC_GPIO_CH2; + + if (readVal & 0x10) + { + *tx2AttenIncPin = MYKGPIO14; + } + else + { + *tx2AttenIncPin = MYKGPIO6; + } + + if (readVal & 0x40) + { + *tx2AttenDecPin = MYKGPIO15; + } + else + { + *tx2AttenDecPin = MYKGPIO7; + } + + /* Getting Pin configuration assignment*/ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_TX_TPC_CONFIG, &readVal); + + en = readVal & MASK_TPC_CH2; + + *enable = (en == MASK_TPC_CH2) ? 1 : 0; + + *useTx1ForTx2 = readVal & MASK_TPC_CH1FCH2; + + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_TX_INCR_DECR_WORD, &readVal); + + *stepSize = readVal & MASK_TPC_STEP; + + return MYKONOS_ERR_GPIO_OK; +} + +/** + * \brief Sets the Mykonos low voltage GPIO output pins level + * + * This function will only affect the GPIO pins that have their OE direction set to output and + * that have the correct source control for the nibbles in GPIO_BITBANG_MODE + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is a pointer to the device settings structure + * \param gpioPinLevel bit per GPIO pin, level to output for each GPIO pin. 0 = low output, 1= high output + * + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + */ +mykonosGpioErr_t MYKONOS_setGpioPinLevel(mykonosDevice_t *device, uint32_t gpioPinLevel) +{ + + mykonosGpioErr_t error = MYKONOS_ERR_GPIO_OK; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setGpioPinLevel()\n"); +#endif + + /* writing GPIO configuration registers */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_GPIO_SPI_SRC_7_0, (gpioPinLevel & 0xFF)); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_GPIO_SPI_SRC_15_8, ((gpioPinLevel >> 8) & 0xFF)); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_GPIO_SPI_SRC_18_16, ((gpioPinLevel >> 16) & 0x07)); + + /* Return */ + return error; +} + +/** + * \brief Reads the Mykonos low voltage GPIO pin levels and returns their contents in a single 32-bit word + * + * The GPIO pins that are set to be inputs in BITBANG mode will read back and be returned + * in the gpioPinLevel parameter. The return value is a bit per pin. GPIO 0 returns on bit 0 of + * the gpioPinLevel parameter. A logic low level returns a 0, a logic high level returns a 1. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is a pointer to the device settings structure + * \param gpioPinLevel Input Gpio pin levels read back on the pins assigned as inputs (bit per pin) + * + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + * \retval MYKONOS_ERR_READGPIOSPI_NULL_PARM The pointer passed for gpioPinLevel parameter is NULL + */ +mykonosGpioErr_t MYKONOS_getGpioPinLevel(mykonosDevice_t *device, uint32_t *gpioPinLevel) +{ + uint8_t readBytes[3] = {0, 0, 0}; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getGpioPinLevel()\n"); +#endif + + if (gpioPinLevel == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_READGPIOSPI_NULL_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_READGPIOSPI_NULL_PARM)); + return MYKONOS_ERR_READGPIOSPI_NULL_PARM; + } + + /* reading the registers into three-byte array */ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GPIO_SPI_READ_7_0, &readBytes[0]); + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GPIO_SPI_READ_15_8, &readBytes[1]); + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GPIO_SPI_READ_18_16, &readBytes[2]); + + /* performing concatenation and assigning value to gpio1v8SpiRead */ + *gpioPinLevel = ((uint32_t)(readBytes[2] & 0x07) << 16) | ((uint32_t)(readBytes[1]) << 8) | (uint32_t)(readBytes[0]); + + return MYKONOS_ERR_GPIO_OK; +} + +/** + * \brief Reads the Mykonos GPIO pin output levels for BITBANG mode + * + * This function allows reading the value that the GPIO output pins are + * set to drive out the pins. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is a pointer to the device settings structure + * \param gpioPinSetLevel is a unit32_t pointer which contains the level of each GPIO pin (bit per pin) + * + * + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + * \retval MYKONOS_ERR_GETGPIOSETLEVEL_NULL_PARM gpioPinSetLevel pointer is NULL in function parameter + * + */ +mykonosGpioErr_t MYKONOS_getGpioSetLevel(mykonosDevice_t *device, uint32_t *gpioPinSetLevel) +{ + uint8_t readBytes[3] = {0, 0, 0}; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getGpioSetLevel()\n"); +#endif + + if (gpioPinSetLevel == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETGPIOSETLEVEL_NULL_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_GETGPIOSETLEVEL_NULL_PARM)); + return MYKONOS_ERR_GETGPIOSETLEVEL_NULL_PARM; + } + + /* reading the registers into two-byte array */ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GPIO_SPI_SRC_7_0, &readBytes[0]); + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GPIO_SPI_SRC_15_8, &readBytes[1]); + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GPIO_SPI_SRC_18_16, &readBytes[2]); + + /* performing concatenation and assigning value to gpioPinSetLevel */ + *gpioPinSetLevel = ((uint32_t)(readBytes[2] & 0x07) << 16) | ((uint32_t)(readBytes[1]) << 8) | (uint32_t)(readBytes[0]); + + return MYKONOS_ERR_GPIO_OK; +} + + + +/** + * \brief Sets the General Purpose (GP) interrupt register bit mask to enable interrupt sources to assert the GP Interrupt pin + * + * Mykonos has a single output pin called General Purpose Interrupt that asserts to a logic high level + * when certain events occur. The events that cause the GP Interrupt pin to assert are user + * selectable by setting the gpMask parameter in this function. Device default is mask = x1FF = ignore + * all events. The ARM Error interrupt can not be ignored and can always assert the GP interrupt pin. + * + * gpMask | Bit description + * ------------|------------ + * [0] | TXPLL LOCK - 0 = allow PLL unlocking to assert GP Interrupt pin, 1 = ignore TXPLL LOCK + * [1] | RXPLL LOCK - 0 = allow PLL unlocking to assert GP Interrupt pin, 1 = ignore RXPLL LOCK + * [2] | SNIFFER PLL LOCK - 0 = allow PLL unlocking to assert GP Interrupt pin, 1 = ignore SNIFFER PLL LOCK + * [3] | CALIBRATION PLL LOCK - 0 = allow PLL unlocking to assert GP Interrupt pin, 1 = ignore CALIBRATION PLL LOCK + * [4] | CLKPLL LOCK - 0 = allow PLL unlocking to assert GP Interrupt pin, 1 = ignore CLKPLL LOCK + * [5] | 0 = Allow JESD204 deframer interrupt to assert GP Interrupt pin, 1 = ignore JESD204 deframer interrupt + * [6] | Tx1 PA protection - 0 = allow Tx1 PA protection event to assert GP Interrupt pin, 1 = ignore Tx1 PA protection + * [7] | Tx2 PA protection - 0 = allow Tx2 PA protection event to assert GP Interrupt pin, 1 = ignore Tx2 PA protection + * [8] | Mykonos ARM Watchdog - 0 = allow Mykonos ARM Watchdog timeout to assert GP Interrupt pin, 1 = ignore Watchdog timeout event + * [15-9] | Reserved for future use + * + * Dependencies + * - device->spiSettings + * + * \param device Pointer to the device settings structure + * \param gpMask Value is passed to enable one or more general purpose interrupt sources + * (1=ignore source, 0 = enable source interrupt to GP Interrupt pin) + * + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + * \retval MYKONOS_ERR_INV_GP_INT_MASK_PARM if invalid interrupt mask is passed + */ +mykonosGpioErr_t MYKONOS_configGpInterrupt(mykonosDevice_t *device, uint16_t gpMask) +{ + const uint16_t GP_INT_VALID_MASK = 0x1FF; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_configGpInterrupt()\n"); +#endif + + /* checking for valid mask setting */ + if (gpMask & ~GP_INT_VALID_MASK) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_GP_INT_MASK_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_INV_GP_INT_MASK_PARM)); + return MYKONOS_ERR_INV_GP_INT_MASK_PARM; + } + + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_GP_INTERRUPT_MASK_1, (gpMask & 0xFF)); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_GP_INTERRUPT_MASK_0, ((gpMask >> 8) & 0x01)); + + return MYKONOS_ERR_GPIO_OK; +} + +/** + * \brief Reads the General Purpose (GP) interrupt status to determine what caused the GP Interrupt pin to assert + * + * When the BBIC detects a rising edge on the General Purpose Interrupt pin, this function + * allows the BBIC to determine the source of the interrupt. The value returned in the status parameter + * will show one or more sources for the interrupt based on the following table. + * + * The PLL unlock bits are not sticky. They will follow the current status of the PLLs. If the PLL relocks, the + * status bit will clear as well. The GP Interrupt pin is the logical OR of all the sources. When all the status + * bits are low, the GP Interrupt pin will be low. The status word readback will show the current value + * for all interrupt sources, even if they are disabled by the masked. However, the GP Interrupt pin will only assert + * for the enabled sources. + * + * status | Bit description + * ------------|------------ + * [0] | 1 = TXPLL UNLOCK + * [1] | 1 = RXPLL UNLOCK + * [2] | 1 = SNIFFER PLL UNLOCK + * [3] | 1 = CALIBRATION PLL UNLOCK + * [4] | 1 = CLK PLL UNLOCK + * [5] | 1 = JESD204 deframer interrupt occurred + * [6] | 1 = Tx1 PA protection event + * [7] | 1 = Tx2 PA protection event + * [8] | 1 = Mykonos ARM Watchdog timeout + * [9] | 1 = ARM interrupt occurred + * [15-10] | Reserved for future use + * + * Dependencies + * - device->spiSettings + * + * \param device Pointer to the device settings structure + * \param status parameter to return the IRQ source(s) that caused the GP Interrpt pin to assert. + * + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + * \retval MYKONOS_ERR_GP_INT_STATUS_NULL_PARAM if null *status pointer is passed + */ +mykonosGpioErr_t MYKONOS_readGpInterruptStatus(mykonosDevice_t *device, uint16_t *status) +{ + uint8_t readStatus1 = 0; + uint8_t readStatus0 = 0; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_readGpInterruptStatus()\n"); +#endif + /* checking for null pointer */ + if (status == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GP_INT_STATUS_NULL_PARAM, + getGpioMykonosErrorMessage(MYKONOS_ERR_GP_INT_STATUS_NULL_PARAM)); + return MYKONOS_ERR_GP_INT_STATUS_NULL_PARAM; + } + + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GP_INTERRUPT_READ_1, &readStatus1); + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GP_INTERRUPT_READ_0, &readStatus0); + + /* PLL Lock status bits are high when locked, invert to match up with other bits */ + *status = ((((uint16_t)(readStatus1) & 0xE0U) | ((~(uint16_t)(readStatus1)) & 0x1F)) | (((uint16_t)(readStatus0) & 0x0003) << 8)) ; + + return MYKONOS_ERR_GPIO_OK; +} + +/** + * \brief Sets the input and output GPIO pin selections for ARM related signals. + * + * The BBP should not have to call this as it will automatically be setup during the + * MYKONOS_loadArmFromBinary() function call. If the BBP wishes to change the GPIO + * assignments this function can be called again to change the configuration while + * the ARM is in the radioOff state. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - device->auxIo->armGpio : all members in structure + * + * \param device is a pointer to the device settings structure + * + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + * \retval MYKONOS_ERR_SET_ARMGPIO_INV_POINTER device->auxIo->armGpio pointer is null + * \retval MYKONOS_ERR_SET_ARMGPIO_PINS_INV_SIGNALID Invalid ARM GPIO pin signal ID + * \retval MYKONOS_ERR_SET_ARMGPIO_PINS_INV_GPIOPIN Invalid GPIO pin selected for ARM output (valid 0-15 + output enable in bit[4]) + * \retval MYKONOS_ERR_SET_ARMGPIO_PINS_ARMERROR ARM returned error setting GPIO pins + */ +mykonosGpioErr_t MYKONOS_setArmGpioPins(mykonosDevice_t *device) +{ + uint8_t i = 0; + uint8_t gpioConfig[3] = {0}; + uint8_t signalId[12] = {ORX_TRIGGER_SIGNALID, ORX_MODE_0_SIGNALID, ORX_MODE_1_SIGNALID, ORX_MODE_2_SIGNALID, RX1_ENABLE_ACK_SIGNALID, + RX2_ENABLE_ACK_SIGNALID, TX1_ENABLE_ACK_SIGNALID, TX2_ENABLE_ACK_SIGNALID, ORX1_ENABLE_ACK_SIGNALID, ORX2_ENABLE_ACK_SIGNALID, + SRX_ENABLE_ACK_SIGNALID, TX_OBS_SELECT_SIGNALID}; + uint32_t timeoutMs = 0; + uint8_t cmdStatusByte = 0; + uint32_t gpioOe = 0; + uint32_t gpioUsedMask = 0; + mykonosGpioErr_t retval = MYKONOS_ERR_GPIO_OK; + + const uint8_t GPIO_CTRL_OBJECTID = 0x60; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setArmGpioPins()\n"); +#endif + + if (device->auxIo->armGpio == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SET_ARMGPIO_INV_POINTER, + getGpioMykonosErrorMessage(MYKONOS_ERR_SET_ARMGPIO_INV_POINTER)); + return MYKONOS_ERR_SET_ARMGPIO_INV_POINTER; + } + + /* Write ARM set command to setup which ARM signals are using which GPIO pins */ + /* Setup input pins for ORX_MODE[2:0] and ORX_MODE_Trigger if orx is in pin mode */ + for(i = 0; i < sizeof(signalId); i++) + { + gpioConfig[0] = GPIO_CTRL_OBJECTID; + gpioConfig[1] = signalId[i]; + + switch(signalId[i]) + { + case ORX_TRIGGER_SIGNALID: gpioConfig[2] = device->auxIo->armGpio->orxTriggerPin; break; + case ORX_MODE_0_SIGNALID: gpioConfig[2] = device->auxIo->armGpio->orxMode0Pin; break; + case ORX_MODE_1_SIGNALID: gpioConfig[2] = device->auxIo->armGpio->orxMode1Pin; break; + case ORX_MODE_2_SIGNALID: gpioConfig[2] = device->auxIo->armGpio->orxMode2Pin; break; + case RX1_ENABLE_ACK_SIGNALID: gpioConfig[2] = device->auxIo->armGpio->rx1EnableAck; break; + case RX2_ENABLE_ACK_SIGNALID: gpioConfig[2] = device->auxIo->armGpio->rx2EnableAck; break; + case TX1_ENABLE_ACK_SIGNALID: gpioConfig[2] = device->auxIo->armGpio->tx1EnableAck; break; + case TX2_ENABLE_ACK_SIGNALID: gpioConfig[2] = device->auxIo->armGpio->tx2EnableAck; break; + case ORX1_ENABLE_ACK_SIGNALID: gpioConfig[2] = device->auxIo->armGpio->orx1EnableAck; break; + case ORX2_ENABLE_ACK_SIGNALID: gpioConfig[2] = device->auxIo->armGpio->orx2EnableAck; break; + case SRX_ENABLE_ACK_SIGNALID: gpioConfig[2] = device->auxIo->armGpio->srxEnableAck; break; + case TX_OBS_SELECT_SIGNALID: gpioConfig[2] = device->auxIo->armGpio->txObsSelect; break; + default: + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SET_ARMGPIO_PINS_INV_SIGNALID, + getGpioMykonosErrorMessage(MYKONOS_ERR_SET_ARMGPIO_PINS_INV_SIGNALID)); + return MYKONOS_ERR_SET_ARMGPIO_PINS_INV_SIGNALID; + } + } + + if (gpioConfig[2] > 0x1F) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SET_ARMGPIO_PINS_INV_GPIOPIN, + getGpioMykonosErrorMessage(MYKONOS_ERR_SET_ARMGPIO_PINS_INV_GPIOPIN)); + return MYKONOS_ERR_SET_ARMGPIO_PINS_INV_GPIOPIN; + } + + /* if output signal */ + if ((signalId[i] >= RX1_ENABLE_ACK_SIGNALID) && (gpioConfig[2] != 0)) + { + gpioOe |= (uint32_t)(((gpioConfig[2] >> 4) & 0x01) << (gpioConfig[2] & 0x0F)); /* 1 = output */ + gpioUsedMask |= (uint32_t)(1 << (gpioConfig[2] & 0x0F)); + } + + /* if input signal and orx Pin mode enabled - currently only input pins are orx pin mode control */ + if ((signalId[i] < RX1_ENABLE_ACK_SIGNALID) && (device->auxIo->armGpio->orxPinMode > 0)) + { + gpioUsedMask |= (1 << (gpioConfig[2] & 0x1F)); + } + + retval = (mykonosGpioErr_t)MYKONOS_sendArmCommand(device, MYKONOS_ARM_SET_OPCODE, &gpioConfig[0], sizeof(gpioConfig)); + if (retval != MYKONOS_ERR_GPIO_OK) + { + return retval; + } + + timeoutMs = 1000; + + if (( retval = (mykonosGpioErr_t)MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_SET_OPCODE, timeoutMs, &cmdStatusByte)) != MYKONOS_ERR_GPIO_OK) + { + return retval; + } + + if (cmdStatusByte > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SET_ARMGPIO_PINS_ARMERROR, + getGpioMykonosErrorMessage(MYKONOS_ERR_SET_ARMGPIO_PINS_ARMERROR)); + return MYKONOS_ERR_SET_ARMGPIO_PINS_ARMERROR; + } + } + + /* Mykonos SPI regs to set GPIO OE direction only for pins used by ARM */ + if ((retval = MYKONOS_setGpioOe(device, gpioOe, gpioUsedMask)) != MYKONOS_ERR_GPIO_OK) + { + return retval; + } + + /* if any output pins enabled, write GPIO nibble source control. ARM outputs only allowed on GPIO[15:0]*/ + if (gpioOe & 0x000F) + { + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_SOURCE_CONTROL_LOWER_BYTE, 0x09, 0x0F, 0); + } + + if (gpioOe & 0x00F0) + { + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_SOURCE_CONTROL_LOWER_BYTE, 0x09, 0xF0, 4); + } + + if (gpioOe & 0x0F00) + { + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_SOURCE_CONTROL_UPPER_BYTE, 0x09, 0x0F, 0); + } + + if (gpioOe & 0xF000) + { + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_SOURCE_CONTROL_UPPER_BYTE, 0x09, 0xF0, 4); + } + + return MYKONOS_ERR_GPIO_OK; +} + +/** + * \brief Sets up the auxiliary ADC + * + * This function configures the AuxADC with the requested decimation. The AuxADC clock is set as close + * as possible to 40MHz. The AuxADC conversion time = (1/40Mhz) * decimation, where the decimation ranges + * from 256 AuxADC clock cycles to 32768 AuxADc clock cycles. + * + * Note: The AuxADC is intended for relative measurements. Two back to back measurements can allow a delta + * measurement with 12bit resolution. If absolute measurements are required, an accurate + * reference should be first measured on AuxADC0 input and used to calibrate the offset/gain error of the AuxADC. + * The reference would need to be measured before each measurement to account for measurement variations caused + * by the transmitter/receiver transients as other circuits in the device are being powered up/down. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device Pointer to the device settings structure + * \param adcDecimation ADC decimation factor (0-7). Decimates by 256 * 2^(adcDecimation) ADC clock cycles. + * \param enable Stop/run ADC (0/1) + * + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + * \retval MYKONOS_ERR_SETUPAUXADC_INV_VCODIV CLKPLL VCO divider is invalid - Check CLKPLL setup + * \retval MYKONOS_ERR_INV_AUX_ADC_DEC_PARM AuxADC decimation out of range (valid 0-7) + */ +mykonosGpioErr_t MYKONOS_setupAuxAdcs(mykonosDevice_t *device, uint8_t adcDecimation, uint8_t enable) +{ + uint32_t hsDigClk_kHz = 0; + uint32_t auxAdcDiv = 0; + uint32_t auxAdcClk_kHz = 40000; + uint32_t vcoDiv = (uint32_t)device->clocks->clkPllVcoDiv; + uint8_t vcoDivTimes10 = 10; + + const uint8_t AUXADC_POWER_BIT_MASK = 0x80; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setupAuxAdcs()\n"); +#endif + + if (enable == 0) + { + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AUX_ADC_BUFFER_CONFIG_0, 0xCF); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AUX_ADC_CFG, 0x01); + + return MYKONOS_ERR_GPIO_OK; + } + else + { + switch(vcoDiv) + { + case VCODIV_1: + vcoDivTimes10 = 10; + break; + case VCODIV_1p5: + vcoDivTimes10 = 15; + break; + case VCODIV_2: + vcoDivTimes10 = 20; + break; + case VCODIV_3: + vcoDivTimes10 = 30; + break; + + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETUPAUXADC_INV_VCODIV, + getGpioMykonosErrorMessage(MYKONOS_ERR_SETUPAUXADC_INV_VCODIV)); + return MYKONOS_ERR_SETUPAUXADC_INV_VCODIV; + } + + hsDigClk_kHz = (device->clocks->clkPllVcoFreq_kHz / vcoDivTimes10 / device->clocks->clkPllHsDiv) * 10; + auxAdcDiv = ((hsDigClk_kHz / 2) / (auxAdcClk_kHz)) - 1; + + if (auxAdcDiv > 63) + { + auxAdcDiv = 63; + } + + if (adcDecimation > 0x07) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AUX_ADC_DEC_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_INV_AUX_ADC_DEC_PARM)); + return MYKONOS_ERR_INV_AUX_ADC_DEC_PARM; + } + + CMB_SPIWriteByte (device->spiSettings, MYKONOS_ADR_AUX_ADC_CLOCK_DIVIDE, (uint8_t)(auxAdcDiv)); + CMB_SPIWriteByte (device->spiSettings, MYKONOS_ADDR_AUX_ADC_CFG, (uint8_t)((adcDecimation << 1))); + CMB_SPIWriteByte (device->spiSettings, MYKONOS_ADDR_AUX_ADC_SEL, 0x00); /* Set AuxADC select to AuxADC0 */ + CMB_SPIWriteField (device->spiSettings, MYKONOS_ADDR_AUX_ADC_BUFFER_CONFIG_0, 0, AUXADC_POWER_BIT_MASK, 7); + + /* Set Clock enable bit to latch divider */ + CMB_SPIWriteByte (device->spiSettings, MYKONOS_ADR_AUX_ADC_CLOCK_DIVIDE, (uint8_t)(auxAdcDiv | 0x80)); + } + return MYKONOS_ERR_GPIO_OK; +} + +/** + * \brief Sets the selected channel of the auxiliary ADC + * + * After setting the AuxADC channel, wait at least 1 AuxADC conversion time before + * reading back the AuxADC value. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is a pointer to the device settings structure + * \param auxAdcChannel desired Aux ADC input(0-4 and 16 = temperature sensor) + * + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + * \retval MYKONOS_ERR_INV_AUX_ADC_CHAN_PARM Invalid AuxADC channel (valid 0-4 and 16) + */ +mykonosGpioErr_t MYKONOS_setAuxAdcChannel(mykonosDevice_t *device, mykonosAuxAdcChannels_t auxAdcChannel) +{ + uint8_t currentAuxAdcChan = 0x00; + + const uint8_t CHANNEL_MASK = 0x17; + const uint8_t POWER_UP_AUXADC = 0x00; + const uint8_t POWER_DOWN_AUXADC = 0x01; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setAuxAdcChannel()\n"); +#endif + + if (((uint8_t)auxAdcChannel & ~CHANNEL_MASK) > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AUX_ADC_CHAN_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_INV_AUX_ADC_CHAN_PARM)); + return MYKONOS_ERR_INV_AUX_ADC_CHAN_PARM; + } + + /* Read current selected channel, if different power down AUXADC and change AUXADC */ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_AUX_ADC_SEL, ¤tAuxAdcChan); + if (currentAuxAdcChan != (uint8_t)auxAdcChannel) + { + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AUX_ADC_CFG, POWER_DOWN_AUXADC, 0x01, 0); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AUX_ADC_SEL, ((auxAdcChannel & MYK_AUXADC_0_DIV2) ? 0: auxAdcChannel)); + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AUX_ADC_CFG, POWER_UP_AUXADC, 0x01, 0); + } + + /* Invalid AuxADC channel, the only valid channel for external ref is channel 0 */ + if (auxAdcChannel == MYK_AUXADC_0_DIV2) + { + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AUX_ADC_BUFFER_CONFIG_1, 0x01, 0x04, 2); + } + else if (auxAdcChannel == MYK_AUXADC_0) + { + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AUX_ADC_BUFFER_CONFIG_1, 0x00, 0x04, 2); + } + + return MYKONOS_ERR_GPIO_OK; +} + +/** + * \brief Reads from the selected channel of the auxiliary ADC + * + * Before using this function to read back the AuxADC value of the + * currently selected AuxADC, make sure that at least 1 conversion time + * of the ADC has passed since setting the AuxADC channel. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is a pointer to the device settings structure + * \param adcCode is a pointer for return of the 12bit ADC read value + * + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + * \retval MYKONOS_ERR_READAUXADC_NULL_PARAM Function parameter adcCode is a NULL pointer + */ +mykonosGpioErr_t MYKONOS_readAuxAdc(mykonosDevice_t *device, uint16_t *adcCode) +{ + uint8_t adcNibble = 0; + + const uint8_t AUXADC_LOCK_BIT_MASK = 0x80; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_readAuxAdcs()\n"); +#endif + + if (adcCode == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_READAUXADC_NULL_PARAM, + getGpioMykonosErrorMessage(MYKONOS_ERR_READAUXADC_NULL_PARAM)); + return MYKONOS_ERR_READAUXADC_NULL_PARAM; + } + + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AUX_ADC_CFG, 1, AUXADC_LOCK_BIT_MASK, 7); + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_AUX_ADC_READ_MSB, &adcNibble); + *adcCode = adcNibble << 4; + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_AUX_ADC_READ_LSB, &adcNibble); + *adcCode |= (adcNibble & 0x0F); + + return MYKONOS_ERR_GPIO_OK; +} + +/** + * \brief Sets up the 10 AuxDACs on the Mykonos device. + * + * This function uses the configuration in the Mykonos device data structure AuxIO substructure to + * setup which of the ten AuxDACs are enabled, their slope, Vref(mid point) and their initial DAC code. + * + * This function can be called any time after MYKONOS_initialize() to reconfigure, enable, disable the + * different AuxDAC outputs. The AuxDACs are used in manual control mode. After calling this setup + * function, it is possible to change a particular AuxDAC code by calling the writeAuxDac() function. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - device->auxIo->auxDacEnable: 1= enabled, 0 = disabled + * - device->auxIo->auxDacSlope[i]: 0 = 1.404mv/code, 1= 0.702mV/code + * - device->auxIo->auxDacVref: 0 = 1v midpoint, 1 = 1.5v midpoint, 2 = 2v midpoint, 3 = 2.5v midpoint + * - device->auxIo->auxDacValue[i]: 10bit DAC code (0-1023) + * + * \param device is a pointer to the device settings structure + * + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + * \retval MYKONOS_ERR_SETUPAUXDAC_NULL_PARAM device->auxIo structure has a NULL pointer + * \retval MYKONOS_ERR_SETUPAUXDAC_INV_AUXDACCODE auxDAC code is out of range (valid 0-1023) + */ +mykonosGpioErr_t MYKONOS_setupAuxDacs(mykonosDevice_t *device) +{ + uint8_t i = 0; /* for loop index */ + uint8_t auxDacConfig = 0 ; + mykonosGpioErr_t error = MYKONOS_ERR_GPIO_OK; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setupAuxDacs()\n"); +#endif + + if (device->auxIo == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETUPAUXDAC_NULL_PARAM, + getGpioMykonosErrorMessage(MYKONOS_ERR_SETUPAUXDAC_NULL_PARAM)); + return MYKONOS_ERR_SETUPAUXDAC_NULL_PARAM; + } + + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PDAUXDAC_MANUAL_CONTROL_5_0, 0x3F); /* Enable Manual AuxDAC control for all AuxDACs[5:0] */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PDAUXDAC_MANUAL_CONTROL_9_6, 0x0F); /* Enable Manual AuxDAC control for all AuxDACs[9:6] */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PDAUXDAC_MANUAL_IN_5_0, 0x3F); /* Power down all AuxDACs[5:0] */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PDAUXDAC_MANUAL_IN_9_6, 0x0F); /* Power down all AuxDACs[9:6] */ + + for (i = 0; i < 10; i++) + { + /* If auxDac enabled, setup AuxDAC configuration */ + if ((device->auxIo->auxDacEnable >> i) & 0x01) + { + if (device->auxIo->auxDacValue[i] > 1023) + { + device->auxIo->auxDacValue[i] = 1023; /* clip value to max */ + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETUPAUXDAC_INV_AUXDACCODE, + getGpioMykonosErrorMessage(MYKONOS_ERR_SETUPAUXDAC_INV_AUXDACCODE)); + error = MYKONOS_ERR_SETUPAUXDAC_INV_AUXDACCODE; /* Complete AuxDAC configuration before returning error code */ + } + + auxDacConfig = 0x00; /* initialize config variable */ + + if (device->auxIo->auxDacSlope[i] > 0) + { + auxDacConfig = 0x40; /* bit [6] sets the slope */ + } + + auxDacConfig |= ((device->auxIo->auxDacVref[i] & 0x03) << 4); + + /* Write AuxDAC config and DAC code */ + CMB_SPIWriteByte(device->spiSettings, (MYKONOS_ADDR_AUXDAC_0_WORD_MSB + (i * 2)), (auxDacConfig | ((device->auxIo->auxDacValue[i] >> 8) & 0x0F))); + CMB_SPIWriteByte(device->spiSettings, (MYKONOS_ADDR_AUXDAC_0_WORD_MSB + (i * 2 ) + 1), (device->auxIo->auxDacValue[i] & 0xFF)); + } + } + + /* Write enable bit to latch DAC codes into DACs */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AUX_DAC_LATCH_CONTROL, 0x01); + + /* Power up selected AuxDacs */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PDAUXDAC_MANUAL_IN_5_0, (~device->auxIo->auxDacEnable & 0x3F)); /* Power up enabled AuxDACs[5:0] */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PDAUXDAC_MANUAL_IN_9_6, (((uint16_t)(~device->auxIo->auxDacEnable) >> 6) & 0x0F)); /* Power up enabled AuxDACs[9:6] */ + + return error; +} + +/** + * \brief Writes the current AuxDAC code for a particular AuxDAC + * + * This function updates the 10bit code that controls the AuxDAC output voltage. + * The auxDacCode is updated for the specified auxDAC. Also the auxDacCode is written + * to the device data structure for future reference. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - device->auxIo->auxDacValue[i] + * + * \param device is a pointer to the device settings structure + * \param auxDacIndex AuxDAC to set the DAC code for (0-9) + * \param auxDacCode DAC code to update the AuxDAC to. Sets the output voltage of the DAC (valid 0-1023) + * + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + * \retval MYKONOS_ERR_WRITEAUXDAC_INV_AUXDACCODE AuxDac code invalid (valid 0-1023) + * \retval MYKONOS_ERR_WRITEAUXDAC_INV_AUXDACINDEX AuxDAC index out of range (valid 0-9) + * \retval MYKONOS_ERR_WRITEAUXDAC_NULL_AUXIO device->auxIo has NULL pointer + */ +mykonosGpioErr_t MYKONOS_writeAuxDac(mykonosDevice_t *device, uint8_t auxDacIndex, uint16_t auxDacCode) +{ + uint16_t auxDacAddr = 0; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_writeAuxDac()\n"); +#endif + + if (auxDacCode > 1023) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_WRITEAUXDAC_INV_AUXDACCODE, + getGpioMykonosErrorMessage(MYKONOS_ERR_WRITEAUXDAC_INV_AUXDACCODE)); + return MYKONOS_ERR_WRITEAUXDAC_INV_AUXDACCODE; + } + + if (auxDacIndex > 9) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_WRITEAUXDAC_INV_AUXDACINDEX, + getGpioMykonosErrorMessage(MYKONOS_ERR_WRITEAUXDAC_INV_AUXDACINDEX)); + return MYKONOS_ERR_WRITEAUXDAC_INV_AUXDACINDEX; + } + + if (device->auxIo == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_WRITEAUXDAC_NULL_AUXIO, + getGpioMykonosErrorMessage(MYKONOS_ERR_WRITEAUXDAC_NULL_AUXIO)); + return MYKONOS_ERR_WRITEAUXDAC_NULL_AUXIO; + } + + device->auxIo->auxDacValue[auxDacIndex] = auxDacCode; + + auxDacAddr = MYKONOS_ADDR_AUXDAC_0_WORD_MSB + (auxDacIndex * 2); + + /* Write AuxDAC config and DAC code */ + CMB_SPIWriteField(device->spiSettings, auxDacAddr, (auxDacCode >> 8), 0x0F, 0); + CMB_SPIWriteByte(device->spiSettings, (auxDacAddr + 1), (auxDacCode & 0xFF)); + + /* Write enable bit to latch DAC codes into DACs */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AUX_DAC_LATCH_CONTROL, 0x01); + + return MYKONOS_ERR_GPIO_OK; +} + +/** + * \brief Sets the Mykonos low voltage GPIO configuration registers + * + * Sets the low voltage GPIO pin direction for each low voltage GPIO pin and + * sets the source control mode (feature) for each group of 4 GPIO pins. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - device->auxIo->gpio - all members + * + * \param device is a pointer to the device settings structure + * + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + * \retval MYKONOS_ERR_SET_GPIO_1V8_INV_POINTER device->auxIo->gpio pointer is NULL + * \retval MYKONOS_ERR_SET_GPIO_1V8_INV_MODE gpio structure members have invalid enum value for the GPIO source control mode. + */ +mykonosGpioErr_t MYKONOS_setupGpio(mykonosDevice_t *device) +{ + uint32_t srcWrite = 0x000000; + uint32_t oEnMask = 0x7FFFF; + mykonosGpioErr_t error = MYKONOS_ERR_GPIO_OK; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setupGpio()\n"); +#endif + + if (device->auxIo->gpio == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SET_GPIO_1V8_INV_POINTER, + getGpioMykonosErrorMessage(MYKONOS_ERR_SET_GPIO_1V8_INV_POINTER)); + return MYKONOS_ERR_SET_GPIO_1V8_INV_POINTER; + } + + /* write GPIO pin direction registers */ + if ((error = MYKONOS_setGpioOe(device, device->auxIo->gpio->gpioOe, oEnMask)) != MYKONOS_ERR_GPIO_OK) + { + return error; + } + + /* write GPIO source control mode */ + if (((uint8_t)device->auxIo->gpio->gpioSrcCtrl3_0 > 15) || ((uint8_t)device->auxIo->gpio->gpioSrcCtrl7_4 > 15) || + ((uint8_t)device->auxIo->gpio->gpioSrcCtrl11_8 > 15) || ((uint8_t)device->auxIo->gpio->gpioSrcCtrl15_12 > 15) || + ((uint8_t)device->auxIo->gpio->gpioSrcCtrl18_16 > 15)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SET_GPIO_1V8_INV_MODE, + getGpioMykonosErrorMessage(MYKONOS_ERR_SET_GPIO_1V8_INV_MODE)); + return MYKONOS_ERR_SET_GPIO_1V8_INV_MODE; + } + + srcWrite = (uint32_t)device->auxIo->gpio->gpioSrcCtrl3_0 + ((uint32_t)device->auxIo->gpio->gpioSrcCtrl7_4 << 4) + + ((uint32_t)device->auxIo->gpio->gpioSrcCtrl11_8 << 8) + ((uint32_t)device->auxIo->gpio->gpioSrcCtrl15_12 << 12) + + ((uint32_t)device->auxIo->gpio->gpioSrcCtrl18_16 << 16); + + error = MYKONOS_setGpioSourceCtrl(device, srcWrite); + + return error; +} + +/** + * \brief Sets the Mykonos low voltage GPIO output pins direction + * + * This function will set the GPIO direction given by the passed parameter, + * the direction can be either output or input. The gpioUsedMask parameter + * allows the function to only affect the GPIO pins of interest. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - device->auxIo->gpio->gpioOe + * + * \param device is a pointer to the device settings structure + * \param gpioOutEn (valid range 0 - 0x07FFFF), bit per GPIO pin, the direction is + * + * gpioOutEn[bit] | GPIO[bit] direction + * ----------------|------------------- + * 0 | input + * 1 | output + * + * \param gpioUsedMask Mask used to control which Oe bits are set/cleared. If + * mask bit =1, that bit will be modified by gpioOutEn bit + * + * \retval MYKONOS_ERR_GPIO_OE_INV_PARAM If the Output enable parameter is invalid + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + */ +mykonosGpioErr_t MYKONOS_setGpioOe(mykonosDevice_t *device, uint32_t gpioOutEn, uint32_t gpioUsedMask) +{ + mykonosGpioErr_t error = MYKONOS_ERR_GPIO_OK; + + const uint32_t GPIO_OE_MASK = 0x7FFFF; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setGpioOe()\n"); +#endif + + /* Error checking for correct number of GPIOs available. */ + if (gpioOutEn > GPIO_OE_MASK ) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OE_INV_PARAM, + getGpioMykonosErrorMessage(MYKONOS_ERR_GPIO_OE_INV_PARAM)); + return MYKONOS_ERR_GPIO_OE_INV_PARAM; + } + + /* Mykonos SPI regs to set GPIO OE direction */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_GPIO_DIR_CTL_7_0, (gpioOutEn & 0xFF), (gpioUsedMask & 0xFF), 0); + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_GPIO_DIR_CTL_15_8, ((gpioOutEn >> 8) & 0xFF), ((gpioUsedMask >> 8) & 0xFF), 0); + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_GPIO_DIR_CTL_18_16, ((gpioOutEn >> 16) & 0xFF), ((gpioUsedMask >> 16) & 0xFF), 0); + + /* Updating gpioConfig->gpioSetup->gpioOe output enable */ + if ((error = MYKONOS_getGpioOe(device, &gpioOutEn)) != MYKONOS_ERR_GPIO_OK) + { + return error; + } + + device->auxIo->gpio->gpioOe = gpioOutEn; + + /* Return */ + return MYKONOS_ERR_GPIO_OK; +} + + +/** + * \brief Gets the Mykonos low voltage GPIO output pins direction + * + * This function will get the GPIO direction currently set in the device, + * the direction can be either output or input. The return gpioOutEn function + * parameter returns a bit per GPIO pin. 1 = output from the Mykonos Device, + * 0 = input into the Mykonos device. + * + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is a pointer to the device settings structure + * \param *gpioOutEn a pointer to the data to be returned with the output enable reading + * + * gpioOutEn[bit] | GPIO[bit] direction + * ----------------|------------------- + * 0 | input + * 1 | output + * + * + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + * \retval MYKONOS_ERR_GETGPIO_OE_NULL_PARM gpioOutEn function parameter is NULL + */ +mykonosGpioErr_t MYKONOS_getGpioOe(mykonosDevice_t *device, uint32_t *gpioOutEn) +{ + uint8_t readBytes[3] = {0}; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getGpioOe()\n"); +#endif + + if (gpioOutEn == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETGPIO_OE_NULL_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_GETGPIO_OE_NULL_PARM)); + return MYKONOS_ERR_GETGPIO_OE_NULL_PARM; + } + + /* Reading GPIO output enable registers */ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GPIO_DIR_CTL_7_0, &readBytes[0]); + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GPIO_DIR_CTL_15_8, &readBytes[1]); + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GPIO_DIR_CTL_18_16, &readBytes[2]); + + /* Updating gpioConfig->gpioSetup->gpioOe output enable */ + *gpioOutEn = ((uint32_t)(readBytes[2] & 0x07) << 16) | ((uint32_t)(readBytes[1]) << 8) | (uint32_t)(readBytes[0]); + + /* Return */ + return MYKONOS_ERR_GPIO_OK; +} + + + +/** + * \brief Sets the Mykonos GPIO source control for different GPIO functionality + * + * This function will only affect the GPIO pins that have their OE direction set to output. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is a pointer to the device settings structure + * \param gpioSrcCtrl nibble based source control, this is a 32 bit containing + * 5 nibbles that will be set the source control. + * + * \retval MYKONOS_ERR_GPIO_SRC_PARAM_INV If the source control parameter is invalid + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + */ +mykonosGpioErr_t MYKONOS_setGpioSourceCtrl(mykonosDevice_t *device, uint32_t gpioSrcCtrl) +{ + const uint32_t GPIO_SRC_MASK = 0xFFFFF; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setGpioSourceCtrl()\n"); +#endif + + /* writing GPIO configuration registers */ + if (gpioSrcCtrl > GPIO_SRC_MASK) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_SRC_PARAM_INV, + getGpioMykonosErrorMessage(MYKONOS_ERR_GPIO_SRC_PARAM_INV)); + return MYKONOS_ERR_GPIO_SRC_PARAM_INV; + } + + /* writing GPIO configuration registers */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_SOURCE_CONTROL_LOWER_BYTE, (gpioSrcCtrl & 0xFF)); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_SOURCE_CONTROL_UPPER_BYTE, ((gpioSrcCtrl >> 8) & 0xFF)); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_SOURCE_CONTROL_EXTRA_BITS, ((gpioSrcCtrl >> 16) & 0x0F)); + + /* Updating gpioConfig->gpioSetup source control */ + device->auxIo->gpio->gpioSrcCtrl3_0 = (mykonosGpioMode_t)(gpioSrcCtrl & 0x0F); + device->auxIo->gpio->gpioSrcCtrl7_4 = (mykonosGpioMode_t)((gpioSrcCtrl >> 4) & 0x0F); + device->auxIo->gpio->gpioSrcCtrl11_8 = (mykonosGpioMode_t)((gpioSrcCtrl >> 8) & 0x0F); + device->auxIo->gpio->gpioSrcCtrl15_12 = (mykonosGpioMode_t)((gpioSrcCtrl >> 12) & 0x0F); + device->auxIo->gpio->gpioSrcCtrl18_16 = (mykonosGpioMode_t)((gpioSrcCtrl >> 16) & 0x0F); + + /* Return */ + return MYKONOS_ERR_GPIO_OK; +} + +/** + * \brief Reads the Mykonos GPIO source control for different GPIO functionality + * + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is a pointer to the device settings structure + * \param gpioSrcCtrl nibble based source control, this is a 32 bit containing + * 5 nibbles that will be set the source control. + * + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + */ +mykonosGpioErr_t MYKONOS_getGpioSourceCtrl(mykonosDevice_t *device, uint32_t *gpioSrcCtrl) +{ + uint8_t readBytes[3] = {0}; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getGpioSourceCtrl()\n"); +#endif + + if (gpioSrcCtrl == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GET_GPIO_SOURCE_CONTROL_NULL_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_GET_GPIO_SOURCE_CONTROL_NULL_PARM)); + return MYKONOS_ERR_GET_GPIO_SOURCE_CONTROL_NULL_PARM; + } + + /* Reading GPIO output enable registers */ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_SOURCE_CONTROL_LOWER_BYTE, &readBytes[0]); + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_SOURCE_CONTROL_UPPER_BYTE, &readBytes[1]); + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_SOURCE_CONTROL_EXTRA_BITS, &readBytes[2]); + + /* Updating gpioConfig->gpioSetup->gpioOe output enable */ + *gpioSrcCtrl = ((uint32_t)(readBytes[2] & 0x0F) << 16) | ((uint32_t)(readBytes[1]) << 8) | (uint32_t)(readBytes[0]); + + /* Return */ + return MYKONOS_ERR_GPIO_OK; +} + + + +/** + * \brief Sets the Mykonos 3.3 VDC GPIO configuration registers + * + * This function sets the GPIO 3.3v pin direction (1=output, 0=input) and + * sets the mode of each nibble of GPIO 3.3v pins. See the mykonosGpio3v3Mode_t + * enum for possible modes. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - device->auxIo->gpio3v3 - all members + * + * \param device is a pointer to the device settings structure + * + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + * \retval MYKONOS_ERR_SET_GPIO_3V3_INV_POINTER device->auxIo->gpio3v3 pointer is NULL + * \retval MYKONOS_ERR_SET_GPIO_3V3_INV_MODE gpio3v3 members have invalid enum value for the GPIO3v3 source control mode. + */ +mykonosGpioErr_t MYKONOS_setupGpio3v3(mykonosDevice_t *device) +{ + mykonosGpioErr_t error = MYKONOS_ERR_GPIO_OK; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setupGpio3v3()\n"); +#endif + + if (device->auxIo->gpio3v3 == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SET_GPIO_3V3_INV_POINTER, + getGpioMykonosErrorMessage(MYKONOS_ERR_SET_GPIO_3V3_INV_POINTER)); + return MYKONOS_ERR_SET_GPIO_3V3_INV_POINTER; + } + else + { + /* write GPIO pin direction registers */ + if ((error = MYKONOS_setGpio3v3Oe(device, device->auxIo->gpio3v3->gpio3v3Oe)) != MYKONOS_ERR_GPIO_OK) + + /* write GPIO3v3 mode */ + if (((uint8_t)device->auxIo->gpio3v3->gpio3v3SrcCtrl3_0 > 15) || + ((uint8_t)device->auxIo->gpio3v3->gpio3v3SrcCtrl7_4 > 15) || + ((uint8_t)device->auxIo->gpio3v3->gpio3v3SrcCtrl11_8 > 15)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SET_GPIO_3V3_INV_MODE, + getGpioMykonosErrorMessage(MYKONOS_ERR_SET_GPIO_3V3_INV_MODE)); + return MYKONOS_ERR_SET_GPIO_3V3_INV_MODE; + } + + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_GPIO_3V3_LSB_SRC_CTL, ((device->auxIo->gpio3v3->gpio3v3SrcCtrl7_4 << 4) | device->auxIo->gpio3v3->gpio3v3SrcCtrl3_0)); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_GPIO_3V3_MSB_SRC_CTL, (device->auxIo->gpio3v3->gpio3v3SrcCtrl11_8 & 0x0F)); + + return error; + } +} + +/** + * \brief If the GPIO3v3 pins are setup for BITBANG mode, this function sets + * the output pin levels per pin + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - device->auxIo->gpio3v3 - all members + * + * \param device is a pointer to the device settings structure + * \param gpio3v3PinLevel Bit per pin to set the level of each GPIO3v3 output pin + * + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + */ +mykonosGpioErr_t MYKONOS_setGpio3v3PinLevel(mykonosDevice_t *device, uint16_t gpio3v3PinLevel) +{ + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setGpio3v3PinLevel()\n"); +#endif + + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_GPIO_3V3_SPI_SRC_7_0, (gpio3v3PinLevel & 0xFF)); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_GPIO_3V3_SPI_SRC_15_8, ((gpio3v3PinLevel >> 8) & 0x0F)); + + return MYKONOS_ERR_GPIO_OK; +} + +/** + * \brief Reads the Mykonos 3.3 VDC GPIO pin output levels for BITBANG mode + * + * This function allows reading the value that the 3.3v GPIO output pins are + * set to drive out the pins. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is a pointer to the device settings structure + * \param gpio3v3SetLevel is a unit16_t pointer which contains the level of each GPIO3V3 pin (bit per pin) + * + * + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + * \retval MYKONOS_ERR_GETGPIO3V3OUT_NULL_PARM gpio3v3SetLevel pointer is NULL in function parameter + */ +mykonosGpioErr_t MYKONOS_getGpio3v3SetLevel(mykonosDevice_t *device, uint16_t *gpio3v3SetLevel) +{ + uint8_t readBytes[2] = {0}; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getGpio3v3SetLevel()\n"); +#endif + + if (gpio3v3SetLevel == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETGPIO3V3OUT_NULL_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_GETGPIO3V3OUT_NULL_PARM)); + return MYKONOS_ERR_GETGPIO3V3OUT_NULL_PARM; + } + + /* reading the registers into two-byte array */ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GPIO_3V3_SPI_SRC_7_0, &readBytes[0]); + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GPIO_3V3_SPI_SRC_15_8, &readBytes[1]); + + /* performing concatenation and assigning value to gpio3v3SpiRead */ + *gpio3v3SetLevel = ((uint16_t)(readBytes[1] & 0x0F) << 8) | (uint16_t)(readBytes[0]); + + return MYKONOS_ERR_GPIO_OK; +} + +/** + * \brief Reads the Mykonos 3.3 VDC GPIO pin levels for BITBANG mode + * + * Note: this function is only capable of reading back pin levels for the + * 3.3v pins set to be inputs. Any pins set to be a GPIO output will read + * back as zero. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is a pointer to the device settings structure + * \param gpio3v3PinLevel is a unit16_t pointer which contains the level of each GPIO3V3 pin + * that is defined as an input + * + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + * \retval MYKONOS_ERR_GETGPIO3V3SPI_NULL_PARM gpio3v3PinLevel pointer is NULL in function parameter + */ +mykonosGpioErr_t MYKONOS_getGpio3v3PinLevel(mykonosDevice_t *device, uint16_t *gpio3v3PinLevel) +{ + uint8_t readBytes[2] = {0}; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getGpio3v3PinLevel()\n"); +#endif + + if (gpio3v3PinLevel == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETGPIO3V3SPI_NULL_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_GETGPIO3V3SPI_NULL_PARM)); + return MYKONOS_ERR_GETGPIO3V3SPI_NULL_PARM; + } + + /* reading the registers for input pin levels */ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GPIO_3V3_SPI_READ_7_0, &readBytes[0]); + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GPIO_3V3_SPI_READ_15_8, &readBytes[1]); + + *gpio3v3PinLevel = ((uint16_t)(readBytes[1] & 0x0F) << 8) | (uint16_t)(readBytes[0]); + + return MYKONOS_ERR_GPIO_OK; +} + +/** + * \brief This function sets the Pin direction control for the Mykonos 3.3 VDC GPIO. + * + * The bits in gpio3v3OutEn are used to configure each corresponding pin as an input or an output. + * If the bit is set, the pin is configured as an output, and if it is clear the pin is configured as an input. + * For example, setting gpio3v3OutEn = 0x02 will configure GPIO_3p3_2 as an output and the rest pins as inputs. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - device->auxIo->gpio3v3 - all members + * + * \param device is a pointer to the device settings structure + * \param gpio3v3OutEn Bit per pin to set the level of each GPIO3v3 output pin + * + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + */ +mykonosGpioErr_t MYKONOS_setGpio3v3Oe(mykonosDevice_t *device, uint16_t gpio3v3OutEn) +{ + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getGpio3v3Oe()\n"); +#endif + + /* write GPIO pin direction registers */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_GPIO_3V3_DIR_CTL_7_0, (gpio3v3OutEn & 0xFF)); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_GPIO_3V3_DIR_CTL_15_8, ((gpio3v3OutEn >> 8) & 0x0F)); + + /* update device->auxIo->gpio3v3 structure */ + device->auxIo->gpio3v3->gpio3v3Oe = gpio3v3OutEn; + + return MYKONOS_ERR_GPIO_OK; +} + +/** + * \brief Reads the Mykonos 3.3 VDC GPIO pin direction + * + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is a pointer to the device settings structure + * \param gpio3v3OutEn is a unit16_t pointer which will contain the output enable parameter, + * this will be a bit field, if a bit is set then the corresponding GPIO pin is an output, + * if the bit is not set then the corresponding pin is an input + * + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + * \retval MYKONOS_ERR_GPIO3V3OUTEN_NULL_PARM gpio3v3OutEn pointer is NULL in function parameter + */ +mykonosGpioErr_t MYKONOS_getGpio3v3Oe(mykonosDevice_t *device, uint16_t *gpio3v3OutEn) +{ + uint8_t readBytes[2] = {0}; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getGpio3v3Oe()\n"); +#endif + + /* checking for null parameter */ + if (gpio3v3OutEn == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO3V3OUTEN_NULL_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_GPIO3V3OUTEN_NULL_PARM)); + return MYKONOS_ERR_GPIO3V3OUTEN_NULL_PARM; + } + + /* reading the registers for input pin levels */ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GPIO_3V3_DIR_CTL_7_0, &readBytes[0]); + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GPIO_3V3_DIR_CTL_15_8, &readBytes[1]); + + *gpio3v3OutEn = ((uint16_t)(readBytes[1] & 0x0F) << 8) | (uint16_t)(readBytes[0]); + + return MYKONOS_ERR_GPIO_OK; +} + + +/** + * \brief Sets the Mykonos GPIO 3.3 VDC source control for different GPIO fucntionality + * + * This function will only affect the GPIO pins that have their OE direction set to output. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is a pointer to the device settings structure + * \param gpio3v3SrcCtrl nibble based source control, this is a 12 bit containing + * 3 nibbles that will be set the source control. + * + * \retval MYKONOS_ERR_SET_GPIO_3V3_INV_SRC_CTRL gpio3v3 members have invalid value for the GPIO3v3 source control mode. + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + */ +mykonosGpioErr_t MYKONOS_setGpio3v3SourceCtrl(mykonosDevice_t *device, uint16_t gpio3v3SrcCtrl) +{ + const uint16_t GPIO_SRC_MASK = 0x0FFF; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setGpio3v3SourceCtrl()\n"); +#endif + + /* writing GPIO configuration registers */ + if (gpio3v3SrcCtrl > GPIO_SRC_MASK) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SET_GPIO_3V3_INV_SRC_CTRL, + getGpioMykonosErrorMessage(MYKONOS_ERR_SET_GPIO_3V3_INV_SRC_CTRL)); + return MYKONOS_ERR_SET_GPIO_3V3_INV_SRC_CTRL; + } + + /* writing GPIO configuration registers */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_GPIO_3V3_LSB_SRC_CTL, (gpio3v3SrcCtrl & 0xFF)); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_GPIO_3V3_MSB_SRC_CTL, ((gpio3v3SrcCtrl >> 8) & 0xFF)); + + /* Updating gpioConfig->gpioSetup source control */ + device->auxIo->gpio3v3->gpio3v3SrcCtrl3_0 = (mykonosGpio3v3Mode_t)(gpio3v3SrcCtrl & 0x0F); + device->auxIo->gpio3v3->gpio3v3SrcCtrl7_4 = (mykonosGpio3v3Mode_t)(gpio3v3SrcCtrl & 0xF0); + device->auxIo->gpio3v3->gpio3v3SrcCtrl11_8 = (mykonosGpio3v3Mode_t)((gpio3v3SrcCtrl >> 8) & 0x0F); + + /* Return */ + return MYKONOS_ERR_GPIO_OK; +} + +/** + * \brief Reads the Mykonos 3v3 GPIO source control for different GPIO functionality + * + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is a pointer to the device settings structure + * \param gpio3v3SrcCtrl nibble based source control, this is a 12 bit containing + * 3 nibbles that will be set the source control. + * + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + */ +mykonosGpioErr_t MYKONOS_getGpio3v3SourceCtrl(mykonosDevice_t *device, uint16_t *gpio3v3SrcCtrl) +{ + uint8_t readBytes[2] = {0}; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getGpio3v3SourceCtrl()\n"); +#endif + + /* checking for null parameter */ + if (gpio3v3SrcCtrl == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO3V3OUTEN_NULL_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_GPIO3V3OUTEN_NULL_PARM)); + return MYKONOS_ERR_GPIO3V3OUTEN_NULL_PARM; + } + + /* Reading GPIO output enable registers */ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GPIO_3V3_LSB_SRC_CTL, &readBytes[0]); + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GPIO_3V3_MSB_SRC_CTL, &readBytes[1]); + + /* Updating gpioConfig->gpioSetup->gpioOe output enable */ + *gpio3v3SrcCtrl = ((uint16_t)(readBytes[1] & 0xFF) << 8) | ((uint16_t)(readBytes[0])); + + /* Return */ + return MYKONOS_ERR_GPIO_OK; +} + + +/** + * \brief Gain compensation enable and setup function. + * + * The gain compensation block is a function that compensates for the attenuation in the internal attenuator for the Rx channels. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is a pointer to the device settings structure + * \param gainComp which is a mykonosGainComp_t structure. + * \param enable this parameter enables or disables the gain compensation block. + * enable = 1 + * disable = 0 + * + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + * \retval MYKONOS_ERR_GAINCOMP_SET_NULL_STRUCT gain compensation structure gainComp is not initialised + * \retval MYKONOS_ERR_GAINCOMP_INV_RX1_OFFSET gain compensation structure gainComp->rx1Offset is invalid + * \retval MYKONOS_ERR_GAINCOMP_INV_RX2_OFFSET gain compensation structure gainComp->rx2Offset is invalid + * \retval MYKONOS_ERR_GAINCOMP_INV_STEP gain compensation structure gainComp->compStep is invalid + * \retval MYKONOS_ERR_GAINCOMP_INV_EN enable is not valid + */ +mykonosGpioErr_t MYKONOS_setRxGainCompensation (mykonosDevice_t *device, mykonosGainComp_t *gainComp, uint8_t enable) +{ + uint8_t regWr2 = 0x00; + uint8_t regWr3 = 0x00; + uint8_t regWr4 = 0x00; + + /* Max parameter values for error checking */ + const uint8_t RXOFFSET_RANGE = 0x1F; + const uint8_t STEP_RANGE = 0x07; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setRxGainCompensation()\n"); +#endif + + /* Check for gainComp initialised */ + if (gainComp == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GAINCOMP_SET_NULL_STRUCT, + getGpioMykonosErrorMessage(MYKONOS_ERR_GAINCOMP_SET_NULL_STRUCT)); + return MYKONOS_ERR_GAINCOMP_SET_NULL_STRUCT; + } + + /* Check for enable */ + if (enable > 1) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GAINCOMP_INV_EN, + getGpioMykonosErrorMessage(MYKONOS_ERR_GAINCOMP_INV_EN)); + return MYKONOS_ERR_GAINCOMP_INV_EN; + } + else if (enable == 1) + { + /* Check for gain compensation Rx1 offset range */ + if (gainComp->rx1Offset > RXOFFSET_RANGE) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GAINCOMP_INV_RX1_OFFSET, + getGpioMykonosErrorMessage(MYKONOS_ERR_GAINCOMP_INV_RX1_OFFSET)); + return MYKONOS_ERR_GAINCOMP_INV_RX1_OFFSET; + } + + /* Check for gain compensation Rx2 offset range */ + if (gainComp->rx2Offset > RXOFFSET_RANGE) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GAINCOMP_INV_RX2_OFFSET, + getGpioMykonosErrorMessage(MYKONOS_ERR_GAINCOMP_INV_RX2_OFFSET)); + return MYKONOS_ERR_GAINCOMP_INV_RX2_OFFSET; + } + + /* Check for gain compensation step range */ + if (gainComp->compStep > STEP_RANGE) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GAINCOMP_INV_STEP, + getGpioMykonosErrorMessage(MYKONOS_ERR_GAINCOMP_INV_STEP)); + return MYKONOS_ERR_GAINCOMP_INV_STEP; + } + + /* Enabling gain compensation block */ + regWr4 = 0x88 | gainComp->compStep; + regWr3 = gainComp->rx2Offset; + regWr2 = gainComp->rx1Offset; + } + + /* Write gain compensation setup to device */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RX1_GAIN_COMP_OFFSET, regWr2); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RX2_GAIN_COMP_OFFSET, regWr3); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RX_GAIN_COMP_CFG, regWr4); + + /* Return */ + return MYKONOS_ERR_GPIO_OK; +} + +/** + * \brief Get gain compensation setup and enabled function. + * + * The gain compensation block is a function that compensates for the attenuation in the internal attenuator for the Rx channels. + * This function will get the current setup and the enable state of the block. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is a pointer to the device settings structure + * \param gainComp pointer to a mykonosGainComp_t structure, will held the current device gain compensation settings. + * \param enabled pointer this parameter will contain the enable state of the gain compensation block. + * enabled = 1 + * disabled = 0 + * + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + * \retval MYKONOS_ERR_GAINCOMP_NULL_STRUCT gain compensation structure gainComp is not initialised + * \retval MYKONOS_ERR_GAINCOMP_EN_NULL_PARM enable is null pointer for the passed parameter + */ +mykonosGpioErr_t MYKONOS_getRxGainCompensation (mykonosDevice_t *device, mykonosGainComp_t *gainComp, uint8_t *enabled) +{ + uint8_t regWr2 = 0x00; + uint8_t regWr3 = 0x00; + uint8_t regWr4 = 0x00; + + /* Mask parameter values populating mykonosGainComp_t structure */ + const uint8_t ENABLED_MASK = 0x80; + const uint8_t STEP_MASK = 0x07; + + /* Shift values for writing gain values */ + const uint8_t ENABLED_SHIFT = 0x07; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getRxGainCompensation()\n"); +#endif + + /* Check for gainComp for Null */ + if (gainComp == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GAINCOMP_NULL_STRUCT, + getGpioMykonosErrorMessage(MYKONOS_ERR_GAINCOMP_NULL_STRUCT)); + return MYKONOS_ERR_GAINCOMP_NULL_STRUCT; + } + + if (enabled == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GAINCOMP_EN_NULL_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_GAINCOMP_EN_NULL_PARM)); + return MYKONOS_ERR_GAINCOMP_EN_NULL_PARM; + } + + /* Read gain compensation setup from device */ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_RX1_GAIN_COMP_OFFSET, ®Wr2); + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_RX2_GAIN_COMP_OFFSET, ®Wr3); + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_RX_GAIN_COMP_CFG, ®Wr4); + + + /* Parsing read data to passed by reference parameters */ + *enabled = (regWr4 & ENABLED_MASK) >> ENABLED_SHIFT; + gainComp->compStep = (regWr4 & STEP_MASK); + gainComp->rx2Offset = regWr3; + gainComp->rx1Offset = regWr2; + + /* Return */ + return MYKONOS_ERR_GPIO_OK; +} + + +/** + * \brief Gain compensation enable and setup function for the observation channel. + * + * The gain compensation block is a function that compensates for the attenuation in the internal attenuator for the observation channels. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is a pointer to the device settings structure + * \param gainComp is a pointer to the mykonosObsRxGainComp_t structure. + * \param enable enables or disables the gain compensation block. + * enable = 1 + * disable = 0 + * + * \retval MYKONOS_ERR_OBS_RX_GAINCOMP_SET_NULL_STRUCT gain compensation structure gainComp is not initialised + * \retval MYKONOS_ERR_OBS_RX_GAINCOMP_INV_OFFSET gain compensation structure gainComp->obsRxOffset is invalid + * \retval MYKONOS_ERR_OBS_RX_GAINCOMP_INV_STEP gain compensation structure gainComp->compStep is invalid + * \retval MYKONOS_ERR_OBS_RX_GAINCOMP_INV_EN enable is not valid + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + */ +mykonosGpioErr_t MYKONOS_setObsRxGainCompensation (mykonosDevice_t *device, mykonosObsRxGainComp_t *gainComp, uint8_t enable) +{ + uint8_t regWr2 = 0x00; + uint8_t regWr3 = 0x00; + + /* Max parameter values for error checking */ + const uint8_t RXOFFSET_RANGE = 0x1F; + + /* Shift values for writing gain values */ + const uint8_t STEP_RANGE = 0x07; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setObsRxGainCompensation()\n"); +#endif + + /* Check for gainComp initialised */ + if (gainComp == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OBS_RX_GAINCOMP_SET_NULL_STRUCT, + getGpioMykonosErrorMessage(MYKONOS_ERR_OBS_RX_GAINCOMP_SET_NULL_STRUCT)); + return MYKONOS_ERR_OBS_RX_GAINCOMP_SET_NULL_STRUCT; + } + + /* Check for enable */ + if (enable > 1) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OBS_RX_GAINCOMP_INV_EN, + getGpioMykonosErrorMessage(MYKONOS_ERR_OBS_RX_GAINCOMP_INV_EN)); + return MYKONOS_ERR_OBS_RX_GAINCOMP_INV_EN; + } + else if (enable == 1) + { + /* Check for gain compensation offset range */ + if (gainComp->obsRxOffset > RXOFFSET_RANGE) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OBS_RX_GAINCOMP_INV_OFFSET, + getGpioMykonosErrorMessage(MYKONOS_ERR_OBS_RX_GAINCOMP_INV_OFFSET)); + return MYKONOS_ERR_OBS_RX_GAINCOMP_INV_OFFSET; + } + + /* Check for gain compensation step range */ + if (gainComp->compStep > STEP_RANGE) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OBS_RX_GAINCOMP_INV_STEP, + getGpioMykonosErrorMessage(MYKONOS_ERR_OBS_RX_GAINCOMP_INV_STEP)); + return MYKONOS_ERR_OBS_RX_GAINCOMP_INV_STEP; + } + + /* Enabling gain compensation block */ + regWr3 = 0x88 | gainComp->compStep; + regWr2 = ((gainComp->obsRxOffset & 0x1E) >> 1) | ((gainComp->obsRxOffset & 0x01) << 4); + } + + /* Write gain compensation setup to device */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DPD_SNF_RX_GAIN_COMP_OFFSET, regWr2); + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DPD_SNF_RX_GAIN_COMP_CFG, regWr3); + + /* Return */ + return MYKONOS_ERR_GPIO_OK; +} + +/** + * \brief Get gain compensation setup and enabled function for the observation channel. + * + * The gain compensation block is a function that compensates for the attenuation in the internal attenuator for the observation + * channels. + * This function will get the current setup and the enable state of the block. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is a pointer to the device settings structure + * \param gainComp pointer to a mykonosObsRxGainComp_t structure, will held the current device gain compensation settings. + * \param enabled pointer this parameter will contain the enable state of the gain compensation block. + * enabled = 1 + * disabled = 0 + * + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + * \retval MYKONOS_ERR_OBS_RX_GAINCOMP_NULL_STRUCT observation channel gain compensation structure gainComp is not initialised + * \retval MYKONOS_ERR_OBS_RX_GAINCOMP_EN_NULL_PARAM enabled is null pointer for the parameter passed + */ +mykonosGpioErr_t MYKONOS_getObsRxGainCompensation (mykonosDevice_t *device, mykonosObsRxGainComp_t *gainComp, uint8_t *enabled) +{ + uint8_t regRd2 = 0x00; + uint8_t regRd3 = 0x00; + + /* Masks values for populating mykonosObsRxGainComp_t structure */ + const uint8_t ENABLED_MASK = 0x80; + const uint8_t STEP_MASK = 0x07; + + /* Shift values for populating mykonosObsRxGainComp_t structure */ + const uint8_t ENABLED_SHIFT = 0x07; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getObsRxGainCompensation()\n"); +#endif + + /* Check for gainComp for Null */ + if (gainComp == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OBS_RX_GAINCOMP_NULL_STRUCT, + getGpioMykonosErrorMessage(MYKONOS_ERR_OBS_RX_GAINCOMP_NULL_STRUCT)); + return MYKONOS_ERR_OBS_RX_GAINCOMP_NULL_STRUCT; + } + + if (enabled == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OBS_RX_GAINCOMP_EN_NULL_PARAM, + getGpioMykonosErrorMessage(MYKONOS_ERR_OBS_RX_GAINCOMP_EN_NULL_PARAM)); + return MYKONOS_ERR_OBS_RX_GAINCOMP_EN_NULL_PARAM; + } + + /* Read gain compensation setup from device */ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_DPD_SNF_RX_GAIN_COMP_OFFSET, ®Rd2); + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_DPD_SNF_RX_GAIN_COMP_CFG, ®Rd3); + + + /* Parsing read data to passed by reference parameters */ + *enabled = (regRd3 & ENABLED_MASK) >> ENABLED_SHIFT; + gainComp->compStep = (regRd3 & STEP_MASK); + gainComp->obsRxOffset = ((regRd2 & 0x0F) << 1) | ((regRd2 & 0x10) >> 4); + + /* Return */ + return MYKONOS_ERR_GPIO_OK; +} + +/** + * \brief Slicer control over GPIO inputs. + * + * The user can control the slicer position via 3 GPIO inputs per channel. + * There are various configurations for the GPIO pins, this configurations are enumerated in the mykonosRxSlicer_t. + * + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - Gain compensation block has to be enabled in order to user the slicer control + * + * \param device is a pointer to the device settings structure + * \param slicerStep configures the step size of the slicer when external pin contol mode is enabled. + * Slicer gain in this mode is determined by multiplying the step size by the input bit code from the BBP. + * Step sizes are as follows: + * sllicerStep | step + * -------------|------------ + * 0 | 1 + * 1 | 2 + * 2 | 3 + * 3 | 4 + * + * \param rx1Pins Rx1 slicer inputs can take values from one of the following combinations that are specified in mykonosRxSlicer_t enum: + * -GPIO_2, GPIO_1, and GPIO_0 + * -GPIO_7, GPIO_6, and GPIO_5 + * -GPIO_10, GPIO_9, and GPIO_8 + * \param rx2Pins Rx2 slicer inputs can take values from one of the following combinations that are specified in mykonosRxSlicer_t enum: + * -GPIO_7, GPIO_6, and GPIO_5 + * -GPIO_13, GPIO_12, and GPIO_11 + * \param enable this parameter enables the external pin control mode so the BBP can control the slicer setting. + * enable = 1 + * disable = 0 + * + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + * \retval MYKONOS_ERR_SLICER_INV_RX1_SEL invalid RX1 GPIO pin selection for Slicer control + * \retval MYKONOS_ERR_SLICER_INV_RX2_SEL invalid RX2 GPIO pin selection for Slicer control + * \retval MYKONOS_ERR_SLICER_STEP_OUT_OF_RANGE slicer step is out of range + * \retval MYKONOS_ERR_SLICER_EN_INV invalid enable + */ +mykonosGpioErr_t MYKONOS_setRxSlicerCtrl(mykonosDevice_t *device, uint8_t slicerStep, mykonosRxSlicer_t rx1Pins, mykonosRxSlicer_t rx2Pins, uint8_t enable) +{ + uint8_t regWr = 0x00; + + const uint8_t STEP_MASK = 0x03; + const uint8_t STEP_SHIFT = 0x05; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setRxSlicerCtrl()\n"); +#endif + + if (enable > 1) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SLICER_EN_INV, + getGpioMykonosErrorMessage(MYKONOS_ERR_SLICER_EN_INV)); + return MYKONOS_ERR_SLICER_EN_INV; + } + else if (enable == 1) + { + /* Enabling Slicer input control */ + regWr = 0x80; + + /* Check for Rx1 Slicer input control */ + switch (rx1Pins) + { + case GPIO_0_1_2: + regWr |= 0x00; + break; + case GPIO_5_6_7: + regWr |= 0x01; + break; + case GPIO_8_9_10: + regWr |= 0x02; + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SLICER_INV_RX1_SEL, + getGpioMykonosErrorMessage(MYKONOS_ERR_SLICER_INV_RX1_SEL)); + return MYKONOS_ERR_SLICER_INV_RX1_SEL; + } + + /* Check for Rx2 Slicer input control */ + switch (rx2Pins) + { + case GPIO_11_12_13: + regWr |= 0x00; + break; + case GPIO_5_6_7: + regWr |= 0x04; + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SLICER_INV_RX2_SEL, + getGpioMykonosErrorMessage(MYKONOS_ERR_SLICER_INV_RX2_SEL)); + return MYKONOS_ERR_SLICER_INV_RX2_SEL; + } + + /* Check for Slicer input step size control */ + if (slicerStep > STEP_MASK) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SLICER_STEP_OUT_OF_RANGE, + getGpioMykonosErrorMessage(MYKONOS_ERR_SLICER_STEP_OUT_OF_RANGE)); + return MYKONOS_ERR_SLICER_STEP_OUT_OF_RANGE; + } + else + { + regWr |= (uint8_t)(slicerStep << STEP_SHIFT); + } + } + + /* Write to device the slicer configuration */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RX_SLCR_PIN_CFG, regWr); + + return MYKONOS_ERR_GPIO_OK; +} + +/** + * \brief This function will get the programmed Slicer control for Rx1 and Rx2 channels. + * + * The user can control the slicer position via 3 GPIO inputs per channel. + * There are various configurations for the GPIO pins, this configurations are enumerated in the mykonosRxSlicer_t. + * + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is a pointer to the device settings structure + * \param slicerStep will contain the configured step size + * \param rx1Pins will contain the configured GPIO combination for Rx1 + * \param rx2Pins will contain the configured GPIO combination for Rx2 + * \param enable will contain the programmed enable setting + * + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + * \retval MYKONOS_ERR_SLICER_RX1PIN_NULL_PARM rx1Pins is null pointer for the passed parameter + * \retval MYKONOS_ERR_SLICER_RX2PIN_NULL_PARM rx1Pins is null pointer for the passed parameter + * \retval MYKONOS_ERR_SLICER_STEP_NULL_PARM slicerStep is null pointer for the passed parameter + * \retval MYKONOS_ERR_SLICER_EN_NULL_PARM enable is null pointer for the passed parameter + */ +mykonosGpioErr_t MYKONOS_getRxSlicerCtrl(mykonosDevice_t *device, uint8_t *slicerStep, mykonosRxSlicer_t *rx1Pins, mykonosRxSlicer_t *rx2Pins, uint8_t *enable) +{ + uint8_t regRd = 0x00; + + /* Mask parameter values populating parameters */ + const uint8_t EN_MASK = 0x80; + const uint8_t STEP_MASK = 0x60; + const uint8_t RX1_MASK = 0x03; + const uint8_t RX2_MASK = 0x0C; + + /* Shift values for populating passed parameters */ + const uint8_t EN_SHIFT = 0x07; + const uint8_t STEP_SHIFT = 0x05; + const uint8_t RX1_SHIFT = 0x00; + const uint8_t RX2_SHIFT = 0x02; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getRxSlicerCtrl()\n"); +#endif + + /* Check for Rx1 Slicer input control null parameter */ + if (rx1Pins == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SLICER_RX1PIN_NULL_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_SLICER_RX1PIN_NULL_PARM)); + return MYKONOS_ERR_SLICER_RX1PIN_NULL_PARM; + } + + /* Check for Rx2 Slicer input control null parameter */ + if (rx2Pins == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SLICER_RX2PIN_NULL_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_SLICER_RX2PIN_NULL_PARM)); + return MYKONOS_ERR_SLICER_RX2PIN_NULL_PARM; + } + + /* Check for Slicer step control null parameter */ + if (slicerStep == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SLICER_STEP_NULL_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_SLICER_STEP_NULL_PARM)); + return MYKONOS_ERR_SLICER_STEP_NULL_PARM; + } + + /* Check for Slicer step control null parameter */ + if (enable == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SLICER_EN_NULL_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_SLICER_EN_NULL_PARM)); + return MYKONOS_ERR_SLICER_EN_NULL_PARM; + } + + /* Reading SLicer control register */ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_RX_SLCR_PIN_CFG, ®Rd); + + /* Parsing values */ + *enable = (regRd & EN_MASK) >> EN_SHIFT; + *slicerStep = (regRd & STEP_MASK) >> STEP_SHIFT; + + /* Map to enum */ + switch ((regRd & RX2_MASK) >> RX2_SHIFT) + { + case 0: + *rx2Pins = GPIO_11_12_13; + break; + case 1: + *rx2Pins = GPIO_5_6_7; + break; + + default: + *rx2Pins = GPIO_11_12_13; + break; + } + + *rx1Pins = (mykonosRxSlicer_t)((regRd & RX1_MASK) >> RX1_SHIFT); + + /* Return */ + return MYKONOS_ERR_GPIO_OK; +} + +/** + * \brief Slicer control over GPIO inputs for the observation channel. + * + * The user can control the slicer position via 3 GPIO inputs for the observation channel. + * There are various configurations for the GPIO pins, this configurations are enumerated in the mykonosObsRxSlicer_t. + * + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - Gain compensation block has to be enabled in order to user the slicer control + * + * \param device is a pointer to the device settings structure + * \param slicerStep configures the step size of the slicer when external pin contol mode is enabled. + * Slicer gain in this mode is determined by multiplying the step size by the input bit code from the BBP. + * Step sizes are as follows: + * sllicerStep | step + * -------------|------------ + * 0 | 1 + * 1 | 2 + * 2 | 3 + * 3 | 4 + * + * \param obsRxPins observation slicer inputs can take values from one of the following combinations that are specified in mykonosObsRxSlicer_t enum: + * -GPIO_18, GPIO_17 and GPIO_16 + * -GPIO_16, GPIO_15 and GPIO_14 + * \param enable enables the external pin control mode so the BBP can control the slicer setting. + * enable = 1 + * disable = 0 + * + * \retval MYKONOS_ERR_SLICER_INV_OBS_RX_SEL invalid observation channel GPIO pin selection for Slicer control + * \retval MYKONOS_ERR_SLICER_OBS_RX_STEP_OUT_OF_RANGE slicer step is out of range + * \retval MYKONOS_ERR_SLICER_OBS_RX_EN_INV invalid enable + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + */ +mykonosGpioErr_t MYKONOS_setObsRxSlicerCtrl(mykonosDevice_t *device, uint8_t slicerStep, mykonosObsRxSlicer_t obsRxPins, uint8_t enable) +{ + uint8_t regWr = 0x00; + + const uint8_t STEP_MASK = 0x03; + const uint8_t STEP_SHIFT = 0x05; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setObsRxSlicerCtrl()\n"); +#endif + + if (enable > 1) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SLICER_OBS_RX_EN_INV, + getGpioMykonosErrorMessage(MYKONOS_ERR_SLICER_OBS_RX_EN_INV)); + return MYKONOS_ERR_SLICER_OBS_RX_EN_INV; + } + else if (enable == 1) + { + /* Enabling Slicer input control */ + regWr = 0x80; + + /* Check for Rx1 Slicer input control */ + switch (obsRxPins) + { + case GPIO_18_17_16: + regWr |= 0x00; + break; + case GPIO_16_15_14: + regWr |= 0x01; + break; + + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SLICER_INV_OBS_RX_SEL, + getGpioMykonosErrorMessage(MYKONOS_ERR_SLICER_INV_OBS_RX_SEL)); + return MYKONOS_ERR_SLICER_INV_OBS_RX_SEL; + } + + /* Check for Slicer input step size control */ + if (slicerStep & ~STEP_MASK) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SLICER_OBS_RX_STEP_OUT_OF_RANGE, + getGpioMykonosErrorMessage(MYKONOS_ERR_SLICER_OBS_RX_STEP_OUT_OF_RANGE)); + return MYKONOS_ERR_SLICER_OBS_RX_STEP_OUT_OF_RANGE; + } + else + { + regWr |= (uint8_t)((slicerStep << STEP_SHIFT)); + } + } + + /* Write to device the slicer configuration */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DPD_SNF_RX_SLCR_PIN_CFG, regWr); + + return MYKONOS_ERR_GPIO_OK; +} + +/** + * \brief This function will get the programmed Slicer control for observation channel. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is a pointer to the device settings structure + * \param slicerStep will contain the configured step size + * \param obsRxPins will contain the configured GPIO combination + * \param enable will contain the programmed enable setting + * + * \retval MYKONOS_ERR_SLICER_OBS_RXPIN_NULL_PARM obsRxPins is null pointer for the passed parameter + * \retval MYKONOS_ERR_SLICER_OBS_RX_STEP_NULL_PARM slicerStep is null pointer for the passed parameter + * \retval MYKONOS_ERR_SLICER_OBS_RX_EN_NULL_PARM, enable is null pointer for the passed parameter + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + */ +mykonosGpioErr_t MYKONOS_getObsRxSlicerCtrl(mykonosDevice_t *device, uint8_t *slicerStep, mykonosObsRxSlicer_t *obsRxPins, uint8_t *enable) +{ + uint8_t regRd = 0x00; + + /* Mask parameter values populating slicer parameters */ + const uint8_t EN_MASK = 0x80; + const uint8_t STEP_MASK = 0x60; + const uint8_t OBS_RX_MASK = 0x03; + + /* Shift values for writing slicer parameters */ + const uint8_t EN_SHIFT = 0x07; + const uint8_t STEP_SHIFT = 0x05; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getObsRxSlicerCtrl()\n"); +#endif + + /* Check for Rx1 Slicer input control null parameter */ + if (obsRxPins == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SLICER_OBS_RXPIN_NULL_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_SLICER_OBS_RXPIN_NULL_PARM)); + return MYKONOS_ERR_SLICER_OBS_RXPIN_NULL_PARM; + } + + /* Check for Slicer step control null parameter */ + if (slicerStep == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SLICER_OBS_RX_STEP_NULL_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_SLICER_OBS_RX_STEP_NULL_PARM)); + return MYKONOS_ERR_SLICER_OBS_RX_STEP_NULL_PARM; + } + + /* Check for Slicer step control null parameter */ + if (enable == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SLICER_OBS_RX_EN_NULL_PARM, + getGpioMykonosErrorMessage(MYKONOS_ERR_SLICER_OBS_RX_EN_NULL_PARM)); + return MYKONOS_ERR_SLICER_OBS_RX_EN_NULL_PARM; + } + + /* Reading Slicer control register */ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_DPD_SNF_RX_SLCR_PIN_CFG, ®Rd); + + /* Parsing values */ + *enable = (regRd & EN_MASK) >> EN_SHIFT; + *slicerStep = (regRd & STEP_MASK) >> STEP_SHIFT; + + /* Map to enum */ + switch (regRd & OBS_RX_MASK) + { + case 0: + *obsRxPins = GPIO_18_17_16; + break; + case 1: + *obsRxPins = GPIO_16_15_14; + break; + + default: + *obsRxPins = (mykonosObsRxSlicer_t)0; + break; + } + + /* Return */ + return MYKONOS_ERR_GPIO_OK; +} + + +/** + * \brief Floating point formatter enable and setup function. + * + * The floating point formatter block is a function that works in conjunction with the gain + * compensating block, as the gain compensation requires increased dynamic range (total gain range on AD9371 is 42dB) + * which increases the bitwidth in the digital datapath. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - Gain compensation block has to be enabled in order to user floating point formatter + * + * \param device is a pointer to the device settings structure + * \param floatFrmt which is a mykonosFloatPntFrmt_t structure. + * + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + * \retval MYKONOS_ERR_FLOATFRMT_SET_NULL_STRUCT floating point formatter structure floatFrmt not initialized + * \retval MYKONOS_ERR_FLOATFRMT_INV_ROUND_MODE floating point formatter structure floatFrmt.roundMode not valid parameter + * \retval MYKONOS_ERR_FLOATFRMT_INV_DATA_FORMAT floating point formatter structure floatFrmt.dataFormat not valid parameter + * \retval MYKONOS_ERR_FLOATFRMT_INV_ENC_NAN floating point formatter structure floatFrmt.encNan not valid parameter + * \retval MYKONOS_ERR_FLOATFRMT_INV_EXP_BITS floating point formatter structure floatFrmt.expBits not valid parameter + * \retval MYKONOS_ERR_FLOATFRMT_INV_LEADING floating point formatter structure floatFrmt.leading not valid parameter + */ +mykonosGpioErr_t MYKONOS_setFloatPointFrmt (mykonosDevice_t *device, mykonosFloatPntFrmt_t *floatFrmt) +{ + uint8_t regWr1 = 0x00; + + /* Max parameter values for error checking */ + const uint8_t ROUND_RANGE = 0x04; + const uint8_t DATA_FRMT_RANGE = 0x01; + const uint8_t ENCODE_RANGE = 0x01; + const uint8_t EXPBITS_RANGE = 0x03; + const uint8_t LEADING_RANGE = 0x01; + + /* Shift values for writing mykonosFloatPntFrmt_t values */ + const uint8_t ROUND_SHIFT = 0x05; + const uint8_t DATA_FRMT_SHIFT = 0x04; + const uint8_t ENCODE_SHIFT = 0x03; + const uint8_t EXPBITS_SHIFT = 0x01; + const uint8_t LEADING_SHIFT = 0x00; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setFloatPointFrmt()\n"); +#endif + + /* Check for gainComp initialised */ + if (floatFrmt == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FLOATFRMT_SET_NULL_STRUCT, + getGpioMykonosErrorMessage(MYKONOS_ERR_FLOATFRMT_SET_NULL_STRUCT)); + return MYKONOS_ERR_FLOATFRMT_SET_NULL_STRUCT; + } + + /* Check for floating point round mode */ + if (floatFrmt->roundMode > ROUND_RANGE) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FLOATFRMT_INV_ROUND_MODE, + getGpioMykonosErrorMessage(MYKONOS_ERR_FLOATFRMT_INV_ROUND_MODE)); + return MYKONOS_ERR_FLOATFRMT_INV_ROUND_MODE; + } + + /* Check for floating point data format */ + if (floatFrmt->dataFormat > DATA_FRMT_RANGE) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FLOATFRMT_INV_DATA_FORMAT, + getGpioMykonosErrorMessage(MYKONOS_ERR_FLOATFRMT_INV_DATA_FORMAT)); + return MYKONOS_ERR_FLOATFRMT_INV_DATA_FORMAT; + } + + /* Check for floating point encode NaN */ + if (floatFrmt->encNan > ENCODE_RANGE) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FLOATFRMT_INV_ENC_NAN, + getGpioMykonosErrorMessage(MYKONOS_ERR_FLOATFRMT_INV_ENC_NAN)); + return MYKONOS_ERR_FLOATFRMT_INV_ENC_NAN; + } + + /* Check for floating point exponent bits range */ + if (floatFrmt->expBits > EXPBITS_RANGE) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FLOATFRMT_INV_EXP_BITS, + getGpioMykonosErrorMessage(MYKONOS_ERR_FLOATFRMT_INV_EXP_BITS)); + return MYKONOS_ERR_FLOATFRMT_INV_EXP_BITS; + } + + /* Check for floating point hide leading ones */ + if (floatFrmt->leading > LEADING_RANGE) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FLOATFRMT_INV_LEADING, + getGpioMykonosErrorMessage(MYKONOS_ERR_FLOATFRMT_INV_LEADING)); + return MYKONOS_ERR_FLOATFRMT_INV_LEADING; + } + + regWr1 = (uint8_t)((floatFrmt->roundMode << ROUND_SHIFT) | (floatFrmt->dataFormat << DATA_FRMT_SHIFT) | + (floatFrmt->encNan << ENCODE_SHIFT) | (floatFrmt->expBits << EXPBITS_SHIFT) | + (floatFrmt->leading << LEADING_SHIFT)); + + + /* Write gain compensation setup to device */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FLOATING_POINT_CFG, regWr1); + + /* Return */ + return MYKONOS_ERR_GPIO_OK; +} + +/** + * \brief Floating point formatter setup function. + * + * The floating point formatter block is a function that works in conjunction with the gain + * compensating block, as the gain compensation requires increased dynamic range + * which increases the bit-width in the digital data-path. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - Gain compensation block has to be enabled in order to user floating point formatter + * + * \param device is a pointer to the device settings structure + * \param floatFrmt which is a mykonosFloatPntFrmt_t structure. + * + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + * \retval MYKONOS_ERR_FLOATFRMT_NULL_STRUCT floating point formatter structure floatFrmt not initialized + * + */ +mykonosGpioErr_t MYKONOS_getFloatPointFrmt (mykonosDevice_t *device, mykonosFloatPntFrmt_t *floatFrmt) +{ + uint8_t regRd1 = 0x00; + + /* Mask parameter values populating mykonosGainComp_t structure */ + const uint8_t ROUND_MASK = 0xE0; + const uint8_t DATA_FRMT_MASK = 0x10; + const uint8_t ENCODE_MASK = 0x08; + const uint8_t EXPBITS_MASK = 0x06; + const uint8_t LEADING_MASK = 0x01; + + /* Shift values for writing gain values */ + const uint8_t ROUND_SHIFT = 0x05; + const uint8_t DATA_FRMT_SHIFT = 0x04; + const uint8_t ENCODE_SHIFT = 0x03; + const uint8_t EXPBITS_SHIFT = 0x01; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getFloatPointFrmt()\n"); +#endif + + /* Check floatFrmt for Null */ + if (floatFrmt == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FLOATFRMT_NULL_STRUCT, + getGpioMykonosErrorMessage(MYKONOS_ERR_FLOATFRMT_NULL_STRUCT)); + return MYKONOS_ERR_FLOATFRMT_NULL_STRUCT; + } + + /* Read gain compensation setup from device */ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_FLOATING_POINT_CFG, ®Rd1); + + /* Parsing read data to passed by reference parameters */ + floatFrmt->roundMode = (regRd1 & ROUND_MASK) >> ROUND_SHIFT; + floatFrmt->dataFormat = (regRd1 & DATA_FRMT_MASK) >> DATA_FRMT_SHIFT; + floatFrmt->encNan = (regRd1 & ENCODE_MASK) >> ENCODE_SHIFT; + floatFrmt->expBits = (regRd1 & EXPBITS_MASK) >> EXPBITS_SHIFT; + floatFrmt->leading = regRd1 & LEADING_MASK; + + /* Return */ + return MYKONOS_ERR_GPIO_OK; +} + +/** + * \brief Floating point formatter enable/disable Rx1 and Rx2 function. + * + * The floating point formatter block is a function that works in conjunction with the gain + * compensating block, as the gain compensation requires increased dynamic range + * which increases the bit-width in the digital data-path. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * - Gain compensation block has to be enabled in order to user floating point formatter + * + * \param device is a pointer to the device settings structure + * \param rx1Att this parameter sets the integer data attenuation for the Rx1 channel in 6dB steps + * to enable the entire data range to be represented in the selected floating point format. + * \param rx2Att this parameter sets the integer data attenuation for the Rx2 channel in 6dB steps + * to enable the entire data range to be represented in the selected floating point format. + * \param enable this parameter enables or disables the gain compensation block. + * enable = 1 + * disable = 0 + * + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + * \retval MYKONOS_ERR_FLOATFRMT_SET_INV_RX1ATT not valid rx1 attenuation parameter passed in MYKONOS_setRxEnFloatPntFrmt() + * \retval MYKONOS_ERR_FLOATFRMT_SET_INV_RX2ATT not valid rx2 attenuation parameter passed in MYKONOS_setRxEnFloatPntFrmt() + * \retval MYKONOS_ERR_FLOATFRMT_SET_INV_EN not valid enable parameter passed in MYKONOS_setRxEnFloatPntFrmt() + */ +mykonosGpioErr_t MYKONOS_setRxEnFloatPntFrmt (mykonosDevice_t *device, uint8_t rx1Att, uint8_t rx2Att, uint8_t enable) +{ + uint8_t regWr = 0x00; + + const uint8_t RXATT_RANGE = 0x07; + const uint8_t RX1ATT_SHIFT = 0x01; + const uint8_t RX2ATT_SHIFT = 0x05; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setRxEnFloatPntFrmt()\n"); +#endif + + if (enable > 1) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FLOATFRMT_SET_INV_EN, + getGpioMykonosErrorMessage(MYKONOS_ERR_FLOATFRMT_SET_INV_EN)); + return MYKONOS_ERR_FLOATFRMT_SET_INV_EN; + } + else if (enable == 1) + { + /* Check for rx1Att range */ + if (rx1Att > RXATT_RANGE) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FLOATFRMT_SET_INV_RX1ATT, + getGpioMykonosErrorMessage(MYKONOS_ERR_FLOATFRMT_SET_INV_RX1ATT)); + return MYKONOS_ERR_FLOATFRMT_SET_INV_RX1ATT; + } + + /* Check for rx2Att range */ + if (rx2Att > RXATT_RANGE) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FLOATFRMT_SET_INV_RX2ATT, + getGpioMykonosErrorMessage(MYKONOS_ERR_FLOATFRMT_SET_INV_RX2ATT)); + return MYKONOS_ERR_FLOATFRMT_SET_INV_RX2ATT; + } + + /* Enabling floating point formatter for Rx1 and Rx2 */ + regWr = 0x11; + regWr |= (uint8_t)((rx1Att << RX1ATT_SHIFT) | (rx2Att << RX2ATT_SHIFT)); + } + + /* Writing floating point formatter enables for Rx1 and Rx2 */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FLOATING_POINT_RX_CTRL, regWr); + + /* Return */ + return MYKONOS_ERR_GPIO_OK; +} + +/** + * \brief Floating point formatter setup function. + * + * The floating point formatter block is a function that works in conjunction with the gain + * compensating block, as the gain compensation requires increased dynamic range (total gain range on AD9371 is 42dB) + * which increases the bitwidth in the digital datapath. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is a pointer to the device settings structure + * \param rx1Att this parameter sets the integer data attenuation for the Rx1 channel in 6dB steps + * to enable the entire data range to be represented in the selected floating point format. + * \param rx2Att this parameter sets the integer data attenuation for the Rx2 channel in 6dB steps + * to enable the entire data range to be represented in the selected floating point format. + * \param enable this parameter enables or disables the gain compensation block. + * enable = 1 + * disable = 0 + * + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + * \retval MYKONOS_ERR_FLOATFRMT_NULL_RX1ATT null pointer passed for rx1 attenuation in MYKONOS_setRxEnFloatPntFrmt() + * \retval MYKONOS_ERR_FLOATFRMT_NULL_RX2ATT null pointer passed for rx2 attenuation in MYKONOS_setRxEnFloatPntFrmt() + * \retval MYKONOS_ERR_FLOATFRMT_NULL_ENABLE null pointer passed for enable in MYKONOS_setRxEnFloatPntFrmt() + */ +mykonosGpioErr_t MYKONOS_getRxEnFloatPntFrmt (mykonosDevice_t *device, uint8_t *rx1Att, uint8_t *rx2Att, uint8_t *enable) +{ + uint8_t regRd = 0x00; + + const uint8_t EN_MASK = 0x11; + const uint8_t RX1ATT_MASK = 0x0E; + const uint8_t RX1ATT_SHIFT = 0x01; + const uint8_t RX2ATT_MASK = 0xE0; + const uint8_t RX2ATT_SHIFT = 0x05; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getRxEnFloatPntFrmt()\n"); +#endif + + /* Check for rx1Att NULL parameter */ + if (rx1Att == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FLOATFRMT_NULL_RX1ATT, + getGpioMykonosErrorMessage(MYKONOS_ERR_FLOATFRMT_NULL_RX1ATT)); + return MYKONOS_ERR_FLOATFRMT_NULL_RX1ATT; + } + + /* Check for rx2Att NULL parameter */ + if (rx2Att == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FLOATFRMT_NULL_RX2ATT, + getGpioMykonosErrorMessage(MYKONOS_ERR_FLOATFRMT_NULL_RX2ATT)); + return MYKONOS_ERR_FLOATFRMT_NULL_RX2ATT; + } + + /* Check for enable NULL parameter */ + if (enable == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FLOATFRMT_NULL_ENABLE, + getGpioMykonosErrorMessage(MYKONOS_ERR_FLOATFRMT_NULL_ENABLE)); + return MYKONOS_ERR_FLOATFRMT_NULL_ENABLE; + } + + /* Read Rx1 and Rx2 floating point enables */ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_FLOATING_POINT_RX_CTRL, ®Rd); + + *rx1Att = (regRd & RX1ATT_MASK) >> RX1ATT_SHIFT; + *rx2Att = (regRd & RX2ATT_MASK) >> RX2ATT_SHIFT ; + *enable = (regRd & EN_MASK) ? 1 : 0; + + /* Return */ + return MYKONOS_ERR_GPIO_OK; +} + + + +/** + * \brief Floating point formatter enable function for ORx channel. + * + * The floating point formatter block is a function that works in conjunction with the gain + * compensating block, as the gain compensation requires increased dynamic range + * which increases the bit-width in the digital data-path. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is a pointer to the device settings structure + * \param orxAtt this parameter sets the integer data attenuation for the ORx channel in 6dB steps + * to enable the entire data range to be represented in the selected floating point format. + * * \param enable this parameter enables or disables the gain compensation block. + * enable = 1 + * disable = 0 + * + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + * \retval MYKONOS_ERR_FLOATFRMT_INV_ORXATT not valid Orx attenuation parameter passed in MYKONOS_setOrxEnFloatPntFrmt() + * \retval MYKONOS_ERR_FLOATFRMT_INV_ORXEN not valid enable parameter passed in MYKONOS_setOrxEnFloatPntFrmt() + */ +mykonosGpioErr_t MYKONOS_setOrxEnFloatPntFrmt (mykonosDevice_t *device, uint8_t orxAtt, uint8_t enable) +{ + uint8_t regWr = 0x00; + + const uint8_t ORXATT_RANGE = 0x07; + const uint8_t ORXATT_SHIFT = 0x01; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setOrxEnFloatPntFrmt()\n"); +#endif + + /* Check for enable */ + if (enable > 1) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FLOATFRMT_INV_ORXEN, + getGpioMykonosErrorMessage(MYKONOS_ERR_FLOATFRMT_INV_ORXEN)); + return MYKONOS_ERR_FLOATFRMT_INV_ORXEN; + } + else if (enable == 1) + { + /* Check for rx1Att range */ + if (orxAtt > ORXATT_RANGE) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FLOATFRMT_INV_ORXATT, + getGpioMykonosErrorMessage(MYKONOS_ERR_FLOATFRMT_INV_ORXATT)); + return MYKONOS_ERR_FLOATFRMT_INV_ORXATT; + } + + /* Enabling floating point formatter for Rx1 and Rx2 */ + regWr = 0x01; + regWr |= (uint8_t)(orxAtt << ORXATT_SHIFT); + } + + /* Writing floating point formatter enable for ORX channel */ + CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FLOATING_POINT_ORX_CTRL, regWr); + + /* Return */ + return MYKONOS_ERR_GPIO_OK; +} + + +/** + * \brief Floating point formatter enable and setup function. + * + * The floating point formatter block is a function that works in conjunction with the gain + * compensating block, as the gain compensation requires increased dynamic range (total gain range on AD9371 is 42dB) + * which increases the bitwidth in the digital datapath. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is a pointer to the device settings structure + * \param orxAtt this parameter sets the integer data attenuation for the ORx channel in 6dB steps + * to enable the entire data range to be represented in the selected floating point format. + * \param enable this parameter enables or disables the gain compensation block. + * enable = 1 + * disable = 0 + * + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + * \retval MYKONOS_ERR_FLOATFRMT_NULL_ORXATT null pointer passed for orxAtt + * \retval MYKONOS_ERR_FLOATFRMT_NULL_ORXENABLE null pointer passed for enable + */ +mykonosGpioErr_t MYKONOS_getOrxEnFloatPntFrmt (mykonosDevice_t *device, uint8_t *orxAtt, uint8_t *enable) +{ + uint8_t regRd = 0x00; + + const uint8_t EN_MASK = 0x01; + const uint8_t ORXATT_MASK = 0x0E; + const uint8_t ORXATT_SHIFT = 0x01; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getOrxEnFloatPntFrmt()\n"); +#endif + + /* Check for orxAtt NULL parameter */ + if (orxAtt == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FLOATFRMT_NULL_ORXATT, + getGpioMykonosErrorMessage(MYKONOS_ERR_FLOATFRMT_NULL_ORXATT)); + return MYKONOS_ERR_FLOATFRMT_NULL_ORXATT; + } + + /* Check for enable NULL parameter */ + if (enable == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FLOATFRMT_NULL_ORXENABLE, + getGpioMykonosErrorMessage(MYKONOS_ERR_FLOATFRMT_NULL_ORXENABLE)); + return MYKONOS_ERR_FLOATFRMT_NULL_ORXENABLE; + } + + /* Read Rx1 and Rx2 floating point enables */ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_FLOATING_POINT_ORX_CTRL, ®Rd); + + *orxAtt = (regRd & ORXATT_MASK) >> ORXATT_SHIFT; + *enable = (regRd & EN_MASK) ? 1 : 0; + + /* Return */ + return MYKONOS_ERR_GPIO_OK; +} + + +/** + * \brief Sets up the Temperature Sensor + * + * Before using this function to set up the temp sensor, + * make sure that you call the MYKONOS_setupAuxADC() function + * to ensure that the AuxADC clock is setup and running correctly at 40 MHz, + * and that the structure mykonosTempSensorConfig_t tempSensor is populated. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is a pointer to the device settings structure + * \param tempSensor is a pointer to the mykonosTempSensorConfig_t which holds + * the configuration settings for the temperature sensor + * + * \retval MYKONOS_ERR_SETUPTEMPSENSOR_NULL_PARAM Function parameter tempSensor is a NULL pointer + * \retval MYKONOS_ERR_SETUPTEMPSENSOR_INV_TEMPDECIMATION tempDecimation value out of range (0-7) + * \retval MYKONOS_ERR_SETUPTEMPSENSOR_INV_OFFSET offset value out of range (0-255) + * \retval MYKONOS_ERR_SETUPTEMPSENSOR_INV_TEMPWINDOW tempWindow out of range (0-15) + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + */ +mykonosGpioErr_t MYKONOS_setupTempSensor(mykonosDevice_t *device, mykonosTempSensorConfig_t *tempSensor) +{ + uint8_t offsetFromDevice = 0; + + const uint8_t OFFSET_API = 0x43; +/* const uint8_t TEMP_OFFSET_MASK = 0xFF;*/ + const uint8_t TEMP_WINDOW_MASK = 0xF0; + const uint8_t TEMP_WINDOW_CHECK = 0x0F; + const uint8_t TEMP_DEC_MASK = 0x07; + const uint8_t OFFSET_OVERRIDE_MASK = 0x10; + +#ifdef MYKONOS_VERBOSE + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setupTempSensor()\n"); +#endif + + /* Check for structure initialisation mykonosTempSensorConfig_t */ + if (tempSensor == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETUPTEMPSENSOR_NULL_PARAM, + getGpioMykonosErrorMessage(MYKONOS_ERR_SETUPTEMPSENSOR_NULL_PARAM)); + return MYKONOS_ERR_SETUPTEMPSENSOR_NULL_PARAM; + } + + /* Check Temperature sensor decimation range */ + if ((tempSensor->tempDecimation & ~TEMP_DEC_MASK) > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETUPTEMPSENSOR_INV_TEMPDECIMATION, + getGpioMykonosErrorMessage(MYKONOS_ERR_SETUPTEMPSENSOR_INV_TEMPDECIMATION)); + return MYKONOS_ERR_SETUPTEMPSENSOR_INV_TEMPDECIMATION; + } + + /* Override fused offset */ + if (tempSensor->overrideFusedOffset > 0) + { + /* Check Temperature sensor offset range */ +/* if (tempSensor->offset & ~TEMP_OFFSET_MASK) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETUPTEMPSENSOR_INV_OFFSET, + getGpioMykonosErrorMessage(MYKONOS_ERR_SETUPTEMPSENSOR_INV_OFFSET)); + return MYKONOS_ERR_SETUPTEMPSENSOR_INV_OFFSET; + }*/ + + CMB_SPIWriteField (device->spiSettings, MYKONOS_ADDR_TEMP_SENSOR_CONFIG, 1, OFFSET_OVERRIDE_MASK, 4); + CMB_SPIWriteByte (device->spiSettings, MYKONOS_ADDR_TEMP_SENSOR_OFFSET, tempSensor->offset); + } + else + { + /* If manual override was not requested, read back device offset value. + * If factory fused it is non-zero; else API adds a typical offset value */ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_TEMP_SENSOR_OFFSET, &(offsetFromDevice)); + if (offsetFromDevice == 0) + { + CMB_SPIWriteByte (device->spiSettings, MYKONOS_ADDR_TEMP_SENSOR_OFFSET, OFFSET_API); + } + } + + /* Check Temperature sensor window range */ + if ((tempSensor->tempWindow & ~TEMP_WINDOW_CHECK) > 0) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETUPTEMPSENSOR_INV_TEMPWINDOW, + getGpioMykonosErrorMessage(MYKONOS_ERR_SETUPTEMPSENSOR_INV_TEMPWINDOW)); + return MYKONOS_ERR_SETUPTEMPSENSOR_INV_TEMPWINDOW; + } + else + { + CMB_SPIWriteField (device->spiSettings, MYKONOS_ADDR_TEMP_SENSOR_CONTROL_LSB, tempSensor->tempWindow, TEMP_WINDOW_MASK, 4); + } + + /* Single shot setup */ + CMB_SPIWriteByte (device->spiSettings, MYKONOS_ADDR_TEMP_SENSOR_CONTROL_MSB, 0x00); + + /* Write decimation factor for the Temperature sensor */ + CMB_SPIWriteField (device->spiSettings, MYKONOS_ADDR_TEMP_SENSOR_CONFIG, tempSensor->tempDecimation, TEMP_DEC_MASK, 0); + + return MYKONOS_ERR_GPIO_OK; +} + +/** + * \brief Reads from the Temperature Sensor registers and populates device data structure + * + * After this function is executed, the tempSensor parameter holds updated values + * from the device registers. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is a pointer to the device settings structure + * \param tempSensor is a pointer to the mykonosTempSensorConfig_t which holds + * the configuration settings for the tempSensor + * + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + * \retval MYKONOS_ERR_GETTEMPSENSORCONFIG_NULL_PARAM Function parameter tempSensor is a NULL pointer + */ +mykonosGpioErr_t MYKONOS_getTempSensorConfig(mykonosDevice_t *device, mykonosTempSensorConfig_t *tempSensor) +{ + uint8_t tempConfig = 0; + + const uint8_t TEMP_WINDOW_MASK = 0xF0; + const uint8_t TEMP_FUSE_MASK = 0x10; + const uint8_t TEMP_DECIMATION_MASK = 0x07; + const uint8_t TEMP_FUSE_SHIFT = 0x04; + +#ifdef MYKONOS_VERBOSE + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getTempSensorConfig()\n"); +#endif + + /* Check tempSensor null parameter passed */ + if (tempSensor == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETTEMPSENSORCFG_NULL_PARAM, + getGpioMykonosErrorMessage(MYKONOS_ERR_GETTEMPSENSORCFG_NULL_PARAM)); + return MYKONOS_ERR_GETTEMPSENSORCFG_NULL_PARAM; + } + + /* Read back factory offset, if fused; else manual offset value */ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_TEMP_SENSOR_OFFSET, &(tempSensor->offset)); + + /* Read back Decimation and override Offset Temperature sensor parameters */ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_TEMP_SENSOR_CONFIG, &tempConfig); + tempSensor->overrideFusedOffset = (tempConfig & TEMP_FUSE_MASK) >> TEMP_FUSE_SHIFT; + tempSensor->tempDecimation = (tempConfig & TEMP_DECIMATION_MASK); + + /* Read back tempWindow */ + CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_TEMP_SENSOR_CONTROL_LSB, &tempConfig, TEMP_WINDOW_MASK, 4); + tempSensor->tempWindow = tempConfig; + + return MYKONOS_ERR_GPIO_OK; +} + +/** + * \brief Initiates temperature measurement + * + * This function will initiate the Temperature sensor measurement. + * + * \pre + * MYKONOS_setupTempSensor() function to set the temperature sensor. + * MYKONOS_setAuxAdcChannel() function with the AuxADC setting for Temperature sensor channel MYK_TEMPSENSOR + * from the enum type mykonosAuxAdcChannels_t. + * + * \post + * Internal temperature sensor will perform measurement and updated register values, + * read back using MYKONOS_readTempSensor() function. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is a pointer to the device settings structure + * + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + */ +mykonosGpioErr_t MYKONOS_startTempMeasurement(mykonosDevice_t *device) +{ + const uint8_t TEMP_LOCK_MASK = 0x80; + const uint8_t TEMP_LOCK_BIT = 0x01; + const uint8_t MEASUREMENT_MASK = 0x01; + +#ifdef MYKONOS_VERBOSE + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_startTempMeasurement()\n"); +#endif + + /* Write the lock bit to ensure that a valid measurement is achieved */ + CMB_SPIWriteField (device->spiSettings, MYKONOS_ADDR_TEMP_SENSOR_CONFIG, TEMP_LOCK_BIT, TEMP_LOCK_MASK, 7); + + /* Initiate Temperature measurement */ + CMB_SPIWriteField (device->spiSettings, MYKONOS_ADDR_TEMP_SENSOR_CONTROL_LSB, 1, MEASUREMENT_MASK, 0); + CMB_SPIWriteField (device->spiSettings, MYKONOS_ADDR_TEMP_SENSOR_CONTROL_LSB, 0, MEASUREMENT_MASK, 0); + + return MYKONOS_ERR_GPIO_OK; +} + +/** + * \brief Reads temperature code and statuses from the Temperature Sensor registers + * + * This function reads the temperature sensor's statuses and temperature code. + * Allow at least one computation period to elapse. + * The temperature sensor computation period is as 6 times the AuxADC conversion time. + * AuxADC conversion time = (1/40Mhz) * (256 * 2^(tempDecimation)) + * + * Before using this function to read back the temperature, make sure that temperature sensor + * is setup using the MYKONOS_setupTempSensor() function. + * + * \pre Before using this function to read back the sensor value: + * MYKONOS_setupTempSensor() function is needed in order to set up the Temperature sensor. + * MYKONOS_setAuxAdcChannel() function has to be called in order to set the proper AuxADC + * channel. AuxADC channel MYK_TEMPSENSOR is used for the Temperature sensor. + * MYKONOS_startTempMeasurement() this function will start the Temperature sensor, this + * function is needed to be called for every reading that needs to be performed. + * + * \post "tempStatus" structure will contain the status information and the temperature + * code. + * If a valid measurement is achieved then tempStatus->tempValid will be set and + * tempStatus->tempCode will contain the actual reading. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is a pointer to the device settings structure + * \param tempStatus is a pointer to the mykonosTempSensorStatus_t structure which will be updated + * with the temp sensor readings + * + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + * \retval MYKONOS_ERR_READTEMPSENSOR_NULL_PARAM Function parameter tempSensor is a NULL pointer + * \retval MYKONOS_ERR_READTEMPSENSOR_NOT_LOCKED temperature sensor reading is not locked + */ +mykonosGpioErr_t MYKONOS_readTempSensor(mykonosDevice_t *device, mykonosTempSensorStatus_t *tempStatus) +{ + int16_t temperature = 0; + uint8_t statusWord = 0; + uint8_t rgRd = 0x00; + + const uint8_t CODE_TO_DEGREE_CELSIUS = 0x67; + const uint8_t TEMP_VALID_MASK = 0x02; + const uint8_t WINDOW_EXCEED_MASK = 0x08; + const uint8_t WINDOW_HI_LO_MASK = 0x04; + const uint8_t TEMP_LOCK = 0x80; + +#ifdef MYKONOS_VERBOSE + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_readTempSensor()\n"); +#endif + + if (tempStatus == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_READTEMPSENSOR_NULL_PARAM, + getGpioMykonosErrorMessage(MYKONOS_ERR_READTEMPSENSOR_NULL_PARAM)); + return MYKONOS_ERR_READTEMPSENSOR_NULL_PARAM; + } + + /* Check for temperature sensor value lock */ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_TEMP_SENSOR_CONFIG, &rgRd); + if ((rgRd & TEMP_LOCK) == TEMP_LOCK) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_READTEMPSENSOR_NOT_LOCKED, + getGpioMykonosErrorMessage(MYKONOS_ERR_READTEMPSENSOR_NOT_LOCKED)); + return MYKONOS_ERR_READTEMPSENSOR_NOT_LOCKED; + } + + /* Perform temperature status reading */ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_TEMP_SENSOR_CONTROL_LSB, &statusWord); + tempStatus->windowExceeded = (statusWord & WINDOW_EXCEED_MASK) >> 3; + tempStatus->windowHiLo = (statusWord & WINDOW_HI_LO_MASK) >> 2; + tempStatus->tempValid = (0x01 & ~((statusWord & TEMP_VALID_MASK) >> 1)); + + /* Perform temperature reading */ + CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_TEMP_SENSOR_READ, &rgRd); + temperature = rgRd - CODE_TO_DEGREE_CELSIUS; + tempStatus->tempCode = temperature; + + return MYKONOS_ERR_GPIO_OK; +} + +/** + * \brief This function sets the drive strength for the required GPIOs. + * + * This function will set the required drive strength, the settings for GPIO drive strength are normal drive and double drive. + * + * GPIO pins that can be assigned independent drive strength are: + * -MYKGPIO0 to MYKGPIO7 and MYKGPIO18 + * + * The rest of GPIOs are paired as: + * -MYKGPIO17 and MYKGPIO16 + * -MYKGPIO8 and MYKGPIO15 + * -MYKGPIO14 and MYKGPIO13 + * -MYKGPIO10 and MYKGPIO9 + * -MYKGPIO12 and MYKGPIO11 + * + * This means that if it is required to double the drive strength for MYKGPIO17 then the drive strength will also be doubled for MYKGPIO16. + * + * If the particular bitfield for gpioDrv is set then the drive strength will be doubled. Note that multiple GPIOs can be set at a time. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is a pointer to the device settings structure + * \param gpioDrv GPIO drive strength setup, valid range is from 0x00000 to 0x7FFFF. + * + * \retval MYKONOS_ERR_GPIO_DRV_INV_PARAM GPIO out of range- valid GPIOs are in the range 0x00000 to 0x7FFFF. + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + */ +mykonosGpioErr_t MYKONOS_setGpioDrv(mykonosDevice_t *device, uint32_t gpioDrv) +{ + mykonosGpioErr_t error = MYKONOS_ERR_GPIO_OK; + uint8_t reg0 = 0x00; + uint8_t reg1 = 0x00; + + const uint32_t GPIO_MASK = 0x7FFFF; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setGpioDrv()\n"); +#endif + + /* Error checking for correct number of GPIOs. */ + if (gpioDrv > GPIO_MASK ) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_DRV_INV_PARAM, + getGpioMykonosErrorMessage(MYKONOS_ERR_GPIO_DRV_INV_PARAM)); + return MYKONOS_ERR_GPIO_DRV_INV_PARAM; + } + + CMB_SPIReadByte(device->spiSettings, MYKONOS_GPIO_DRV_CTL_0, ®0); + CMB_SPIReadByte(device->spiSettings, MYKONOS_GPIO_DRV_CTL_1, ®1); + + reg1 = reg1 & 0xC0; + + if (gpioDrv & 0xFF) + { + reg0 = (uint8_t)(gpioDrv & 0xFF); + } + else + { + reg0 = 0x00; + } + + if (gpioDrv & (uint32_t)MYKGPIO18) + { + reg1 |= 0x01; + } + + if ((gpioDrv & (uint32_t)MYKGPIO17) || (gpioDrv & (uint32_t)MYKGPIO16)) + { + reg1 |= 0x02; + } + + if ((gpioDrv & (uint32_t)MYKGPIO15) || (gpioDrv & (uint32_t)MYKGPIO8)) + { + reg1 |= 0x04; + } + + if ((gpioDrv & (uint32_t)MYKGPIO14) || (gpioDrv & (uint32_t)MYKGPIO13)) + { + reg1 |= 0x08; + } + + if ((gpioDrv & (uint32_t)MYKGPIO10) || (gpioDrv & (uint32_t)MYKGPIO9)) + { + reg1 |= 0x10; + } + + if ((gpioDrv & (uint32_t)MYKGPIO12) || (gpioDrv & (uint32_t)MYKGPIO11)) + { + reg1 |= 0x20; + } + + CMB_SPIWriteByte (device->spiSettings, MYKONOS_GPIO_DRV_CTL_0, reg0); + CMB_SPIWriteByte (device->spiSettings, MYKONOS_GPIO_DRV_CTL_1, reg1); + + return error; +} + + +/** + * \brief This function gets the GPIOs drive strength. + * + * This function will get the programmed drive strength for all the GPIOs + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is a pointer to the device settings structure. + * \param gpioDrv will contain the current GPIOs drive strength setting. + * + * \retval MYKONOS_ERR_GETGPIODRV_NULL_PARAM null parameter passed to the function. + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + */ +mykonosGpioErr_t MYKONOS_getGpioDrv(mykonosDevice_t *device, uint32_t *gpioDrv) +{ + mykonosGpioErr_t error = MYKONOS_ERR_GPIO_OK; + uint8_t reg0 = 0x00; + uint8_t reg1 = 0x00; + uint32_t gpioDrvRd = 0x00; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getGpioDrv()\n"); +#endif + + /* Error checking for correct number of GPIOs. */ + if (gpioDrv == NULL ) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETGPIODRV_NULL_PARAM, + getGpioMykonosErrorMessage(MYKONOS_ERR_GETGPIODRV_NULL_PARAM)); + return MYKONOS_ERR_GETGPIODRV_NULL_PARAM; + } + + CMB_SPIReadByte(device->spiSettings, MYKONOS_GPIO_DRV_CTL_0, ®0); + CMB_SPIReadByte(device->spiSettings, MYKONOS_GPIO_DRV_CTL_1, ®1); + + gpioDrvRd = (uint32_t)reg0 & 0xFF; + + if (reg1 & 0x01) + { + gpioDrvRd |= (uint32_t)MYKGPIO18; + } + + if (reg1 & 0x02) + { + gpioDrvRd |= (uint32_t)MYKGPIO17 | (uint32_t)MYKGPIO16; + } + + if (reg1 & 0x04) + { + gpioDrvRd |= (uint32_t)MYKGPIO8 | (uint32_t)MYKGPIO15; + } + + if (reg1 & 0x08) + { + gpioDrvRd |= (uint32_t)MYKGPIO14 | (uint32_t)MYKGPIO13; + } + + if (reg1 & 0x10) + { + gpioDrvRd |= (uint32_t)MYKGPIO10 | (uint32_t)MYKGPIO9; + } + + if (reg1 & 0x20) + { + gpioDrvRd |= (uint32_t)MYKGPIO12 | (uint32_t)MYKGPIO11; + } + + *gpioDrv = (mykonosGpioSelect_t)gpioDrvRd; + + return error; +} + +/** + * \brief This function sets the slew rate for the required GPIOs. + * + * This function will set the required slew rate, the settings for GPIO slew rate are given by the enumeration type mykonosGpioSlewRate_t. + * + * GPIO pins that can be assigned independent slew rate are: + * -MYKGPIO0 to MYKGPIO7 and MYKGPIO18 + * + * The rest of GPIOs are paired as: + * -MYKGPIO17 and MYKGPIO16 + * -MYKGPIO8 and MYKGPIO15 + * -MYKGPIO14 and MYKGPIO13 + * -MYKGPIO10 and MYKGPIO9 + * -MYKGPIO12 and MYKGPIO11 + * + * This means that if it is required to set the slew rate for MYKGPIO17 then the same slew rate will be applied for MYKGPIO16. + * + * If the particular bitfield for gpioSelect is set then slewRate will be set for that GPIO. Note that multiple GPIOs can be set at a time. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is a pointer to the device settings structure + * \param gpioSelect GPIO for which the slew rate will be changed, valid range 0x00000 to 0x7FFFF. + * \param slewRate slew rate setting, valid slew rate settings are given by the enumeration type mykonosGpioSlewRate_t + * + * \retval MYKONOS_ERR_GPIO_SLEW_RATE_INV_PARAM GPIO out of range- valid GPIOs are in the range 0x00000 to 0x7FFFF. + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + */ +mykonosGpioErr_t MYKONOS_setGpioSlewRate(mykonosDevice_t *device, mykonosGpioSelect_t gpioSelect, mykonosGpioSlewRate_t slewRate) +{ + mykonosGpioErr_t error = MYKONOS_ERR_GPIO_OK; + uint8_t reg0 = 0x00; + uint8_t reg1 = 0x00; + uint8_t reg2 = 0x00; + uint8_t reg3 = 0x00; + + const uint32_t GPIO_MASK = 0x7FFFF; + const uint8_t SLEWRATE_MASK = 0x03; + const uint32_t SHIFT4NIBLE = 0x06; + const uint32_t SHIFT3NIBLE = 0x04; + const uint32_t SHIFT2NIBLE = 0x02; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setGpioSlewRate()\n"); +#endif + + /* Error checking for correct number of GPIOs. */ + if (((uint32_t)gpioSelect > GPIO_MASK) || ((uint8_t)slewRate > SLEWRATE_MASK)) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_SLEW_RATE_INV_PARAM, + getGpioMykonosErrorMessage(MYKONOS_ERR_GPIO_SLEW_RATE_INV_PARAM)); + return MYKONOS_ERR_GPIO_SLEW_RATE_INV_PARAM; + } + + CMB_SPIReadByte(device->spiSettings, MYKONOS_GPIO_SLEW_CTL_0, ®0); + CMB_SPIReadByte(device->spiSettings, MYKONOS_GPIO_SLEW_CTL_1, ®1); + CMB_SPIReadByte(device->spiSettings, MYKONOS_GPIO_SLEW_CTL_2, ®2); + CMB_SPIReadByte(device->spiSettings, MYKONOS_GPIO_SLEW_CTL_3, ®3); + + if ((uint32_t)gpioSelect & (uint32_t)MYKGPIO18) + { + reg0 = (reg0 & ~(SLEWRATE_MASK << SHIFT4NIBLE)) | ((uint8_t)slewRate << SHIFT4NIBLE); + } + if (((uint32_t)gpioSelect & (uint32_t)MYKGPIO17) || ((uint32_t)gpioSelect & (uint32_t)MYKGPIO16)) + { + reg0 = (reg0 & ~(SLEWRATE_MASK << SHIFT3NIBLE)) | ((uint8_t)slewRate << SHIFT3NIBLE); + } + if (((uint32_t)gpioSelect & (uint32_t)MYKGPIO15) || ((uint32_t)gpioSelect & (uint32_t)MYKGPIO8)) + { + reg0 = (reg0 & ~(SLEWRATE_MASK << SHIFT2NIBLE)) | ((uint8_t)slewRate << SHIFT2NIBLE); + } + if (((uint32_t)gpioSelect & (uint32_t)MYKGPIO14) || ((uint32_t)gpioSelect & (uint32_t)MYKGPIO13)) + { + reg0 = (reg0 & ~(SLEWRATE_MASK)) | (uint8_t)slewRate; + } + if (((uint32_t)gpioSelect & (uint32_t)MYKGPIO11) || ((uint32_t)gpioSelect & (uint32_t)MYKGPIO12)) + { + reg1 = (reg1 & ~(SLEWRATE_MASK << SHIFT4NIBLE)) | ((uint8_t)slewRate << SHIFT4NIBLE); + } + if (((uint32_t)gpioSelect & (uint32_t)MYKGPIO9) || ((uint32_t)gpioSelect & (uint32_t)MYKGPIO10)) + { + reg1 = (reg1 & ~(SLEWRATE_MASK << SHIFT3NIBLE)) | ((uint8_t)slewRate << SHIFT3NIBLE); + } + if ((uint32_t)gpioSelect & (uint32_t)MYKGPIO7) + { + reg1 = (reg1 & ~(SLEWRATE_MASK << SHIFT2NIBLE)) | ((uint8_t)slewRate << SHIFT2NIBLE); + } + if ((uint32_t)gpioSelect & (uint32_t)MYKGPIO6) + { + reg1 = (reg1 & ~(SLEWRATE_MASK)) | (uint8_t)slewRate; + } + if ((uint32_t)gpioSelect & (uint32_t)MYKGPIO5) + { + reg2 = (reg2 & ~(SLEWRATE_MASK << SHIFT4NIBLE)) | ((uint8_t)slewRate << SHIFT4NIBLE); + } + if ((uint32_t)gpioSelect & (uint32_t)MYKGPIO4) + { + reg2 = (reg2 & ~(SLEWRATE_MASK << SHIFT3NIBLE)) | ((uint8_t)slewRate << SHIFT3NIBLE); + } + if ((uint32_t)gpioSelect & (uint32_t)MYKGPIO3) + { + reg2 = (reg2 & ~(SLEWRATE_MASK << SHIFT2NIBLE)) | ((uint8_t)slewRate << SHIFT2NIBLE); + } + if ((uint32_t)gpioSelect & (uint32_t)MYKGPIO2) + { + reg2 = (reg2 & ~(SLEWRATE_MASK)) | (uint8_t)slewRate; + } + if ((uint32_t)gpioSelect & (uint32_t)MYKGPIO1) + { + reg3 = (reg3 & ~(SLEWRATE_MASK << SHIFT2NIBLE)) | ((uint8_t)slewRate << SHIFT2NIBLE); + } + if ((uint32_t)gpioSelect & (uint32_t)MYKGPIO0) + { + reg3 = (reg3 & ~(SLEWRATE_MASK)) | (uint8_t)slewRate; + } + + /* Prepare registers */ + CMB_SPIWriteByte (device->spiSettings, MYKONOS_GPIO_SLEW_CTL_0, reg0); + CMB_SPIWriteByte (device->spiSettings, MYKONOS_GPIO_SLEW_CTL_1, reg1); + CMB_SPIWriteByte (device->spiSettings, MYKONOS_GPIO_SLEW_CTL_2, reg2); + CMB_SPIWriteByte (device->spiSettings, MYKONOS_GPIO_SLEW_CTL_3, reg3); + + return error; +} + + +/** + * \brief This function gets the GPIO slew rate setting. + * + * This function will get the programmed slew rate for the GPIO given by slewRateGpio. + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is a pointer to the device settings structure. + * \param gpioSelect GPIO selection for getting the slew rate setting. + * \param slewRate will contain the GPIO slew rate setting. + * + * \retval MYKONOS_ERR_GPIO_GETSLEW_NULL_PARAM null parameter passed to the function. + * \retval MYKONOS_ERR_GPIO_SLEW_RATE_INV_PARAM GPIO out of range- valid GPIOs are in the range 0x00000 to 0x7FFFF. + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + */ +mykonosGpioErr_t MYKONOS_getGpioSlewRate(mykonosDevice_t *device, mykonosGpioSelect_t gpioSelect, mykonosGpioSlewRate_t *slewRate) +{ + uint8_t reg0 = 0x00; + uint8_t reg1 = 0x00; + uint8_t reg2 = 0x00; + uint8_t reg3 = 0x00; + mykonosGpioSlewRate_t slewSetting = MYK_SLEWRATE_NONE; + + const uint32_t SLEWRATE_MASK = 0x03; + const uint32_t SHIFT4NIBLE = 0x06; + const uint32_t SHIFT3NIBLE = 0x04; + const uint32_t SHIFT2NIBLE = 0x02; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getGpioSlewRate()\n"); +#endif + + /* Error checking for NULL parameter. */ + if (slewRate == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_GETSLEW_NULL_PARAM, + getGpioMykonosErrorMessage(MYKONOS_ERR_GPIO_GETSLEW_NULL_PARAM)); + return MYKONOS_ERR_GPIO_GETSLEW_NULL_PARAM; + } + + CMB_SPIReadByte(device->spiSettings, MYKONOS_GPIO_SLEW_CTL_0, ®0); + CMB_SPIReadByte(device->spiSettings, MYKONOS_GPIO_SLEW_CTL_1, ®1); + CMB_SPIReadByte(device->spiSettings, MYKONOS_GPIO_SLEW_CTL_2, ®2); + CMB_SPIReadByte(device->spiSettings, MYKONOS_GPIO_SLEW_CTL_3, ®3); + + switch (gpioSelect) + { + case MYKGPIO18: + slewSetting = (mykonosGpioSlewRate_t)((reg0 & (SLEWRATE_MASK << SHIFT4NIBLE)) >> SHIFT4NIBLE); + break; + case MYKGPIO17: + case MYKGPIO16: + slewSetting = (mykonosGpioSlewRate_t)((reg0 & (SLEWRATE_MASK << SHIFT3NIBLE)) >> SHIFT3NIBLE); + break; + case MYKGPIO15: + case MYKGPIO8: + slewSetting = (mykonosGpioSlewRate_t)((reg0 & (SLEWRATE_MASK << SHIFT2NIBLE)) >> SHIFT2NIBLE); + break; + case MYKGPIO14: + case MYKGPIO13: + slewSetting = (mykonosGpioSlewRate_t)(reg0 & (SLEWRATE_MASK)); + break; + case MYKGPIO11: + case MYKGPIO12: + slewSetting = (mykonosGpioSlewRate_t)((reg1 & (SLEWRATE_MASK << SHIFT4NIBLE)) >> SHIFT4NIBLE); + break; + case MYKGPIO9: + case MYKGPIO10: + slewSetting = (mykonosGpioSlewRate_t)((reg1 & (SLEWRATE_MASK << SHIFT3NIBLE)) >> SHIFT3NIBLE); + break; + case MYKGPIO7: + slewSetting = (mykonosGpioSlewRate_t)((reg1 & (SLEWRATE_MASK << SHIFT2NIBLE)) >> SHIFT2NIBLE); + break; + case MYKGPIO6: + slewSetting = (mykonosGpioSlewRate_t)(reg1 & (SLEWRATE_MASK)); + break; + case MYKGPIO5: + slewSetting = (mykonosGpioSlewRate_t)((reg2 & (SLEWRATE_MASK << SHIFT4NIBLE)) >> SHIFT4NIBLE); + break; + case MYKGPIO4: + slewSetting = (mykonosGpioSlewRate_t)((reg2 & (SLEWRATE_MASK << SHIFT3NIBLE)) >> SHIFT3NIBLE); + break; + case MYKGPIO3: + slewSetting = (mykonosGpioSlewRate_t)((reg2 & (SLEWRATE_MASK << SHIFT2NIBLE)) >> SHIFT2NIBLE); + break; + case MYKGPIO2: + slewSetting = (mykonosGpioSlewRate_t)(reg2 & (SLEWRATE_MASK)); + break; + case MYKGPIO1: + slewSetting = (mykonosGpioSlewRate_t)((reg3 & (SLEWRATE_MASK << SHIFT2NIBLE)) >> SHIFT2NIBLE); + break; + case MYKGPIO0: + slewSetting = (mykonosGpioSlewRate_t)(reg3 & (SLEWRATE_MASK)); + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_SLEW_RATE_INV_PARAM, + getGpioMykonosErrorMessage(MYKONOS_ERR_GPIO_SLEW_RATE_INV_PARAM)); + return MYKONOS_ERR_GPIO_SLEW_RATE_INV_PARAM; + } + + *slewRate = slewSetting; + + return MYKONOS_ERR_GPIO_OK; +} + + +/** + * \brief This function sets the CMOS output driver. + * + * This function sets the CMOS output driver to increase pad drive strength for the SPI_DIO and GP_INTERRUPT pads + * according to the following settings of the enumeration type mykonosCmosPadDrvStr_t + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is a pointer to the device settings structure + * \param cmosDrv drive for the CMOS output driver + * + * \retval MYKONOS_ERR_CMOS_DRV_INV_PARAM invalid drive strength, valid settings are given by mykonosCmosPadDrvStr_t + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + */ +mykonosGpioErr_t MYKONOS_setCmosDrv(mykonosDevice_t *device, mykonosCmosPadDrvStr_t cmosDrv) +{ + const uint8_t CMOS_DRV_MASK = 0x0F; + const uint8_t CMOS_DRV_SHIFT = 0x04; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setCmosDrv()\n"); +#endif + + /* Error checking for correct drive */ + switch (cmosDrv) + { /* fall through since this is only checking */ + case MYK_CMOSPAD_DRV_1X: + case MYK_CMOSPAD_DRV_2X: + case MYK_CMOSPAD_DRV_3X: + case MYK_CMOSPAD_DRV_4X: + case MYK_CMOSPAD_DRV_5X: + break; + default: + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CMOS_DRV_INV_PARAM, + getGpioMykonosErrorMessage(MYKONOS_ERR_CMOS_DRV_INV_PARAM)); + return MYKONOS_ERR_CMOS_DRV_INV_PARAM; + } + + CMB_SPIWriteField(device->spiSettings, MYKONOS_GPIO_SLEW_CTL_3, cmosDrv, (~CMOS_DRV_MASK), CMOS_DRV_SHIFT); + + return MYKONOS_ERR_GPIO_OK; +} + +/** + * \brief This function gets the programmed CMOS output driver + * + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is a pointer to the device settings structure + * \param cmosDrv will be the programmed drive for the CMOS output driver + * + * \retval MYKONOS_ERR_CMOS_DRV_NULL_PARAM Null parameter passed to the function + * \retval MYKONOS_ERR_GPIO_OK Function completed successfully + */ +mykonosGpioErr_t MYKONOS_getCmosDrv(mykonosDevice_t *device, mykonosCmosPadDrvStr_t *cmosDrv) +{ + uint8_t regRd = 0x00; + + const uint8_t CMOS_DRV_MASK = 0xF0; + const uint8_t CMOS_DRV_SHIFT = 0x04; + +#if MYKONOS_VERBOSE == 1 + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getCmosDrv()\n"); +#endif + + if (cmosDrv == NULL) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CMOS_DRV_NULL_PARAM, + getGpioMykonosErrorMessage(MYKONOS_ERR_CMOS_DRV_NULL_PARAM)); + return MYKONOS_ERR_CMOS_DRV_NULL_PARAM; + } + + CMB_SPIReadByte(device->spiSettings, MYKONOS_GPIO_SLEW_CTL_3, ®Rd); + + *cmosDrv = (mykonosCmosPadDrvStr_t)((regRd & CMOS_DRV_MASK) >> CMOS_DRV_SHIFT); + + return MYKONOS_ERR_GPIO_OK; +} + +/** +* \brief This API function configures and enables the secondary SPI port. +* +* This port allows control compatibility with BBPs that employ dual SPI ports. +* The GPIO mapping for the SPI2 is fixed: +* SPI signal | GPIO +* -------------|------------------- +* CSB_2 | GPIO 3 +* SCLK_2 | GPIO 2 +* SDO_2 | GPIO 1 +* SDO_2/SDI2 | GPIO 0 +* +* The secondary SPI port only has a small subset of registers that affect the +* attenuation of the TX channels. It uses a fifth GPIO pin in order to decide +* which TxAttenuation word is active. The Tx Attenuation words in the 2nd SPI +* port are different than the first SPI port. On the 2nd SPI port, each +* transmitter has two Tx Attenuation words (an active word and an inactive +* word). The BBIC should write to the inactive TxAttenuation word. Then the +* fifth GPIO pin should be asserted to make the inactive TxAttenuation word +* active. This allows the BBIC to tightly control in real time when the +* TxAttenuation updates. +* +* Dependencies +* - device->spiSettings +* - device->spiSettings->chipSelectIndex +* +* \param device is a pointer to the device settings structure +* \param enable This is parameter will enable the secondary SPI port: 1 = enable, 0 = disable +* \param updateTxAttenPinSelect This parameter set the GPIO pin to be toggle for using the inactive attenuation words for both channels +* tx update | GPIO +* ------------|------------------- +* 0x00 | GPIO 4 +* 0x01 | GPIO 8 +* 0x02 | GPIO 14 +* 0x03 | none selected +* +* \retval MYKONOS_ERR_SPI2_INV_GPIO if an invalid GPIO pin configuration is passed +* \retval MYKONOS_ERR_HAL_LAYER if HAL function error is passed +* \retval MYKONOS_ERR_OK Function completed successfully +*/ +mykonosGpioErr_t MYKONOS_spi2GpioSetup(mykonosDevice_t *device, uint8_t enable, uint8_t updateTxAttenPinSelect) +{ + uint8_t regWrite = 0; + uint8_t enableBit = 0; + + const uint32_t SPI2_PIN_MASK = 0x03; + +#ifdef MYKONOS_VERBOSE + CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_spi2GpioSetup()\n"); +#endif + + /* Error checking for correctness of GPIO to control attenuation word. */ + if (updateTxAttenPinSelect & ~SPI2_PIN_MASK) + { + CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SPI2_INV_GPIO, + getGpioMykonosErrorMessage(MYKONOS_ERR_SPI2_INV_GPIO)); + return MYKONOS_ERR_SPI2_INV_GPIO; + } + + /* masking the enable bit and the required pin */ + enableBit = (enable > 0) ? 1 : 0; + regWrite = (uint8_t)((updateTxAttenPinSelect << 4) | (enableBit << 3)); + + /* Set the SPI2 enable and the GPIO pin associated. */ + CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_CONFIGURATION_CONTROL_1, regWrite, 0x38, 0); + + return MYKONOS_ERR_GPIO_OK; +} + diff --git a/df_datalink_ge/src/hardware/mykonos/mykonos_gpio.h b/df_datalink_ge/src/hardware/mykonos/mykonos_gpio.h new file mode 100644 index 0000000..f69ec74 --- /dev/null +++ b/df_datalink_ge/src/hardware/mykonos/mykonos_gpio.h @@ -0,0 +1,172 @@ +/*! + * \file mykonos_gpio.h + * \brief Contains macro definitions and function prototypes for mykonos_gpio.c + * + * Mykonos API version: 1.5.2.3566 + */ + +/** +* \page Disclaimer Legal Disclaimer +* Copyright 2015-2017 Analog Devices Inc. +* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file. +* +*/ + +#ifndef MYKONOSGPIO_H_ +#define MYKONOSGPIO_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "t_mykonos.h" +#include "t_mykonos_gpio.h" + +/* + ***************************************************************************** + * GPIO functions + ***************************************************************************** + */ + +/* GPIO CMOS and SPI setting Functions */ +mykonosGpioErr_t MYKONOS_setGpioDrv(mykonosDevice_t *device, uint32_t gpioDrv); +mykonosGpioErr_t MYKONOS_getGpioDrv(mykonosDevice_t *device, uint32_t *gpioDrv); + +mykonosGpioErr_t MYKONOS_setGpioSlewRate(mykonosDevice_t *device, mykonosGpioSelect_t gpioSelect, mykonosGpioSlewRate_t slewRate); +mykonosGpioErr_t MYKONOS_getGpioSlewRate(mykonosDevice_t *device, mykonosGpioSelect_t gpioSelect, mykonosGpioSlewRate_t *slewRate); + +mykonosGpioErr_t MYKONOS_setCmosDrv(mykonosDevice_t *device, mykonosCmosPadDrvStr_t spiDrv); +mykonosGpioErr_t MYKONOS_getCmosDrv(mykonosDevice_t *device, mykonosCmosPadDrvStr_t *spiDrv); + + +/* Monitor output Functions */ +mykonosGpioErr_t MYKONOS_setGpioMonitorOut(mykonosDevice_t *device, uint8_t monitorIndex, uint8_t monitorMask); +mykonosGpioErr_t MYKONOS_getGpioMonitorOut(mykonosDevice_t *device, uint8_t *monitorIndex, uint8_t *monitorMask); + +/* RX GPIO Functions */ +mykonosGpioErr_t MYKONOS_setRx1GainCtrlPin(mykonosDevice_t *device, uint8_t incStep, uint8_t decStep, mykonosGpioSelect_t rx1GainIncPin, mykonosGpioSelect_t rx1GainDecPin, uint8_t enable); +mykonosGpioErr_t MYKONOS_setRx2GainCtrlPin(mykonosDevice_t *device, uint8_t incStep, uint8_t decStep, mykonosGpioSelect_t rx2GainIncPin, mykonosGpioSelect_t rx2GainDecPin, uint8_t enable); +mykonosGpioErr_t MYKONOS_getRx1GainCtrlPin(mykonosDevice_t *device, uint8_t *incStep, uint8_t *decStep, mykonosGpioSelect_t *rx1GainIncPin, mykonosGpioSelect_t *rx1GainDecPin, uint8_t *enable); +mykonosGpioErr_t MYKONOS_getRx2GainCtrlPin(mykonosDevice_t *device, uint8_t *incStep, uint8_t *decStep, mykonosGpioSelect_t *rx2GainIncPin, mykonosGpioSelect_t *rx2GainDecPin, uint8_t *enable); + +mykonosGpioErr_t MYKONOS_setRxHybridGainChangePin(mykonosDevice_t *device, mykonosGpioSelect_t rx1GainChangePin, mykonosGpioSelect_t rx2GainChangePin); +mykonosGpioErr_t MYKONOS_getRxHybridGainChangePin(mykonosDevice_t *device, mykonosGpioSelect_t *rx1GainChangePin, mykonosGpioSelect_t *rx2GainChangePin); +mykonosGpioErr_t MYKONOS_setObsRxHybridGainChangePin(mykonosDevice_t *device, mykonosGpioSelect_t obsRxGainChangePin); +mykonosGpioErr_t MYKONOS_getObsRxHybridGainChangePin(mykonosDevice_t *device, mykonosGpioSelect_t *obsRxGainChangePin); + +mykonosGpioErr_t MYKONOS_setRxAgcEnSyncPin(mykonosDevice_t *device, mykonosGpioSelect_t rx1AgcSyncPin, mykonosGpioSelect_t rx2AgcSyncPin); +mykonosGpioErr_t MYKONOS_getRxAgcEnSyncPin(mykonosDevice_t *device, mykonosGpioSelect_t *rx1AgcSyncPin, mykonosGpioSelect_t *rx2AgcSyncPin); +mykonosGpioErr_t MYKONOS_setObsRxAgcEnSyncPin(mykonosDevice_t *device, mykonosGpioSelect_t obsRxAgcSyncPin); +mykonosGpioErr_t MYKONOS_getObsRxAgcEnSyncPin(mykonosDevice_t *device, mykonosGpioSelect_t *obsRxAgcSyncPin); + +/* TX GPIO Functions */ +mykonosGpioErr_t MYKONOS_setTx1AttenCtrlPin(mykonosDevice_t *device, uint8_t stepSize, mykonosGpioSelect_t tx1AttenIncPin, mykonosGpioSelect_t tx1AttenDecPin, uint8_t enable, uint8_t useTx1ForTx2); +mykonosGpioErr_t MYKONOS_setTx2AttenCtrlPin(mykonosDevice_t *device, uint8_t stepSize, mykonosGpioSelect_t tx2AttenIncPin, mykonosGpioSelect_t tx2AttenDecPin, uint8_t enable); +mykonosGpioErr_t MYKONOS_getTx1AttenCtrlPin(mykonosDevice_t *device, uint8_t *stepSize, mykonosGpioSelect_t *tx1AttenIncPin, mykonosGpioSelect_t *tx1AttenDecPin, uint8_t *enable, uint8_t *useTx1ForTx2); +mykonosGpioErr_t MYKONOS_getTx2AttenCtrlPin(mykonosDevice_t *device, uint8_t *stepSize, mykonosGpioSelect_t *tx2AttenIncPin, mykonosGpioSelect_t *tx2AttenDecPin, uint8_t *enable, uint8_t *useTx1ForTx2); + +mykonosGpioErr_t MYKONOS_spi2GpioSetup(mykonosDevice_t *device, uint8_t enable, uint8_t updateTxAttenPinSelect); + +/* GPIO memory source Functions */ +mykonosGpioErr_t MYKONOS_setGpioPinLevel(mykonosDevice_t *device, uint32_t gpioPinLevel); +mykonosGpioErr_t MYKONOS_getGpioPinLevel(mykonosDevice_t *device, uint32_t *gpioPinLevel); +mykonosGpioErr_t MYKONOS_getGpioSetLevel(mykonosDevice_t *device, uint32_t *gpioPinSetLevel); + +/* Gain Compensation Functions */ +mykonosGpioErr_t MYKONOS_setRxGainCompensation (mykonosDevice_t *device, mykonosGainComp_t *gainComp, uint8_t enable); +mykonosGpioErr_t MYKONOS_getRxGainCompensation (mykonosDevice_t *device, mykonosGainComp_t *gainComp, uint8_t *enabled); + +mykonosGpioErr_t MYKONOS_setObsRxGainCompensation (mykonosDevice_t *device, mykonosObsRxGainComp_t *gainComp, uint8_t enable); +mykonosGpioErr_t MYKONOS_getObsRxGainCompensation (mykonosDevice_t *device, mykonosObsRxGainComp_t *gainComp, uint8_t *enabled); + +/* SLICER Functions */ +mykonosGpioErr_t MYKONOS_setRxSlicerCtrl(mykonosDevice_t *device, uint8_t slicerStep, mykonosRxSlicer_t rx1Pins, mykonosRxSlicer_t rx2Pins, uint8_t enable); +mykonosGpioErr_t MYKONOS_getRxSlicerCtrl(mykonosDevice_t *device, uint8_t *slicerStep, mykonosRxSlicer_t *rx1Pins, mykonosRxSlicer_t *rx2Pins, uint8_t *enable); + +mykonosGpioErr_t MYKONOS_setObsRxSlicerCtrl(mykonosDevice_t *device, uint8_t slicerStep, mykonosObsRxSlicer_t obsRxPins, uint8_t enable); +mykonosGpioErr_t MYKONOS_getObsRxSlicerCtrl(mykonosDevice_t *device, uint8_t *slicerStep, mykonosObsRxSlicer_t *obsRxPins, uint8_t *enable); + +/* Floating Point Formatter Functions */ +mykonosGpioErr_t MYKONOS_setFloatPointFrmt (mykonosDevice_t *device, mykonosFloatPntFrmt_t *floatFrmt); +mykonosGpioErr_t MYKONOS_getFloatPointFrmt (mykonosDevice_t *device, mykonosFloatPntFrmt_t *floatFrmt); + +mykonosGpioErr_t MYKONOS_setRxEnFloatPntFrmt (mykonosDevice_t *device, uint8_t rx1Att, uint8_t rx2Att, uint8_t enable); +mykonosGpioErr_t MYKONOS_getRxEnFloatPntFrmt (mykonosDevice_t *device, uint8_t *rx1Att, uint8_t *rx2Att, uint8_t *enable); + +mykonosGpioErr_t MYKONOS_setOrxEnFloatPntFrmt (mykonosDevice_t *device, uint8_t orxAtt, uint8_t enable); +mykonosGpioErr_t MYKONOS_getOrxEnFloatPntFrmt (mykonosDevice_t *device, uint8_t *orxAtt, uint8_t *enable); + +/* + ***************************************************************************** + * General Purpose Interrupt functions + ***************************************************************************** + */ +mykonosGpioErr_t MYKONOS_configGpInterrupt(mykonosDevice_t *device, uint16_t gpMask); +mykonosGpioErr_t MYKONOS_readGpInterruptStatus(mykonosDevice_t *device, uint16_t *status); + +/* + ***************************************************************************** + * ARM GPIO usage functions + ***************************************************************************** + */ +mykonosGpioErr_t MYKONOS_setArmGpioPins(mykonosDevice_t *device); + +/* + ***************************************************************************** + * AuxADC/AuxDAC functions + ***************************************************************************** + */ +mykonosGpioErr_t MYKONOS_setupAuxAdcs(mykonosDevice_t *device, uint8_t adcDecimation, uint8_t enable); +mykonosGpioErr_t MYKONOS_setAuxAdcChannel(mykonosDevice_t *device, mykonosAuxAdcChannels_t auxAdcChannel); +mykonosGpioErr_t MYKONOS_readAuxAdc(mykonosDevice_t *device, uint16_t *adcCode); +mykonosGpioErr_t MYKONOS_setupAuxDacs(mykonosDevice_t *device); +mykonosGpioErr_t MYKONOS_writeAuxDac(mykonosDevice_t *device, uint8_t auxDacIndex, uint16_t auxDacCode); + +/* + ***************************************************************************** + * GPIO3v3 functions + ***************************************************************************** + */ +mykonosGpioErr_t MYKONOS_setupGpio3v3(mykonosDevice_t *device); + +mykonosGpioErr_t MYKONOS_setGpio3v3PinLevel(mykonosDevice_t *device, uint16_t gpio3v3PinLevel); +mykonosGpioErr_t MYKONOS_getGpio3v3SetLevel(mykonosDevice_t *device, uint16_t *gpio3v3SetLevel); + +mykonosGpioErr_t MYKONOS_getGpio3v3PinLevel(mykonosDevice_t *device, uint16_t *gpio3v3PinLevel); + +mykonosGpioErr_t MYKONOS_setGpio3v3Oe(mykonosDevice_t *device, uint16_t gpio3v3OutEn); +mykonosGpioErr_t MYKONOS_getGpio3v3Oe(mykonosDevice_t *device, uint16_t *gpio3v3OutEn); + +mykonosGpioErr_t MYKONOS_setGpio3v3SourceCtrl(mykonosDevice_t *device, uint16_t gpio3v3SrcCtrl); +mykonosGpioErr_t MYKONOS_getGpio3v3SourceCtrl(mykonosDevice_t *device, uint16_t *gpio3v3SrcCtrl); + +/* + ***************************************************************************** + * GPIO helper functions + ***************************************************************************** + */ +mykonosGpioErr_t MYKONOS_setupGpio(mykonosDevice_t *device); +mykonosGpioErr_t MYKONOS_setGpioOe(mykonosDevice_t *device, uint32_t gpioOutEn, uint32_t gpioUsedMask); +mykonosGpioErr_t MYKONOS_getGpioOe(mykonosDevice_t *device, uint32_t *gpioOutEn); + +mykonosGpioErr_t MYKONOS_setGpioSourceCtrl(mykonosDevice_t *device, uint32_t gpioSrcCtrl); +mykonosGpioErr_t MYKONOS_getGpioSourceCtrl(mykonosDevice_t *device, uint32_t *gpioSrcCtrl); + +/* + ***************************************************************************** + * Temperature Sensor functions + ***************************************************************************** + */ +mykonosGpioErr_t MYKONOS_setupTempSensor(mykonosDevice_t *device, mykonosTempSensorConfig_t *tempSensor); +mykonosGpioErr_t MYKONOS_getTempSensorConfig(mykonosDevice_t *device, mykonosTempSensorConfig_t *tempSensor); + +mykonosGpioErr_t MYKONOS_startTempMeasurement(mykonosDevice_t *device); +mykonosGpioErr_t MYKONOS_readTempSensor(mykonosDevice_t *device, mykonosTempSensorStatus_t *tempStatus); + +const char* getGpioMykonosErrorMessage(mykonosGpioErr_t errorCode); + +#ifdef __cplusplus +} +#endif + +#endif /* MYKONOSGPIO_H_ */ diff --git a/df_datalink_ge/src/hardware/mykonos/mykonos_macros.h b/df_datalink_ge/src/hardware/mykonos/mykonos_macros.h new file mode 100644 index 0000000..354f561 --- /dev/null +++ b/df_datalink_ge/src/hardware/mykonos/mykonos_macros.h @@ -0,0 +1,707 @@ +/** + * \file mykonos_macros.h + * \brief Contains address and miscellaneous macro definitions for Mykonos API + * + * Mykonos API version: 1.5.2.3566 + */ + +/** +* \page Disclaimer Legal Disclaimer +* Copyright 2015-2017 Analog Devices Inc. +* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file. +* +*/ + +#ifndef CLEMENTE_TDD_MACROS_H +#define CLEMENTE_TDD_MACROS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define MYKONOS_ADDR_CONFIGURATION_CONTROL_0 0x000 +#define MYKONOS_ADDR_SPI_CONFIGURATION_CONTROL_1 0x001 +#define MYKONOS_ADDR_PRODUCT_ID 0x004 +#define MYKONOS_GPIO_DRV_CTL_0 0x020 +#define MYKONOS_GPIO_DRV_CTL_1 0x021 +#define MYKONOS_GPIO_SLEW_CTL_0 0x022 +#define MYKONOS_GPIO_SLEW_CTL_1 0x023 +#define MYKONOS_GPIO_SLEW_CTL_2 0x024 +#define MYKONOS_GPIO_SLEW_CTL_3 0x025 + +#define MYKONOS_ADDR_DIGITAL_IO_CONTROL 0x028 + +#define MYKONOS_ADDR_SYSREF_PAD_CONFIG 0x040 +#define MYKONOS_ADDR_TX1_SYNC_PAD_CONFIG 0x041 +#define MYKONOS_ADDR_TX2_SYNC_PAD_CONFIG 0x042 +#define MYKONOS_ADDR_RX1_SYNC_CONFIG 0x043 +#define MYKONOS_ADDR_RX2_SYNC_CONFIG 0x044 + +/* Mykonos Framer Registers */ +#define MYKONOS_ADDR_FRAMER_RESET 0x059 +#define MYKONOS_ADDR_FRAMER_CLK_EN 0x05A +#define MYKONOS_ADDR_FRAMER_ADDR 0x05B +#define MYKONOS_ADDR_FRAMER_DATA 0x05C +#define MYKONOS_ADDR_FRAMER_WRITE_EN 0x05D +#define MYKONOS_ADDR_FRAMER_SYSREF_FIFO_EN 0x05E +#define MYKONOS_ADDR_FRAMER_CONFIG_F 0x05F +#define MYKONOS_ADDR_FRAMER_LANE_CTL 0x060 +#define MYKONOS_ADDR_FRAMER_ADC_XBAR_SEL 0x061 +#define MYKONOS_ADDR_FRAMER_LANE_XBAR_SEL 0x062 +#define MYKONOS_ADDR_FRAMER_CONFIG_LOOPBACK_XBAR_REV 0x063 +#define MYKONOS_ADDR_FRAMER_SYNCN_FILT 0x064 +#define MYKONOS_ADDR_FRAMER_LMFC_F_OFFSET 0x065 +#define MYKONOS_ADDR_FRAMER_LMFC_K_OFFSET 0x066 +#define MYKONOS_ADDR_FRAMER_TEST_CNTR_CTL 0x067 +#define MYKONOS_ADDR_FRAMER_STATUS_STRB 0x068 +#define MYKONOS_ADDR_FRAMER_STATUS 0x069 +#define MYKONOS_ADDR_FRAMER_SYSREF_TO_LMFC_CNTR_STAT 0x06A +#define MYKONOS_ADDR_FRAMER_SYSREF_TO_LMFC_ERR_MARGIN 0x06B +#define MYKONOS_ADDR_FRAMER_LANE_FIFO_STRB 0x06C +#define MYKONOS_ADDR_FRAMER_LANE0_FIFO_RDWR_ADDR 0x06D +#define MYKONOS_ADDR_FRAMER_LANE1_FIFO_RDWR_ADDR 0x06E +#define MYKONOS_ADDR_FRAMER_LANE2_FIFO_RDWR_ADDR 0x06F +#define MYKONOS_ADDR_FRAMER_LANE3_FIFO_RDWR_ADDR 0x070 +#define MYKONOS_ADDR_FRAMER_PRBS10_CTL 0x071 +#define MYKONOS_ADDR_FRAMER_PRBS20_CTL 0x072 +#define MYKONOS_ADDR_FRAMER_PATTERN_GEN_EN 0x073 +#define MYKONOS_ADDR_FRAMER_PATTERN_GEN_7_TO_0 0x074 +#define MYKONOS_ADDR_FRAMER_PATTERN_GEN_15_TO_8 0x075 +#define MYKONOS_ADDR_FRAMER_PATTERN_GEN_19_TO_16 0x076 +#define MYKONOS_ADDR_FRAMER_CONFIG_JTX_GEN 0x077 +#define MYKONOS_ADDR_FRAMER_LANE_DATA_CTL 0x078 +#define MYKONOS_ADDR_FRAMER_DATA_SAMPLE_CTL 0x079 + +/* Mykonos Deframer Sub Address Map */ +#define MYKONOS_SUBADDR_DEFRAMER_LANE0_ILAS_RECVD 0x00 +#define MYKONOS_SUBADDR_DEFRAMER_LANE0_ILAS_CFG 0x50 + +/* Mykonos Deframer Registers */ +#define MYKONOS_ADDR_DEFRAMER_RESET 0x07A +#define MYKONOS_ADDR_DEFRAMER_CLK_EN 0x07B +#define MYKONOS_ADDR_DEFRAMER_ADDR 0x07C +#define MYKONOS_ADDR_DEFRAMER_DATA 0x07D +#define MYKONOS_ADDR_DEFRAMER_WR_EN 0x07E +#define MYKONOS_ADDR_DEFRAMER_SYSREF_FIFO_EN 0x07F +#define MYKONOS_ADDR_DEFRAMER_CONFIG_F 0x080 +#define MYKONOS_ADDR_DEFRAMER_LANE_FIFO_CTL 0x081 +#define MYKONOS_ADDR_DEFRAMER_DAC_XBAR_SEL 0x082 +#define MYKONOS_ADDR_DEFRAMER_LANE_XBAR_SEL 0x083 +#define MYKONOS_ADDR_DEFRAMER_LMFC_F_OFFSET 0x084 +#define MYKONOS_ADDR_DEFRAMER_LMFC_K_OFFSET 0x085 +#define MYKONOS_ADDR_DEFRAMER_CONFIG_SYNC_USER_DATA_CTL 0x086 +#define MYKONOS_ADDR_DEFRAMER_SYNC_REQ_RETIME 0x087 +#define MYKONOS_ADDR_DEFRAMER_TEST 0x088 +#define MYKONOS_ADDR_DEFRAMER_DET_FIFO_WR_STRT_DAC_XBAR_REV 0x089 +#define MYKONOS_ADDR_DEFRAMER_STAT_STRB 0x08A +#define MYKONOS_ADDR_DEFRAMER_STAT 0x08B +#define MYKONOS_ADDR_DEFRAMER_TEST_ERR_CNT_STAT 0x08C +#define MYKONOS_ADDR_DEFRAMER_DET_FIFO_RD_ADDR 0x08D +#define MYKONOS_ADDR_DEFRAMER_DET_FIFO_WR_ADDR 0x08E +#define MYKONOS_ADDR_DEFRAMER_QBLMFC_VS_EXTLMFC_CNTR_STAT 0x08F +#define MYKONOS_ADDR_DEFRAMER_DET_FIFO_STAT 0x090 +#define MYKONOS_ADDR_DEFRAMER_STRT_RD_DEL_STOP_WR 0x091 +#define MYKONOS_ADDR_DEFRAMER_FIFO_SAMPLE_SPI_ADDR_RD 0x092 +#define MYKONOS_ADDR_DEFRAMER_FIFO_BYTE_SPI_ADDR_RD 0x093 +#define MYKONOS_ADDR_DEFRAMER_FIFO_BYTE_SPI_DATA_RD 0x094 +#define MYKONOS_ADDR_DEFRAMER_SAMPLE0_7_TO_0 0x095 +#define MYKONOS_ADDR_DEFRAMER_SAMPLE0_15_TO_8 0x096 +#define MYKONOS_ADDR_DEFRAMER_SAMPLE1_7_TO_0 0x097 +#define MYKONOS_ADDR_DEFRAMER_SAMPLE1_15_TO_8 0x098 +#define MYKONOS_ADDR_DEFRAMER_SAMPLE2_7_TO_0 0x099 +#define MYKONOS_ADDR_DEFRAMER_SAMPLE2_15_TO_8 0x09A +#define MYKONOS_ADDR_DEFRAMER_SAMPLE3_7_TO_0 0x09B +#define MYKONOS_ADDR_DEFRAMER_SAMPLE3_15_TO_8 0x09C +#define MYKONOS_ADDR_DEFRAMER_LANE_FIFO_STRB 0x09D +#define MYKONOS_ADDR_DEFRAMER_LANE0_FIFO_RDWR_ADDR 0x09E +#define MYKONOS_ADDR_DEFRAMER_LANE1_FIFO_RDWR_ADDR 0x09F +#define MYKONOS_ADDR_DEFRAMER_LANE2_FIFO_RDWR_ADDR 0x0A0 +#define MYKONOS_ADDR_DEFRAMER_LANE3_FIFO_RDWR_ADDR 0x0A1 +#define MYKONOS_ADDR_DEFRAMER_SYSREF_TO_LMFC_CNTR_STAT 0x0A2 +#define MYKONOS_ADDR_DEFRAMER_SYSREF_TO_LMFC_ERR_MARGIN 0x0A3 +#define MYKONOS_ADDR_DEFRAMER_PRBS10_CTL 0x0A4 +#define MYKONOS_ADDR_DEFRAMER_PRBS20_CTL 0x0A5 +#define MYKONOS_ADDR_DEFRAMER_PRBS20_STRB_CHKSUM_TYPE 0x0A6 +#define MYKONOS_ADDR_DEFRAMER_PRBS20_ERR_CNTR_7_TO_0 0x0A7 +#define MYKONOS_ADDR_DEFRAMER_PRBS20_ERR_CNTR_15_TO_8 0x0A8 +#define MYKONOS_ADDR_DEFRAMER_PRBS20_ERR_CNTR_23_TO_16 0x0A9 +#define MYKONOS_ADDR_DEFRAMER_LANE_DATA_CTL 0x0AA +#define MYKONOS_ADDR_DEFRAMER_STATUS_2 0x0AB +#define MYKONOS_ADDR_DEFRAMER_DET_FIFO_PHASE 0x0AC + +/* Mykonos Serializer Registers */ +#define MYKONOS_ADDR_SERIALIZER_CTL_0 0x0B0 +#define MYKONOS_ADDR_SERIALIZER_CTL_1 0x0B1 +#define MYKONOS_ADDR_SERIALIZER_CTL_2 0x0B2 +#define MYKONOS_ADDR_SERIALIZER_CTL_3 0x0B3 +#define MYKONOS_ADDR_SERIALIZER_HS_DIV_TXSER_CLK_EN 0x0B4 +#define MYKONOS_ADDR_SERIALIZER_SPECIAL 0x0B5 + +/* Mykonos Deserializer Registers */ +#define MYKONOS_ADDR_DESERIALIZER_PDET_CTL 0x0BC +#define MYKONOS_ADDR_DESERIALIZER_CTL_0 0x0BD +#define MYKONOS_ADDR_DESERIALIZER_SIN_SHAPE_0 0x0BE +#define MYKONOS_ADDR_DESERIALIZER_SIN_SHAPE_1 0x0BF +#define MYKONOS_ADDR_DESERIALIZER_EQ_CTL_0 0x0C1 +#define MYKONOS_ADDR_DESERIALIZER_EQ_CTL_1 0x0C2 +#define MYKONOS_ADDR_DESERIALIZER_MISC_CTL 0x0C3 +#define MYKONOS_ADDR_DESERIALIZER_EQ_HP_EN 0x0C4 +#define MYKONOS_ADDR_DESERIALIZER_EQ_CTL_1_TO_0 0x0C5 +#define MYKONOS_ADDR_DESERIALIZER_EQ_CTL_3_TO_2 0x0C6 +#define MYKONOS_ADDR_DESERIALIZER_HS_DIV_RXCDR_CLK_EN 0x0CD +#define MYKONOS_ADDR_DESERIALIZER_SPECIAL 0x0CE +#define MYKONOS_ADDR_DESERIALIZER_CDR_CAL_CTL 0x0D0 + +#define MYKONOS_ADDR_CONFIGURATION_CONTROL_1 0x100 +#define MYKONOS_ADDR_CONFIGURATION_CONTROL_2 0x101 +#define MYKONOS_ADDR_CONFIGURATION_CONTROL_4 0x102 +#define MYKONOS_ADDR_CONFIGURATION_CONTROL_5 0x103 +#define MYKONOS_ADDR_DPD_SNIFFER_CONFIGURATION_CONTROL_1 0x104 +#define MYKONOS_ADDR_DPD_SNIFFER_CONFIGURATION_CONTROL_2 0x105 +#define MYKONOS_ADDR_DPD_SNIFFER_GPIO_SELECT 0x106 +#define MYKONOS_ADDR_SNIFFER_CONFIGURATION_CONTROL 0x107 +#define MYKONOS_ADDR_DPD_CONFIGURATION_CONTROL 0x108 +#define MYKONOS_ADDR_LOOPBACK_CONFIGURATION_CONTROL 0x109 + +#define MYKONOS_ADDR_CLOCK_CONTROL_0 0x117 +#define MYKONOS_ADDR_CLOCK_CONTROL_1 0x118 +#define MYKONOS_ADDR_CLOCK_CONTROL_2 0x119 +#define MYKONOS_ADDR_CLOCK_CONTROL_3 0x11A +#define MYKONOS_ADDR_CLOCK_CONTROL_4 0x11B +#define MYKONOS_ADDR_CLOCK_CONTROL_5 0x11C + +#define MYKONOS_ADDR_MCS_CONTROL 0x120 +#define MYKONOS_ADDR_MCS_STATUS 0x121 + +/* CLK PLL Registers */ +#define MYKONOS_ADDR_CLK_SYNTH_DIVIDER_INT_BYTE0 0x141 +#define MYKONOS_ADDR_CLK_SYNTH_DIVIDER_INT_BYTE1 0x142 +#define MYKONOS_ADDR_CLK_SYNTH_DIVIDER_FRAC_BYTE0 0x143 +#define MYKONOS_ADDR_CLK_SYNTH_DIVIDER_FRAC_BYTE1 0x144 +#define MYKONOS_ADDR_CLK_SYNTH_DIVIDER_FRAC_BYTE2 0x145 +#define MYKONOS_ADDR_CLK_SYNTH_F_VCOTN_BYTE1 0x148 +#define MYKONOS_ADDR_CLK_SYNTH_BYTE1 0x149 +#define MYKONOS_ADDR_CLK_SYNTH_BYTE2 0x14A +#define MYKONOS_ADDR_CLK_SYNTH_BYTE3 0x14B +#define MYKONOS_ADDR_CLK_SYNTH_BYTE5 0x14D +#define MYKONOS_ADDR_CLK_SYNTH_BYTE6 0x14E +#define MYKONOS_ADDR_CLK_SYNTH_BYTE7 0x14F +#define MYKONOS_ADDR_CLK_SYNTH_LF_R3 0x150 +#define MYKONOS_ADDR_CLK_SYNTH_BYTE9 0x152 +#define MYKONOS_ADDR_CLK_SYNTH_CAL_STAT 0x154 +#define MYKONOS_ADDR_CLK_SYNTH_VCO_CAL_REF 0x155 +#define MYKONOS_ADDR_CLK_SYNTH_VCO_BAND_BYTE1 0x157 +#define MYKONOS_ADDR_CLK_SYNTH_CAL_CONTROL 0x159 +#define MYKONOS_ADDR_CLK_SYNTH_VCO_VAR_CTL1 0x15E +#define MYKONOS_ADDR_CLK_SYNTH_VCO_VAR_CTL2 0x15F + +/* DPD Registers */ +#define MYKONOS_ADDR_TX1_DPD_MODEL_INDIRECT_PTR 0x178 +#define MYKONOS_ADDR_TX2_DPD_MODEL_INDIRECT_PTR 0x17C +#define MYKONOS_ADDR_DPD_RMS_BUF_SIZE 0x180 +#define MYKONOS_ADDR_TX1_DPD_MODEL_WORKING_PTR 0x188 +#define MYKONOS_ADDR_TX2_DPD_MODEL_WORKING_PTR 0x18C + +/* Rx NCO Control registers */ +#define MYKONOS_ADDR_CALPLL_SDM_CONTROL 0x17F +#define MYKONOS_ADDR_RX_NCO_CONTROL 0x190 +#define MYKONOS_ADDR_RX_NCO_CH1_FTW_BYTE_3 0x191 +#define MYKONOS_ADDR_RX_NCO_CH1_FTW_BYTE_2 0x192 +#define MYKONOS_ADDR_RX_NCO_CH1_FTW_BYTE_1 0x193 +#define MYKONOS_ADDR_RX_NCO_CH2_FTW_BYTE_3 0x194 +#define MYKONOS_ADDR_RX_NCO_CH2_FTW_BYTE_2 0x195 +#define MYKONOS_ADDR_RX_NCO_CH2_FTW_BYTE_1 0x196 +#define MYKONOS_ADDR_RX_NCO_DPD_SNIFFER_FTW_BYTE_3 0x197 +#define MYKONOS_ADDR_RX_NCO_DPD_SNIFFER_FTW_BYTE_2 0x198 +#define MYKONOS_ADDR_RX_NCO_DPD_SNIFFER_FTW_BYTE_1 0x199 + +#define MYKONOS_ADDR_ENSM_CONFIG_7_0 0x1B0 +#define MYKONOS_ADDR_CALIBRATION_CONTROL 0x1B2 +#define MYKONOS_ADDR_ENSM_MANUAL_GAIN_LOCK_GPIO_SELECT 0x1B5 +#define MYKONOS_ADDR_REFERENCE_CLOCK_CYCLES 0x1C0 +#define MYKONOS_ADDR_TX_PD_OVERIDE_7_0 0x209 +#define MYKONOS_ADDR_RCAL_CONTROL 0x224 +#define MYKONOS_ADDR_REF_PAD_CONFIG1 0x230 +#define MYKONOS_ADDR_REF_PAD_CONFIG2 0x231 + +#define MYKONOS_ADDR_RXSYNTH_CP_CAL_STAT 0x254 +#define MYKONOS_ADDR_RXSYNTH_VCO_BAND_BYTE1 0x257 +#define MYKONOS_ADDR_TXSYNTH_CP_CAL_STAT 0x2C4 +#define MYKONOS_ADDR_TXSYNTH_VCO_BAND_BYTE1 0x2C7 +#define MYKONOS_ADDR_SNIFF_RXSYNTH_CP_CAL_STAT 0x354 +#define MYKONOS_ADDR_SNIFF_RXSYNTH_VCO_BAND_BYTE1 0x357 +#define MYKONOS_ADDR_SNIFF_RXLOGEN_BYTE1 0x380 + +#define MYKONOS_ADDR_RX_FILTER_CONFIGURATION 0x410 +#define MYKONOS_ADDR_RX_FILTER_GAIN 0x411 +#define MYKONOS_ADDR_DPD_SNIFFER_RX_FILTER_GAIN 0x412 + +/* Mykonos Temperature Gain Compensation Registers */ +#define MYKONOS_ADDR_RX1_TEMP_GAIN_COMP 0x420 +#define MYKONOS_ADDR_RX2_TEMP_GAIN_COMP 0x421 +#define MYKONOS_ADDR_OBS_TEMP_GAIN_COMP 0x422 + +/* Mykonos AGC General Registers */ +#define MYKONOS_ADDR_AGC_CFG_1 0x42E +#define MYKONOS_ADDR_AGC_CFG_2 0x42F +#define MYKONOS_ADDR_AGC_GAIN_CHANGE_GPIO_SEL 0x430 +#define MYKONOS_ADDR_AGC_RX1_MAX_GAIN_INDEX 0x431 +#define MYKONOS_ADDR_AGC_RX1_MIN_GAIN_INDEX 0x432 +#define MYKONOS_ADDR_AGC_MANUAL_GAIN_CFG 0x433 +#define MYKONOS_ADDR_AGC_MANUAL_GAIN_GPIO_SEL 0x434 +#define MYKONOS_ADDR_AGC_MANUAL_GAIN_INDEX_CH_1 0x435 +#define MYKONOS_ADDR_AGC_MANUAL_GAIN_INDEX_CH_2 0x436 +#define MYKONOS_ADDR_AGC_LOCK_LEVEL 0x437 +#define MYKONOS_ADDR_AGC_OVRG_GAIN_STEP_1 0x438 +#define MYKONOS_ADDR_AGC_OVRG_GAIN_STEP_2 0x439 +#define MYKONOS_ADDR_AGC_OVRG_GAIN_STEP_3 0x43A +#define MYKONOS_ADDR_AGC_OVRG_GAIN_STEP_4 0x43B +#define MYKONOS_ADDR_AGC_OVRG_GAIN_STEP_5 0x43C +#define MYKONOS_ADDR_AGC_OVRG_GAIN_STEP_6 0x43D +#define MYKONOS_ADDR_AGC_RX1_GAIN_LOCK_DELAY 0x43E +#define MYKONOS_ADDR_AGC_RX2_GAIN_LOCK_DELAY 0x43F +#define MYKONOS_ADDR_AGC_RX1_ATTACK_DELAY 0x440 +#define MYKONOS_ADDR_AGC_RX2_ATTACK_DELAY 0x441 +#define MYKONOS_ADDR_AGC_ULB_THRSH 0x442 +#define MYKONOS_ADDR_AGC_LLB_THRSH 0x443 +#define MYKONOS_ADDR_AGC_RX_BLOCK_DET_DECAY 0x444 +#define MYKONOS_ADDR_AGC_RESET_PD_HIGH_CNT 0x445 +#define MYKONOS_ADDR_AGC_RX2_MAX_GAIN_INDEX 0x446 +#define MYKONOS_ADDR_AGC_RX2_MIN_GAIN_INDEX 0x447 +#define MYKONOS_ADDR_AGC_ORX_SNRX_CFG_1 0x448 +#define MYKONOS_ADDR_AGC_ORX_SNRX_CFG_2 0x449 +#define MYKONOS_ADDR_AGC_ORX_SNRX_MAX_GAIN_INDEX 0x44A +#define MYKONOS_ADDR_AGC_ORX_SNRX_MIN_GAIN_INDEX 0x44B +#define MYKONOS_ADDR_AGC_ORX_SNRX_MANUAL_GAIN_CFG 0x44C +#define MYKONOS_ADDR_AGC_ORX_SNRX_GPIO_SEL 0x44D +#define MYKONOS_ADDR_AGC_ORX_SNRX_LOCK_LEVEL 0x44E +#define MYKONOS_ADDR_AGC_ORX_SNRX_OVRG_GAIN_STEP_1 0x44F +#define MYKONOS_ADDR_AGC_ORX_SNRX_OVRG_GAIN_STEP_2 0x450 +#define MYKONOS_ADDR_AGC_ORX_SNRX_OVRG_GAIN_STEP_3 0x451 +#define MYKONOS_ADDR_AGC_ORX_SNRX_OVRG_GAIN_STEP_4 0x452 +#define MYKONOS_ADDR_AGC_ORX_SNRX_OVRG_GAIN_STEP_5 0x453 +#define MYKONOS_ADDR_AGC_ORX_SNRX_OVRG_GAIN_STEP_6 0x454 +#define MYKONOS_ADDR_AGC_ORX_SNRX_GAIN_LOCK_DELAY 0x455 +#define MYKONOS_ADDR_AGC_ORX_SNRX_ATTACK_DELAY 0x456 +#define MYKONOS_ADDR_AGC_ORX_SNRX_ULB_THRSH 0x457 +#define MYKONOS_ADDR_AGC_ORX_SNRX_LLB_THRSH 0x458 +#define MYKONOS_ADDR_AGC_ORX_SNRX_BLOCK_DET_DECAY 0x459 +#define MYKONOS_ADDR_AGC_ORX_SNRX_RESET_PD_HIGH_CNT 0x45A +#define MYKONOS_ADDR_AGC_ORX1_MANUAL_GAIN_INDEX 0x45B +#define MYKONOS_ADDR_AGC_ORX2_MANUAL_GAIN_INDEX 0x45C +#define MYKONOS_ADDR_AGC_SNRX_MANUAL_GAIN_INDEX 0x45D +#define MYKONOS_ADDR_AGC_LOOPBACK1_MANUAL_GAIN_INDEX 0x45E +#define MYKONOS_ADDR_AGC_LOOPBACK2_MANUAL_GAIN_INDEX 0x45F +#define MYKONOS_ADDR_AGC_ORX_SNRX_ACTIVE 0x460 + +/* Mykonos Fast Attack AGC Registers */ +#define MYKONOS_ADDR_AGC_FAST_CFG_1 0x468 +#define MYKONOS_ADDR_AGC_FAST_CFG_2 0x469 +#define MYKONOS_ADDR_AGC_FAST_ENRGY_LOST_THRSH 0x46A +#define MYKONOS_ADDR_AGC_FAST_STRONG_SIG_THRSH 0x46B +#define MYKONOS_ADDR_AGC_FAST_SETTING_DELAY 0x46C +#define MYKONOS_ADDR_AGC_FAST_OPT_MAX_GAIN 0x46D +#define MYKONOS_ADDR_AGC_FAST_ENRGY_DET_CNT 0x46E +#define MYKONOS_ADDR_AGC_FAST_AGCLL_UPPER_LIMIT 0x46F +#define MYKONOS_ADDR_AGC_FAST_GAIN_LOCK_EXIT_CNT 0x470 +#define MYKONOS_ADDR_AGC_FAST_ORX_SNRX_CFG_1 0x471 +#define MYKONOS_ADDR_AGC_FAST_ORX_SNRX_CFG_2 0x472 +#define MYKONOS_ADDR_AGC_FAST_ORX_SNRX_ENRGY_LOST_THRSH 0x473 +#define MYKONOS_ADDR_AGC_FAST_ORX_SNRX_STRONG_SIG_THRSH 0x474 +#define MYKONOS_ADDR_AGC_FAST_ORX_SNRX_SET_DELAY 0x475 +#define MYKONOS_ADDR_AGC_FAST_ORX_SNRX_OPT_MAX_GAIN 0x476 +#define MYKONOS_ADDR_AGC_FAST_ORX_SNRX_ENRGY_DET_CNT 0x477 +#define MYKONOS_ADDR_AGC_FAST_ORX_SNRX_AGCLL_UPPER_LIMIT 0x478 +#define MYKONOS_ADDR_AGC_FAST_ORX_SNRX_GAIN_LOCK_EXIT_CNT 0x479 + +/* Mykonos Slow Loop - Hybrid AGC Registers */ +#define MYKONOS_ADDR_AGC_SLOW_LOCK_LEV_THRSH 0x480 +#define MYKONOS_ADDR_AGC_SLOW_ULB_CNT_THRSH 0x481 +#define MYKONOS_ADDR_AGC_SLOW_LLB_CNT_THRSH 0x482 +#define MYKONOS_ADDR_AGC_SLOW_HIGH_OVRG_CNT_THRSH 0x483 +#define MYKONOS_ADDR_AGC_SLOW_LOW_OVRG_CNT_THRSH 0x484 +#define MYKONOS_ADDR_AGC_SLOW_VERYLOW_OVRG_CNT_THRSH 0x485 +#define MYKONOS_ADDR_AGC_SLOW_DIG_SAT_CNT_THRSH 0x486 +#define MYKONOS_ADDR_AGC_SLOW_UPPER0_THRSH_GAIN_STEP 0x487 +#define MYKONOS_ADDR_AGC_SLOW_LOWER0_THRSH_GAIN_STEP 0x488 +#define MYKONOS_ADDR_AGC_SLOW_UPPER1_THRSH_GAIN_STEP 0x489 +#define MYKONOS_ADDR_AGC_SLOW_LOWER1_THRSH_GAIN_STEP 0x48A +#define MYKONOS_ADDR_AGC_SLOW_GAIN_UPDATE_CNT_1 0x48B +#define MYKONOS_ADDR_AGC_SLOW_GAIN_UPDATE_CNT_2 0x48C +#define MYKONOS_ADDR_AGC_SLOW_GAIN_UPDATE_CNT_3 0x48D +#define MYKONOS_ADDR_AGC_SLOW_LOOP_CFG 0x48E +#define MYKONOS_ADDR_AGC_SLOW_POWER_THRSH 0x48F +#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_LOCK_LEV_THRSH 0x490 + +#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_ULB_CNT_THRSH 0x491 +#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_LLB_CNT_THRSH 0x492 +#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_ADC_HIGH_OVRG_CNT_THRSH 0x493 +#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_ADC_LOW_OVRG_CNT_THRSH 0x494 +#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_ADC_VERYLOW_OVRG_CNT_THRSH 0x495 + +#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_DIG_SAT_CNT_THRSH 0x496 +#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_UPPER0_THRSH_GAIN_STEP 0x497 +#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_LOWER0_THRSH_GAIN_STEP 0x498 +#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_UPPER1_THRSH_GAIN_STEP 0x499 +#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_LOWER1_THRSH_GAIN_STEP 0x49A +#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_GAIN_UPDATE_CTR_1 0x49B +#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_GAIN_UPDATE_CTR_2 0x49C +#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_GAIN_UPDATE_CTR_3 0x49D +#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_LOOP_CFG 0x49E +#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_POWER_THRSH 0x49F +#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_UL_SIG_POW_MEAS_DEL_1 0x4A0 +#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_UL_SIG_POW_MEAS_DEL_2 0x4A1 +#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_UL_SIG_POW_MEAS_DUR_1 0x4A2 +#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_UL_SIG_POW_MEAS_DUR_2 0x4A3 + +/* Mykonos Gain Control Read Registers */ +#define MYKONOS_ADDR_GAIN_CTL_CHANNEL_1 0x4B0 +#define MYKONOS_ADDR_GAIN_CTL_FAST_ATTK_STATE 0x4B1 +#define MYKONOS_ADDR_GAIN_CTL_SLOW_LOOP_STATE 0x4B2 +#define MYKONOS_ADDR_GAIN_CTL_CHANNEL_2 0x4B3 +#define MYKONOS_ADDR_GAIN_CTL_OVRG_SIGS_CHANNEL_1 0x4B4 +#define MYKONOS_ADDR_GAIN_CTL_OVRG_SIGS_CHANNEL_2 0x4B5 +#define MYKONOS_ADDR_GAIN_CTL_ORX_SNRX_GAIN 0x4B6 +#define MYKONOS_ADDR_GAIN_CTL_ORX_SNRX_LOOP_STATE 0x4B7 +#define MYKONOS_ADDR_GAIN_CTL_ORX_SNRX_OVRG_SIGS 0x4B8 + +/* Mykonos Rx Data Path Overrange Registers */ +#define MYKONOS_ADDR_RX_OVRG_DATAPATH_OVRFLW 0x4B9 +#define MYKONOS_ADDR_RX_OVRG_ORX_SNRX_DATAPATH_OVRFLW 0x4BA + +/* Mykonos RSSI Measurement Registers and Dec Power Measurement Registers*/ +#define MYKONOS_ADDR_RSSI_MEAS_DURATION_0_1 0x4C0 +#define MYKONOS_ADDR_RSSI_MEAS_DURATION_2_3 0x4C1 +#define MYKONOS_ADDR_RSSI_CFG 0x4C6 +#define MYKONOS_DEC_POWER_CONFIG_1 0x4C7 +#define MYKONOS_DEC_POWER_CONFIG_2 0x4C8 +#define MYKONOS_ADDR_DPD_SNF_RSSI_CFG 0x4CF +#define MYKONOS_ADDR_DPD_RSSI_CFG 0x4D6 +#define MYKONOS_SNIFFER_DEC_POWER_CONFIG_1 0x4D7 +#define MYKONOS_SNIFFER_DEC_POWER_CONFIG_2 0x4D8 +#define MYKONOS_CH1_DECIMATED_PWR 0x4DE +#define MYKONOS_CH2_DECIMATED_PWR 0x4DF +#define MYKONOS_SNIFFER_DECIMATED_PWR 0x4E6 + +#define MYKONOS_ADDR_DIGITAL_GAIN_CONFIG 0x4F0 +#define MYKONOS_ADDR_DPD_SNIFFER_DIGITAL_GAIN_CONFIG 0x4F1 +#define MYKONOS_ADDR_GAIN_TABLE_ADDR 0x500 +#define MYKONOS_ADDR_GAIN_TABLE_RX1_FE_GAIN 0x501 +#define MYKONOS_ADDR_GAIN_TABLE_RX1_EXT_CTL 0x502 +#define MYKONOS_ADDR_GAIN_TABLE_RX1_DIG_GAIN 0x503 +#define MYKONOS_ADDR_GAIN_TABLE_RX2_FE_GAIN 0x504 +#define MYKONOS_ADDR_GAIN_TABLE_RX2_EXT_CTL 0x505 +#define MYKONOS_ADDR_GAIN_TABLE_RX2_DIG_GAIN 0x506 +#define MYKONOS_ADDR_GAIN_TABLE_RX3_FE_GAIN 0x507 +#define MYKONOS_ADDR_GAIN_TABLE_RX3_LNA_ENAB 0x508 +#define MYKONOS_ADDR_GAIN_TABLE_RX3_DIG_GAIN 0x509 +#define MYKONOS_ADDR_GAIN_TABLE_CONFIGURATION 0x516 +#define MYKONOS_ADDR_CH3_GAIN_TABLE_CONFIGURATION 0x517 +#define MYKONOS_ADDR_RXFE1_LOCM 0x520 +#define MYKONOS_ADDR_RXFE2_LOCM 0x521 +#define MYKONOS_ADDR_RXLOOPBACK1_CNTRL_1 0x540 +#define MYKONOS_ADDR_RXLOOPBACK2_CNTRL_1 0x541 +#define MYKONOS_ADDR_RX_LOOPBACK1_CNTRL_4 0x546 +#define MYKONOS_ADDR_RX_LOOPBACK2_CNTRL_4 0x547 + +/* Mykonos Overload/Peak Detection Registers */ +#define MYKONOS_ADDR_OVRLD_ADC_OVRLD_CFG 0x580 +#define MYKONOS_ADDR_OVRLD_ADC_OVRLD_UPPER_THRSH 0x581 +#define MYKONOS_ADDR_OVRLD_ADC_OVRLD_LOWER_THRSH 0x582 + +#define MYKONOS_ADDR_OVRLD_PD_DEC_OVRLD_CFG 0x583 +#define MYKONOS_ADDR_OVRLD_PD_DEC_OVRLD_UPPER_THRSH 0x584 +#define MYKONOS_ADDR_OVRLD_PD_DEC_OVRLD_LOWER_THRSH 0x585 +#define MYKONOS_ADDR_OVRLD_PD_DEC_VERYLOW_THRSH 0x586 +#define MYKONOS_ADDR_ORX_SNRX_OVRLD_ADC_OVRLD_CFG 0x587 +#define MYKONOS_ADDR_ORX_SNRX_OVRLD_PD_DEC_OVRLD_CFG 0x58A +#define MYKONOS_ADDR_ORX_SNRX_OVRLD_PD_DEC_OVRLD_UPPER_THRSH 0x58B +#define MYKONOS_ADDR_ORX_SNRX_OVRLD_PD_DEC_OVRLD_LOWER_THRSH 0x58C +#define MYKONOS_ADDR_ORX_SNRX_OVRLD_PD_DEC_OVRLD_VERYLOW_THRSH 0x58D + +#define MYKONOS_ADDR_RX_ADC_FLASH_DELAY 0x5B6 +#define MYKONOS_ADDR_RX_ADC_FLASH_CTRL 0x5B7 +#define MYKONOS_ADDR_RX_ADC1_PRFL 0x5DD +#define MYKONOS_ADDR_RX_ADC2_PRFL 0x5DE +#define MYKONOS_ADDR_ORX_ADC_PRFL 0x5DF + +#define MYKONOS_ADDR_RFDC_MEASURE_COUNT_1 0x631 +#define MYKONOS_ADDR_RFDC_MEASURE_COUNT_2 0x632 +#define MYKONOS_ADDR_RFDC_PROGRAM_SHIFT 0x635 +#define MYKONOS_ADDR_RFDC_CONFIG2 0x636 +#define MYKONOS_DPD_Sniffer_RFDC_CAL_TRACK_EN 0x642 +#define MYKONOS_ADDR_RFDC_SNF_MEASURE_COUNT_1 0x644 +#define MYKONOS_ADDR_RFDC_SNF_MEASURE_COUNT_2 0x645 +#define MYKONOS_ADDR_RFDC_ORX_MEASURE_COUNT_1 0x650 +#define MYKONOS_ADDR_RFDC_ORX_MEASURE_COUNT_2 0x651 +#define MYKONOS_ADDR_DIGITAL_DC_MIN_CAL_IDX 0x63A +#define MYKONOS_ADDR_DIGITAL_DC_OFFSET_SHIFT 0x674 +#define MYKONOS_ADDR_DIGITAL_DC_OFFSET_CONFIG 0x676 +#define MYKONOS_DIGITAL_DC_OFFSET_CH3_TRACKING 0x67A +#define MYKONOS_ADDR_DIGITAL_DC_OFFSET_SNF 0x67C +#define MYKONOS_ADDR_DIGITAL_DC_OFFSET_CH3_DPD_M_SHIFT 0x67D + +#define MYKONOS_ADDR_RX_GAIN_COMP_DELAY 0x710 +#define MYKONOS_ADDR_RX1_GAIN_COMP_OFFSET 0x711 +#define MYKONOS_ADDR_RX2_GAIN_COMP_OFFSET 0x712 +#define MYKONOS_ADDR_RX_GAIN_COMP_CFG 0x713 +#define MYKONOS_ADDR_RX_SLCR_PIN_CFG 0x714 +#define MYKONOS_ADDR_DPD_SNF_RX_GAIN_COMP_DELAY 0x715 +#define MYKONOS_ADDR_DPD_SNF_RX_GAIN_COMP_OFFSET 0x716 +#define MYKONOS_ADDR_DPD_SNF_RX_GAIN_COMP_CFG 0x717 +#define MYKONOS_ADDR_DPD_SNF_RX_SLCR_PIN_CFG 0x718 + +#define MYKONOS_ADDR_FLOATING_POINT_CFG 0x750 +#define MYKONOS_ADDR_FLOATING_POINT_RX_CTRL 0x751 +#define MYKONOS_ADDR_FLOATING_POINT_ORX_CTRL 0x752 + + +#define MYKONOS_ADDR_SNRX_LNA_BIAS_C 0x81B + + +#define MYKONOS_ADDR_ORX_ADC_FLASH_DELAY 0x846 +#define MYKONOS_ADDR_ORX_ADC_FLASH_CTRL 0x847 + +#define MYKONOS_ADDR_TX_FILTER_CONFIGURATION 0x910 +#define MYKONOS_ADDR_TX1_ATTENUATION_0_READBACK 0x940 +#define MYKONOS_ADDR_TX1_ATTENUATION_1_READBACK 0x941 +#define MYKONOS_ADDR_TX2_ATTENUATION_0_READBACK 0x942 +#define MYKONOS_ADDR_TX2_ATTENUATION_1_READBACK 0x943 +#define MYKONOS_ADDR_TX_FILTER_OVERFLOW 0x950 + +/* Mykonos PA Protection Block Registers */ +#define MYKONOS_ADDR_PA_PROTECTION_CONFIGURATION 0x955 +#define MYKONOS_ADDR_PA_PROTECTION_ATTEN_CONTROL 0x956 +#define MYKONOS_ADDR_PA_PROTECTION_THRESHOLD_LSB 0x957 +#define MYKONOS_ADDR_PA_PROTECTION_THRESHOLD_MSB 0x958 +#define MYKONOS_ADDR_PA_PROTECTION_POWER_READBACK_LSB 0x959 +#define MYKONOS_ADDR_PA_PROTECTION_POWER_READBACK_MSB 0x95A +#define MYKONOS_ADDR_TX1_ATTENUATION_0 0x960 +#define MYKONOS_ADDR_TX1_ATTENUATION_1 0x961 +#define MYKONOS_ADDR_TX2_ATTENUATION_0 0x962 +#define MYKONOS_ADDR_TX2_ATTENUATION_1 0x963 +#define MYKONOS_ADDR_TX1_GAIN_0 0x967 +#define MYKONOS_ADDR_TX1_GAIN_1 0x968 +#define MYKONOS_ADDR_TX1_GAIN_2 0x969 +#define MYKONOS_ADDR_TX2_GAIN_0 0x96A +#define MYKONOS_ADDR_TX2_GAIN_1 0x96B +#define MYKONOS_ADDR_TX2_GAIN_2 0x96C +#define MYKONOS_ADDR_TX_INCR_DECR_WORD 0x96D +#define MYKONOS_ADDR_TX_TPC_CONFIG 0x96E +#define MYKONOS_ADDR_TX_TPC_GPIO_CFG 0x96F + +#define MYKONOS_ADDR_TX_ABBF_FREQ_CAL_NCO_I_MSB 0x9CB +#define MYKONOS_ADDR_TX_ABBF_FREQ_CAL_NCO_I_LSB 0x9CC +#define MYKONOS_ADDR_TX_ABBF_FREQ_CAL_NCO_Q_MSB 0x9CD +#define MYKONOS_ADDR_TX_ABBF_FREQ_CAL_NCO_Q_LSB 0x9CE + +/* Mykonos GPIO Registers */ +#define MYKONOS_ADDR_GPIO_3V3_DIR_CTL_7_0 0xB00 +#define MYKONOS_ADDR_GPIO_3V3_DIR_CTL_15_8 0xB01 +#define MYKONOS_ADDR_GPIO_3V3_SPI_SRC_7_0 0xB02 +#define MYKONOS_ADDR_GPIO_3V3_SPI_SRC_15_8 0xB03 +#define MYKONOS_ADDR_GPIO_3V3_SPI_READ_7_0 0xB04 +#define MYKONOS_ADDR_GPIO_3V3_SPI_READ_15_8 0xB05 +#define MYKONOS_ADDR_GPIO_3V3_LSB_SRC_CTL 0xB06 +#define MYKONOS_ADDR_GPIO_3V3_MSB_SRC_CTL 0xB07 + +#define MYKONOS_ADDR_GPIO_DIR_CTL_7_0 0xB20 +#define MYKONOS_ADDR_GPIO_DIR_CTL_15_8 0xB21 +#define MYKONOS_ADDR_GPIO_DIR_CTL_18_16 0xB22 +#define MYKONOS_ADDR_GPIO_SPI_SRC_7_0 0xB23 +#define MYKONOS_ADDR_GPIO_SPI_SRC_15_8 0xB24 +#define MYKONOS_ADDR_GPIO_SPI_SRC_18_16 0xB25 +#define MYKONOS_ADDR_GPIO_SPI_READ_7_0 0xB26 +#define MYKONOS_ADDR_GPIO_SPI_READ_15_8 0xB27 +#define MYKONOS_ADDR_GPIO_SPI_READ_18_16 0xB28 +#define MYKONOS_ADDR_SOURCE_CONTROL_LOWER_BYTE 0xB29 +#define MYKONOS_ADDR_SOURCE_CONTROL_UPPER_BYTE 0xB2A +#define MYKONOS_ADDR_SOURCE_CONTROL_EXTRA_BITS 0xB2B + +#define MYKONOS_ADDR_GPIO_MONITOR_INDEX 0xB40 +#define MYKONOS_ADDR_GPIO_MONITOR_ENABLE 0xB41 + +#define MYKONOS_ADDR_GP_INTERRUPT_MASK_1 0xB42 +#define MYKONOS_ADDR_GP_INTERRUPT_MASK_0 0xB43 +#define MYKONOS_ADDR_GP_INTERRUPT_READ_1 0xB44 +#define MYKONOS_ADDR_GP_INTERRUPT_READ_0 0xB45 + +#define MYKONOS_ADDR_PDAUXDAC_MANUAL_CONTROL_5_0 0xB73 +#define MYKONOS_ADDR_PDAUXDAC_MANUAL_CONTROL_9_6 0xB74 +#define MYKONOS_ADDR_PDAUXDAC_MANUAL_IN_5_0 0xB75 +#define MYKONOS_ADDR_PDAUXDAC_MANUAL_IN_9_6 0xB76 +#define MYKONOS_ADDR_AUX_DAC_LATCH_CONTROL 0xB9F +#define MYKONOS_ADDR_AUXDAC_0_WORD_MSB 0xBA0 + +#define MYKONOS_ADR_AUX_ADC_CLOCK_DIVIDE 0xBC0 +#define MYKONOS_ADDR_AUX_ADC_CFG 0xBC1 +#define MYKONOS_ADDR_AUX_ADC_READ_MSB 0xBC2 +#define MYKONOS_ADDR_AUX_ADC_READ_LSB 0xBC3 +#define MYKONOS_ADDR_AUX_ADC_SEL 0xBC4 +#define MYKONOS_ADDR_AUX_ADC_BUFFER_CONFIG_0 0xBC5 +#define MYKONOS_ADDR_AUX_ADC_BUFFER_CONFIG_1 0xBC6 + +#define MYKONOS_ADDR_TEMP_SENSOR_OFFSET 0xBE0 +#define MYKONOS_ADDR_TEMP_SENSOR_CONTROL_LSB 0xBE1 +#define MYKONOS_ADDR_TEMP_SENSOR_CONTROL_MSB 0xBE2 +#define MYKONOS_ADDR_TEMP_SENSOR_READ 0xBE3 +#define MYKONOS_ADDR_TEMP_SENSOR_CONFIG 0xBE4 + +#define MYKONOS_ADDR_DIGITAL_TEST_BYTE_0 0xC40 + +/* ARM subsystem registers */ +#define MYKONOS_ADDR_ARM_CTL_1 0xD00 +#define MYKONOS_ADDR_ARM_CTL_2 0xD01 +#define MYKONOS_ADDR_ARM_ADDR_BYTE_0 0xD02 +#define MYKONOS_ADDR_ARM_ADDR_BYTE_1 0xD03 +#define MYKONOS_ADDR_ARM_DATA_BYTE_0 0xD04 +#define MYKONOS_ADDR_ARM_DATA_BYTE_1 0xD05 +#define MYKONOS_ADDR_ARM_DATA_BYTE_2 0xD06 +#define MYKONOS_ADDR_ARM_DATA_BYTE_3 0xD07 +#define MYKONOS_ADDR_ARM_CLK_CTL 0xD08 +#define MYKONOS_ADDR_AHB_SPI_BRIDGE 0xD09 +#define MYKONOS_ADDR_ARM_BOOT_ADDR_BYTE_0 0xD0A +#define MYKONOS_ADDR_ARM_BOOT_ADDR_BYTE_1 0xD0B +#define MYKONOS_ADDR_ARM_BOOT_ADDR_BYTE_2 0xD0C +#define MYKONOS_ADDR_ARM_BOOT_ADDR_BYTE_3 0xD0D +#define MYKONOS_ADDR_ARM_STACK_PTR_BYTE_0 0xD0E +#define MYKONOS_ADDR_ARM_STACK_PTR_BYTE_1 0xD0F +#define MYKONOS_ADDR_ARM_STACK_PTR_BYTE_2 0xD10 +#define MYKONOS_ADDR_ARM_STACK_PTR_BYTE_3 0xD11 +#define MYKONOS_ADDR_ARM_BRIDGE_CLK_CTL 0xD14 + +/* ARM mailbox registers */ +#define MYKONOS_ADDR_ARM_CMD 0xD30 +#define MYKONOS_ADDR_ARM_EXT_CMD_BYTE_1 0xD31 +#define MYKONOS_ADDR_ARM_EXT_CMD_BYTE_2 0xD32 +#define MYKONOS_ADDR_ARM_EXT_CMD_BYTE_3 0xD33 +#define MYKONOS_ADDR_ARM_EXT_CMD_BYTE_4 0xD34 +#define MYKONOS_ADDR_ARM_EXT_CMD_BYTE_5 0xD35 +#define MYKONOS_ADDR_ARM_EXT_CMD_BYTE_6 0xD36 +#define MYKONOS_ADDR_ARM_EXT_CMD_BYTE_7 0xD37 +#define MYKONOS_ADDR_ARM_CMD_STATUS_0 0xD38 +#define MYKONOS_ADDR_ARM_CMD_STATUS_1 0xD39 +#define MYKONOS_ADDR_ARM_CMD_STATUS_2 0xD3A +#define MYKONOS_ADDR_ARM_CMD_STATUS_3 0xD3B +#define MYKONOS_ADDR_ARM_CMD_STATUS_4 0xD3C +#define MYKONOS_ADDR_ARM_CMD_STATUS_5 0xD3D +#define MYKONOS_ADDR_ARM_CMD_STATUS_6 0xD3E +#define MYKONOS_ADDR_ARM_CMD_STATUS_7 0xD3F + +#define MYKONOS_ADDR_ARM_OPCODE_STATE_0 0xD40 +#define MYKONOS_ADDR_ARM_OPCODE_STATE_1 0xD41 +#define MYKONOS_ADDR_ARM_OPCODE_STATE_2 0xD42 +#define MYKONOS_ADDR_ARM_OPCODE_STATE_3 0xD43 +#define MYKONOS_ADDR_ARM_OPCODE_STATE_4 0xD44 +#define MYKONOS_ADDR_ARM_OPCODE_STATE_5 0xD45 +#define MYKONOS_ADDR_ARM_OPCODE_STATE_6 0xD46 +#define MYKONOS_ADDR_ARM_OPCODE_STATE_7 0xD47 + +/* Mykonos Power-Down Override Control Registers */ +#define MYKONOS_ADDR_TX_PD_OVERRIDE_CONTROL_7_0 0xD89 + +/* Mykonos Observation Framer Registers */ +#define MYKONOS_ADDR_OBS_FRAMER_RESET 0xDC0 +#define MYKONOS_ADDR_OBS_FRAMER_CLK_EN 0xDC1 +#define MYKONOS_ADDR_OBS_FRAMER_ADDR 0xDC2 +#define MYKONOS_ADDR_OBS_FRAMER_DATA 0xDC3 +#define MYKONOS_ADDR_OBS_FRAMER_WRITE_EN 0xDC4 +#define MYKONOS_ADDR_OBS_FRAMER_SYSREF_FIFO_EN 0xDC5 +#define MYKONOS_ADDR_OBS_FRAMER_CONFIG_F 0xDC6 +#define MYKONOS_ADDR_OBS_FRAMER_LANE_CTL 0xDC7 +#define MYKONOS_ADDR_OBS_FRAMER_ADC_XBAR_SEL 0xDC8 +#define MYKONOS_ADDR_OBS_FRAMER_LANE_XBAR_SEL 0xDC9 +#define MYKONOS_ADDR_OBS_FRAMER_CONFIG_LOOPBACK_XBAR_REV 0xDCA +#define MYKONOS_ADDR_OBS_FRAMER_SYNCN_FILT 0xDCB +#define MYKONOS_ADDR_OBS_FRAMER_LMFC_F_OFFSET 0xDCC +#define MYKONOS_ADDR_OBS_FRAMER_LMFC_K_OFFSET 0xDCD +#define MYKONOS_ADDR_OBS_FRAMER_TEST_CNTR_CTL 0xDCE +#define MYKONOS_ADDR_OBS_FRAMER_STATUS_STRB 0xDCF +#define MYKONOS_ADDR_OBS_FRAMER_STATUS 0xDD0 +#define MYKONOS_ADDR_OBS_FRAMER_SYSREF_TO_LMFC_CNTR_STAT 0xDD1 +#define MYKONOS_ADDR_OBS_FRAMER_SYSREF_TO_LMFC_ERR_MARGIN 0xDD2 +#define MYKONOS_ADDR_OBS_FRAMER_LANE_FIFO_STRB 0xDD3 +#define MYKONOS_ADDR_OBS_FRAMER_LANE0_FIFO_RDWR_ADDR 0xDD4 +#define MYKONOS_ADDR_OBS_FRAMER_LANE1_FIFO_RDWR_ADDR 0xDD5 +#define MYKONOS_ADDR_OBS_FRAMER_LANE2_FIFO_RDWR_ADDR 0xDD6 +#define MYKONOS_ADDR_OBS_FRAMER_LANE3_FIFO_RDWR_ADDR 0xDD7 +#define MYKONOS_ADDR_OBS_FRAMER_PRBS10_CTL 0xDD8 +#define MYKONOS_ADDR_OBS_FRAMER_PRBS20_CTL 0xDD9 +#define MYKONOS_ADDR_OBS_FRAMER_PATTERN_GEN_EN 0xDDA +#define MYKONOS_ADDR_OBS_FRAMER_PATTERN_GEN_7_TO_0 0xDDB +#define MYKONOS_ADDR_OBS_FRAMER_PATTERN_GEN_15_TO_8 0xDDC +#define MYKONOS_ADDR_OBS_FRAMER_PATTERN_GEN_19_TO_16 0xDDD +#define MYKONOS_ADDR_OBS_FRAMER_CONFIG_JTX_GEN 0xDDE +#define MYKONOS_ADDR_OBS_FRAMER_LANE_DATA_CTL 0xDDF +#define MYKONOS_ADDR_OBS_FRAMER_DATA_SAMPLE_CTL 0xDE0 + +#define MYKONOS_ADDR_PFIR_COEFF_CTL 0xDFF +#define MYKONOS_ADDR_PFIR_COEFF_DATA 0xE00 +#define MYKONOS_ADDR_PFIR_COEFF_ADDR 0xE01 + +/* ARM memory */ +#define MYKONOS_ADDR_ARM_START_PROG_ADDR 0x01000000 +#define MYKONOS_ADDR_ARM_END_PROG_ADDR 0x01017FFF +#define MYKONOS_ADDR_ARM_START_DATA_ADDR 0x20000000 +#define MYKONOS_ADDR_ARM_END_DATA_ADDR 0x2000FFFF +#define MYKONOS_ADDR_ARM_BUILD_CHKSUM_ADDR 0x01017FE0 +#define MYKONOS_ADDR_ARM_CALC_CHKSUM_ADDR 0x01017FE4 +#define MYKONOS_ADDR_ARM_VERSION 0x01000128 +#define MYKONOS_ARM_ABORT_OPCODE 0x00 +#define MYKONOS_ARM_RUNINIT_OPCODE 0x02 +#define MYKONOS_ARM_RADIOON_OPCODE 0x04 +#define MYKONOS_ARM_WRITECFG_OPCODE 0x06 +#define MYKONOS_ARM_READCFG_OPCODE 0x08 +#define MYKONOS_ARM_SET_OPCODE 0x0A +#define MYKONOS_ARM_GET_OPCODE 0x0C + +#define MYKONOS_ARM_OBJECTID_DPDINIT_CONFIG 0x0F +#define MYKONOS_ARM_OBJECTID_CLGCINIT_CONFIG 0x10 +#define MYKONOS_ARM_OBJECTID_VSWRINIT_CONFIG 0x11 +#define MYKONOS_ARM_OBJECTID_DPDCONFIG 0x24 +#define MYKONOS_ARM_DPD_RESET 0x02 +#define MYKONOS_ARM_OBJECTID_GS_TRACKCALS 0x66 +#define MYKONOS_ARM_OBJECTID_RXQEC_TRACKING 0x20 +#define MYKONOS_ARM_OBJECTID_ORXQEC_TRACKING 0x21 +#define MYKONOS_ARM_OBJECTID_TXLOL_TRACKING 0x22 +#define MYKONOS_ARM_OBJECTID_TXQEC_TRACKING 0x23 +#define MYKONOS_ARM_OBJECTID_CLGCCONFIG 0x25 +#define MYKONOS_ARM_OBJECTID_VSWRCONFIG 0x26 +#define MYKONOS_ARM_OBJECTID_CAL_STATUS 0x42 +#define MYKONOS_ARM_OBJECTID_INIT_CAL_DONE 0x43 +#define MYKONOS_ARM_OBJECTID_ORX_MODE 0x61 +#define MYKONOS_ARM_OBJECTID_TRACKING_CAL_SUSPEND_RESUME 0x65 +#define MYKONOS_ARM_OBJECTID_TRACKING_CAL_CONTROL 0x66 +#define MYKONOS_ARM_OBJECTID_TRACKING_CAL_PENDING 0x67 +#define MYKONOS_ARM_OBJECTID_RADIO_CONTROL 0x81 +#define MYKONOS_ARM_OBJECTID_CALSCHEDULER 0x83 + +#define MYKONOS_ARM_SYSTEMSTATE_POWERUP 0x00 +#define MYKONOS_ARM_SYSTEMSTATE_READY 0x01 +#define MYKONOS_ARM_SYSTEMSTATE_IDLE 0x02 +#define MYKONOS_ARM_SYSTEMSTATE_RADIO_ON 0x03 + +#define ORX_TRIGGER_SIGNALID 0x00 +#define ORX_MODE_0_SIGNALID 0x01 +#define ORX_MODE_1_SIGNALID 0x02 +#define ORX_MODE_2_SIGNALID 0x03 +#define RX1_ENABLE_ACK_SIGNALID 0x04 +#define RX2_ENABLE_ACK_SIGNALID 0x05 +#define TX1_ENABLE_ACK_SIGNALID 0x06 +#define TX2_ENABLE_ACK_SIGNALID 0x07 +#define ORX1_ENABLE_ACK_SIGNALID 0x08 +#define ORX2_ENABLE_ACK_SIGNALID 0x09 +#define SRX_ENABLE_ACK_SIGNALID 0x0A +#define TX_OBS_SELECT_SIGNALID 0x0B + +#define DISABLE_DPD_ACTUATOR 0x03 +#define ENABLE_DPD_ACTUATOR 0x04 +#define SET_CLGC_DESIRED_GAIN_1 0x05 +#define SET_CLGC_DESIRED_GAIN_2 0x06 +#define SET_PATH_DELAY 0x08 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/df_datalink_ge/src/hardware/mykonos/mykonos_user.c b/df_datalink_ge/src/hardware/mykonos/mykonos_user.c new file mode 100644 index 0000000..5cedb57 --- /dev/null +++ b/df_datalink_ge/src/hardware/mykonos/mykonos_user.c @@ -0,0 +1,176 @@ +/** + * \file mykonos_user.c + * \brief Contains Mykonos default gain table values for Rx, ObsRx, and SnRx + * + * Mykonos API version: 1.5.2.3566 + */ + +/** +* \page Disclaimer Legal Disclaimer +* Copyright 2015-2017 Analog Devices Inc. +* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file. +* +*/ + +#include +#include "t_mykonos.h" +#include "mykonos_user.h" + +/** + * \brief Default Rx gain table settings + */ +uint8_t RxGainTable [61][4] = +{ + /* Order: {FE table, External Ctl, Digital Gain/Atten, Enable Atten} */ + {0, 0, 0, 0}, /* Gain index 255 */ + {3, 0, 2, 1}, /* Gain index 254 */ + {6, 0, 3, 1}, /* Gain index 253 */ + {10, 0, 0, 0}, /* Gain index 252 */ + {13, 0, 1, 1}, /* Gain index 251 */ + {16, 0, 0, 0}, /* Gain index 250 */ + {18, 0, 3, 1}, /* Gain index 249 */ + {21, 0, 1, 1}, /* Gain index 248 */ + {23, 0, 3, 1}, /* Gain index 247 */ + {25, 0, 4, 1}, /* Gain index 246 */ + {28, 0, 0, 0}, /* Gain index 245 */ + {30, 0, 0, 0}, /* Gain index 244 */ + {31, 0, 5, 1}, /* Gain index 243 */ + {33, 0, 4, 1}, /* Gain index 242 */ + {35, 0, 2, 1}, /* Gain index 241 */ + {37, 0, 0, 0}, /* Gain index 240 */ + {38, 0, 4, 1}, /* Gain index 239 */ + {39, 0, 7, 1}, /* Gain index 238 */ + {41, 0, 2, 1}, /* Gain index 237 */ + {42, 0, 4, 1}, /* Gain index 236 */ + {43, 0, 6, 1}, /* Gain index 235 */ + {44, 0, 8, 1}, /* Gain index 234 */ + {45, 0, 9, 1}, /* Gain index 233 */ + {46, 0, 10, 1}, /* Gain index 232 */ + {47, 0, 10, 1}, /* Gain index 231 */ + {48, 0, 9, 1}, /* Gain index 230 */ + {49, 0, 8, 1}, /* Gain index 229 */ + {50, 0, 6, 1}, /* Gain index 228 */ + {51, 0, 3, 1}, /* Gain index 227 */ + {51, 0, 13, 1}, /* Gain index 226 */ + {52, 0, 9, 1}, /* Gain index 225 */ + {53, 0, 5, 1}, /* Gain index 224 */ + {53, 0, 15, 1}, /* Gain index 223 */ + {54, 0, 9, 1}, /* Gain index 222 */ + {54, 0, 19, 1}, /* Gain index 221 */ + {55, 0, 11, 1}, /* Gain index 220 */ + {55, 0, 21, 1}, /* Gain index 219 */ + {56, 0, 11, 1}, /* Gain index 218 */ + {56, 0, 21, 1}, /* Gain index 217 */ + {57, 0, 9, 1}, /* Gain index 216 */ + {57, 0, 19, 1}, /* Gain index 215 */ + {57, 0, 29, 1}, /* Gain index 214 */ + {58, 0, 12, 1}, /* Gain index 213 */ + {58, 0, 22, 1}, /* Gain index 212 */ + {58, 0, 32, 1}, /* Gain index 211 */ + {59, 0, 11, 1}, /* Gain index 210 */ + {59, 0, 21, 1}, /* Gain index 209 */ + {59, 0, 31, 1}, /* Gain index 208 */ + {59, 0, 41, 1}, /* Gain index 207 */ + {60, 0, 13, 1}, /* Gain index 206 */ + {60, 0, 23, 1}, /* Gain index 205 */ + {60, 0, 33, 1}, /* Gain index 204 */ + {60, 0, 43, 1}, /* Gain index 203 */ + {60, 0, 53, 1}, /* Gain index 202 */ + {61, 0, 14, 1}, /* Gain index 201 */ + {61, 0, 24, 1}, /* Gain index 200 */ + {61, 0, 34, 1}, /* Gain index 199 */ + {61, 0, 44, 1}, /* Gain index 198 */ + {61, 0, 54, 1}, /* Gain index 197 */ + {61, 0, 64, 1}, /* Gain index 196 */ + {61, 0, 74, 1}, /* Gain index 195 */ +}; + +/** + * \brief Default ORx gain table settings + */ +uint8_t ORxGainTable [19][4] = +{ + /* Order: {FE table, External Ctl, Digital Gain/Atten, Enable Atten} */ + {0, 0, 0, 0}, /* Gain index 255 */ + {7, 0, 0, 0}, /* Gain index 254 */ + {13, 0, 1, 1}, /* Gain index 253 */ + {18, 0, 3, 1}, /* Gain index 252 */ + {23, 0, 3, 1}, /* Gain index 251 */ + {28, 0, 0, 0}, /* Gain index 250 */ + {32, 0, 0, 0}, /* Gain index 249 */ + {35, 0, 2, 1}, /* Gain index 248 */ + {38, 0, 4, 1}, /* Gain index 247 */ + {41, 0, 2, 1}, /* Gain index 246 */ + {43, 0, 6, 1}, /* Gain index 245 */ + {46, 0, 0, 0}, /* Gain index 244 */ + {47, 0, 10, 1}, /* Gain index 243 */ + {49, 0, 8, 1}, /* Gain index 242 */ + {51, 0, 3, 1}, /* Gain index 241 */ + {52, 0, 9, 1}, /* Gain index 240 */ + {53, 0, 14, 1}, /* Gain index 239 */ + {54, 0, 18, 1}, /* Gain index 238 */ + {56, 0, 0, 0} /* Gain index 237 */ + +}; + +/** + * \brief Default SnRx gain table settings + */ +uint8_t SnRxGainTable [53][4] = +{ + /* Order: {FE table, LNA Bypass, Digital Gain/Atten, Enable Atten} */ + {0, 0, 0, 0}, /* Gain index 255 */ + {1, 0, 7, 1}, /* Gain index 254 */ + {3, 0, 1, 0}, /* Gain index 253 */ + {3, 0, 15, 1}, /* Gain index 252 */ + {5, 0, 0, 0}, /* Gain index 251 */ + {6, 0, 2, 1}, /* Gain index 250 */ + {7, 0, 2, 1}, /* Gain index 249 */ + {8, 0, 12, 1}, /* Gain index 248 */ + {9, 0, 7, 1}, /* Gain index 247 */ + {11, 0, 1, 0}, /* Gain index 246 */ + {11, 0, 15, 1},/* Gain index 245 */ + {13, 0, 1, 0}, /* Gain index 244 */ + {14, 0, 2, 0}, /* Gain index 243 */ + {14, 0, 10, 1},/* Gain index 242 */ + {15, 0, 0, 0}, /* Gain index 241 */ + {15, 0, 20, 1},/* Gain index 240 */ + {16, 0, 2, 1}, /* Gain index 239 */ + {16, 0, 22, 1},/* Gain index 238 */ + {17, 0, 1, 0}, /* Gain index 237 */ + {17, 0, 15, 1},/* Gain index 236 */ + {17, 0, 35, 1},/* Gain index 235 */ + {17, 0, 55, 1},/* Gain index 234 */ + {18, 0, 7, 1}, /* Gain index 233 */ + {18, 0, 27, 1},/* Gain index 232 */ + { 6, 1, 7, 1}, /* Gain index 231 */ + { 7, 1, 7, 1}, /* Gain index 230 */ + { 8, 1, 17, 1}, /* Gain index 229 */ + { 9, 1, 12, 1}, /* Gain index 228 */ + {11, 1, 0, 0}, /* Gain index 227 */ + {12, 1, 3, 1}, /* Gain index 226 */ + {13, 1, 0, 0}, /* Gain index 225 */ + {14, 1, 1, 0}, /* Gain index 224 */ + {14, 1, 15, 1},/* Gain index 223 */ + {15, 1, 5, 1}, /* Gain index 222 */ + {15, 1, 25, 1},/* Gain index 221 */ + {16, 1, 7, 1}, /* Gain index 220 */ + {16, 1, 27, 1},/* Gain index 219 */ + {17, 1, 0, 0}, /* Gain index 218 */ + {17, 1, 20, 1},/* Gain index 217 */ + {17, 1, 40, 1},/* Gain index 216 */ + {17, 1, 60, 1},/* Gain index 215 */ + {18, 1, 12, 1},/* Gain index 214 */ + {18, 1, 32, 1},/* Gain index 213 */ + {18, 1, 52, 1},/* Gain index 212 */ + {18, 1, 72, 1},/* Gain index 211 */ + {18, 1, 92, 1},/* Gain index 210 */ + {19, 1, 1, 0}, /* Gain index 209 */ + {19, 1, 15, 1},/* Gain index 208 */ + {19, 1, 35, 1},/* Gain index 207 */ + {19, 1, 55, 1},/* Gain index 206 */ + {19, 1, 75, 1},/* Gain index 205 */ + {19, 1, 95, 1},/* Gain index 204 */ + {19, 1, 115, 1}/* Gain index 203 */ +}; + diff --git a/df_datalink_ge/src/hardware/mykonos/mykonos_user.h b/df_datalink_ge/src/hardware/mykonos/mykonos_user.h new file mode 100644 index 0000000..2875837 --- /dev/null +++ b/df_datalink_ge/src/hardware/mykonos/mykonos_user.h @@ -0,0 +1,85 @@ +/** + * \file mykonos_user.h + * + * \brief Contains macro definitions and global structure declarations for mykonos_user.c + * + * Mykonos API version: 1.5.2.3566 + */ + +/** +* \page Disclaimer Legal Disclaimer +* Copyright 2015-2017 Analog Devices Inc. +* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file. +* +*/ + +#ifndef _MYKONOSPROFILES_H_ +#define _MYKONOSPROFILES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* turns verbose messaging on */ +#define MYKONOS_VERBOSE 1 +#define MYK_ENABLE_SPIWRITEARRAY 1 + +/* 3 Bytes per SPI transaction * 341 transactions = ~1024 byte buffer size */ +/* Minimum MYK_SPIWRITEARRAY_BUFFERSIZE = 27 */ +#define MYK_SPIWRITEARRAY_BUFFERSIZE 341 +/* + ***************************************** + * Rx, ObsRx, and Sniffer gain tables + ****************************************** + */ +#define MAX_GAIN_TABLE_INDEX 255 + +#define START_RX_GAIN_INDEX 255 +#define MAX_RX_GAIN_TABLE_NUMINDEXES (START_RX_GAIN_INDEX + 1) +#define MIN_RX_GAIN_TABLE_INDEX 0 + +#define START_ORX_GAIN_INDEX 47 +#define MAX_ORX_GAIN_TABLE_NUMINDEXES (START_ORX_GAIN_INDEX + 1) +#define MIN_ORX_GAIN_TABLE_INDEX (MAX_GAIN_TABLE_INDEX - START_ORX_GAIN_INDEX) + +#define START_SNRX_GAIN_INDEX 127 +#define MAX_SNRX_GAIN_TABLE_NUMINDEXES (START_SNRX_GAIN_INDEX + 1) +#define MIN_SNRX_GAIN_TABLE_INDEX (MAX_GAIN_TABLE_INDEX - START_SNRX_GAIN_INDEX) + +#define START_LOOPBACK_GAIN_INDEX 47 +#define MAX_LOOPBACK_GAIN_TABLE_NUMINDEXES (START_LOOPBACK_GAIN_INDEX + 1) +#define MIN_LOOPBACK_GAIN_TABLE_INDEX (MAX_GAIN_TABLE_INDEX - START_SNRX_GAIN_INDEX) + +extern uint8_t RxGainTable [61][4]; +extern uint8_t ORxGainTable [19][4]; +extern uint8_t SnRxGainTable [53][4]; + + +/* + ******************************************** + * Rx, Sniffer, ObsRx and Tx Profiles limits + ******************************************** + */ +#define MIN_RX_IQRATE_KHZ 15000 /*!< Mykonos minimum IQ rate for the Rx channel, expressed in KHz */ +#define MAX_RX_IQRATE_KHZ 320000 /*!< Mykonos maximum IQ rate for the Rx channel, expressed in KHz */ + +#define MIN_TX_IQRATE_KHZ 15000 /*!< Mykonos minimum IQ rate for the Tx channel, expressed in KHz */ +#define MAX_TX_IQRATE_KHZ 492000 /*!< Mykonos maximum IQ rate for the Tx channel, expressed in KHz */ + +#define MIN_SNIFFER_RFBW_HZ 5000000 /*!< Mykonos minimum Sniffer channel bandwidth expressed in Hz */ +#define MAX_SNIFFER_RFBW_HZ 20000000 /*!< Mykonos maximum Sniffer channel bandwidth expressed in Hz */ + +#define MIN_ORX_RFBW_HZ 5000000 /*!< Mykonos minimum Observation channel bandwidth expressed in Hz */ +#define MAX_ORX_RFBW_HZ 250000000 /*!< Mykonos maximum Observation channel bandwidth expressed in Hz */ + +#define MIN_RX_RFBW_HZ 5000000 /*!< Mykonos minimum Rx channel bandwidth expressed in Hz */ +#define MAX_RX_RFBW_HZ 100000000 /*!< Mykonos maximum Rx channel bandwidth expressed in Hz */ + +#define MIN_TX_RFBW_HZ 20000000 /*!< Mykonos minimum Tx channel bandwidth expressed in Hz */ +#define MAX_TX_RFBW_HZ 250000000 /*!< Mykonos maximum Tx channel bandwidth expressed in Hz */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/df_datalink_ge/src/hardware/mykonos/mykonos_version.h b/df_datalink_ge/src/hardware/mykonos/mykonos_version.h new file mode 100644 index 0000000..c7f58d2 --- /dev/null +++ b/df_datalink_ge/src/hardware/mykonos/mykonos_version.h @@ -0,0 +1,31 @@ +/** + * \file mykonos_version.h + * \brief Contains the version number for the Mykonos API + * + * Mykonos API version: 1.5.2.3566 + */ + +/** +* \page Disclaimer Legal Disclaimer +* Copyright 2015-2017 Analog Devices Inc. +* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in * this zip file. +* +*/ + +#ifndef MYKONOS_VERSION_H_ +#define MYKONOS_VERSION_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define MYKONOS_CURRENT_SI_VERSION 1 /*!< Mykonos current silicon version */ +#define MYKONOS_CURRENT_MAJOR_VERSION 5 /*!< Mykonos current ARM major version */ +#define MYKONOS_CURRENT_MINOR_VERSION 2 /*!< Mykonos current ARM minor version */ +#define MYKONOS_CURRENT_BUILD_VERSION 3566 /*!< Mykonos current API build version */ + +#ifdef __cplusplus +} +#endif + +#endif /* MYKONOS_VERSION_H_ */ diff --git a/df_datalink_ge/src/hardware/mykonos/t_ad9528.h b/df_datalink_ge/src/hardware/mykonos/t_ad9528.h new file mode 100644 index 0000000..02cd278 --- /dev/null +++ b/df_datalink_ge/src/hardware/mykonos/t_ad9528.h @@ -0,0 +1,194 @@ +/** + * \file t_ad9528.h + * \brief Contains enum and structure data types for all AD9528 function calls + */ + +/** +* \page Disclaimer Legal Disclaimer +* Copyright 2015-2017 Analog Devices Inc. +* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file. +* +*/ + +#ifndef _AD9528_TYPES_H_ +#define _AD9528_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "../common.h" + +/* AD9528 SPI Address defines */ +#define AD9528_ADDR_ADI_SPI_CONFIG_A 0x000 +#define AD9528_ADDR_ADI_SPI_CONFIG_B 0x001 +#define AD9528_ADDR_IO_UPDATE 0x00F + +#define AD9528_ADDR_REF_A_DIVIDER_LSB 0x100 +#define AD9528_ADDR_REF_A_DIVIDER_MSB 0x101 +#define AD9528_ADDR_REF_B_DIVIDER_LSB 0x102 +#define AD9528_ADDR_REF_B_DIVIDER_MSB 0x103 +#define AD9528_ADDR_PLL1_N_DIV_LSB 0x104 +#define AD9528_ADDR_PLL1_N_DIV_MSB 0x105 +#define AD9528_ADDR_PLL1_CHARGEPUMP 0x106 +#define AD9528_ADDR_PLL1_CP_CTRL2 0x107 +#define AD9528_ADDR_INPUT_RECEIVERS1 0x108 +#define AD9528_ADDR_INPUT_RECEIVERS2 0x109 +#define AD9528_ADDR_INPUT_RECEIVERS3 0x10A +#define AD9528_ADDR_PLL1_FASTLOCK 0x10B + +#define AD9528_ADDR_PLL2_CHARGEPUMP 0x200 +#define AD9528_ADDR_PLL2_N_DIV 0x201 +#define AD9528_ADDR_PLL2_CTRL 0x202 +#define AD9528_ADDR_PLL2_VCO_CTRL 0x203 +#define AD9528_ADDR_PLL2_VCO_DIV 0x204 +#define AD9528_ADDR_PLL2_LF_CTRL1 0x205 +#define AD9528_ADDR_PLL2_LF_CTRL2 0x206 +#define AD9528_ADDR_PLL2_RDIV 0x207 +#define AD9528_ADDR_PLL2_REPLICA_CHDIV 0x208 +#define AD9528_ADDR_PLL2_REPLICA_DIV_PHASE 0x209 + +#define AD9528_ADDR_CH_OUT0_CTRL1 0x300 +#define AD9528_ADDR_CH_OUT0_CTRL2 0x301 +#define AD9528_ADDR_CH_OUT0_CHDIV 0x302 +#define AD9528_ADDR_OUTPUT_SYNC 0x32A +#define AD9528_ADDR_MASK_SYNC1 0x32B +#define AD9528_ADDR_MASK_SYNC2 0x32C +#define AD9528_ADDR_EN_OUTPUT_PATH_SEL1 0x32D +#define AD9528_ADDR_EN_OUTPUT_PATH_SEL2 0x32E + +#define AD9528_ADDR_SYSERF_DIV_LSB 0x400 +#define AD9528_ADDR_SYSERF_DIV_MSB 0x401 +#define AD9528_ADDR_SYSREF_CTRL3 0x402 +#define AD9528_ADDR_SYSREF_CTRL4 0x403 +#define AD9528_ADDR_SYSREF_CTRL5 0x404 + +#define AD9528_ADDR_POWERDOWN_CTRL 0x500 +#define AD9528_ADDR_CH_POWERDOWN1 0x501 +#define AD9528_ADDR_CH_POWERDOWN2 0x502 +#define AD9528_ADDR_LDO_ENABLES1 0x503 +#define AD9528_ADDR_LDO_ENABLES2 0x504 +#define AD9528_ADDR_STATUS0_CTRL 0x505 +#define AD9528_ADDR_STATUS1_CTRL 0x506 +#define AD9528_ADDR_STATUS_OE 0x507 +#define AD9528_ADDR_STATUS_READBACK0 0x508 +#define AD9528_ADDR_STATUS_READBACK1 0x509 + + + +///Enum to select what source outputs from each AD9528 output channel +typedef enum +{ + CHANNEL_DIV = 0, PLL1_OUTPUT = 1, //VCXO frequency + SYSREF = 2, + INV_PLL1_OUTPUT = 5 //VCXO inverted +} ad9528outSourceSel_t; + +///Enum to select what output buffer standard is used for the clock outputs +typedef enum +{ + LVDS = 0, LVDS_BOOST = 1, HSTL = 2 +} ad9528outBufferControl_t; + +///Enum to select the clock input buffer mode. +typedef enum +{ + DISABLED = 0, SINGLE_ENDED, NEG_SINGLE_ENDED, DIFFERENTIAL +} ad9528RefBuffer_t; + +/// Structure to hold AD9528 PLL1 settings +typedef struct +{ + uint32_t refA_Frequency_Hz; + uint16_t refA_Divider; + ad9528RefBuffer_t refA_bufferCtrl; + + uint32_t refB_Frequency_Hz; + uint16_t refB_Divider; + ad9528RefBuffer_t refB_bufferCtrl; + + uint32_t vcxo_Frequency_Hz; + ad9528RefBuffer_t vcxoBufferCtrl; + + uint16_t nDivider; + uint8_t bypassPll1; +} ad9528pll1Settings_t; + +/// Structure to hold AD9528 PLL2 settings +typedef struct +{ + uint8_t rfDivider; //VCO divider: Valid range (3,4,5) + uint8_t n2Divider; //PLL2 N2 Divider + uint8_t totalNdiv; //NDiv = 4*Bdiv + Adiv //Bdiv valid range (3 to 63), Adiv valid range (0-3) +} ad9528pll2Settings_t; + +/// Structure to hold AD9528 Output Clock settings +typedef struct +{ + uint16_t outPowerDown; //bit per output, if 1 power down that output. + ad9528outSourceSel_t outSource[14]; //CHANNEL_DIV, PLL1_OUTPUT, SYSREF, INV_PLL1_OUTPUT + ad9528outBufferControl_t outBufferCtrl[14]; //LVDS, LVDS_BOOST, HSTL + uint8_t outAnalogDelay[14]; //5 bits + uint8_t outDigitalDelay[14]; //6 bits, 1/2 clock resolution @ channel div input frequency + uint8_t outChannelDiv[14]; //8 bit channel divider + uint32_t outFrequency_Hz[14]; //output clock frequency per clock output +} ad9528outputSettings_t; + +///Enum to select the SYSREF output source +typedef enum +{ + EXTERNAL = 0, EXT_RESAMPLED = 1, INTERNAL = 2 +} sysrefSourceSelection_t; + +///Enum to choose the SYSREF pattern mode. +typedef enum +{ + NSHOT = 0, CONTINUOUS = 1, PRBS = 2, STOP = 3 +} sysrefPatternMode_t; + +///Enum to select the SYSREF input pin mode. +typedef enum +{ + LEVEL_ACTIVE_HIGH = 0, LEVEL_ACTIVE_LOW = 1, RISING_EDGE = 2, FALLING_EDGE = 3 +} sysrefPinEdgeMode_t; + +///Enum to select the SYSREF output # of pulses for NSHOT mode. +typedef enum +{ + ONE_PULSE = 0, TWO_PULSES = 2, FOUR_PULSES = 3, SIX_PULSES = 4, EIGHT_PULSES = 5 +} sysrefNshotMode_t; + +//Enum to select how a SYSREF is requested. +typedef enum +{ + SPI = 0, PIN = 1 +} sysrefRequestMethod_t; + +/// Structure to hold AD9528 SYSREF output settings +typedef struct +{ + sysrefRequestMethod_t sysrefRequestMethod; + sysrefSourceSelection_t sysrefSource; + sysrefPinEdgeMode_t sysrefPinEdgeMode; + ad9528RefBuffer_t sysrefPinBufferMode; + sysrefPatternMode_t sysrefPatternMode; + sysrefNshotMode_t sysrefNshotMode; + uint16_t sysrefDivide; + +} ad9528sysrefSettings_t; + +/// Structure to hold AD9528 settings +typedef struct +{ + spiSettings_t *spiSettings; + ad9528pll1Settings_t *pll1Settings; + ad9528pll2Settings_t *pll2Settings; + ad9528outputSettings_t *outputSettings; + ad9528sysrefSettings_t *sysrefSettings; +} ad9528Device_t; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/df_datalink_ge/src/hardware/mykonos/t_mykonos.h b/df_datalink_ge/src/hardware/mykonos/t_mykonos.h new file mode 100644 index 0000000..66db0d7 --- /dev/null +++ b/df_datalink_ge/src/hardware/mykonos/t_mykonos.h @@ -0,0 +1,1710 @@ +/*! + * \file t_mykonos.h + * \brief Contains type definitions for Mykonos API + * + * Mykonos API version: 1.5.2.3566 + */ + +/** +* \page Disclaimer Legal Disclaimer +* Copyright 2015-2017 Analog Devices Inc. +* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file. +* +*/ + +#ifndef _T_MYKONOS_LIB_H_ +#define _T_MYKONOS_LIB_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "../common.h" + + +/** + * \brief Enum of unique error codes from the Mykonos API functions. + * Each error condition in the library should get its own enum value to allow + * easy debug of errors. + */ +typedef enum +{ + MYKONOS_ERR_OK=0, + MYKONOS_ERR_HAL_LAYER, + MYKONOS_ERR_INV_PARM, + MYKONOS_ERR_FAILED, + MYKONOS_ERR_WAITFOREVENT_INV_PARM, + MYKONOS_ERR_WAITFOREVENT_TIMEDOUT, + MYKONOS_ERR_SETENSM_INVALID_NEWSTATE_WAIT, + MYKONOS_ERR_SETENSM_INVALID_NEWSTATE_ALERT, + MYKONOS_ERR_SETENSM_INVALID_NEWSTATE_TXRX, + MYKONOS_ERR_SETENSM_INVALIDSTATE, + MYKONOS_ERR_PU_RXPATH_INV_PARAM, + MYKONOS_ERR_PU_TXPATH_INV_PARAM, + MYKONOS_ERR_PU_OBSRXPATH_INV_PARAM, + MYKONOS_ERR_INIT_INV_ORXCHAN, + MYKONOS_ERR_INIT_INV_RXSYNCB_ORXSYNCB_MODE, + MYKONOS_ERR_INIT_INV_TXFIR_INTERPOLATION, + MYKONOS_ERR_INIT_INV_TXHB2_INTERPOLATION, + MYKONOS_ERR_INIT_INV_TXHB1_INTERPOLATION, + MYKONOS_ERR_INIT_INV_RXFIR_DECIMATION, + MYKONOS_ERR_INIT_INV_RXDEC5_DECIMATION, + MYKONOS_ERR_INIT_INV_RXHB1_DECIMATION, + MYKONOS_ERR_INIT_INV_SNIFFER_RHB1, + MYKONOS_ERR_INIT_INV_SNIFFER_RFIR_DEC, + MYKONOS_ERR_INIT_INV_ORX_RHB1, + MYKONOS_ERR_INIT_INV_ORX_RFIR_DEC, + MYKONOS_ERR_INIT_INV_ADCDIV, + MYKONOS_ERR_INIT_INV_DACDIV, + MYKONOS_ERR_INIT_INV_OBSRX_ADCDIV, + MYKONOS_ERR_CLKPLL_INV_HSDIV, + MYKONOS_ERR_CLKPLL_INV_VCODIV, + MYKONOS_ERR_CLKPLL_INV_RXTXPROFILES, + MYKONOS_ERR_SETCLKPLL_INV_VCOINDEX, + MYKONOS_ERR_SETCLKPLL_INV_FRACWORD, + MYKONOS_ERR_SETRFPLL_INV_PLLNAME, + MYKONOS_ERR_SETRFPLL_INV_LO_PARM, + MYKONOS_ERR_INV_SCALEDDEVCLK_PARAM, + MYKONOS_ERR_NULL_DEVICE_PARAM, + MYKONOS_ERR_CALCDEVCLK_NULLPARAM, + MYKONOS_ERR_SETRFPLL_INV_VCOINDEX, + MYKONOS_ERR_SETRFPLL_INV_REFCLK, + MYKONOS_ERR_SETORXGAIN_INV_CHANNEL, + MYKONOS_ERR_SETORXGAIN_INV_GAIN, + MYKONOS_ERR_GETORX1GAIN_INV_POINTER, + MYKONOS_ERR_GETORX2GAIN_INV_POINTER, + MYKONOS_ERR_GETSNIFFGAIN_INV_POINTER, + MYKONOS_ERR_GETOBSRXGAIN_CH_DISABLED, + MYKONOS_ERR_SETTX1ATTEN_INV_PARM, + MYKONOS_ERR_SETTX1ATTEN_INV_STEPSIZE_PARM, + MYKONOS_ERR_SETTX2ATTEN_INV_PARM, + MYKONOS_ERR_SETTX2ATTEN_INV_STEPSIZE_PARM, + MYKONOS_ERR_PROGRAMFIR_INV_NUMTAPS_PARM, + MYKONOS_ERR_PROGRAMFIR_INV_FIRNAME_PARM, + MYKONOS_ERR_RXFIR_INV_GAIN_PARM, + MYKONOS_ERR_OBSRXFIR_INV_GAIN_PARM, + MYKONOS_ERR_SRXFIR_INV_GAIN_PARM, + MYKONOS_ERR_TXFIR_INV_GAIN_PARM, + MYKONOS_ERR_READFIR_NULL_PARM, + MYKONOS_ERR_READFIR_COEFS_NULL, + MYKONOS_ERR_READFIR_INV_FIRNAME_PARM, + MYKONOS_ERR_READFIR_INV_NUMTAPS_PARM, + MYKONOS_ERR_SETRX1GAIN_INV_GAIN_PARM, + MYKONOS_ERR_SETRX2GAIN_INV_GAIN_PARM, + MYKONOS_ERR_INITSER_INV_VCODIV_PARM, + MYKONOS_ERR_INITSER_INV_VCODIV1_HSCLK_PARM, + MYKONOS_ERR_INITSER_INV_VCODIV1P5_HSCLK_PARM, + MYKONOS_ERR_INITDES_INV_VCODIV_PARM, + MYKONOS_ERR_SER_INV_M_PARM, + MYKONOS_ERR_SER_INV_L_PARM, + MYKONOS_ERR_SER_INV_LANERATE_PARM, + MYKONOS_ERR_SER_INV_LANEEN_PARM, + MYKONOS_ERR_SER_INV_AMP_PARM, + MYKONOS_ERR_SER_INV_PREEMP_PARM, + MYKONOS_ERR_SER_INV_LANEPN_PARM, + MYKONOS_ERR_SER_LANE_CONFLICT_PARM, + MYKONOS_ERR_SER_INV_TXSER_DIV_PARM, + MYKONOS_ERR_SER_LANE_RATE_CONFLICT_PARM, + MYKONOS_ERR_SER_INV_REAL_IF_DATA_PARM, + MYKONOS_ERR_HS_AND_LANE_RATE_NOT_INTEGER_MULT, + MYKONOS_ERR_DES_HS_AND_LANE_RATE_NOT_INTEGER_MULT, + MYKONOS_ERR_DESER_INV_M_PARM, + MYKONOS_ERR_DESER_INV_L_PARM, + MYKONOS_ERR_DESER_INV_HSCLK_PARM, + MYKONOS_ERR_DESER_INV_LANERATE_PARM, + MYKONOS_ERR_DESER_INV_LANEEN_PARM, + MYKONOS_ERR_DESER_INV_EQ_PARM, + MYKONOS_ERR_DESER_INV_LANEPN_PARM, + MYKONOS_ERR_FRAMER_INV_M_PARM, + MYKONOS_ERR_FRAMER_INV_BANKID_PARM, + MYKONOS_ERR_FRAMER_INV_LANEID_PARM, + MYKONOS_ERR_FRAMER_INV_K_OFFSET_PARAM, + MYKONOS_ERR_FRAMER_INV_REAL_IF_DATA_PARM, + MYKONOS_ERR_OBSRX_FRAMER_INV_M_PARM, + MYKONOS_ERR_OBSRX_FRAMER_INV_BANKID_PARM, + MYKONOS_ERR_OBSRX_FRAMER_INV_LANEID_PARM, + MYKONOS_ERR_OBSRX_FRAMER_INV_K_OFFSET_PARAM, + MYKONOS_ERR_OBSRX_FRAMER_INV_REAL_IF_DATA_PARM, + MYKONOS_ERR_DEFRAMER_INV_M_PARM, + MYKONOS_ERR_DEFRAMER_INV_BANKID_PARM, + MYKONOS_ERR_ERR_DEFRAMER_INV_LANEID_PARM, + MYKONOS_ERR_DEFRAMER_INV_K_OFFSET_PARAM, + MYKONOS_ERR_DEFRAMER_INV_K_PARAM, + MYKONOS_ERR_DEFRAMER_INV_FK_PARAM, + MYKONOS_ERR_RX_FRAMER_INV_PRBS_POLYORDER_PARAM, + MYKONOS_ERR_OBSRX_FRAMER_INV_PRBS_POLYORDER_PARAM, + MYKONOS_ERR_DEFRAMER_INV_PRBS_ENABLE_PARAM, + MYKONOS_ERR_DEFRAMER_INV_PRBS_POLYORDER_PARAM, + MYKONOS_ERR_DEFRAMER_INV_PRBS_CNTR_SEL_PARAM, + MYKONOS_ERR_INITARM_INV_DATARATE_PARM, + MYKONOS_ERR_INITARM_INV_REGCLK, + MYKONOS_ERR_INITARM_INV_ARMCLK_PARAM, + MYKONOS_ERR_LOADHEX_INV_CHARCOUNT, + MYKONOS_ERR_LOADHEX_INVALID_FIRSTCHAR, + MYKONOS_ERR_LOADHEX_INVALID_CHKSUM, + MYKONOS_ERR_LOADBIN_INVALID_BYTECOUNT, + MYKONOS_ERR_ARM_INVALID_BUILDCHKSUM, + MYKONOS_ERR_READARMMEM_INV_ADDR_PARM, + MYKONOS_ERR_WRITEARMMEM_INV_ADDR_PARM, + MYKONOS_ERR_ARMCMD_INV_OPCODE_PARM, + MYKONOS_ERR_ARMCMD_INV_NUMBYTES_PARM, + MYKONOS_ERR_ARMCMDSTATUS_INV_OPCODE_PARM, + MYKONOS_ERR_CHECKDEVSTRUCT_SPI, + MYKONOS_ERR_CHECKDEVSTRUCT_RX, + MYKONOS_ERR_CHECKDEVSTRUCT_RXSUB, + MYKONOS_ERR_CHECKDEVSTRUCT_RXFIR, + MYKONOS_ERR_CHECKDEVSTRUCT_TX, + MYKONOS_ERR_CHECKDEVSTRUCT_TXSUB, + MYKONOS_ERR_CHECKDEVSTRUCT_TXFIR, + MYKONOS_ERR_CHECKDEVSTRUCT_OBSRX, + MYKONOS_ERR_CHECKDEVSTRUCT_OBSRXSUB, + MYKONOS_ERR_CHECKDEVSTRUCT_SNIFFERFIR, + MYKONOS_ERR_CHECKDEVSTRUCT_ORXFIR, + MYKONOS_ERR_CHECKDEVSTRUCT_ORXGAINCTRL, + MYKONOS_ERR_CHECKDEVSTRUCT_SNIFFERGAINCTRL, + MYKONOS_ERR_CHECKDEVSTRUCT_OBSRXFRAMER, + MYKONOS_ERR_INITSER_INV_PROFILE, + MYKONOS_ERR_INITDES_INV_TXPROFILE, + MYKONOS_ERR_JESD204B_ILAS_MISMATCH, + MYKONOS_ERR_RXGAINTABLE_INV_CHANNEL, + MYKONOS_ERR_RXGAINTABLE_INV_GAIN_INDEX_RANGE, + MYKONOS_ERR_WRITE_CFG_MEMORY_FAILED, + MYKONOS_ERR_INV_RXFRAMER_PCLKDIV_PARM, + MYKONOS_ERR_RXFRAMER_INV_FK_PARAM, + MYKONOS_ERR_OBSRXFRAMER_INV_FK_PARAM, + MYKONOS_ERR_INV_OBSRXFRAMER_PCLKDIV_PARM, + MYKONOS_ERR_PU_OBSRXPATH_INV_LOSOURCE_PARAM, + MYKONOS_ERR_ARM_RADIOON_FAILED, + MYKONOS_ERR_INV_RX_GAIN_MODE_PARM, + MYKONOS_ERR_INV_ORX_GAIN_MODE_PARM, + MYKONOS_ERR_INV_AGC_RX_STRUCT_INIT, + MYKONOS_ERR_INV_AGC_RX_APD_THRESH_DIFF_VS_ATTACK_GAIN_STEP, + MYKONOS_ERR_INV_AGC_RX_PEAK_WAIT_TIME_PARM, + MYKONOS_ERR_INV_AGC_RX_GAIN_UPDATE_TIME_PARM, + MYKONOS_ERR_INV_AGC_RX_APD_HIGH_THRESH_PARM, + MYKONOS_ERR_INV_AGC_RX_APD_LOW_THRESH_PARM, + MYKONOS_ERR_INV_AGC_RX_BLOCK_DET_DECAY_PARM, + MYKONOS_ERR_INV_AGC_RX_APD_GAIN_STEP_PARM, + MYKONOS_ERR_INV_AGC_RX_HB2_GAIN_STEP_PARM, + MYKONOS_ERR_INV_AGC_RX_RECOVERY_GAIN_STEP_PARM, + MYKONOS_ERR_INV_AGC_PMD_MEAS_CONFIG, + MYKONOS_ERR_INV_AGC_PMD_MEAS_DURATION, + MYKONOS_ERR_INV_AGC_RX_ENABLE_SYNC_PULSE_GAIN_COUNTER, + MYKONOS_ERR_INV_AGC_RX_LOW_THS_PREV_GAIN_INC, + MYKONOS_ERR_INV_AGC_RX_PEAK_STRUCT_INIT, + MYKONOS_ERR_INV_AGC_RX_PEAK_THRESH_MODE, + MYKONOS_ERR_INV_AGC_RX_PWR_STRUCT_INIT, + MYKONOS_ERR_INV_AGC_RX_RESET_ON_RX_ENABLE, + MYKONOS_ERR_INV_AGC_RX_SLOW_LOOP_SETTLING_DELAY, + MYKONOS_ERR_INV_AGC_RX1_MAX_GAIN_INDEX, + MYKONOS_ERR_INV_AGC_RX1_MIN_GAIN_INDEX, + MYKONOS_ERR_INV_AGC_RX2_MAX_GAIN_INDEX, + MYKONOS_ERR_INV_AGC_RX2_MIN_GAIN_INDEX, + MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_HIGH_THRESH, + MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_LOW_THRESH, + MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_HIGH_THRESH, + MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_LOW_THRESH, + MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_LOW_GAIN_STEP, + MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_HIGH_GAIN_STEP, + MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_LOW_GAIN_STEP, + MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_HIGH_GAIN_STEP, + MYKONOS_ERR_INV_AGC_RX_APD_HIGH_GAIN_STEP_PARM, + MYKONOS_ERR_INV_AGC_RX_APD_LOW_GAIN_STEP_PARM, + MYKONOS_ERR_INV_AGC_RX_HB2_HIGH_GAIN_STEP_PARM, + MYKONOS_ERR_INV_AGC_RX_HB2_HIGH_THRESH_PARM, + MYKONOS_ERR_INV_AGC_RX_HB2_LOW_GAIN_STEP_PARM, + MYKONOS_ERR_INV_AGC_RX_HB2_LOW_THRESH_PARM, + MYKONOS_ERR_INV_AGC_RX_HB2_VERY_LOW_GAIN_STEP_PARM, + MYKONOS_ERR_INV_AGC_RX_HB2_VERY_LOW_THRESH_PARM, + MYKONOS_ERR_INV_AGC_RX_PKDET_FAST_ATTACK_VALUE, + MYKONOS_ERR_INV_AGC_RX_HB2_OVLD_ENABLE, + MYKONOS_ERR_INV_AGC_RX_HB2_OVLD_DUR_CNT, + MYKONOS_ERR_INV_AGC_RX_HB2_OVLD_THRESH_CNT, + MYKONOS_ERR_INV_AGC_OBSRX_STRUCT_INIT, + MYKONOS_ERR_INV_AGC_OBSRX_APD_THRESH_DIFF_VS_ATTACK_GAIN_STEP, + MYKONOS_ERR_INV_AGC_OBSRX_PEAK_WAIT_TIME_PARM, + MYKONOS_ERR_INV_AGC_OBSRX_GAIN_UPDATE_TIME_PARM, + MYKONOS_ERR_INV_AGC_OBSRX_APD_HIGH_THRESH_PARM, + MYKONOS_ERR_INV_AGC_OBSRX_APD_LOW_THRESH_PARM, + MYKONOS_ERR_INV_AGC_OBSRX_BLOCK_DET_DECAY_PARM, + MYKONOS_ERR_INV_AGC_OBSRX_APD_GAIN_STEP_PARM, + MYKONOS_ERR_INV_AGC_OBSRX_HB2_GAIN_STEP_PARM, + MYKONOS_ERR_INV_AGC_OBSRX_RECOVERY_GAIN_STEP_PARM, + MYKONOS_ERR_INV_AGC_OBSRX_MAX_GAIN_INDEX, + MYKONOS_ERR_INV_AGC_OBSRX_MIN_GAIN_INDEX, + MYKONOS_ERR_INV_AGC_OBSRX_SELECT, + MYKONOS_ERR_INV_AGC_OBSRX_PMD_MEAS_CONFIG, + MYKONOS_ERR_INV_AGC_OBSRX_PMD_MEAS_DURATION, + MYKONOS_ERR_INV_AGC_OBSRX_ENABLE_SYNC_PULSE_GAIN_COUNTER, + MYKONOS_ERR_INV_AGC_OBSRX_LOW_THS_PREV_GAIN_INC, + MYKONOS_ERR_INV_AGC_OBSRX_PEAK_STRUCT_INIT, + MYKONOS_ERR_INV_AGC_OBSRX_PEAK_THRESH_MODE, + MYKONOS_ERR_INV_AGC_OBSRX_PWR_STRUCT_INIT, + MYKONOS_ERR_INV_AGC_OBSRX_RESET_ON_RX_ENABLE, + MYKONOS_ERR_INV_AGC_OBSRX_SLOW_LOOP_SETTLING_DELAY, + MYKONOS_ERR_INV_AGC_OBSRX1_MAX_GAIN_INDEX, + MYKONOS_ERR_INV_AGC_OBSRX1_MIN_GAIN_INDEX, + MYKONOS_ERR_INV_AGC_OBSRX2_MAX_GAIN_INDEX, + MYKONOS_ERR_INV_AGC_OBSRX2_MIN_GAIN_INDEX, + MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_HIGH_THRESH, + MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_LOW_THRESH, + MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_HIGH_THRESH, + MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_LOW_THRESH, + MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_LOW_GAIN_STEP, + MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_HIGH_GAIN_STEP, + MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_LOW_GAIN_STEP, + MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_HIGH_GAIN_STEP, + MYKONOS_ERR_INV_AGC_OBSRX_APD_HIGH_GAIN_STEP_PARM, + MYKONOS_ERR_INV_AGC_OBSRX_APD_LOW_GAIN_STEP_PARM, + MYKONOS_ERR_INV_AGC_OBSRX_HB2_HIGH_GAIN_STEP_PARM, + MYKONOS_ERR_INV_AGC_OBSRX_HB2_HIGH_THRESH_PARM, + MYKONOS_ERR_INV_AGC_OBSRX_HB2_LOW_GAIN_STEP_PARM, + MYKONOS_ERR_INV_AGC_OBSRX_HB2_LOW_THRESH_PARM, + MYKONOS_ERR_INV_AGC_OBSRX_HB2_VERY_LOW_GAIN_STEP_PARM, + MYKONOS_ERR_INV_AGC_OBSRX_HB2_VERY_LOW_THRESH_PARM, + MYKONOS_ERR_INV_AGC_OBSRX_PKDET_FAST_ATTACK_VALUE, + MYKONOS_ERR_INV_AGC_OBSRX_HB2_OVLD_ENABLE, + MYKONOS_ERR_INV_AGC_OBSRX_HB2_OVLD_DUR_CNT, + MYKONOS_ERR_INV_AGC_OBSRX_HB2_OVLD_THRESH_CNT, + MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_CALPLL_LOCK, + MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_CLKPLLCP, + MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_CLKPLL_LOCK, + MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_RXPLLCP, + MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_RXPLL_LOCK, + MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_TXPLLCP, + MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_TXPLL_LOCK, + MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_SNIFFPLLCP, + MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_SNIFFPLL_LOCK, + MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_RXBBFCALDONE, + MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_TXBBFCALDONE, + MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_RFDCCALDONE, + MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_ADCTUNECALDONE, + MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_RX1ADCPROFILE, + MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_RX2ADCPROFILE, + MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_ORXADCPROFILE, + MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_RCALDONE, + MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_ARMBUSY, + MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_INITARMDONE, + MYKONOS_ERR_TIMEDOUT_ARMMAILBOXBUSY, + MYKONOS_ERR_PU_OBSRXPATH_ARMERROR, + MYKONOS_ERR_EN_TRACKING_CALS_ARMSTATE_ERROR, + MYKONOS_ERR_SET_RADIOCTRL_PINS_ARMERROR, + MYKONOS_ERR_EN_TRACKING_CALS_ARMERROR, + MYKONOS_ERR_SETRFPLL_ARMERROR, + MYKONOS_ERR_INIT_INV_TXINPUTHB_PARM, + MYKONOS_ERR_LOAD_ADCPROFILE_INV_VCODIV, + MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_RXREQUIRED, + MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_ORXREQUIRED, + MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_SNRXREQUIRED, + MYKONOS_ERR_SETUP_PA_PROT_INV_AVG_DURATION, + MYKONOS_ERR_SETUP_PA_PROT_INV_STICKY_ENABLE, + MYKONOS_ERR_SETUP_PA_PROT_INV_ATTEN_STEP, + MYKONOS_ERR_SETUP_PA_PROT_INV_ATTEN_ENABLE, + MYKONOS_ERR_SETUP_PA_PROT_INV_POWER_THRESH, + MYKONOS_ERR_SETUP_PA_PROT_INV_TX_CHANNEL, + MYKONOS_ERR_GET_DAC_PWR_INV_POINTER, + MYKONOS_ERR_GET_PA_FLAG_STATUS_INV_POINTER, + MYKONOS_ERR_GET_OBSRX_OVERLOADS_NULL_PARM, + MYKONOS_ERR_GET_RX1_OVERLOADS_NULL_PARM, + MYKONOS_ERR_GET_RX2_OVERLOADS_NULL_PARM, + MYKONOS_ERR_GETRADIOSTATE_NULL_PARAM, + MYKONOS_ERR_ABORT_INITCALS_NULL_PARAM, + MYKONOS_ERR_ARM_RADIOOFF_FAILED, + MYKONOS_ERR_WAIT_INITCALS_NULL_PARAM, + MYKONOS_ERR_WAIT_INITCALS_CALFAILED, + MYKONOS_ERR_WAIT_INITCALS_ARMERROR, + MYKONOS_ERR_CHECK_PLL_LOCK_NULL_PARM, + MYKONOS_ERR_GET_TXFILTEROVRG_NULL_PARM, + MYKONOS_ERR_PROGRAM_RXGAIN_TABLE_NULL_PARM, + MYKONOS_ERR_PROGRAMFIR_NULL_PARM, + MYKONOS_ERR_PROGRAMFIR_COEFS_NULL, + MYKONOS_ERR_READ_DEFRAMERSTATUS_NULL_PARAM, + MYKONOS_ERR_READ_DEFRAMERPRBS_NULL_PARAM, + MYKONOS_ERR_READ_ORXFRAMERSTATUS_NULL_PARAM, + MYKONOS_ERR_READ_RXFRAMERSTATUS_NULL_PARAM, + MYKONOS_ERR_ARMCMDSTATUS_NULL_PARM, + MYKONOS_ERR_READARMCMDSTATUS_INV_OPCODE_PARM, + MYKONOS_ERR_READARMCMDSTATUS_NULL_PARM, + MYKONOS_ERR_READARMCMDSTATUSBYTE_NULL_PARM, + MYKONOS_ERR_ARMCMD_NULL_PARM, + MYKONOS_ERR_WRITEARMMEM_NULL_PARM, + MYKONOS_ERR_LOADBIN_NULL_PARAM, + MYKONOS_ERR_ARM_INV_ADDR_PARM, + MYKONOS_ERR_LOADARMCON_INVALID_BYTECOUNT, + MYKONOS_ERR_LOADARMCON_NULL_PARAM, + MYKONOS_ERR_GETTX1ATTEN_NULL_PARM, + MYKONOS_ERR_GETTX2ATTEN_NULL_PARM, + MYKONOS_ERR_ENFRAMERLINK_INV_LANESEN_PARM, + MYKONOS_ERR_ENOBSFRAMERLINK_INV_LANESEN_PARM, + MYKONOS_ERR_ENTXNCO_TXPROFILE_INVALID, + MYKONOS_ERR_ENTXNCO_TX1_FREQ_INVALID, + MYKONOS_ERR_ENTXNCO_TX2_FREQ_INVALID, + MYKONOS_ERR_JESD204B_ILAS_MISMATCH_NULLPARAM, + MYKONOS_ERR_LOAD_LBADCPROFILE_ARMMEM_FAILED, + MYKONOS_ERR_LOAD_SNRXADCPROFILE_ARMMEM_FAILED, + MYKONOS_ERR_LOAD_ADCPROFILE_SNRX_ADCDIV_ZERO, + MYKONOS_ERR_LOAD_ORXADCPROFILE_ARMMEM_FAILED, + MYKONOS_ERR_LOAD_ADCPROFILE_ORXADCDIV_ZERO, + MYKONOS_ERR_LOAD_RXADCPROFILE_ARMMEM_FAILED, + MYKONOS_ERR_LOAD_ADCPROFILE_RXADCDIV_ZERO, + MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_LBREQUIRED, + MYKONOS_ERR_LOAD_ADCPROFILE_MISSING_ORX_PROFILE, + MYKONOS_ERR_GETRFPLL_INV_PLLNAME, + MYKONOS_ERR_GETRFPLL_ARMERROR, + MYKONOS_ERR_GETRFPLL_NULLPARAM, + MYKONOS_ERR_INITARM_INV_VCODIV, + MYKONOS_ERR_GET_PLLFREQ_INV_HSDIV, + MYKONOS_ERR_GET_PLLFREQ_INV_VCODIV, + MYKONOS_ERR_GET_PLLFREQ_INV_REFCLKDIV, + MYKONOS_ERR_SETORXGAIN_INV_ORX1GAIN, + MYKONOS_ERR_SETORXGAIN_INV_ORX2GAIN, + MYKONOS_ERR_SETORXGAIN_INV_SNRXGAIN, + MYKONOS_ERR_GET_RX1_DEC_POWER_NUM_SAMPLES, + MYKONOS_ERR_GET_RX1_DEC_POWER_NULL_PARM, + MYKONOS_ERR_GET_RX2_DEC_POWER_NUM_SAMPLES, + MYKONOS_ERR_GET_RX2_DEC_POWER_NULL_PARM, + MYKONOS_ERR_GET_OBSRX_DEC_POWER_NUM_SAMPLES, + MYKONOS_ERR_GET_OBSRX_DEC_POWER_NULL_PARM, + MYKONOS_ERR_GETARMVER_NULL_PARM, + MYKONOS_ERR_EN_CLGCTRACKING_ARMSTATE_ERROR, + MYKONOS_ERR_EN_DPDTRACKING_ARMSTATE_ERROR, + MYKONOS_ERR_RESTDPDMOD_WRONGBUFFERSIZE, + MYKONOS_ERR_RESTDPDMOD_ARMSTATE, + MYKONOS_ERR_RESTDPDMOD_INVALID_TXCHANNEL, + MYKONOS_ERR_RESTDPDMOD_ARMERRFLAG, + MYKONOS_ERR_SAVDPDMOD_WRONGBUFFERSIZE, + MYKONOS_ERR_SAVDPDMOD_ARMSTATE, + MYKONOS_ERR_SAVDPDMOD_INVALID_TXCHANNEL, + MYKONOS_ERR_SAVDPDMOD_ARMERRFLAG, + MYKONOS_ERR_WRITEARMCFG_ARMERRFLAG, + MYKONOS_ERR_CFGDPD_TXORX_PROFILE_INV, + MYKONOS_ERR_CFGDPD_NULL_DPDCFGSTRUCT, + MYKONOS_ERR_CFGDPD_INV_DPDDAMPING, + MYKONOS_ERR_CFGDPD_INV_DPDSAMPLES, + MYKONOS_ERR_CFGDPD_INV_DPDOUTLIERTHRESH, + MYKONOS_ERR_CFGDPD_INV_DPDPRIORWEIGHT, + MYKONOS_ERR_CFGCLGC_INV_DESIREDGAIN, + MYKONOS_ERR_CFGCLGC_INV_TXATTENLIMIT, + MYKONOS_ERR_CFGCLGC_INV_CLGC_CTRLRATIO, + MYKONOS_ERR_SETCLGCGAIN_INV_DESIREDGAIN, + MYKONOS_ERR_SETCLGCGAIN_INV_TXCHANNEL, + MYKONOS_ERR_SETCLGCGAIN_TRACK_ARMERRFLAG, + MYKONOS_ERR_CFGDPD_INV_DPD_ADDDELAY, + MYKONOS_ERR_CFGDPD_INV_PNSEQLEVEL, + MYKONOS_ERR_READARMCFG_ARMERRFLAG, + MYKONOS_ERR_GETPENDTRKCALS_NULL_PARAM, + MYKONOS_ERR_ARMCMDSTATUS_ARMERROR, + MYKONOS_ERR_WAITARMCMDSTATUS_TIMEOUT, + MYKONOS_ERR_PU_GETOBSRXPATH_ARMERROR, + MYKONOS_ERR_GETDPDCFG_NULL_DPDCFGSTRUCT, + MYKONOS_ERR_GETDPDCFG_TXORX_PROFILE_INV, + MYKONOS_ERR_GETDPDSTATUS_ARMERRFLAG, + MYKONOS_ERR_GETDPDSTATUS_NULLPARAM, + MYKONOS_ERR_SETDEFOBSRXPATH_NULL_OBSRX_STRUCT, + MYKONOS_ERR_SETDEFOBSRXPATH_NULL_DEF_OBSRX_STRUCT, + MYKONOS_ERR_GETCLGCSTATUS_NULLPARAM, + MYKONOS_ERR_GETCLGCSTATUS_ARMERRFLAG, + MYKONOS_ERR_CHECKDEVSTRUCT_NULLDEVPOINTER, + MYKONOS_ERR_READ_DEFFIFODEPTH_NULL_PARAM, + MYKONOS_ERR_READ_DEFFIFODEPTH_LMFCCOUNT_NULL_PARAM, + MYKONOS_ERR_GETDPDSTATUS_INV_CH, + MYKONOS_ERR_GETCLGCSTATUS_INV_CH, + MYKONOS_ERR_INIT_INV_TXINPUTHB_INV_RATE, + MYKONOS_ERR_INIT_INV_TXINPUTHB0_INV_RATE, + MYKONOS_ERR_TXFIR_TAPSEXCEEDED, + MYKONOS_ERR_TXFIR_INV_NUMROWS, + MYKONOS_ERR_TXFIR_INV_NUMTAPS_PARM, + MYKONOS_ERR_RXFIR_TAPSEXCEEDED, + MYKONOS_ERR_ORXFIR_TAPSEXCEEDED, + MYKONOS_ERR_SNRXFIR_TAPSEXCEEDED, + MYKONOS_ERR_GETINITCALSTATUS_NULL_PARAM, + MYKONOS_ERR_GETINITCALSTATUS_ARMERROR, + MYKONOS_ERR_CFGDPD_INV_NUMWEIGHTS, + MYKONOS_ERR_CFGDPD_INV_MODELVERSION, + MYKONOS_ERR_SETDPDACT_INV_TXCHANNEL, + MYKONOS_ERR_SETDPDACT_INV_STATE, + MYKONOS_ERR_SETDPDACT_ARMERRFLAG, + MYKONOS_ERR_CFGCLGC_TXORX_PROFILE_INV, + MYKONOS_ERR_CFGCLGC_NULL_CLGCCFGSTRUCT, + MYKONOS_ERR_GETCLGCCFG_TXORX_PROFILE_INV, + MYKONOS_ERR_GETCLGCCFG_NULL_CFGSTRUCT, + MYKONOS_ERR_CALCDIGCLK_NULLDEV_PARAM, + MYKONOS_ERR_CALCDIGCLK_NULL_CLKSTRUCT, + MYKONOS_ERR_CFGCLGC_INV_CLGC_ADDDELAY, + MYKONOS_ERR_CFGCLGC_INV_PNSEQLEVEL, + MYKONOS_ERR_CFGVSWR_TXORX_PROFILE_INV, + MYKONOS_ERR_CFGVSWR_ARMSTATE_ERROR, + MYKONOS_ERR_CFGVSWR_INV_3P3GPIOPIN, + MYKONOS_ERR_CFGVSWR_INV_PNSEQLEVEL, + MYKONOS_ERR_CFGVSWR_INV_VSWR_ADDDELAY, + MYKONOS_ERR_CFGVSWR_NULL_VSWRCFGSTRUCT, + MYKONOS_ERR_GETVSWRCFG_NULL_CFGSTRUCT, + MYKONOS_ERR_GETVSWRCFG_TXORX_PROFILE_INV, + MYKONOS_ERR_GETVSWRSTATUS_ARMERRFLAG, + MYKONOS_ERR_GETVSWRSTATUS_INV_CH, + MYKONOS_ERR_GETVSWRSTATUS_NULLPARAM, + MYKONOS_ERR_SET_RX_MAX_GAIN_INDEX, + MYKONOS_ERR_SET_RX_MIN_GAIN_INDEX, + MYKONOS_ERR_AGC_MIN_MAX_RX_CHANNEL, + MYKONOS_ERR_SET_ORX_MAX_GAIN_INDEX_CHANNEL, + MYKONOS_ERR_SET_ORX_MAX_GAIN_INDEX, + MYKONOS_ERR_SET_ORX_MIN_GAIN_INDEX, + MYKONOS_ERR_AGC_MIN_MAX_ORX_CHANNEL, + MYKONOS_ERR_RX1_TEMP_GAIN_COMP_RANGE, + MYKONOS_ERR_RX2_TEMP_GAIN_COMP_RANGE, + MYKONOS_ERR_OBS_RX_TEMP_GAIN_COMP_RANGE, + MYKONOS_ERR_RX1_TEMP_GAIN_COMP_STEP, + MYKONOS_ERR_RX2_TEMP_GAIN_COMP_STEP, + MYKONOS_ERR_OBS_RX_TEMP_GAIN_COMP_STEP, + MYKONOS_ERR_RX1_TEMP_GAIN_COMP_NULL, + MYKONOS_ERR_RX2_TEMP_GAIN_COMP_NULL, + MYKONOS_ERR_OBS_RX_TEMP_GAIN_COMP_NULL, + MYKONOS_ERR_GETTXLOLSTATUS_NULLPARAM, + MYKONOS_ERR_GETTXLOLSTATUS_INV_CH, + MYKONOS_ERR_GETTXLOLSTATUS_ARMERRFLAG, + MYKONOS_ERR_GETTXQECSTATUS_NULLPARAM, + MYKONOS_ERR_GETTXQECSTATUS_INV_CH, + MYKONOS_ERR_GETTXQECSTATUS_ARMERRFLAG, + MYKONOS_ERR_GETRXQECSTATUS_NULLPARAM, + MYKONOS_ERR_GETRXQECSTATUS_INV_CH, + MYKONOS_ERR_GETRXQECSTATUS_ARMERRFLAG, + MYKONOS_ERR_GETORXQECSTATUS_NULLPARAM, + MYKONOS_ERR_GETORXQECSTATUS_INV_CH, + MYKONOS_ERR_GETORXQECSTATUS_ARMERRFLAG, + MYKONOS_ERR_RESCHEDULE_TRACK_CAL_INV, + MYKONOS_ERR_RESCHEDULE_TRACK_ARMERRFLAG, + + MYKONOS_ERR_SETSTATEALL_TRACK_CAL_INV, + MYKONOS_ERR_SETSTATEALL_TRACK_ARMERRFLAG, + + MYKONOS_ERR_GETSTATEALL_TRACK_NULL_PARAM, + MYKONOS_ERR_GETSTATEALL_TRACK_ARMERRFLAG, + MYKONOS_ERR_GETSTATEALL_TRACK_ARMERROR, + + MYKONOS_ERR_SETSTATE_TRACK_CAL_INV, + MYKONOS_ERR_SETSTATE_TRACK_ARMERRFLAG, + + MYKONOS_ERR_GETSTATE_TRACK_NULL_PARAM, + MYKONOS_ERR_GETSTATE_TRACK_ARMERRFLAG, + MYKONOS_ERR_GETSTATE_TRACK_ARMERROR, + + MYKONOS_ERR_ARMSTATE_PROFILE_ERROR, + MYKONOS_ERR_ARMSTATE_CAL_ERROR, + MYKONOS_ERR_ARMSTATE_EXCEPTION, + MYKONOS_ERR_WAITARMCSTATE_TIMEOUT, + + MYKONOS_ERR_GETPRODUCTID_NULL_PARAM, + MYKONOS_ERR_GET_API_VERSION_NULL_PARAM, + + MYKONOS_ERR_PROFILES_HSDIGCLK, + MYKONOS_ERR_RXPROFILE_RXCHANNEL, + MYKONOS_ERR_RXPROFILE_IQRATE, + MYKONOS_ERR_RXPROFILE_RFBW, + MYKONOS_ERR_RXPROFILE_FILTER_DECIMATION, + MYKONOS_ERR_RXPROFILE_FIR_COEFS, + MYKONOS_ERR_RXPROFILE_ADCDIV, + MYKONOS_ERR_TXPROFILE_IQRATE, + MYKONOS_ERR_TXPROFILE_RFBW, + MYKONOS_ERR_TXPROFILE_FILTER_INTERPOLATION, + MYKONOS_ERR_TXPROFILE_FIR_COEFS, + MYKONOS_ERR_TXPROFILE_DACDIV, + MYKONOS_ERR_RESET_TXLOL_INV_PARAM, + MYKONOS_ERR_RESET_TXLOL_ARMERROR, + MYKONOS_ERR_SETRFPLL_LF_INV_STABILITY, + MYKONOS_ERR_SETRFPLL_LF_PLLNAME, + MYKONOS_ERR_SETRFPLL_LF_INV_TXRX_LOOPBANDWIDTH, + MYKONOS_ERR_SETRFPLL_LF_INV_SNF_LOOPBANDWIDTH, + MYKONOS_ERR_SETRFPLL_LF_ARMERROR, + MYKONOS_ERR_GETRFPLL_LF_ARMERROR, + MYKONOS_ERR_GETRFPLL_LF_NULLPARAM, + MYKONOS_ERR_GETRFPLL_LF_INV_PLLNAME, + MYKONOS_ERR_DC_OFFSET_INV_CHAN, + MYKONOS_ERR_SET_RF_DC_OFFSET_INV_MEASURECNT, + MYKONOS_ERR_SET_RF_DC_OFFSET_MEASURECNT_MIN_LIMIT, + MYKONOS_ERR_GET_RF_DC_OFFSET_NULL_MEASURECNT, + MYKONOS_ERR_RF_DC_OFFSET_INV_ENABLE_MASK, + MYKONOS_ERR_RF_DC_OFFSET_NULL_ENABLE_MASK, + MYKONOS_ERR_SET_DIG_DC_OFFSET_INV_MSHIFT, + MYKONOS_ERR_GET_DIG_DC_OFFSET_NULL_MSHIFT, + MYKONOS_ERR_DIG_DC_OFFSET_INV_ENABLE_MASK, + MYKONOS_ERR_DIG_DC_OFFSET_NULL_ENABLE_MASK, + MYKONOS_ERR_CFGCLGC_INV_THRESHOLD, + MYKONOS_ERR_RESETDPD_INV_TXCHANNEL, + MYKONOS_ERR_RESETDPD_ARMERRFLAG, + MYKONOS_ERR_RESETDPD_WRONG_PARAM, + MYKONOS_WRN_RADIO_ON_NOT_MODIFIABLE, + MYKONOS_ERR_SET_PATH_DELAY_NULL_PARAM, + MYKONOS_ERR_SET_PATH_DELAY_PARAM_OUT_OF_RANGE, + MYKONOS_ERR_GET_PATH_DELAY_NULL_PARAM, + MYKONOS_ERR_GET_PATH_DELAY_INVALID_SELECTION, + MYKONOS_ERR_GET_PATH_DELAY_ARMERRFLAG, + + + MYKONOS_ERR_GETDPD_ERROR_CNT_NULLPARAM, + MYKONOS_ERR_GETDPD_ERROR_CNT_INV_CH, + MYKONOS_ERR_GETDPD_ERROR_CNT_ARMERRFLAG, + + MYKONOS_ERR_SETDPDACT_NULL_ACTSTRUCT, + MYKONOS_ERR_SETDPDACT_INV_ACTMODE, + MYKONOS_ERR_SETDPDACT_INV_LEVEL, + MYKONOS_ERR_GETDPDACT_NULL_ACTSTRUCT, + + MYKONOS_ERR_SETDPDACTCHECK_NULL_ACTSTRUCT, + MYKONOS_ERR_SETDPDACTCHECK_INV_ACTMODE, + MYKONOS_ERR_SETDPDACTCHECK_INV_LEVEL, + MYKONOS_ERR_GETDPDACTCHECK_NULL_ACTSTRUCT, + + MYKONOS_ERR_CLGCATTENTUNCFG_NULL_ATTRANGECFGSTRUCT, + MYKONOS_ERR_CLGCATTENTUNCFG_INVALID_MODE, + MYKONOS_ERR_CLGCATTENTUNCFG_INVALID_PRESET, + MYKONOS_ERR_CLGCATTENTUNCFG_INVALID_RANGE, + MYKONOS_ERR_CLGCATTENTUNCFG_INVALID_TX1_SETTINGS, + MYKONOS_ERR_CLGCATTENTUNCFG_INVALID_TX2_SETTINGS, + + MYKONOS_ERR_CLGCATTENTUNCFGGET_NULL_ATTRANGECFGSTRUCT, + + MYKONOS_ERR_END +} mykonosErr_t; + +/** + * \brief Enum for Mykonos low voltage GPIO available pins + */ +typedef enum +{ + MYKGPIONAN = 0x00, + MYKGPIO0 = 0x1, + MYKGPIO1 = 0x2, + MYKGPIO2 = 0x4, + MYKGPIO3 = 0x8, + MYKGPIO4 = 0x10, + MYKGPIO5 = 0x20, + MYKGPIO6 = 0x40, + MYKGPIO7 = 0x80, + MYKGPIO8 = 0x100, + MYKGPIO9 = 0x200, + MYKGPIO10 = 0x400, + MYKGPIO11 = 0x800, + MYKGPIO12 = 0x1000, + MYKGPIO13 = 0x2000, + MYKGPIO14 = 0x4000, + MYKGPIO15 = 0x8000, + MYKGPIO16 = 0x10000, + MYKGPIO17 = 0x20000, + MYKGPIO18 = 0x40000 +} mykonosGpioSelect_t; + + +/** + * \brief Enum of valid Mykonos Enable State Machine (ENSM) states + */ +typedef enum +{ + WAIT = 0, /*!< Mykonos ENSM state upon which a power up in the WAIT/SLEEP state occurs */ + INIT = 1, /*!< Mykonos ENSM state upon which a power up delay state ocurrs to allow clocks to stabilize */ + WAITCALS = 2, /*!< Mykonos ENSM state upon which calibrations are initializing */ + ALERTCALS = 3, /*!< Mykonos ENSM state upon which calibrations are occurring */ + ALERTLDS = 4, /*!< Mykonos ENSM state upon which a delay state is occurring when moving from WAIT to ALERT to allow internal circuits to power up */ + ALERT = 5, /*!< Mykonos ENSM state upon which the internal RF synth is powered up, and TX and RX data paths are still powered down */ + TX_RX = 6, /*!< Mykonos ENSM state upon which the ability to power up data paths depending on the TxEnable/RxEnable pins or SPI bits */ + FLUSH = 7 /*!< Mykonos ENSM state upon which the data paths are cleared when exiting the TX_RX state */ +} mykonosEnsmState_t; + + +/** + * \brief Enum of possible Tx channels + */ +typedef enum +{ + TXOFF = 0, + TX1 = 1, + TX2 = 2, + TX1_TX2 = 3 +} mykonosTxChannels_t; + +/** + * \brief Enum of possible Rx channels + */ +typedef enum +{ + RXOFF = 0, + RX1 = 1, + RX2 = 2, + RX1_RX2 = 3 +} mykonosRxChannels_t; + +/** + * \brief Enum of possible Observation Rx channels + */ +typedef enum +{ + OBS_RXOFF = 0, + OBS_RX1_TXLO = 1, + OBS_RX2_TXLO = 2, + OBS_INTERNALCALS = 3, + OBS_SNIFFER = 4, + OBS_RX1_SNIFFERLO = 5, + OBS_RX2_SNIFFERLO = 6, + OBS_SNIFFER_A = 0x14, + OBS_SNIFFER_B = 0x24, + OBS_SNIFFER_C = 0x34 +} mykonosObsRxChannels_t; + +/** + * \brief Enum of possible Sniffer Rx channels + */ +typedef enum +{ + SNIFFER_A = 1, + SNIFFER_B = 2, + SNIFFER_C = 3 +} mykonosSnifferChannel_t; + +/** + * \brief Enum of possible Observation Rx channels to enable and run calibrations for during init. + * Choose ENUM value that enables all channels that will be used in the system. During system use, + * only one channel can be used at a time. This is also used to alert the ARM processor + * which observation channels are valid for the current desired system setup. + */ +typedef enum +{ + MYK_OBS_RXOFF = 0x00, + MYK_ORX1 = 0x01, + MYK_ORX2 = 0x02, + MYK_ORX1_ORX2 = 0x03, + MYK_SNRXA = 0x04, + MYK_SNRXB = 0x08, + MYK_SNRXC = 0x10, + MYK_SNRXA_B_C = 0x1C +} mykonosObsRxChannelsEn_t; + +/** + * \brief Enum of possible DAC divider settings (2x, 2.5x, 4x) + */ +typedef enum +{ + DACDIV_2, + DACDIV_2p5, + DACDIV_4 +} mykonosDacDiv_t; + +/** + * \brief Enum of possible VCO divider settings (1x, 1.5x, 2x, 3x) + */ +typedef enum +{ + VCODIV_1 = 0, + VCODIV_1p5 = 1, + VCODIV_2 = 2, + VCODIV_3 = 3 +} mykonosVcoDiv_t; + +/** + * \brief Enum of possible PRBS pattern settings + */ +typedef enum +{ + MYK_PRBS7 = 0, + MYK_PRBS15 = 1, + MYK_PRBS31 = 2 +} mykonosPrbsOrder_t; + +/** + * \brief Enum of RF PLL names + */ +typedef enum +{ + CLK_PLL, + RX_PLL, + TX_PLL, + SNIFFER_PLL +} mykonosRfPllName_t; + +/** + * \brief Enum of Rx profile types + */ +typedef enum +{ + MYK_RX_PROFILE, + MYK_OBS_PROFILE, + MYK_SNIFFER_PROFILE +} mykonosRxProfType_t; + +/** + * \brief Enum of ORx PLL names + */ +typedef enum +{ + OBSLO_TX_PLL, + OBSLO_SNIFFER_PLL +} mykonosObsRxLoSource_t; + +/** + * \brief Enum of possible wait events to use with MYKONOS_waitForEvent() + */ +typedef enum +{ + CALPLL_LOCK, + CLKPLLCP, + CLKPLL_LOCK, + RF_RXPLLCP, + RF_RXPLL_LOCK, + RF_TXPLLCP, + RF_TXPLL_LOCK, + RF_SNIFFERPLLCP, + RF_SNIFFERPLL_LOCK, + RXBBF_CALDONE, + TXBBF_CALDONE, + RX_RFDC_CALDONE, + RX_ADCTUNER_CALDONE, + RX1_ADCPROFILE, + RX2_ADCPROFILE, + ORX_ADCPROFILE, + RCAL_CALDONE, + ARMBUSY, + INITARM_DONE +} waitEvent_t; + +/** + * \brief Enum to set the desired FIR filter type for related functions + */ +typedef enum +{ + TX1_FIR = 1, + TX2_FIR = 2, + TX1TX2_FIR = 3, + RX1_FIR = 4, + RX2_FIR = 8, + RX1RX2_FIR = 12, + OBSRX_A_FIR = 16, + OBSRX_B_FIR = 32 +} mykonosfirName_t; + +/** + * \brief Enum to set the desired Rx gain table channel + */ +typedef enum +{ + RX1_GT = 1, + RX2_GT, + RX1_RX2_GT, + ORX_GT, + SNRX_GT, + LOOPBACK_GT +}mykonosGainTable_t; + +/** + * \brief Enum to set the Rx Gain control mode + */ +typedef enum +{ + MGC = 0, /*!< Manual Gain Control */ + AGC = 2, /*!< Automatic Gain Control (AGC) */ + HYBRID = 3 /*!< Hybrid AGC Gain Control */ + +} mykonosGainMode_t; + +/** + * \brief Enum to set the Tx Atenuation step size + */ +typedef enum +{ + TXATTEN_0P05_DB = 0, /*!< Tx attenuation 0.05dB step size */ + TXATTEN_0P1_DB = 1, /*!< Tx attenuation 0.1dB step size */ + TXATTEN_0P2_DB = 2, /*!< Tx attenuation 0.2dB step size */ + TXATTEN_0P4_DB = 3 /*!< Tx attenuation 0.4dB step size */ +} mykonosTxAttenStepSize_t; + +/** + * \brief Enum to help set the init calibration mask + */ +typedef enum +{ + TX_BB_FILTER = 0x0001, + ADC_TUNER = 0x0002, + TIA_3DB_CORNER = 0x0004, + DC_OFFSET = 0x0008, + TX_ATTENUATION_DELAY = 0x0010, + RX_GAIN_DELAY = 0x0020, + FLASH_CAL = 0x0040, + PATH_DELAY = 0x0080, + TX_LO_LEAKAGE_INTERNAL = 0x0100, + TX_LO_LEAKAGE_EXTERNAL = 0x0200, + TX_QEC_INIT = 0x0400, + LOOPBACK_RX_LO_DELAY = 0x0800, + LOOPBACK_RX_RX_QEC_INIT = 0x1000, + RX_LO_DELAY = 0x2000, + RX_QEC_INIT = 0x4000, + DPD_INIT = 0x8000, + CLGC_INIT = 0x10000, + VSWR_INIT = 0x20000 +} mykonosInitCalibrations_t; + +/** + * \brief Enum to help set the tracking calibration mask + */ +typedef enum +{ + TRACK_RX1_QEC = 0x00001, + TRACK_RX2_QEC = 0x00002, + TRACK_ORX1_QEC = 0x00004, + TRACK_ORX2_QEC = 0x00008, + TRACK_TX1_LOL = 0x00010, + TRACK_TX2_LOL = 0x00020, + TRACK_TX1_QEC = 0x00040, + TRACK_TX2_QEC = 0x00080, + TRACK_TX1_DPD = 0x00100, + TRACK_TX2_DPD = 0x00200, + TRACK_TX1_CLGC = 0x00400, + TRACK_TX2_CLGC = 0x00800, + TRACK_TX1_VSWR = 0x01000, + TRACK_TX2_VSWR = 0x02000, + TRACK_ORX1_QEC_SNLO = 0x10000, + TRACK_ORX2_QEC_SNLO = 0x20000, + TRACK_SRX_QEC = 0x40000 +} mykonosTrackingCalibrations_t; + + +/** + * \brief Enum to select the desired status calibration path delay read back + */ +typedef enum +{ + MYK_DPD_PATH_DELAY = 0, + MYK_CLGC_PATH_DELAY = 1, + MYK_VSWR_PATH_DELAY = 2 +} mykonosPathDelaySel_t; + +/** + * \brief Enum to set the GPIO3v3 mode + */ +typedef enum +{ + GPIO3V3_LEVELTRANSLATE_MODE = 1, /*!< Level translate mode, signal level on low voltage GPIO output on GPIO3v3 pins */ + GPIO3V3_INVLEVELTRANSLATE_MODE = 2, /*!< Inverted Level translate mode, inverse of signal level on low voltage GPIO output on GPIO3v3 pins */ + GPIO3V3_BITBANG_MODE = 3, /*!< Manual mode, API function sets output pin levels and reads input pin levels */ + GPIO3V3_EXTATTEN_LUT_MODE = 4 /*!< GPIO3v3 output level follows Rx1/Rx2 gain table external control 6bit field. */ +} mykonosGpio3v3Mode_t; + +/** + * \brief Enum to set the low voltage GPIO mode + */ +typedef enum +{ + GPIO_MONITOR_MODE = 0, /*!< Allows a choice of debug signals to output from Mykonos to monitor the state of the device */ + GPIO_BITBANG_MODE = 3, /*!< Manual mode, API function sets output pin levels and reads input pin levels */ + GPIO_ARM_OUT_MODE = 9, /*!< Allows internal ARM processor to output on GPIO pins */ + GPIO_SLICER_OUT_MODE = 10 /*!< Allows Slicer active configuration to the GPIO output pins */ +} mykonosGpioMode_t; + +/** + * \brief Enum for ARM states + */ +typedef enum +{ + MYK_ARM_POWERUP = 0x00, /*!< ARM is powered up and ready to be programmed */ + MYK_ARM_READY = 0x01, /*!< ARM enter this state once the boot up sequence is completed */ + MYK_ARM_IDLE = 0x02, /*!< ARM enter this state after initial calibrations are completed */ + MYK_ARM_RADIO_ON = 0x04, /*!< ARM has moved from MYKONOS_ARM_IDLE state into MYKONOS_ARM_RADIO_ON after the proper command, an abort command will move back to MYKONOS_ARM_IDLE state */ + MYK_ARM_PROFILE_ERROR = 0x08, /*!< ARM has detected an illegal profile */ + MYK_ARM_CAL_ERROR = 0x40, /*!< ARM has detected an error in the tracking calibrations */ + MYK_ARM_EXCEPTION = 0x80 /*!< ARM system problem has been detected */ +} mykonosArmState_t; + +/** + * \brief Enum for channel selection for DC offset settings. + */ +typedef enum +{ + MYK_DC_OFFSET_RX_CHN = 0x01, /*!< Select Rx channel */ + MYK_DC_OFFSET_ORX_CHN = 0x02, /*!< Select ORx channel */ + MYK_DC_OFFSET_SNF_CHN = 0x04 /*!< Select Sniffer channel */ +}mykonosDcOffsetChannels_t; + +/** + * \brief Enum of Rx channels for configuring (Enable /disable) DC offsets. + */ +typedef enum +{ + MYK_DC_OFFSET_ALL_OFF = 0x00, /*!< Disable all the channels */ + MYK_DC_OFFSET_RX1 = 0x01, /*!< Enables Rx1 */ + MYK_DC_OFFSET_RX2 = 0x02, /*!< Enables Rx2 */ + MYK_DC_OFFSET_SNF = 0x04, /*!< Enables Sniffer */ + MYK_DC_OFFSET_ORX = 0x08, /*!< Enables ORx */ + MYK_DC_OFFSET_AVAILABLE = 0x0F /*!< Enables all the channels */ +}mykonosRxDcOffsettEn_t; + +/** + * \brief Enum of build type + */ +typedef enum +{ + MYK_BUILD_RELEASE = 0X00, + MYK_BUILD_DEBUG = 0x01, + MYK_BUILD_TEST_OBJECT = 0x04 +}mykonosBuild_t; + +/** + * \brief Enum for DPD error codes + */ +typedef enum +{ + MYK_NO_ERROR = 0, /*!< No Error */ + MYK_ORX_DISABLED = 1, /*!< ORX_DISABLED */ + MYK_TX_DISABLED = 2, /*!< TX_DISABLED */ + MYK_PATHDELAY_NOT_SETUP = 3, /*!< PATHDELAY_NOT_SETUP */ + MYK_DPD_INIT_NOT_RUN = 4, /*!< DPD_INIT_NOT_RUN */ + MYK_ORX_SIG_TOO_LOW = 5, /*!< ORX_SIG_TOO_LOW */ + MYK_ORX_SIG_SATURATED = 6, /*!< ORX_SIG_SATURATED */ + MYK_TX_SIG_TOO_LOW = 7, /*!< TX_SIG_TOO_LOW */ + MYK_TX_SIG_SATURATED = 8, /*!< TX_SIG_SATURATED */ + MYK_MODEL_ERROR_HIGH = 9, /*!< MODEL_ERROR_HIGH */ + MYK_AM_AM_OUTLIERS = 10, /*!< AM_AM_OUTLIERS */ + MYK_INVALID_TX_PROFILE = 11, /*!< INVALID_TX_PROFILE */ + MYK_ORX_TRACKING_DISABLED = 12, /*!< ORX_TRACKING_DISABLED ORx tracking must be enabled */ + MYK_ERR_RESERVED_13 = 13, /*!< Reserved DPD error */ + MYK_ERR_BAD_ACTUATOR_MODEL = 14, /*!< DPD actuator model is in bad state */ + MYK_ERR_LOW_POWER_ACTUATOR_BYPASS = 15, /*!< DPD actuator bypassed due to low input power */ + + MYK_DPD_ERROR_END +} mykonosDpdErrors_t; + +/** + * \brief Enum for DPD reset modes + */ +typedef enum +{ + MYK_DPD_NO_ACTION = 0, /*!< DPD no Action error */ + MYK_DPD_RESET_FULL = 1, /*!< Full DPD reset */ + MYK_DPD_RESET_PRIOR = 4, /*!< Reset only prior model */ + MYK_DPD_RESET_CORRELATOR = 8, /*!< Reset correlator only */ + + MYK_DPD_RESET_END +} mykonosDpdResetMode_t; + + +/** + * \brief Enum for CLGC Tx attenuation tuning range modes + */ +typedef enum +{ + MYK_CLGC_ATTEN_TUNING_PRESET = 0, /*!< Set attenuation to the tx[]AttenTuningPreset */ + MYK_CLGC_ATTEN_DISCARD = 1, /*!< Ignore calculated attenuation level and keep the existing one */ + MYK_CLGC_ATTEN_UPDATE = 2, /*!< Set attenuation to tx[]AttenTuningPreset + tx[]AttenTuningRange if calculated attenuation is above this level + Set attenuation to tx[]AttenTuningPreset - tx[]AttenTuningRange if calculated attenuation is below this level*/ + + MYK_CLGC_ATTEN_END +} mykonosClgcAttenTuningMode_t; + +/** + * \brief Data structure to hold 3.3 VDC GPIO settings + */ +typedef struct +{ + uint16_t gpio3v3Oe; /*!< Pin direction: bit per 3.3v GPIO, 0=Input, 1=Output from Mykonos device */ + mykonosGpio3v3Mode_t gpio3v3SrcCtrl3_0; /*!< Mode for GPIO3v3[3:0] pins */ + mykonosGpio3v3Mode_t gpio3v3SrcCtrl7_4; /*!< Mode for GPIO3v3[7:4] pins */ + mykonosGpio3v3Mode_t gpio3v3SrcCtrl11_8; /*!< Mode for GPIO3v3[11:8] pins */ +} mykonosGpio3v3_t; + +/** + * \brief Data structure to hold low voltage GPIO settings + */ +typedef struct +{ + uint32_t gpioOe; /*!< Output Enable per low voltage GPIO pin (1=output, 0=input) */ + mykonosGpioMode_t gpioSrcCtrl3_0; /*!< Mode for low voltage GPIO[3:0] pins */ + mykonosGpioMode_t gpioSrcCtrl7_4; /*!< Mode for low voltage GPIO[7:4] pins */ + mykonosGpioMode_t gpioSrcCtrl11_8; /*!< Mode for low voltage GPIO[11:8] pins */ + mykonosGpioMode_t gpioSrcCtrl15_12; /*!< Mode for low voltage GPIO[15:12] pins */ + mykonosGpioMode_t gpioSrcCtrl18_16; /*!< Mode for low voltage GPIO[18:16] pins */ +} mykonosGpioLowVoltage_t; + +/** + * \brief Structure used within the DPD config structure to hold a int8_t complex number + */ +typedef struct{ + int8_t real; /*!< real part of the complex number */ + int8_t imag; /*!< imaginary part of the complex number */ +} int8_cpx; + +/** + * \brief Structure to configure DPD (Only valid for a DPD-enabled transceiver) + * \deprecated robustModeling member of this structure is no longer in use. + * This information is loaded into the ARM memory using the + * MYKONOS_configDpd() function before running the DPD init or tracking + * calibrations. These values can only be changed when the ARM is in the + * radioOff state. + */ +typedef struct +{ + uint8_t damping; /*!< 1/2^(damping + 8) fraction of previous model 'forgotten' per adaptation (default: 5 = '1/8192' , valid 0 to 15), 0 = infinite damping */ + uint8_t numWeights; /*!< number of weights to use for int8_cpx weights weights member of this structure (default = 1) */ + uint8_t modelVersion; /*!< DPD model version: one of four different generalized polynomial models: 0 = same as R0 silicon, 1-3 are new and the best one depends on the PA (default: 2) */ + uint8_t highPowerModelUpdate; /*!< 1 = Update saved model whenever peak Tx digital RMS is within 1dB of historical peak Tx RMS */ + uint8_t modelPriorWeight; /*!< Determines how much weight the loaded prior model has on DPD modeling (Valid 0 - 32, default 20) */ + uint8_t robustModeling; /*!< This is deprecated and no longer in use */ + uint16_t samples; /*!< number of samples to capture (default: 512, valid 64 - 32768) */ + uint16_t outlierThreshold; /*!< threshold for sample in AM-AM plot outside of 1:1 line to be thrown out. (default: 50% = 8192/2, valid 8192 to 1) */ + int16_t additionalDelayOffset; /*!< 16th of an ORx sample (16=1sample), (default 0, valid -64 to 64) */ + uint16_t pathDelayPnSeqLevel; /*!< Default 255 (-30dBFs=(20Log10(value/8192)), (valid range 1 to 8191) */ + int8_cpx weights[3]; /*!< DPD model error weighting (real/imag valid from -128 to 127) */ +} mykonosDpdConfig_t; + +/** + * \brief Structure to configure the feature to bypass DPD actuator when signal power below a threshold + * + */ +typedef struct +{ + uint8_t bypassActuatorEn; /*!< Enable/Disable feature to bypass actuator when input power below a certain threshold */ + mykonosDpdResetMode_t bypassActuatorMode; /*!< Follows reset DPD enum */ + uint16_t bypassActuatorLevel; /*!< Tx RMS level below which actuator is bypassed. P_dBFS = 20*log10(bypassActuatorLevel/8192) */ +} mykonosDpdBypassConfig_t; + + + +/** + * \brief Structure to configure the DPD actuator gain check + * + */ +typedef struct +{ + uint8_t actuatorGainCheckEn; /*!< Enable Gain check for DPD actuator */ + mykonosDpdResetMode_t actuatorGainCheckMode; /*!< Follows reset DPD enum */ + uint16_t actuatorGainCheckLevel; /*!< If the gain difference before and after the actuator exceeds this value an error will be issued + and the actuator will reset depending on the actuatorGainCheckMode, in 0.01dB, where a value of 200 => 2dB*/ +} mykonosDpdActuatorCheck_t; + +/** + * \brief Structure to configure CLGC (Closed Loop Gain Control) (Only valid for a DPD-enabled transceiver) + * + * This information is loaded into the ARM memory using the + * MYKONOS_configClgc() function before running the CLGC init or tracking + * calibrations. + * These values can be changed when the ARM is in the radioOff or radioOn states. + */ +typedef struct +{ + int16_t tx1DesiredGain; /*!< (value = 100 * dB (valid range -32768 to 32767) - total gain and attenuation from Mykonos Tx1 output to ORx1 input in (dB * 100) */ + int16_t tx2DesiredGain; /*!< (value = 100 * dB (valid range -32768 to 32767) - total gain and attenuation from Mykonos Tx2 output to ORx2 input in (dB * 100) */ + uint16_t tx1AttenLimit; /*!< (valid range 0 - 40dB), no default, depends on PA, Protects PA by making sure Tx1Atten is not reduced below the limit */ + uint16_t tx2AttenLimit; /*!< (valid range 0 - 40dB), no default, depends on PA, Protects PA by making sure Tx2Atten is not reduced below the limit */ + uint16_t tx1ControlRatio; /*!< valid range 1-100, default 45 */ + uint16_t tx2ControlRatio; /*!< valid range 1-100, default 45 */ + uint8_t allowTx1AttenUpdates; /*!< 0= allow CLGC to run, but Tx1Atten will not be updated. User can still read back power measurements. 1=CLGC runs, and Tx1Atten automatically updated */ + uint8_t allowTx2AttenUpdates; /*!< 0= allow CLGC to run, but Tx2Atten will not be updated. User can still read back power measurements. 1=CLGC runs, and Tx2Atten automatically updated */ + + int16_t additionalDelayOffset; /*!< 16th of an ORx sample (16=1sample), (default 0, valid -64 to 64) */ + uint16_t pathDelayPnSeqLevel; /*!< Default 255 (-30dBFs=(20Log10(value/8192)), (valid range 1 to 8191) */ + + uint16_t tx1RelThreshold; /*!< Threshold for Tx1 in order to stop tracking, value = 100 * dB, default 6db then value = 600 */ + uint16_t tx2RelThreshold; /*!< Threshold for Tx2 in order to stop tracking, value = 100 * dB, default 6db then value = 600 */ + uint8_t tx1RelThresholdEn; /*!< Threshold feature enable for Tx1, 0 = disable, 1 = enable, default = 0 */ + uint8_t tx2RelThresholdEn; /*!< Threshold feature enable for Tx2, 0 = disable, 1 = enable, default = 0 */ +} mykonosClgcConfig_t; + +/** + * \brief Structure to configure the CLGC attenuation tuning range + */ +typedef struct +{ + mykonosClgcAttenTuningMode_t tx1AttenTuningLimitMode; /*!< Tx1 CLGC Attenuation tuning mode */ + mykonosClgcAttenTuningMode_t tx2AttenTuningLimitMode; /*!< Tx2 CLGC Attenuation tuning mode */ + uint16_t tx1AttenTuningPreset; /*!< Tx1 CLGC nominal attenuation, valid range is 0 to 839 with a 0.05dB*/ + uint16_t tx2AttenTuningPreset; /*!< Tx2 CLGC nominal attenuation, valid range is 0 to 839 with a 0.05dB*/ + uint16_t tx1AttenTuningRange; /*!< Tx1 CLGC relative attenuation range around nominal attenuation, valid range is 0 to 420 with a 0.05dB*/ + uint16_t tx2AttenTuningRange; /*!< Tx2 CLGC relative attenuation range around nominal attenuation, valid range is 0 to 420 with a 0.05dB*/ +} mykonosClgcAttenTuningConfig_t; + +/** + * \brief Structure to configure VSWR (Only valid for a DPD-enabled transceiver) + * + * This information is loaded into the ARM memory using the + * MYKONOS_configVswr() function before running the VSWR init or tracking + * calibrations. + * These values can be changed when the ARM is in the radioOff states. + */ +typedef struct +{ + /* VSWR init cal parameters */ + int16_t additionalDelayOffset; /*!< 16th of an ORx sample (16=1sample), (default 0, valid -64 to 64) */ + uint16_t pathDelayPnSeqLevel; /*!< Default 255 (-30dBFs=(20Log10(value/8192)), (valid range 1 to 8191) */ + + /* VSWR tracking cal parameters */ + uint8_t tx1VswrSwitchGpio3p3Pin; /*!< 3p3V GPIO pin to use to control VSWR switch for Tx1 (valid 0-11) (output from Mykonos) */ + uint8_t tx2VswrSwitchGpio3p3Pin; /*!< 3p3V GPIO pin to use to control VSWR switch for Tx2 (valid 0-11) (output from Mykonos) */ + uint8_t tx1VswrSwitchPolarity; /*!< 3p3v GPIO pin polarity for forward path of Tx1, opposite used for reflection path (1 = high level, 0 = low level) */ + uint8_t tx2VswrSwitchPolarity; /*!< 3p3v GPIO pin polarity for forward path of Tx2, opposite used for reflection path (1 = high level, 0 = low level) */ + uint8_t tx1VswrSwitchDelay_us; /*!< Delay for Tx1 after flipping the VSWR switch until measurement is made. In us resolution with a range from 0 to 255us */ + uint8_t tx2VswrSwitchDelay_us; /*!< Delay for Tx2 after flipping the VSWR switch until measurement is made. In us resolution with a range from 0 to 255us */ +} mykonosVswrConfig_t; + +typedef struct +{ + /** + * errorStatus(decimal) | Description + * ---------------------|----------------------- + * 0 | NO ERROR (Tracking success) + * 1 | Tx data path not enabled + * 2 | ORX data path is not enabled + * 3 | Loopback switch closed + * 4 | VSWR init cal was not run + * 5 | Path delay not setup + * 6 | Data measurement was aborted + * 7 | VSWR disabled + * 8 | If set, entered cal but not finished + * 9 | No GPIO configured in single ORx configuration + * 10 | Tx is not observable with any of the ORx Channels + * 11 | ORX_TRACKING_DISABLED ORx tracking must be enabled + * + */ + uint32_t errorStatus; + uint32_t trackCount; /*!< Number of times VSWR tracking has run since last reset */ + int32_t forwardGainRms_dB; /*!< Forward RMS gain measured from Tx to ORx path (1 = 0.01 dB Gain) */ + int32_t forwardGainReal; /*!< Real part of the forward path complex gain (1 = 0.01 linear Gain) */ + int32_t forwardGainImag; /*!< Imaginary part of the forward path complex gain (1 = 0.01 linear Gain) */ + int32_t reflectedGainRms_dB; /*!< Measured reflection path gain in RMS (1 = 0.01 dB Gain) */ + int32_t reflectedGainReal; /*!< Real part of the reflection path complex gain (1 = 0.01 linear Gain) */ + int32_t reflectedGainImag; /*!< Imaginary part of the reflection path complex gain (1 = 0.01 linear Gain) */ + int32_t vswr_forward_tx_rms; /*!< Forward RMS measured from Tx path (1 = 0.01 dBFS) */ + int32_t vswr_forward_orx_rms; /*!< Forward RMS measured from ORx path (1 = 0.01 dBFS) */ + int32_t vswr_reflection_tx_rms; /*!< Reflected RMS measured from Tx path (1 = 0.01 dBFS) */ + int32_t vswr_reflection_orx_rms; /*!< Reflected RMS measured from ORx path (1 = 0.01 dBFS) */ +} mykonosVswrStatus_t; + +/** + * \brief Data structure to hold Mykonos FIR filter settings + */ +typedef struct +{ + int8_t gain_dB; /*!< Filter gain in dB*/ + uint8_t numFirCoefs; /*!< Number of coefficients in the FIR filter */ + int16_t *coefs; /*!< A pointer to an array of filter coefficients */ +} mykonosFir_t; + +/** + * \brief Data structure to hold Mykonos JESD204b Framer configuration settings + */ +typedef struct +{ + uint8_t bankId; /*!< JESD204B Configuration Bank ID extension to Device ID. Range is 0..15 */ + uint8_t deviceId; /*!< JESD204B Configuration Device ID link identification number. Range is 0..255 */ + uint8_t lane0Id; /*!< JESD204B Configuration starting Lane ID. If more than one lane is used, each lane will increment from the Lane0 ID. Range is 0..31 */ + uint8_t M; /*!< Number of ADCs (0, 2, or 4) where 2 ADCs are required per receive chain (I and Q) */ + uint8_t K; /*!< Number of frames in a multiframe. Default = 32, F*K must be modulo 4. Where, F=2*M/numberOfLanes */ + uint8_t scramble; /*!< Scrambling off if framerScramble = 0, if framerScramble > 0 scrambling is enabled */ + uint8_t externalSysref; /*!< External SYSREF select. 0 = use internal SYSREF, 1 = use external SYSREF */ + uint8_t serializerLanesEnabled; /*!< Serializer lane select bit field. Where, [0] = Lane0 enabled, [1] = Lane1 enabled, etc */ + uint8_t serializerLaneCrossbar; /*!< Lane crossbar to map framer lane outputs to physical lanes */ + uint8_t serializerAmplitude; /*!< Serializer amplitude setting. Default = 22. Range is 0..31 */ + uint8_t preEmphasis; /*!< Serializer pre-emphasis setting. Default = 4 Range is 0..7 */ + uint8_t invertLanePolarity; /*!< Lane inversion select. Default = 0. Where, bit[0] = 0 will invert lane [0], bit[1] = 0 will invert lane 1, etc. */ + uint8_t lmfcOffset; /*!< LMFC offset value for deterministic latency setting. Range is 0..31 */ + uint8_t newSysrefOnRelink; /*!< Flag for determining if SYSREF on relink should be set. Where, if > 0 = set, 0 = not set */ + uint8_t enableAutoChanXbar; /*!< Flag for determining if auto channel select for the xbar should be set. Where, if > 0 = set, '0' = not set */ + uint8_t obsRxSyncbSelect; /*!< Selects SYNCb input source. Where, 0 = use RXSYNCB for this framer, 1 = use OBSRX_SYNCB for this framer */ + uint8_t rxSyncbMode; /*!< Flag for determining if CMOS mode for RX Sync signal is used. Where, if > 0 = CMOS, '0' = LVDS */ + uint8_t overSample; /*!< Selects framer bit repeat or oversampling mode for lane rate matching. Where, 0 = bitRepeat mode (changes effective lanerate), 1 = overSample (maintains same lane rate between ObsRx framer and Rx framer and oversamples the ADC samples) */ + uint8_t enableManualLaneXbar; /*!< Flag for determining if API will calculate the appropriate settings for framer lane outputs to physical lanes. Where, if '0' = API will set automatic lane crossbar, '1' = set to manual mode and the value in serializerLaneCrossbar will be used */ +} mykonosJesd204bFramerConfig_t; + +/* NO Doxygen content required for this data structure as this is used internally */ +/// @cond +typedef struct +{ + uint8_t DID; /*!< JESD204B Configuration Device ID for ILAS check */ + uint8_t BID; /*!< JESD204B Configuration Bank ID for ILAS check */ + uint8_t LID0; /*!< JESD204B Configuration starting Lane ID for ILAS check */ + uint8_t L; /*!< JESD204B Configuration L = lanes per data converter for ILAS check */ + uint8_t SCR; /*!< JESD204B Configuration scramble setting for ILAS check */ + uint8_t F; /*!< JESD204B Configuration F = octets per frame for ILAS check */ + uint8_t K; /*!< JESD204B Configuration K = frames per multiframe for ILAS check */ + uint8_t M; /*!< JESD204B Configuration M = number of data converters for ILAS check */ + uint8_t N; /*!< JESD204B Configuration N = data converter sample resolution for ILAS check */ + uint8_t CS; /*!< JESD204B Configuration CS = number of control bits transferred per sample per frame for ILAS check */ + uint8_t NP; /*!< JESD204B Configuration NP = JESD204B word size based on the highest resolution of the data converter for ILAS check */ + uint8_t S; /*!< JESD204B Configuration S = number of samples/data converter/frame for ILAS check */ + uint8_t CF; /*!< JESD204B Configuration CF = '0' = control bits appended to each sample, '1' = appended to end of frame for ILAS check */ + uint8_t HD; /*!< JESD204B Configuration HD = high density bit - samples are contained within lane (0) or divided over more than one lane (1) for ILAS check */ + uint8_t FCHK0; /*!< JESD204B Configuration checksum for ILAS check */ +} mykonosJesd204bLane0Config_t; +/// @endcond + +/** +* \brief Data structure to hold the settings for the deserializer and deframer configuration +* +* EQ Settings | 3GHz Loss (dB) |6GHz Loss (dB) | max FR408HR Length (in) | max FR4 Length (in) +*-------------|----------------|---------------|-------------------------|--------------------- +* 0 | 6.5 | 14 | 20 | 12 +* 1 | 11.5 | 21 | 30 | 20 +* 2 | 18 | 31 | 46 | 32 +* 3 | 21.5 | 38 | 56 | 40 +* 4 | 22 | 39 | 60 | 43 +*/ +typedef struct +{ + uint8_t bankId; /*!< Extension to Device ID. Range is 0..15 */ + uint8_t deviceId; /*!< Link identification number. Range is 0..255 */ + uint8_t lane0Id; /*!< Lane0 ID. Range is 0..31 */ + uint8_t M; /*!< Number of DACs (0, 2, or 4) - 2 DACs per transmit chain (I and Q) */ + uint8_t K; /*!< Number of frames in a multiframe. Default = 32, F*K = modulo 4. Where, F=2*M/numberOfLanes */ + uint8_t scramble; /*!< Scrambling off if scramble = 0, if framerScramble > 0 scrambling is enabled */ + uint8_t externalSysref; /*!< External SYSREF select. 0 = use internal SYSREF, 1 = external SYSREF */ + uint8_t deserializerLanesEnabled; /*!< Deserializer lane select bit field. Where, [0] = Lane0 enabled, [1] = Lane1 enabled, etc */ + uint8_t deserializerLaneCrossbar; /*!< Lane crossbar to map physical lanes to deframer lane inputs [1:0] = Deframer Input 0 Lane section, [3:2] = Deframer Input 1 lane select, etc */ + uint8_t EQSetting; /*!< Equalizer setting. Applied to all deserializer lanes. Range is 0..4 */ + uint8_t invertLanePolarity; /*!< PN inversion per each lane. bit[0] = 1 Invert PN of Lane 0, bit[1] = Invert PN of Lane 1, etc */ + uint8_t lmfcOffset; /*!< LMFC offset value to adjust deterministic latency. Range is 0..31 */ + uint8_t newSysrefOnRelink; /*!< Flag for determining if SYSREF on relink should be set. Where, if > 0 = set, '0' = not set */ + uint8_t enableAutoChanXbar; /*!< Flag for determining if auto channel select for the xbar should be set. Where, if > 0 = set, '0' = not set */ + uint8_t txSyncbMode; /*!< Flag for determining if CMOS mode for TX Sync signal is used. Where, if > 0 = CMOS, '0' = LVDS */ + uint8_t enableManualLaneXbar; /*!< Flag for determining if API will calculate the appropriate settings for deframer lane in to physical lanes. Where, if '0' = API will set automatic lane crossbar, '1' = set to manual mode and the value in deserializerLaneCrossbar will be used */ +} mykonosJesd204bDeframerConfig_t; + +/** + * \brief Data structure to hold settings for the current Rx specific use case profile + */ +typedef struct +{ + uint8_t adcDiv; /*!< The divider used to generate the ADC clock (Valid: 1,2) */ + mykonosFir_t *rxFir; /*!< Pointer to Rx FIR filter structure */ + uint8_t rxFirDecimation; /*!< Rx FIR decimation (1,2,4) */ + uint8_t rxDec5Decimation; /*!< Decimation of Dec5 or Dec4 filter (5,4) */ + uint8_t enHighRejDec5; /*!< If set, and DEC5 filter used, will use a higher rejection DEC5 FIR filter. Where, 1 = enabled, 0 = disabled */ + uint8_t rhb1Decimation; /*!< RX Halfband1 (HB1) decimation. Can be either 1 or 2 */ + uint32_t iqRate_kHz; /*!< Rx IQ data rate in kHz */ + uint32_t rfBandwidth_Hz; /*!< Rx RF passband bandwidth for the profile */ + uint32_t rxBbf3dBCorner_kHz; /*!< Rx BBF (TIA) 3dB corner in kHz */ + uint16_t *customAdcProfile; /*!< Custom ADC profile to set the bandwidth of the ADC response */ +} mykonosRxProfile_t; + +/** + * \brief Data structure to hold settings for the current Tx specific use case profile + */ +typedef struct +{ + mykonosDacDiv_t dacDiv; /*!< The divider used to generate the DAC clock (ENUM Values)*/ + mykonosFir_t *txFir; /*!< Pointer to Tx FIR filter structure */ + uint8_t txFirInterpolation; /*!< The TX digital FIR filter interpolation (1,2,4) */ + uint8_t thb1Interpolation; /*!< Tx Halfband1 (HB1) filter interpolation (1,2) */ + uint8_t thb2Interpolation; /*!< Tx Halfband2 (HB2) filter interpolation (1,2) */ + uint8_t txInputHbInterpolation; /*!< Interpolation of half band filter before the programmable FIR (valid 1,2,4) */ + uint32_t iqRate_kHz; /*!< Tx IQ data rate in kHz */ + uint32_t primarySigBandwidth_Hz; /*!< Tx primary signal BW */ + uint32_t rfBandwidth_Hz; /*!< Tx RF passband bandwidth for the profile */ + uint32_t txDac3dBCorner_kHz; /*!< DAC filter 3dB corner in kHz */ + uint32_t txBbf3dBCorner_kHz; /*!< Tx BBF 3dB corner in kHz */ + uint8_t enableDpdDataPath; /*!< Enable Tx Dynamic pre distortion - only valid for a DPD-enabled transceiver */ +} mykonosTxProfile_t; + +/** + * \brief Data structure to hold SnRx gain control settings for initialization and during use + */ +typedef struct +{ + mykonosGainMode_t gainMode; /*!< Current Sniffer gain control mode setting */ + uint8_t gainIndex; /*!< Current Sniffer gain index. Can be used differently for Manual Gain control/AGC */ + uint8_t maxGainIndex; /*!< Max gain index for the currently loaded Sniffer Gain table */ + uint8_t minGainIndex; /*!< Min gain index for the currently loaded Sniffer Gain table */ +} mykonosSnifferGainControl_t; + +/** + * \brief Data structure to hold ORx gain control settings for initialization and during use + */ +typedef struct +{ + mykonosGainMode_t gainMode; /*!< Current ORx gain control mode setting */ + uint8_t orx1GainIndex; /*!< ORx1 Gain Index, can be used in different ways for manual and AGC gain control */ + uint8_t orx2GainIndex; /*!< ORx2 Gain Index, can be used in different ways for manual and AGC gain control */ + uint8_t maxGainIndex; /*!< Max gain index for the currently loaded ORx Gain table */ + uint8_t minGainIndex; /*!< Min gain index for the currently loaded ORx Gain table */ +} mykonosORxGainControl_t; + +/** + * \brief Data structure to hold Rx gain control settings for initialization and during use + */ +typedef struct +{ + mykonosGainMode_t gainMode; /*!< Current Rx gain control mode setting */ + uint8_t rx1GainIndex; /*!< Rx1 Gain Index, can be used in different ways for manual and AGC gain control */ + uint8_t rx2GainIndex; /*!< Rx2 Gain Index, can be used in different ways for manual and AGC gain control */ + uint8_t rx1MaxGainIndex; /*!< Max gain index for the currently loaded Rx1 Gain table */ + uint8_t rx1MinGainIndex; /*!< Min gain index for the currently loaded Rx1 Gain table */ + uint8_t rx2MaxGainIndex; /*!< Max gain index for the currently loaded Rx2 Gain table */ + uint8_t rx2MinGainIndex; /*!< Min gain index for the currently loaded Rx2 Gain table */ + uint8_t rx1Rssi; /*!< Stores Rx1 RSSI value read back from the Mykonos */ + uint8_t rx2Rssi; /*!< Stores Rx2 RSSI value read back from the Mykonos */ +} mykonosRxGainControl_t; + +/** + * \brief Data structure to hold peak detector settings for the AGC + */ +typedef struct +{ + /* Threshold Settings */ + uint8_t apdHighThresh; /*!< APD high threshold. Must be greater than apdLowThresh. Min = apdLowThresh, Max = 0x3F. 6-bit field. */ + uint8_t apdLowThresh; /*!< APD low threshold. Must be less than apdHighThresh. Min = 0, Max = apdHighThresh. 6-bit field. */ + uint8_t hb2HighThresh; /*!< HB2 high threshold. Must be greater than hb2LowThresh. Min = hb2LowThresh, Max = 0xFF. 8-bit field. */ + uint8_t hb2LowThresh; /*!< HB2 low threshold. Must be less than hb2HighThresh. Min = 0, Max = hb2HighThresh. 8-bit field. */ + uint8_t hb2VeryLowThresh; /*!< HB2 very low threshold. Must be less than hb2LowThresh. Min = 0, Max = hb2LowThresh. 8-bit field. */ + + /* Threshold Counter Settings */ + uint8_t apdHighThreshExceededCnt; /*!< APD high threshold exceeded counter. Sets number of peaks to detect above apdHighThresh to cause gain decrement according to apdHighGainStepAttack. 8-bit field. */ + uint8_t apdLowThreshExceededCnt; /*!< APD low threshold exceeded counter. Sets number of peaks to detect below apdLowThresh to cause gain increment according to apdLowGainStepRecovery. 8-bit field. */ + uint8_t hb2HighThreshExceededCnt; /*!< HB2 high threshold exceeded counter. Sets number of overloads to detect above hb2HighThresh to cause gain decrement according to hb2HighGainStepAttack. 8-bit field. */ + uint8_t hb2LowThreshExceededCnt; /*!< HB2 low threshold exceeded counter. Sets number of peaks to detect below hb2LowThresh to cause gain increment according to hb2LowGainStepRecovery. 8-bit field. */ + uint8_t hb2VeryLowThreshExceededCnt; /*!< HB2 very low threshold exceeded counter. Sets number of peaks to detect below hb2VeryLowThresh to cause gain increment according to hb2VeryLowGainStepRecovery. 8-bit field. */ + + /* Gain Step Settings */ + uint8_t apdHighGainStepAttack; /*!< Number of gain indices to decrement gain when apdHighThreshExceededCnt is exceeded. 5-bit field. */ + uint8_t apdLowGainStepRecovery; /*!< Number of gain indices to increment gain when apdLowThreshExceededCnt is exceeded. 5-bit field */ + uint8_t hb2HighGainStepAttack; /*!< Number of gain indices to decrement gain when hb2HighThreshExceededCnt is exceeded. 5-bit field */ + uint8_t hb2LowGainStepRecovery; /*!< Number of gain indices to increment gain when hb2LowThreshExceededCnt is exceeded. 5-bit field*/ + uint8_t hb2VeryLowGainStepRecovery; /*!< Number of gain indices to increment gain when hb2VeryLowThreshExceededCnt is exceeded. 5-bit field */ + + /* Fast Attack Settings */ + uint8_t apdFastAttack; /*!< [1] Enables APD fast attack mode - gain decrements immediately when apdHighThreshExceededCnt is exceeded. [0] disables APD fast attack mode - gain decrements at the expiry of agcGainUpdateCounter. 1-bit field. */ + uint8_t hb2FastAttack; /*!< [1] Enables HB2 fast attack mode - gain decrements immediately when hb2HighThreshExceededCnt is exceeded. [0] disables HB2 fast attack mode - gain decrements at the expiry of agcGainUpdateCounter. 1-bit field. */ + + /* HB2 Configuration Settings */ + uint8_t hb2OverloadDetectEnable; /*!< [1] Enables the HB2 overload detector. [0] Disables the HB2 overload detector. 1-bit field. */ + uint8_t hb2OverloadDurationCnt; /*!< Sets the samples size window of the HB2 overload detector. If hb2OverloadThreshCnt number of overloads are detected, the hb2xxxThreshExceededCnt increments. 3-bit field. [001]=1, [001]=4, [010]=8, [011]=12, [100]=16, [101]=24, [110]=32, [111]=INVALID */ + uint8_t hb2OverloadThreshCnt; /*!< Sets the number of individual overloads necessary within hb2OverloadDurationCnt samples to increment the hb2xxxThreshExceededCnt */ +} mykonosPeakDetAgcCfg_t; + +/** + * \brief Data structure to hold power measurement settings for the AGC + */ +typedef struct +{ + /* Threshold Settings */ + uint8_t pmdUpperHighThresh; /*!< Power measurement upper band, high threshold . This value is a positive offset to the pmdUpperLowThresh threshold. 4-bit field */ + uint8_t pmdUpperLowThresh; /*!< Power measurement upper band, low threshold. This value sets the threshold in (negative) -dBFS. Byte value must be less than pmdLowerHighThresh. 7-bit field */ + uint8_t pmdLowerHighThresh; /*!< Power measurement lower band, high threshold. This value sets the threshold in (negative) -dBFS. Byte value must be greater than pmdUpperLowThresh. 7-bit field */ + uint8_t pmdLowerLowThresh; /*!< Power measurement lower band, low threshold. This value is a negative offset to the pmdLowerHighThresh threshold. 4-bit field */ + + /* Gain Step Settings */ + uint8_t pmdUpperHighGainStepAttack; /*!< Number of gain indices to decrement gain if pmdUpperHighThresh is exceeded by the end of the agcGainUpdateCounter. 5-bit field */ + uint8_t pmdUpperLowGainStepAttack; /*!< Number of gain indices to decrement gain if pmdUpperLowThresh is exceeded by the end of the agcGainUpdateCounter. 5-bit field */ + uint8_t pmdLowerHighGainStepRecovery; /*!< Number of gain indices to increment gain if pmdLowerHighThresh is not exceeded by the end of the agcGainUpdateCounter. 5-bit field */ + uint8_t pmdLowerLowGainStepRecovery; /*!< Number of gain indices to increment gain if pmdLowerLowThresh is not exceeded by the end of the agcGainUpdateCounter. 5-bit field */ + + /* PMD Configuration Settings */ + uint8_t pmdMeasDuration; /*!< Number of samples to measure power on. The number of samples corresponding to the 4-bit word is 8*2^(pmdMeasDuration[3:0]). This value must be less than agcGainUpdateCounter */ + uint8_t pmdMeasConfig; /*!< Power measurement configuration. 2-bit field. [00]=PMD disabled, [01]=PMD Enabled at HB2 output, [10]=Enabled at RFIR output (recommended), [11]=PMD Enabled at BBDC2 */ +} mykonosPowerMeasAgcCfg_t; + +/** + * \brief Data structure to hold general AGC settings for initialization and during use + */ +typedef struct +{ + /* Gain Table Settings */ + uint8_t agcRx1MaxGainIndex; /*!< Maximum Rx1 gain index allowed in AGC mode. Must be greater than agcRx1MinGainIndex and valid gain index. 8-bit field */ + uint8_t agcRx1MinGainIndex; /*!< Minimum Rx1 gain index allowed in AGC mode. Must be less than agcRx1MinGainIndex and valid gain index. 8-bit field */ + uint8_t agcRx2MaxGainIndex; /*!< Maximum Rx2 gain index allowed in AGC mode. Must be greater than agcRx2MinGainIndex and valid gain index. 8-bit field */ + uint8_t agcRx2MinGainIndex; /*!< Minimum Rx2 gain index allowed in AGC mode. Must be less than agcRx2MinGainIndex and valid gain index. 8-bit field */ + uint8_t agcObsRxMaxGainIndex; /*!< Maximum ObsRx gain index allowed in AGC mode. Must be greater than agcObsRxMinGainIndex and valid gain index. 8-bit field */ + uint8_t agcObsRxMinGainIndex; /*!< Minimum ObsRx gain index allowed in AGC mode. Must be less than agcObsRxMaxGainIndex and valid gain index. 8-bit field */ + uint8_t agcObsRxSelect; /*!< Sniffer or ObsRx AGC channel select. [1] = SnRx */ + + /* AGC Mode Selection */ + uint8_t agcPeakThresholdMode; /*!< [1] = Peak Threshold Mode, power based gain changes are disabled. [0] = Peak and overload detectors are ignored for gain changes */ + uint8_t agcLowThsPreventGainIncrease; /*!< [1] PMD based gain increments are ignored if apd/hb2LowThreshExceedCnt is high [0] apdLowThreshExceededCnt and hb2LowThreshExceededCnt are "Don't cares" to the AGC gain recovery */ + + /* AGC General Settings */ + uint32_t agcGainUpdateCounter; /*!< Number of samples for the AGC gain update counter. Counter operates on the IQ data rate. 22-bit field. Min = 0x000001, Max = 0x3FFFFF */ + uint8_t agcSlowLoopSettlingDelay; /*!< Number of IQ data rate clock cycles to wait after a gain change before peak/power measurements resume. 7-bit field */ + uint8_t agcPeakWaitTime; /*!< Number of IQ data rate clock cycles to wait to enable peak/overload detectors after AGC is enabled. 5-bit field. Min = 0x02. Max = 0x1F */ + uint8_t agcResetOnRxEnable; /*!< [1] = Performs a reset of the AGC slow loop state machine when Rx is disabled. [0] = AGC slow loop state machine maintains its state when Rx is disabled. */ + uint8_t agcEnableSyncPulseForGainCounter; /*!< [1] = Allows sync of agcGainUpdateCounter to the time-slot boundary. GPIO setup required. [0] = agcGainUpdateCounter functions as normal */ + + mykonosPeakDetAgcCfg_t *peakAgc; /*!< pointer to structure for Peak AGC */ + mykonosPowerMeasAgcCfg_t *powerAgc; /*!< pointer to structure for Power AGC */ +} mykonosAgcCfg_t; + +/** + * \brief Data structure to hold Tx data path settings + */ +typedef struct +{ + mykonosTxProfile_t *txProfile; /*!< Tx datapath profile, 3dB corner frequencies, and digital filter enables */ + mykonosJesd204bDeframerConfig_t *deframer; /*!< Mykonos JESD204b deframer config for the Tx data path */ + mykonosTxChannels_t txChannels; /*!< The desired Tx channels to enable during initialization */ + uint8_t txPllUseExternalLo; /*!< Internal LO=0, external LO*2 if =1 */ + uint64_t txPllLoFrequency_Hz; /*!< Tx PLL LO frequency (internal or external LO) */ + mykonosTxAttenStepSize_t txAttenStepSize; /*!< Tx Attenuation step size */ + uint16_t tx1Atten_mdB; /*!< Initial and current Tx1 Attenuation */ + uint16_t tx2Atten_mdB; /*!< Initial and current Tx2 Attenuation */ + mykonosDpdConfig_t *dpdConfig; /*!< DPD settings. Only valid for a DPD-enabled transceiver, set pointer to NULL otherwise */ + mykonosClgcConfig_t *clgcConfig; /*!< CLGC settings. Only valid for a DPD-enabled transceiver, set pointer to NULL otherwise */ + mykonosVswrConfig_t *vswrConfig; /*!< VSWR settings. Only valid for a DPD-enabled transceiver, set pointer to NULL otherwise */ +} mykonosTxSettings_t; + +/** + * \brief Data structure to hold Rx data path settings + */ +typedef struct +{ + mykonosRxProfile_t *rxProfile; /*!< Rx datapath profile, 3dB corner frequencies, and digital filter enables */ + mykonosJesd204bFramerConfig_t *framer; /*!< Rx JESD204b framer configuration structure */ + mykonosRxGainControl_t *rxGainCtrl; /*!< Rx Gain control settings structure */ + mykonosAgcCfg_t *rxAgcCtrl; /*!< Rx AGC control settings structure */ + mykonosRxChannels_t rxChannels; /*!< The desired Rx Channels to enable during initialization */ + uint8_t rxPllUseExternalLo; /*!< Internal LO = 0, external LO*2 = 1 */ + uint64_t rxPllLoFrequency_Hz; /*!< Rx PLL LO Frequency (internal or external LO) */ + uint8_t realIfData; /*!< Flag to choose if complex baseband or real IF data are selected for Rx and ObsRx paths. Where, if > 0 = real IF data, '0' = zero IF (IQ) data*/ +} mykonosRxSettings_t; + +/** + * \brief Data structure to hold ORx data path settings + */ +typedef struct +{ + mykonosRxProfile_t *orxProfile; /*!< ORx datapath profile, 3dB corner frequencies, and digital filter enables. */ + mykonosORxGainControl_t *orxGainCtrl; /*!< ObsRx gain control settings structure */ + mykonosAgcCfg_t *orxAgcCtrl; /*!< ORx AGC control settings structure */ + mykonosRxProfile_t *snifferProfile; /*!< Sniffer datapath profile, 3dB corner frequencies, and digital filter enables. */ + mykonosSnifferGainControl_t *snifferGainCtrl; /*!< SnRx gain control settings structure */ + mykonosJesd204bFramerConfig_t *framer; /*!< ObsRx JESD204b framer configuration structure */ + mykonosObsRxChannelsEn_t obsRxChannelsEnable; /*!< The desired ObsRx channels to configure/calibrate during initialization */ + mykonosObsRxLoSource_t obsRxLoSource; /*!< The sniffer/ORx mixers can use the TX_PLL or SNIFFER_PLL */ + uint64_t snifferPllLoFrequency_Hz; /*!< SnRx PLL LO frequency in Hz */ + uint8_t realIfData; /*!< Flag to choose if complex baseband or real IF data are selected for Rx and ObsRx paths. Where if > 0 = real IF data, '0' = complex data */ + uint16_t *customLoopbackAdcProfile; /*!< Custom Loopback ADC profile to set the bandwidth of the ADC response */ + mykonosObsRxChannels_t defaultObsRxChannel; /*!< Default ObsRx channel to enter when radioOn called */ +} mykonosObsRxSettings_t; + + +/** + * \brief Data structure to hold ARM GPIO pin assignments for each ARM input/output pin. + */ +typedef struct +{ + uint8_t useRx2EnablePin; /*!< 0= RX1_ENABLE controls RX1 and RX2, 1 = separate RX1_ENABLE/RX2_ENABLE pins */ + uint8_t useTx2EnablePin; /*!< 0= TX1_ENABLE controls TX1 and TX2, 1 = separate TX1_ENABLE/TX2_ENABLE pins */ + uint8_t txRxPinMode; /*!< 0= ARM command mode, 1 = Pin mode to power up Tx/Rx chains */ + uint8_t orxPinMode; /*!< 0= ARM command mode, 1 = Pin mode to power up ObsRx receiver*/ + + /* Mykonos ARM input GPIO pins -- Only valid if orxPinMode = 1 */ + uint8_t orxTriggerPin; /*!< Select desired GPIO pin (valid 4-15) */ + uint8_t orxMode2Pin; /*!< Select desired GPIO pin (valid 0-18) */ + uint8_t orxMode1Pin; /*!< Select desired GPIO pin (valid 0-18) */ + uint8_t orxMode0Pin; /*!< Select desired GPIO pin (valid 0-18) */ + + /* Mykonos ARM output GPIO pins -- always available, even when pin mode not enabled*/ + uint8_t rx1EnableAck; /*!< Select desired GPIO pin (0-15), [4] = Output Enable */ + uint8_t rx2EnableAck; /*!< Select desired GPIO pin (0-15), [4] = Output Enable */ + uint8_t tx1EnableAck; /*!< Select desired GPIO pin (0-15), [4] = Output Enable */ + uint8_t tx2EnableAck; /*!< Select desired GPIO pin (0-15), [4] = Output Enable */ + uint8_t orx1EnableAck; /*!< Select desired GPIO pin (0-15), [4] = Output Enable */ + uint8_t orx2EnableAck; /*!< Select desired GPIO pin (0-15), [4] = Output Enable */ + uint8_t srxEnableAck; /*!< Select desired GPIO pin (0-15), [4] = Output Enable */ + uint8_t txObsSelect; /*!< Select desired GPIO pin (0-15), [4] = Output Enable */ + /* When 2Tx are used with only 1 ORx input, this GPIO tells the BBIC which Tx channel is */ + /* active for calibrations, so BBIC can route correct RF Tx path into the single ORx input */ +} mykonosArmGpioConfig_t; + +/** + * \brief Data structure to hold auxiliary IO settings (AuxDAC, ARM GPIO, GPIO3.3v, low voltage GPIO, HSCP, etc) + */ +typedef struct +{ + uint16_t auxDacEnable; /*!< Aux DAC enable. One bit per Aux DAC. Where bit[0] = Aux DAC 0, bit[1] = Aux DAC 1, etc */ + uint16_t auxDacValue[10]; /*!< Aux DAC value */ + uint8_t auxDacSlope[10]; /*!< Aux DAC slope */ + uint8_t auxDacVref[10]; /*!< Aux DAC voltage reference value */ + + mykonosGpio3v3_t *gpio3v3; /*!< GPIO 3.3 VDC settings data structure pointer */ + mykonosGpioLowVoltage_t *gpio; /*!< Low voltage GPIO settings data structure pointer */ + mykonosArmGpioConfig_t *armGpio; /*!< Mykonos ARM GPIO settings*/ +} mykonosAuxIo_t; + +/** + * \brief Data structure to hold digital clock settings + */ +typedef struct +{ + uint32_t deviceClock_kHz; /*!< CLKPLL and device reference clock frequency in kHz */ + uint32_t clkPllVcoFreq_kHz; /*!< CLKPLL VCO frequency in kHz */ + mykonosVcoDiv_t clkPllVcoDiv; /*!< CLKPLL VCO divider */ + uint8_t clkPllHsDiv; /*!< CLKPLL high speed clock divider */ +} mykonosDigClocks_t; + + +/** + * \brief Data structure used to read back the Init Calibration Status + */ +typedef struct +{ + uint32_t calsDoneLastRun; /*!< Init cals that completed in the last call to MYKONOS_runInitCals() */ + uint32_t calsDoneLifetime; /*!< Init cals that have completed successfully since loading of the ARM processor */ + uint32_t calsMinimum; /*!< Minimum set of init cals that must complete before device can move to radioOn state */ + uint8_t initErrCal; /*!< If an init cal had an error, this represents the opcode of the init cal that reported an error */ + uint8_t initErrCode; /*!< If an init cal had an error, this represents the ARM error code describing the failure */ +} mykonosInitCalStatus_t; + +/** + * \brief Data structure used to read back DPD calibration status + */ +typedef struct +{ + /** + * dpdErrorStatus (decimal) | Description + * --------------------------|----------------------- + * 0 | No Error + * 1 | ORX_DISABLED + * 2 | TX_DISABLED + * 3 | PATHDELAY_NOT_SETUP + * 4 | DPD_INIT_NOT_RUN + * 5 | ORX_SIG_TOO_LOW + * 6 | ORX_SIG_SATURATED + * 7 | TX_SIG_TOO_LOW + * 8 | TX_SIG_SATURATED + * 9 | MODEL_ERROR_HIGH + * 10 | AM_AM_OUTLIERS + * 11 | INVALID_TX_PROFILE + * 12 | ORX_TRACKING_DISABLED ORx tracking must be enabled + * 13 | Cal suspended + * 14 | Reserved + * 15 | Reserved + * 16 | Reserved + * 17 | Reserved + * 18 | Reserved + */ + uint32_t dpdErrorStatus; + uint32_t dpdTrackCount; /*!< Number of times DPD tracking has run since last reset */ + uint32_t dpdModelErrorPercent; /*!< Percent Error of PA model * 10 to include 1 decimal place */ + uint32_t dpdExtPathDelay; /*!< External path delay from Tx output to ORx input, at 1/16 sample resolution of ORx sample rate */ + uint16_t dpdMaxAdaptationCurrent; /*!< max amplitude of current adaptation */ + uint16_t dpdMaxAdaptation; /*!< max amplitude of adaptation since DPD started*/ + uint32_t dpdIterCount; /*!< number of times DPD tracking has run since last reset*/ +} mykonosDpdStatus_t; + +/** + * \brief Data structure used to read back CLGC calibration status + */ +typedef struct +{ + /** + * clgcErrorStatus(decimal) | Description + * -------------------------|----------------------- + * 0 | NO ERROR + * 1 | TX Disabled + * 2 | ORx is disabled + * 3 | Loopback switch is clo + * 4 | Data measurement aborted during capture + * 5 | No initial calibration was done + * 6 | Path delay not setup + * 7 | No apply control is possible + * 8 | Control value is out of range + * 9 | CLGC feature is disabled + * 10 | TX attenuation is capped + * 11 | Gain measurement + * 12 | No GPIO configured in single ORx configuration + * 13 | Tx is not observable with any of the ORx Channels + * 14 | ORX_TRACKING_DISABLED ORx tracking must be enabled + * 15 | PA Protection Activated + * 16 | Relative Threshold Violated + * 17 | RESERVED + * 18 | Tx power too low + * 19 | ORx power too low + */ + uint32_t errorStatus; + uint32_t trackCount; /*!< Number of times CLGC tracking has run since last reset */ + int32_t desiredGain; /*!< Desired gain/attenuation from Tx output to ORx input of Mykonos device. 0.01 dB resolution */ + int32_t currentGain; /*!< Current measured gain in 0.01 dB resolution. */ + uint32_t txGain; /*!< Current TxAttenuation setting, same as MYKONOS_getTx1/2Attenuation(), in 0.05dB resolution */ + int32_t txRms; /*!< Tx digital sample power measured at DPD block input (0.01 dB resolution) */ + int32_t orxRms; /*!< ORx digital sample power measured at ORx port (0.01 dB resolution) */ +} mykonosClgcStatus_t; + +/** + * \brief Data structure to hold Tx LOL Status + */ +typedef struct +{ + uint32_t errorCode; /*!< error code from Tx LOL */ + uint32_t percentComplete; /*!< percent of required data collected for the current cal. Range 0 to 100 */ + uint32_t performanceMetric; /*!< Variance of the corrections, and gives an indication in dB on how much LO leakage is corrected on an average tracking pass. */ + uint32_t iterCount; /*!< running counter that increments each time the cal runs to completion */ + uint32_t updateCount; /*!< running counter that increments each time the cal updates the correction/actuator hardware */ +} mykonosTxLolStatus_t; + +/** + * \brief This structure contains the internal path delay + * + */ +typedef struct +{ + uint32_t forwardPathDelayCh1; /*!< Forward path delay for Channel 1 valid range is from 0 to 4095 at 1/16 sample resolution of ORx sample rate */ + uint32_t reversePathDelayCh1; /*!< Reverse path delay for Channel 1 valid range is from 0 to 4095 at 1/16 sample resolution of ORx sample rate */ + uint32_t forwardPathDelayCh2; /*!< Forward path delay for Channel 2 valid range is from 0 to 4095 at 1/16 sample resolution of ORx sample rate */ + uint32_t reversePathDelayCh2; /*!< Reverse path delay for Channel 2 valid range is from 0 to 4095 at 1/16 sample resolution of ORx sample rate */ +} mykonosPathdelay_t; + +/** + * \brief This structure contains the DPD error status counters for the different errors + * + */ +typedef struct +{ + uint32_t dpdErrorCount; /*!< DPD total error count */ + uint32_t errorCounter[MYK_DPD_ERROR_END]; /*!< array for individual error counters corresponding to ::mykonosDpdErrors_t */ +} mykonosDpdErrorCounters_t; + +/** + * \brief Data structure to hold Tx QEC Status + */ +typedef struct +{ + uint32_t errorCode; /*!< error code from Tx QEC */ + uint32_t percentComplete; /*!< percent of required data collected for the current cal. Range 0 to 100 */ + uint32_t performanceMetric; /*!< Number of codes adjusted which is the number of codes of correction made last time which can be converted to an IRR power metric as with Rx QEC, if desired. */ + uint32_t iterCount; /*!< running counter that increments each time the cal runs to completion */ + uint32_t updateCount; /*!< running counter that increments each time the cal updates the correction/actuator hardware */ +} mykonosTxQecStatus_t; + +/** + * \brief Data structure to hold Rx QEC Status + */ +typedef struct +{ + uint32_t errorCode; /*!< error code from Rx QEC */ + uint32_t percentComplete; /*!< percent of required data collected for the current cal. Range 0 to 100 */ + uint32_t selfcheckIrrDb; /*!< selfCheckIrrdDb - Power-weighted average Image Rejection Ratio (IRR) in dBc. */ + uint32_t iterCount; /*!< running counter that increments each time the cal runs to completion */ + uint32_t updateCount; /*!< running counter that increments each time the cal updates the correction/actuator hardware */ +} mykonosRxQecStatus_t; + +/** + * \brief Data structure to hold Orx QEC Status + */ +typedef struct +{ + uint32_t errorCode; /*!< error code from Orx QEC */ + uint32_t percentComplete; /*!< percent of required data collected for the current cal. Range 0 to 100 */ + uint32_t selfcheckIrrDb; /*!< selfCheckIrrdDb - Power-weighted average Image Rejection Ratio (IRR) in dBc. */ + uint32_t iterCount; /*!< running counter that increments each time the cal runs to completion */ + uint32_t updateCount; /*!< running counter that increments each time the cal updates the correction/actuator hardware */ +} mykonosOrxQecStatus_t; + +/** + * \brief Data structure to hold Mykonos device settings + */ +typedef struct +{ + spiSettings_t *spiSettings; /*!< SPI settings data structure pointer */ + mykonosRxSettings_t *rx; /*!< Rx settings data structure pointer */ + mykonosTxSettings_t *tx; /*!< Tx settings data structure pointer */ + mykonosObsRxSettings_t *obsRx; /*!< ObsRx settings data structure pointer */ + mykonosAuxIo_t *auxIo; /*!< Auxiliary IO settings data structure pointer */ + mykonosDigClocks_t *clocks; /*!< Holds settings for CLKPLL and reference clock */ + uint8_t profilesValid; /*!< Mykonos initialize function uses this as an output to remember which profile data structure pointers are valid */ +} mykonosDevice_t; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/df_datalink_ge/src/hardware/mykonos/t_mykonos_gpio.h b/df_datalink_ge/src/hardware/mykonos/t_mykonos_gpio.h new file mode 100644 index 0000000..71f2cf9 --- /dev/null +++ b/df_datalink_ge/src/hardware/mykonos/t_mykonos_gpio.h @@ -0,0 +1,375 @@ +/*! + * \file t_mykonos_gpio.h + * \brief Mykonos GPIO error handling and type defines + * + * Mykonos API version: 1.5.2.3566 + */ + +/** +* \page Disclaimer Legal Disclaimer +* Copyright 2015-2017 Analog Devices Inc. +* Released under the AD9371 API license, for more information see the "LICENSE.txt" file in this zip file. +* +*/ + +#ifndef T_MYKONOSGPIO_H_ +#define T_MYKONOSGPIO_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "../common.h" + +/** + * \brief Enum of unique error codes from the Mykonos GPIO API functions. + * Each error condition in the library should get its own enum value to allow + * easy debug of errors. + */ +typedef enum +{ + MYKONOS_ERR_GPIO_OK = 0, + MYKONOS_ERR_EN_MONITOR_OUT_NOT_ENABLED, + MYKONOS_ERR_EN_MONITOR_OUT_SRC_CTRL, + MYKONOS_ERR_MONITOR_OUT_INDEX_RANGE, + MYKONOS_ERR_GETGPIOMON_INDEX_NULL_PARM, + MYKONOS_ERR_GETGPIOMON_MONITORMASK_NULL_PARM, + + MYKONOS_ERR_MGCRX2_GPIO_DECPIN_INV_PARAM, + MYKONOS_ERR_MGCRX2_GPIO_INCPIN_INV_PARAM, + MYKONOS_ERR_MGCRX2_SOURCE_CONFIG, + MYKONOS_ERR_MGCRX2_STEP_INV_PARAM, + MYKONOS_ERR_MGCRX1_GPIO_DECPIN_INV_PARAM, + MYKONOS_ERR_MGCRX1_GPIO_INCPIN_INV_PARAM, + MYKONOS_ERR_MGCRX1_STEP_INV_PARAM, + MYKONOS_ERR_GETRX2PIN_INCSTEP_NULL_PARM, + MYKONOS_ERR_GETRX2PIN_DECSTEP_NULL_PARM, + MYKONOS_ERR_GETRX2PIN_INCPIN_NULL_PARM, + MYKONOS_ERR_GETRX2PIN_DECPIN_NULL_PARM, + MYKONOS_ERR_GETRX2PIN_EN_NULL_PARM, + MYKONOS_ERR_GETRX1PIN_INCSTEP_NULL_PARM, + MYKONOS_ERR_GETRX1PIN_DECSTEP_NULL_PARM, + MYKONOS_ERR_GETRX1PIN_INCPIN_NULL_PARM, + MYKONOS_ERR_GETRX1PIN_DECPIN_NULL_PARM, + MYKONOS_ERR_GETRX1PIN_EN_NULL_PARM, + + MYKONOS_ERR_TPCTX2_GPIO_DECPIN_INV_PARAM, + MYKONOS_ERR_TPCTX2_GPIO_INCPIN_INV_PARAM, + MYKONOS_ERR_TPCTX2_GPIO_STEP_INV_PARAM, + MYKONOS_ERR_TPCTX1_GPIO_DECPIN_INV_PARAM, + MYKONOS_ERR_TPCTX1_GPIO_INCPIN_INV_PARAM, + MYKONOS_ERR_TPCTX1_GPIO_STEP_INV_PARAM, + MYKONOS_ERR_GETTX2PIN_STEP_NULL_PARM, + MYKONOS_ERR_GETTX2PIN_INC_NULL_PARM, + MYKONOS_ERR_GETTX2PIN_DEC_NULL_PARM, + MYKONOS_ERR_GETTX2PIN_EN_NULL_PARM, + MYKONOS_ERR_GETTX2PIN_TX1TX2_NULL_PARM, + MYKONOS_ERR_GETTX1PIN_STEP_NULL_PARM, + MYKONOS_ERR_GETTX1PIN_INC_NULL_PARM, + MYKONOS_ERR_GETTX1PIN_DEC_NULL_PARM, + MYKONOS_ERR_GETTX1PIN_EN_NULL_PARM, + MYKONOS_ERR_GETTX1PIN_TX1TX2_NULL_PARM, + + MYKONOS_ERR_SPI2_INV_GPIO, + MYKONOS_ERR_SPI2_INV_SETUP, + + MYKONOS_ERR_SET_GPIO_1V8_INV_POINTER, + + MYKONOS_ERR_GETGPIOSETLEVEL_NULL_PARM, + MYKONOS_ERR_READGPIOSPI_NULL_PARM, + MYKONOS_ERR_SET_GPIO_1V8_INV_MODE, + MYKONOS_ERR_GETGPIO_OE_NULL_PARM, + MYKONOS_ERR_GPIO_OE_INV_PARAM, + MYKONOS_ERR_GPIO_SRC_PARAM_INV, + MYKONOS_ERR_GET_GPIO_SOURCE_CONTROL_NULL_PARM, + + MYKONOS_ERR_INV_GP_INT_MASK_PARM, + MYKONOS_ERR_GP_INT_STATUS_NULL_PARAM, + + MYKONOS_ERR_GETGPIO3V3OUT_NULL_PARM, + MYKONOS_ERR_SET_GPIO_3V3_INV_POINTER, + MYKONOS_ERR_GETGPIO3V3SPI_NULL_PARM, + MYKONOS_ERR_GPIO3V3OUTEN_NULL_PARM, + MYKONOS_ERR_SET_GPIO_3V3_INV_MODE, + MYKONOS_ERR_SET_GPIO_3V3_INV_SRC_CTRL, + + MYKONOS_ERR_SET_ARMGPIO_INV_POINTER, + MYKONOS_ERR_SET_ARMGPIO_PINS_ARMERROR, + MYKONOS_ERR_SET_ARMGPIO_PINS_INV_SIGNALID, + MYKONOS_ERR_SET_ARMGPIO_PINS_INV_GPIOPIN, + + MYKONOS_ERR_SETUPAUXDAC_NULL_PARAM, + MYKONOS_ERR_WRITEAUXDAC_NULL_AUXIO, + MYKONOS_ERR_READAUXADC_NULL_PARAM, + MYKONOS_ERR_SETUPAUXDAC_INV_AUXDACCODE, + MYKONOS_ERR_WRITEAUXDAC_INV_AUXDACCODE, + MYKONOS_ERR_WRITEAUXDAC_INV_AUXDACINDEX, + MYKONOS_ERR_INV_AUX_ADC_CHAN_PARM, + MYKONOS_ERR_SETUPAUXADC_INV_VCODIV, + MYKONOS_ERR_INV_AUX_ADC_DEC_PARM, + + MYKONOS_ERR_GAINCOMP_NULL_STRUCT, + MYKONOS_ERR_GAINCOMP_EN_NULL_PARM, + MYKONOS_ERR_GAINCOMP_SET_NULL_STRUCT, + MYKONOS_ERR_GAINCOMP_INV_RX1_OFFSET, + MYKONOS_ERR_GAINCOMP_INV_RX2_OFFSET, + MYKONOS_ERR_GAINCOMP_INV_STEP, + MYKONOS_ERR_GAINCOMP_INV_EN, + + MYKONOS_ERR_OBS_RX_GAINCOMP_SET_NULL_STRUCT, + MYKONOS_ERR_OBS_RX_GAINCOMP_EN_NULL_PARAM, + MYKONOS_ERR_OBS_RX_GAINCOMP_INV_EN, + MYKONOS_ERR_OBS_RX_GAINCOMP_INV_OFFSET, + MYKONOS_ERR_OBS_RX_GAINCOMP_INV_STEP, + MYKONOS_ERR_OBS_RX_GAINCOMP_NULL_STRUCT, + + MYKONOS_ERR_SLICER_STEP_OUT_OF_RANGE, + MYKONOS_ERR_SLICER_INV_RX1_SEL, + MYKONOS_ERR_SLICER_INV_RX2_SEL, + MYKONOS_ERR_SLICER_EN_INV, + + MYKONOS_ERR_SLICER_RX1PIN_NULL_PARM, + MYKONOS_ERR_SLICER_RX2PIN_NULL_PARM, + MYKONOS_ERR_SLICER_STEP_NULL_PARM, + MYKONOS_ERR_SLICER_EN_NULL_PARM, + + MYKONOS_ERR_SLICER_INV_OBS_RX_SEL, + MYKONOS_ERR_SLICER_OBS_RX_STEP_OUT_OF_RANGE, + MYKONOS_ERR_SLICER_OBS_RX_EN_INV, + MYKONOS_ERR_SLICER_OBS_RX_EN_NULL_PARM, + MYKONOS_ERR_SLICER_OBS_RX_STEP_NULL_PARM, + MYKONOS_ERR_SLICER_OBS_RXPIN_NULL_PARM, + + MYKONOS_ERR_FLOATFRMT_NULL_STRUCT, + MYKONOS_ERR_FLOATFRMT_SET_NULL_STRUCT, + MYKONOS_ERR_FLOATFRMT_INV_ROUND_MODE, + MYKONOS_ERR_FLOATFRMT_INV_DATA_FORMAT, + MYKONOS_ERR_FLOATFRMT_INV_ENC_NAN, + MYKONOS_ERR_FLOATFRMT_INV_EXP_BITS, + MYKONOS_ERR_FLOATFRMT_INV_LEADING, + MYKONOS_ERR_FLOATFRMT_INV_RX1ATT, + MYKONOS_ERR_FLOATFRMT_INV_RX2ATT, + MYKONOS_ERR_FLOATFRMT_INV_EN, + MYKONOS_ERR_FLOATFRMT_NULL_RX1ATT, + MYKONOS_ERR_FLOATFRMT_NULL_RX2ATT, + MYKONOS_ERR_FLOATFRMT_NULL_ENABLE, + MYKONOS_ERR_FLOATFRMT_SET_INV_EN, + MYKONOS_ERR_FLOATFRMT_SET_INV_RX1ATT, + MYKONOS_ERR_FLOATFRMT_SET_INV_RX2ATT, + + MYKONOS_ERR_FLOATFRMT_INV_ORXATT, + MYKONOS_ERR_FLOATFRMT_INV_ORXEN, + MYKONOS_ERR_FLOATFRMT_NULL_ORXATT, + MYKONOS_ERR_FLOATFRMT_NULL_ORXENABLE, + + MYKONOS_ERR_SETUPTEMPSENSOR_NULL_PARAM, + MYKONOS_ERR_SETUPTEMPSENSOR_INV_TEMPDECIMATION, + MYKONOS_ERR_SETUPTEMPSENSOR_INV_OFFSET, + MYKONOS_ERR_SETUPTEMPSENSOR_INV_TEMPWINDOW, + MYKONOS_ERR_GETTEMPSENSORCFG_NULL_PARAM, + MYKONOS_ERR_READTEMPSENSOR_NULL_PARAM, + MYKONOS_ERR_READTEMPSENSOR_NOT_LOCKED, + + MYKONOS_ERR_GAIN_CONTROL_NOT_HYBRID, + MYKONOS_ERR_GPIO_HYBRID_RX1_PIN, + MYKONOS_ERR_GPIO_HYBRID_RX2_PIN, + MYKONOS_ERR_GPIO_HYBRID_RX1_PIN_NULL_PARM, + MYKONOS_ERR_GPIO_HYBRID_RX2_PIN_NULL_PARM, + MYKONOS_ERR_GPIO_HYBRID_RX1_PIN_READ, + MYKONOS_ERR_GPIO_HYBRID_RX2_PIN_READ, + MYKONOS_ERR_AGC_OBS_NOT_IN_HYBRID, + MYKONOS_ERR_GPIO_HYBRID_ORX_PIN, + MYKONOS_ERR_GPIO_HYBRID_ORX_PIN_NULL_PARM, + + MYKONOS_ERR_GAIN_CONTROL_NOT_AGC, + MYKONOS_ERR_GPIO_AGC_SYNC_RX1_PIN, + MYKONOS_ERR_GPIO_AGC_SYNC_RX2_PIN, + MYKONOS_ERR_GPIO_AGC_SYNC_RX1_PIN_NULL_PARM, + MYKONOS_ERR_GPIO_AGC_SYNC_RX2_PIN_NULL_PARM, + MYKONOS_ERR_OBS_GAIN_CONTROL_NOT_AGC, + MYKONOS_ERR_GPIO_AGC_SYNC_ORX_PIN, + MYKONOS_ERR_GPIO_AGC_SYNC_ORX_PIN_NULL_PARM, + + MYKONOS_ERR_GETGPIODRV_NULL_PARAM, + MYKONOS_ERR_GPIO_DRV_INV_PARAM, + + MYKONOS_ERR_GPIO_SLEW_RATE_INV_PARAM, + MYKONOS_ERR_GPIO_GETSLEW_NULL_PARAM, + + MYKONOS_ERR_CMOS_DRV_INV_PARAM, + MYKONOS_ERR_CMOS_DRV_NULL_PARAM +} mykonosGpioErr_t; + +/** + * \brief Enum of possible Rx Slicer pin combinations + */ +typedef enum +{ + GPIO_0_1_2 = 0, /*!< GPIO combination for RX1 */ + GPIO_5_6_7 = 1, /*!< GPIO combination for RX1 or RX2 */ + GPIO_8_9_10 = 2, /*!< GPIO combination for RX1 */ + GPIO_11_12_13 = 3 /*!< GPIO combination for RX2 */ +} mykonosRxSlicer_t; + +/** + * \brief Enum of possible observation channel Slicer pin combinations + */ +typedef enum +{ + GPIO_18_17_16 = 0, /*!< GPIO combination for observation channel */ + GPIO_16_15_14 = 1 /*!< GPIO combination for observation channel */ +} mykonosObsRxSlicer_t; + +/** + * \brief Enum of possible GPIO slew rate settings + */ +typedef enum +{ + MYK_SLEWRATE_NONE = 0, /*!< Lower slew rate for the GPIO */ + MYK_SLEWRATE_LOW = 1, /*!< Low slew rate for the GPIO */ + MYK_SLEWRATE_MEDIUM = 2, /*!< Medium slew rate for the GPIO */ + MYK_SLEWRATE_HIGH = 3 /*!< High slew rate for the GPIO */ +} mykonosGpioSlewRate_t; + +/** + * \brief Enumerated list of CMOS pads drive strength options + */ +typedef enum +{ + MYK_CMOSPAD_DRV_1X = 0x00, /*!< 2.5pF load @ 65MHz */ + MYK_CMOSPAD_DRV_2X = 0x01, /*!< 5pF load @ 65MHz */ + MYK_CMOSPAD_DRV_3X = 0x03, /*!< 7.5pF load @ 65MHz */ + MYK_CMOSPAD_DRV_4X = 0x07, /*!< 10pF load @ 65MHz */ + MYK_CMOSPAD_DRV_5X = 0x0F /*!< 12.5pF load @ 65MHz */ +} mykonosCmosPadDrvStr_t; + + +/** + * \brief Enumerated list for Aux ADCs + */ +typedef enum +{ + MYK_AUXADC_0 = 0x00, /*!< Aux ADC channel 0 */ + MYK_AUXADC_1 = 0x01, /*!< Aux ADC channel 1 */ + MYK_AUXADC_2 = 0x02, /*!< Aux ADC channel 2 */ + MYK_AUXADC_3 = 0x03, /*!< Aux ADC channel 3 */ + MYK_AUXADC_0_DIV2 = 0x04, /*!< Aux ADC channel 0 with the divider by 2 set */ + MYK_TEMPSENSOR = 0x10 /*!< Temperature sensor channel */ +} mykonosAuxAdcChannels_t; + + +/** + * \brief Data structure to hold Gain compensation settings for the main receive channels + **/ +typedef struct +{ + uint8_t rx1Offset; /*!< These parameter contains the Rx1 offset word used for the gain compensation + when the gain index is at its maximum setting. + It has a range of 0 to 0x1F with a resolution is 0.5dB per LSB. */ + uint8_t rx2Offset; /*!< These parameter contains the Rx2 offset word used for the gain compensation + when the gain index is at its maximum setting. + It has a range of 0 to 0x1F with a resolution is 0.5dB per LSB. */ + uint8_t compStep; /*!< These bits contains the value in dB that the total Rx gain changes + when there is an LSB change in the gain index according to the following settings: + compStep | dB ramp + ---------|------------ + 0 | 0.25dB + 1 | 0.5dB + 2 | 1.0dB + 3 | 2.0dB + 4 | 3.0dB + 5 | 4.0dB + 6 | 6.0dB + 7 | Not valid defaulted to 0.25dB */ +} mykonosGainComp_t; + +/** + * \brief Data structure to hold Gain compensation settings for the observation channel + **/ +typedef struct +{ + uint8_t obsRxOffset; /*!< These parameter contains the Rx1 offset word used for the gain compensation + when the gain index is at its maximum setting. + It has a range of 0 to 0x1F with a resolution is 0.5dB per LSB. */ + uint8_t compStep; /*!< These bits contains the value in dB that the total Rx gain changes + when there is an LSB change in the gain index according to the following settings: + compStep | dB ramp + ---------|------------ + 0 | 0.25dB + 1 | 0.5dB + 2 | 1.0dB + 3 | 2.0dB + 4 | 3.0dB + 5 | 4.0dB + 6 | 6.0dB + 7 | Not valid defaulted to 0.25dB */ +} mykonosObsRxGainComp_t; + +/** + * \brief Data structure to hold floating point formatter settings for the floating point + * number generation + **/ +typedef struct +{ + uint8_t roundMode; /*! +#include +#include "platform_drivers.h" + +/******************************************************************************/ +/************************ Functions Definitions *******************************/ +/******************************************************************************/ + +/** + * @brief Initialize the I2C communication peripheral. + * @param desc - The I2C descriptor. + * @param init_param - The structure that contains the I2C parameters. + * @return SUCCESS in case of success, FAILURE otherwise. + */ +int32_t i2c_init(struct i2c_desc **desc, + const struct i2c_init_param *param) +{ + if (desc) { + // Unused variable - fix compiler warning + } + + if (param->type) { + // Unused variable - fix compiler warning + } + + return SUCCESS; +} + +/** + * @brief Free the resources allocated by i2c_init(). + * @param desc - The I2C descriptor. + * @return SUCCESS in case of success, FAILURE otherwise. + */ +int32_t i2c_remove(struct i2c_desc *desc) +{ + if (desc) { + // Unused variable - fix compiler warning + } + + return SUCCESS; +} + +/** + * @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 SUCCESS in case of success, FAILURE otherwise. + */ +int32_t i2c_write(struct i2c_desc *desc, + uint8_t *data, + uint8_t bytes_number, + uint8_t stop_bit) +{ + if (desc) { + // Unused variable - fix compiler warning + } + + if (data) { + // Unused variable - fix compiler warning + } + + if (bytes_number) { + // Unused variable - fix compiler warning + } + + if (stop_bit) { + // Unused variable - fix compiler warning + } + + return SUCCESS; +} + +/** + * @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 SUCCESS in case of success, FAILURE otherwise. + */ +int32_t i2c_read(struct i2c_desc *desc, + uint8_t *data, + uint8_t bytes_number, + uint8_t stop_bit) +{ + if (desc) { + // Unused variable - fix compiler warning + } + + if (data) { + // Unused variable - fix compiler warning + } + + if (bytes_number) { + // Unused variable - fix compiler warning + } + + if (stop_bit) { + // Unused variable - fix compiler warning + } + + return SUCCESS; +} + +/** + * @brief Initialize the SPI communication peripheral. + * @param desc - The SPI descriptor. + * @param init_param - The structure that contains the SPI parameters. + * @return SUCCESS in case of success, FAILURE otherwise. + */ +int32_t spi_init(struct spi_desc **desc, + const struct spi_init_param *param) +{ + spi_desc *descriptor; + int32_t ret; + + descriptor = (struct spi_desc *) calloc(1, sizeof(*descriptor)); + if (!descriptor) + return FAILURE; + + descriptor->mode = param->mode; + descriptor->chip_select = param->chip_select; + descriptor->flags = param->flags; + +#ifdef _XPARAMETERS_PS_H_ + descriptor->config = XSpiPs_LookupConfig(param->id); + if (descriptor->config == NULL) + goto error; + + ret = XSpiPs_CfgInitialize(&descriptor->instance, + descriptor->config, descriptor->config->BaseAddress); + if (ret != 0) + goto error; + + XSpiPs_SetOptions(&descriptor->instance, + XSPIPS_MASTER_OPTION | + ((descriptor->flags & SPI_CS_DECODE) ? + XSPIPS_DECODE_SSELECT_OPTION : 0) | + XSPIPS_FORCE_SSELECT_OPTION | + ((descriptor->mode & SPI_CPOL) ? + XSPIPS_CLK_ACTIVE_LOW_OPTION : 0) | + ((descriptor->mode & SPI_CPHA) ? + XSPIPS_CLK_PHASE_1_OPTION : 0)); + + XSpiPs_SetClkPrescaler(&descriptor->instance, + XSPIPS_CLK_PRESCALE_64); + + XSpiPs_SetSlaveSelect(&descriptor->instance, 0xf); +#else + ret = XSpi_Initialize(&descriptor->instance, param->id); + if (ret != 0) + goto error; + + XSpi_SetOptions(&descriptor->instance, + XSP_MASTER_OPTION | + ((descriptor->mode & SPI_CPOL) ? + XSP_CLK_ACTIVE_LOW_OPTION : 0) | + ((descriptor->mode & SPI_CPHA) ? + XSP_CLK_PHASE_1_OPTION : 0)); + + XSpi_Start(&descriptor->instance); + + XSpi_IntrGlobalDisable(&descriptor->instance); +#endif + + *desc = descriptor; + + return SUCCESS; + +error: + free(descriptor); + + return FAILURE; +} + +/** + * @brief Free the resources allocated by spi_init(). + * @param desc - The SPI descriptor. + * @return SUCCESS in case of success, FAILURE otherwise. + */ +int32_t spi_remove(struct spi_desc *desc) +{ + if (desc) { + // Unused variable - fix compiler warning + } + + return SUCCESS; +} + +/** + * @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 SUCCESS in case of success, FAILURE otherwise. + */ + +int32_t spi_write_and_read(struct spi_desc *desc, + uint8_t *data, + uint8_t bytes_number) +{ +#ifdef _XPARAMETERS_PS_H_ + XSpiPs_SetOptions(&desc->instance, + XSPIPS_MASTER_OPTION | + ((desc->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)); + + XSpiPs_SetSlaveSelect(&desc->instance, desc->chip_select); + // 0xf & ~desc->chip_select); + XSpiPs_PolledTransfer(&desc->instance, + data, data, bytes_number); +#else + XSpi_SetOptions(&desc->instance, + XSP_MASTER_OPTION | + ((desc->mode & SPI_CPOL) ? + XSP_CLK_ACTIVE_LOW_OPTION : 0) | + ((desc->mode & SPI_CPHA) ? + XSP_CLK_PHASE_1_OPTION : 0)); + + XSpi_SetSlaveSelect(&desc->instance, + desc->chip_select); + + XSpi_Transfer(&desc->instance, + data, data, bytes_number); +#endif + return 0; +} + +/** + * @brief Obtain the GPIO decriptor. + * @param desc - The GPIO descriptor. + * @param gpio_number - The number of the GPIO. + * @return SUCCESS in case of success, FAILURE otherwise. + */ +int32_t gpio_get(struct gpio_desc **desc, + uint8_t gpio_number) +{ + gpio_desc *descriptor; + int32_t ret; + + descriptor = (struct gpio_desc *) malloc(sizeof(*descriptor)); + if (!descriptor) + return FAILURE; + +#ifdef _XPARAMETERS_PS_H_ + descriptor->config = XGpioPs_LookupConfig(0); + if (descriptor->config == NULL) + goto error; + + ret = XGpioPs_CfgInitialize(&descriptor->instance, + descriptor->config, descriptor->config->BaseAddr); + if (ret != 0) + goto error; +#else + ret = XGpio_Initialize(&descriptor->instance, 0); + if (ret != 0) + goto error; +#endif + + descriptor->number = gpio_number; + + *desc = descriptor; + + return SUCCESS; + +error: + free(descriptor); + + return FAILURE; +} + +/** + * @brief Free the resources allocated by gpio_get(). + * @param desc - The SPI descriptor. + * @return SUCCESS in case of success, FAILURE otherwise. + */ +int32_t gpio_remove(struct gpio_desc *desc) +{ + if (desc) { + // Unused variable - fix compiler warning + } + + return SUCCESS; +} + +/** + * @brief Enable the input direction of the specified GPIO. + * @param desc - The GPIO descriptor. + * @return SUCCESS in case of success, FAILURE otherwise. + */ +int32_t gpio_direction_input(struct gpio_desc *desc) +{ + if (desc) { + // Unused variable - fix compiler warning + } + + 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 SUCCESS in case of success, FAILURE otherwise. + */ +int32_t gpio_direction_output(struct gpio_desc *desc, + uint8_t value) +{ +#ifdef _XPARAMETERS_PS_H_ + XGpioPs_SetDirectionPin(&desc->instance, desc->number, 1); + + XGpioPs_SetOutputEnablePin(&desc->instance, desc->number, 1); + + XGpioPs_WritePin(&desc->instance, desc->number, value); +#else + uint8_t pin = desc->number; + uint8_t channel; + uint32_t reg_val; + + if (pin >= 32) { + channel = 2; + pin -= 32; + } else + channel = 1; + + reg_val = XGpio_GetDataDirection(&desc->instance, channel); + reg_val &= ~(1 << pin); + XGpio_SetDataDirection(&desc->instance, channel, reg_val); + + reg_val = XGpio_DiscreteRead(&desc->instance, channel); + if(value) + reg_val |= (1 << pin); + else + reg_val &= ~(1 << pin); + XGpio_DiscreteWrite(&desc->instance, channel, reg_val); +#endif + + return SUCCESS; +} + +/** + * @brief Get the direction of the specified GPIO. + * @param desc - The GPIO descriptor. + * @param direction - The direction. + * Example: GPIO_OUT + * GPIO_IN + * @return SUCCESS in case of success, FAILURE otherwise. + */ +int32_t gpio_get_direction(struct gpio_desc *desc, + uint8_t *direction) +{ + if (desc) { + // Unused variable - fix compiler warning + } + + if (direction) { + // Unused variable - fix compiler warning + } + + 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 SUCCESS in case of success, FAILURE otherwise. + */ +int32_t gpio_set_value(struct gpio_desc *desc, + uint8_t value) +{ +#ifdef _XPARAMETERS_PS_H_ + XGpioPs_WritePin(&desc->instance, desc->number, value); +#else + uint8_t pin = desc->number; + uint8_t channel; + uint32_t reg_val; + + if (pin >= 32) { + channel = 2; + pin -= 32; + } else + channel = 1; + + reg_val = XGpio_DiscreteRead(&desc->instance, channel); + if(value) + reg_val |= (1 << pin); + else + reg_val &= ~(1 << pin); + XGpio_DiscreteWrite(&desc->instance, channel, reg_val); +#endif + + 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 SUCCESS in case of success, FAILURE otherwise. + */ +int32_t gpio_get_value(struct gpio_desc *desc, + uint8_t *value) +{ + if (desc) { + // Unused variable - fix compiler warning + } + + if (value) { + // Unused variable - fix compiler warning + } + + return 0; +} + +/** + * @brief Generate microseconds delay. + * @param usecs - Delay in microseconds. + * @return None. + */ +void udelay(uint32_t usecs) +{ + usleep(usecs); +} + +/** + * @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(msecs * 50); // FIXME +#endif +} diff --git a/df_datalink_ge/src/hardware/platform_drivers.h b/df_datalink_ge/src/hardware/platform_drivers.h new file mode 100644 index 0000000..5a744b9 --- /dev/null +++ b/df_datalink_ge/src/hardware/platform_drivers.h @@ -0,0 +1,223 @@ +/***************************************************************************//** + * @file platform_drivers.h + * @brief Header file of Xilinx Platform Drivers. + * @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 PLATFORM_DRIVERS_H_ +#define PLATFORM_DRIVERS_H_ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ +#include +#include +#ifdef _XPARAMETERS_PS_H_ +#include +#include +#else +#include +#include +#endif + +/******************************************************************************/ +/********************** Macros and Constants Definitions **********************/ +/******************************************************************************/ + +#define SUCCESS 0 +#define FAILURE -1 + +#define SPI_CPHA 0x01 +#define SPI_CPOL 0x02 + +#define SPI_CS_DECODE 0x01 +#define SPI_CS_DECODE_DISABLE 0x00 + +#define GPIO_OUT 0x01 +#define GPIO_IN 0x00 + +#define GPIO_HIGH 0x01 +#define GPIO_LOW 0x00 + +/******************************************************************************/ +/*************************** Types Declarations *******************************/ +/******************************************************************************/ + +typedef enum i2c_type { + XILINX_I2C +} i2c_type; + +typedef struct i2c_init_param { + enum i2c_type type; + uint32_t id; + uint32_t max_speed_hz; + uint8_t slave_address; +} i2c_init_param; + +typedef struct i2c_desc { + enum i2c_type type; + uint32_t id; + uint32_t max_speed_hz; + uint8_t slave_address; +} i2c_desc; + +typedef enum spi_type { + XILINX_SPI +} spi_type; + +/** + * @enum spi_mode + * @brief SPI configuration for clock phase and polarity. + */ +typedef 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 falling, shift out on rising */ + SPI_MODE_2 = (SPI_CPOL | 0), + /** Data on rising, shift out on falling */ + SPI_MODE_3 = (SPI_CPOL | SPI_CPHA) +} spi_mode; + +typedef struct spi_init_param { + enum spi_type type; + uint32_t id; + uint32_t max_speed_hz; + enum spi_mode mode; + uint8_t chip_select; + uint32_t flags; +} spi_init_param; + +typedef struct spi_desc { + enum spi_type type; + uint32_t id; + uint32_t max_speed_hz; + enum spi_mode mode; + uint8_t chip_select; + uint32_t flags; +#ifdef _XPARAMETERS_PS_H_ + XSpiPs_Config *config; + XSpiPs instance; +#else + XSpi instance; +#endif +} spi_desc; + +typedef enum gpio_type { + XILINX_GPIO +} gpio_type; + +typedef struct gpio_desc { + enum gpio_type type; + uint32_t id; + uint8_t number; +#ifdef _XPARAMETERS_PS_H_ + XGpioPs_Config *config; + XGpioPs instance; +#else + XGpio instance; +#endif +} gpio_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); + +/* 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, + uint8_t bytes_number); + +/* Obtain the GPIO decriptor. */ +int32_t gpio_get(struct gpio_desc **desc, + uint8_t gpio_number); + +/* 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); + +/* Generate microseconds delay. */ +void udelay(uint32_t usecs); + +/* Generate miliseconds delay. */ +void mdelay(uint32_t msecs); + +#endif // PLATFORM_DRIVERS_H_ diff --git a/df_datalink_ge/src/include/axi_io.h b/df_datalink_ge/src/include/axi_io.h new file mode 100644 index 0000000..ac8b67d --- /dev/null +++ b/df_datalink_ge/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_ge/src/include/circ_queue.h b/df_datalink_ge/src/include/circ_queue.h new file mode 100644 index 0000000..a6dc655 --- /dev/null +++ b/df_datalink_ge/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_ge/src/include/clist.h b/df_datalink_ge/src/include/clist.h new file mode 100644 index 0000000..8a2e925 --- /dev/null +++ b/df_datalink_ge/src/include/clist.h @@ -0,0 +1,118 @@ + +// +// clist.h +// +// Copyright (c) 2010 TJ Holowaychuk +// + +#ifndef __CLIST_H__ +#define __CLIST_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include + + /* + * clist_t iterator direction. + */ + + typedef enum + { + LIST_HEAD, + LIST_TAIL + } clist_direction_t; + + /* + * clist_t node struct. + */ + + typedef struct clist_node + { + struct clist_node *prev; + struct clist_node *next; + void *val; + } clist_node_t; + + /* + * clist_t struct. + */ + + typedef struct + { + clist_node_t *head; + clist_node_t *tail; + uint32_t len; + void (*free)(void *val); + int8_t (*compare)(void *a, void *b); + } clist_t; + + /* + * clist_t iterator struct. + */ + + typedef struct + { + clist_node_t *next; + clist_direction_t direction; + } clist_iterator_t; + + // Node prototypes. + + clist_node_t * + clist_node_new(void *val); + + // clist_t prototypes. + + clist_t * + clist_new(void); + + clist_node_t * + clist_rpush(clist_t *self, clist_node_t *node); + + clist_node_t * + clist_lpush(clist_t *self, clist_node_t *node); + + clist_node_t * + clist_find(clist_t *self, void *val); + + clist_node_t * + clist_at(clist_t *self, int index); + + clist_node_t * + clist_rpop(clist_t *self); + + clist_node_t * + clist_lpop(clist_t *self); + + void + clist_remove(clist_t *self, clist_node_t *node); + + void + clist_clear(clist_t *self); + + void + clist_destroy(clist_t *self); + + // clist_t iterator prototypes. + + clist_iterator_t * + clist_iterator_new(clist_t *list, clist_direction_t direction); + + clist_iterator_t * + clist_iterator_new_from_node(clist_node_t *node, clist_direction_t direction); + + clist_node_t * + clist_iterator_next(clist_iterator_t *self); + + void + clist_iterator_destroy(clist_iterator_t *self); + +#ifdef __cplusplus +} +#endif + +#endif /* __CLIBS_LIST_H__ */ diff --git a/df_datalink_ge/src/include/common.h b/df_datalink_ge/src/include/common.h new file mode 100644 index 0000000..b5edcc2 --- /dev/null +++ b/df_datalink_ge/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_ge/src/include/error.h b/df_datalink_ge/src/include/error.h new file mode 100644 index 0000000..1e20199 --- /dev/null +++ b/df_datalink_ge/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_ge/src/include/global_timer.h b/df_datalink_ge/src/include/global_timer.h new file mode 100644 index 0000000..d0572ed --- /dev/null +++ b/df_datalink_ge/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_ge/src/include/gpio.h b/df_datalink_ge/src/include/gpio.h new file mode 100644 index 0000000..fb2c113 --- /dev/null +++ b/df_datalink_ge/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_ge/src/include/irq.h b/df_datalink_ge/src/include/irq.h new file mode 100644 index 0000000..34fa6c4 --- /dev/null +++ b/df_datalink_ge/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_ge/src/include/list.h b/df_datalink_ge/src/include/list.h new file mode 100644 index 0000000..517a51c --- /dev/null +++ b/df_datalink_ge/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_ge/src/include/timer.h b/df_datalink_ge/src/include/timer.h new file mode 100644 index 0000000..99ee4f4 --- /dev/null +++ b/df_datalink_ge/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_ge/src/include/trng.h b/df_datalink_ge/src/include/trng.h new file mode 100644 index 0000000..1c469b3 --- /dev/null +++ b/df_datalink_ge/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_ge/src/include/util.h b/df_datalink_ge/src/include/util.h new file mode 100644 index 0000000..a4a4608 --- /dev/null +++ b/df_datalink_ge/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_ge/src/lscript.ld b/df_datalink_ge/src/lscript.ld new file mode 100644 index 0000000..9ca5b4b --- /dev/null +++ b/df_datalink_ge/src/lscript.ld @@ -0,0 +1,292 @@ +/*******************************************************************/ +/* */ +/* 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_tx_frame_bram_ctrl_Mem0 : ORIGIN = 0x40000000, LENGTH = 0x2000 + phy_data_interface_ant_info_bram_ctrl_Mem0 : ORIGIN = 0x42000000, LENGTH = 0x2000 + mpc_bram_interface_mpc_bram_ctrl_Mem0 : ORIGIN = 0x44000000, LENGTH = 0x8000 + phy_data_interface_rx_frame_bram_ctrl_Mem0 : ORIGIN = 0x46000000, 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_ge/src/main.c b/df_datalink_ge/src/main.c new file mode 100644 index 0000000..11e54bc --- /dev/null +++ b/df_datalink_ge/src/main.c @@ -0,0 +1,505 @@ +/*****************************************************************************/ +/** + * Description: main.c + * + + * Date: 2021-11-13 13:19 + * Last Editors: Fan Hao + * Last Edit Time: [2022-03-28 20:32] + * + * Revisions: Rev 0.0 + * History: + * [2021-11-13]: Initial edition. + * [2022-03-28]: Add bit error test mode. + * + * Copyright(c) 2021 Beijing Institute of Technology. + * Lab of Communication and Networking + * + ******************************************************************************/ + +/***************************** 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" +// 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" +// RF-Driver +#include "hardware/headless.h" +#include "hardware/platform_drivers.h" + +/************************** Function Prototypes ******************************/ +int32_t SetupInterruptSystem(struct irq_ctrl_desc *descPtr); +void Phy_IntrHandler(void *context); +void PeriodicPull_Handler(void *callBackRef); +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 periodicpull_callback_desc = { + .callback = PeriodicPull_Handler, + .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 L2_CONFIG linkConfig = { + .myType = L2_NODE_HEAD, + .clustId = 1, + .myId = 1, + .headId = 1, + .bkpHeadId = 0, + .netScale = 2, + .phyInstPtr = NULL, // pyhsical layer reference + .tmcInstPtr = NULL +}; + +// static L2_CONFIG linkConfig = { +// .myType = L2_NODE_MEMBER, +// .clustId = 1, +// .myId = 2, +// .headId = 1, +// .bkpHeadId = 0, +// .netScale = 2, +// .phyInstPtr = NULL, // pyhsical layer reference +// .tmcInstPtr = 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 +}; + +TIMECTRL_CONFIG tmcConfig = { + .baseAddr = 0, //TIME_CONTROLLER_BASEADDR, + .reset = 10 +}; + +//static SYSBUS_CONFIG sysbusConfig = { +// .baseAddr = SYSBUS_BASE_ADDR, +// .txQueueMax = 16, +// .rxQueueMax = 16 +//}; +/************************** Function Prototypes ******************************/ +static struct irq_ctrl_desc *intcDescPtr; // General interrupt controller descriptor +static struct timer_desc *logTmPtr; +static SYSBUS *sysbusDescPtr; +static PHY_INST *phyInstPtr; +static TIMECTRL_INST *tmcInstPtr = NULL; +static L2_INST *linkInstPtr; + +/****************************************************************************/ +/** + * 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, 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, PHY_INTR_ID, &phy_callback_desc); + if (Status != SUCCESS) + { + DBG_ERROR("PHY_INTR register callback FAILED, ErrorCode: %ld.\n", Status); + return Status; + } + + /* Initialize linklayer layer interrupt. */ + Status = irq_trigger_level_set(descPtr, PERIODIC_5MS_INTR_ID, IRQ_EDGE_RISING); + if (Status != SUCCESS) + { + DBG_ERROR("PERIODIC_5MS_INTR_ID trigger level set FAILED, ErrorCode: %ld.\n", Status); + return Status; + } + // Set highest interrupt priority + Status = irq_set_priority(descPtr, PERIODIC_5MS_INTR_ID, 0x00); + if (Status != SUCCESS) + { + DBG_ERROR("PERIODIC_5MS_INTR_ID 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, &periodicpull_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, 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_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, 0x18); +// 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, PERIODIC_5MS_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) +{ + Phy_UpdateState(phyInstPtr); +} // PhyIntr_Handler + + +/****************************************************************************/ +/** + * Handler of periodic 5ms interrupt + * + * @param callBackRef is the linklayer instance pointer. + * + * @return None. + * + *****************************************************************************/ +void PeriodicPull_Handler(void *callBackRef) +{ + int32_t Status; + Status = Linklayer_Proc(linkInstPtr); + if (Status != SUCCESS) + { + DBG_ERROR("Link layer runs failed, with error code: %ld\n", Status); + _nop_(); + } +} // PeriodicPull_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 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_initialize(); + if (Status == SUCCESS) + { + DBG_PRINT("Hardware Init SUCCESS! \n"); + } + else + { + DBG_PRINT("Hardware Init FAILED! \n"); + return Status; + } + + // Init time controller + Status = TimeCtrl_Init(&tmcInstPtr, &tmcConfig); + if (Status == SUCCESS) + { + DBG_PRINT("TmcCtrl Init SUCCESS! \n"); + } + else + { + DBG_PRINT("TmcCtrl 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.phyInstPtr = phyInstPtr; + linkConfig.tmcInstPtr = tmcInstPtr; + 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); + + DBG_PRINT("Physical started...\n"); + Phy_Start(phyInstPtr); + + Linklayer_Start(linkInstPtr); + + 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_ge/src/networking b/df_datalink_ge/src/networking new file mode 120000 index 0000000..0c2f40a --- /dev/null +++ b/df_datalink_ge/src/networking @@ -0,0 +1 @@ +../../df_datalink_sp/src/networking \ No newline at end of file diff --git a/df_datalink_ge/src/system_monitor.c b/df_datalink_ge/src/system_monitor.c new file mode 120000 index 0000000..d8d8d8a --- /dev/null +++ b/df_datalink_ge/src/system_monitor.c @@ -0,0 +1 @@ +../../df_datalink_sp/src/system_monitor.c \ No newline at end of file diff --git a/df_datalink_ge/src/system_monitor.h b/df_datalink_ge/src/system_monitor.h new file mode 120000 index 0000000..44c445a --- /dev/null +++ b/df_datalink_ge/src/system_monitor.h @@ -0,0 +1 @@ +../../df_datalink_sp/src/system_monitor.h \ No newline at end of file diff --git a/df_datalink_ge/src/systembus b/df_datalink_ge/src/systembus new file mode 120000 index 0000000..b447a96 --- /dev/null +++ b/df_datalink_ge/src/systembus @@ -0,0 +1 @@ +../../df_datalink_sp/src/systembus \ No newline at end of file diff --git a/df_datalink_ge/src/time_ctrl b/df_datalink_ge/src/time_ctrl new file mode 120000 index 0000000..c7914a4 --- /dev/null +++ b/df_datalink_ge/src/time_ctrl @@ -0,0 +1 @@ +../../df_datalink_sp/src/time_ctrl \ No newline at end of file diff --git a/df_datalink_ge/src/util b/df_datalink_ge/src/util new file mode 120000 index 0000000..1a9a737 --- /dev/null +++ b/df_datalink_ge/src/util @@ -0,0 +1 @@ +../../df_datalink_sp/src/util \ No newline at end of file